From d302f9db62ee0f443a9c5273d6fed846b844e4e0 Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Mon, 13 Nov 2023 10:28:53 +0100 Subject: [PATCH 01/26] GH-2569: Content assist not working at specific location in code (#2570) * add tests * fix --- .../N4JSContentAssistContextFactory.java | 80 +++++++++++++++++++ .../xt-tests/contentassist/GH_2569a.n4js.xt | 35 ++++++++ .../xt-tests/contentassist/GH_2569b.n4js.xt | 40 ++++++++++ 3 files changed, 155 insertions(+) create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/contentassist/GH_2569a.n4js.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/contentassist/GH_2569b.n4js.xt diff --git a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/editor/contentassist/N4JSContentAssistContextFactory.java b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/editor/contentassist/N4JSContentAssistContextFactory.java index ed0fe1facf..bc4f7ba987 100644 --- a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/editor/contentassist/N4JSContentAssistContextFactory.java +++ b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/editor/contentassist/N4JSContentAssistContextFactory.java @@ -28,10 +28,18 @@ import org.eclipse.xtext.RuleCall; import org.eclipse.xtext.ide.editor.contentassist.ContentAssistContext; import org.eclipse.xtext.ide.editor.contentassist.antlr.ContentAssistContextFactory; +import org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElement; import org.eclipse.xtext.ide.editor.contentassist.antlr.PartialContentAssistContextFactory; +import org.eclipse.xtext.nodemodel.ICompositeNode; +import org.eclipse.xtext.nodemodel.ILeafNode; import org.eclipse.xtext.nodemodel.INode; +import org.eclipse.xtext.nodemodel.impl.CompositeNode; +import org.eclipse.xtext.nodemodel.util.NodeModelUtils; import org.eclipse.xtext.parser.IParseResult; +import org.eclipse.xtext.util.ITextRegion; +import org.eclipse.xtext.util.TextRegion; +import com.google.common.base.Strings; import com.google.common.collect.Multimap; import com.google.inject.Inject; @@ -102,4 +110,76 @@ protected ContentAssistContext[] doCreateContexts(int offset) { return super.doCreateContexts(offset); } } + + @Override + protected void handleLastCompleteNodeAsPartOfDatatypeNode() { + String prefix = getPrefix(datatypeNode); + Collection followElements = parseFollowElements(datatypeNode.getOffset(), false); + if (followElements.isEmpty()) { + // modification wrt. to superclass: no follow elements indicate situation where an identifier is incomplete + // in a single line. Grammar wise this is correct, but scoping wise this identifier cannot be found. Hence + // completion would be necessary. + handleLastCompleteNodeIsAtEndOfDatatypeNode(); + + } else { + INode lastCompleteNodeBeforeDatatype = getLastCompleteNodeByOffset(rootNode, datatypeNode.getTotalOffset()); + doCreateContexts(lastCompleteNodeBeforeDatatype, datatypeNode, prefix, currentModel, followElements); + } + } + + @Override + protected void handleLastCompleteNodeIsAtEndOfDatatypeNode() { + String prefix = getPrefix(lastCompleteNode); + INode previousNode = getLastCompleteNodeByOffset(rootNode, lastCompleteNode.getOffset()); + EObject previousModel = previousNode.getSemanticElement(); + INode currentDatatypeNode = getContainingDatatypeRuleNode(currentNode); + Collection followElements = parseFollowElements(lastCompleteNode.getOffset(), false); + + if (followElements.isEmpty() && !Strings.isNullOrEmpty(prefix)) { + // modification wrt. to superclass: no follow elements indicate situation where an identifier is incomplete + // in a single line. Grammar wise this is correct, but scoping wise this identifier cannot be found. Hence + // completion would be necessary. + + ContentAssistContext.Builder ctxBuilder = contentAssistContextProvider.get(); + ctxBuilder.setRootNode(rootNode); + ctxBuilder.setLastCompleteNode(lastCompleteNode); + ctxBuilder.setCurrentNode(currentNode); + ctxBuilder.setRootModel(parseResult.getRootASTElement()); + ctxBuilder.setCurrentModel(currentModel); + ctxBuilder.setPreviousModel(previousModel); + ctxBuilder.setOffset(completionOffset); + ctxBuilder.setPrefix(prefix); + int regionLength = prefix.length(); + if (selection.getLength() > 0) { + regionLength = regionLength + selection.getLength(); + } + ITextRegion region = new TextRegion(completionOffset - prefix.length(), regionLength); + if (selection.getOffset() >= 0 && selection.getLength() >= 0) { + ctxBuilder.setSelectedText(prefix); + } + ctxBuilder.setReplaceRegion(region); + ctxBuilder.setResource(resource); + + ICompositeNode curNode = NodeModelUtils.getNode(currentModel); + if (curNode instanceof CompositeNode) { + CompositeNode curCompNode = (CompositeNode) curNode; + ICompositeNode synParent = curCompNode.resolveAsParent(); + EObject grammarElement = synParent.getGrammarElement(); + if (grammarElement instanceof CrossReference) { + ctxBuilder.accept((AbstractElement) grammarElement); + contextBuilders.add(ctxBuilder); + } + } + + } else { + int prevSize = contextBuilders.size(); + doCreateContexts(previousNode, currentDatatypeNode, prefix, previousModel, followElements); + + if (lastCompleteNode instanceof ILeafNode && lastCompleteNode.getGrammarElement() == null + && contextBuilders.size() != prevSize) { + handleLastCompleteNodeHasNoGrammarElement(contextBuilders.subList(prevSize, contextBuilders.size()), + previousModel); + } + } + } } diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/contentassist/GH_2569a.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/contentassist/GH_2569a.n4js.xt new file mode 100644 index 0000000000..3d9ae9006c --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/contentassist/GH_2569a.n4js.xt @@ -0,0 +1,35 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest + + File "RequestHeader.n4js" { + export enum RequestHeader { + AcceptLanguage: "accept-language", + Origin: "origin", + Host: "host" + } + } + + END_SETUP + */ + + + +function *generator() { + if (true) { + yield 2; + } + // XPECT errors --> "Couldn't resolve reference to IdentifiableElement 'RequestH'." at "RequestH" + // XPECT completion at 'RequestH<|>' --> RequestHeader + RequestH +} + diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/contentassist/GH_2569b.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/contentassist/GH_2569b.n4js.xt new file mode 100644 index 0000000000..6fe4fc94f9 --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/contentassist/GH_2569b.n4js.xt @@ -0,0 +1,40 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest + + File "RequestHeader.n4js" { + export enum RequestHeader { + AcceptLanguage: "accept-language", + Origin: "origin", + Host: "host" + } + } + + END_SETUP + */ + + + +import {RequestHeader} from "RequestHeader"; +function *generator() { + if (true) { + yield 2; + } + /* XPECT FIXME completion at 'RequestHeader.<|>' --- + ExportEquals, Global, IDEBUG, IgnoreImplementation, ModuleAugmentation, + ProvidedByRuntime, StaticPolyfillAware, StaticPolyfillModule + --- */ + // XPECT errors --> "no viable alternative at input ';'" at ";" + RequestHeader.; +} + + From 72bb84234243102aa49c5480ec8984eaa52c4ba8 Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Tue, 21 Nov 2023 14:15:18 +0100 Subject: [PATCH 02/26] GH-2573: As a smith I want to migrate some Xtend files to Java (part 6) (#2574) * migrate some files * remove obsolete package * migrate files in transpiler.dts * disable xtend in bundle transpiler.dts * two fixes * fix a bug * small refactorings * fix bug * fix bug * fix a bug --- .../.classpath | 1 - .../build.properties | 3 +- .../org.eclipse.n4js.transpiler.dts/pom.xml | 5 - .../dts/transform/CutOffTransformation.java | 64 ++ .../dts/transform/CutOffTransformation.xtend | 48 -- ...mAddMissingInitializersTransformation.java | 88 +++ ...AddMissingInitializersTransformation.xtend | 71 -- .../ImplementedMemberTransformation.java | 299 ++++++++ .../ImplementedMemberTransformation.xtend | 240 ------ .../InferredTypesTransformation.java | 136 ++++ .../InferredTypesTransformation.xtend | 112 --- ... => ModuleSpecifierTransformationDts.java} | 11 +- .../OverriddenAccessorsTransformation.java | 179 +++++ .../OverriddenAccessorsTransformation.xtend | 152 ---- .../transform/ReturnTypeTransformation.java | 63 ++ .../transform/ReturnTypeTransformation.xtend | 52 -- .../dts/transform/ThisTypeTransformation.java | 283 +++++++ .../transform/ThisTypeTransformation.xtend | 263 ------- .../dts/transform/TrimTransformationDts.java | 160 ++++ .../dts/transform/TrimTransformationDts.xtend | 125 --- .../TypeReferenceTransformation.java | 709 ++++++++++++++++++ .../TypeReferenceTransformation.xtend | 654 ---------------- .../xtend-gen/.gitignore | 2 - .../META-INF/MANIFEST.MF | 1 - .../beans/IgnorePropertyChangeEvents.java | 27 - .../IgnorePropertyChangeEventsProcessor.xtend | 49 -- .../utils/beans/PropertyChangeSupport.java | 35 - .../PropertyChangeSupportProcessor.xtend | 257 ------- .../{Collections2.xtend => Collections2.java} | 111 +-- .../n4js/utils/collections/Iterables2.java | 127 ++++ .../n4js/utils/collections/Iterables2.xtend | 111 --- .../utils/nodemodel/NodeModelUtilsN4.java | 185 +++++ .../utils/nodemodel/NodeModelUtilsN4.xtend | 176 ----- 33 files changed, 2364 insertions(+), 2435 deletions(-) create mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/CutOffTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/CutOffTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/EnumAddMissingInitializersTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/EnumAddMissingInitializersTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ImplementedMemberTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ImplementedMemberTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/InferredTypesTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/InferredTypesTransformation.xtend rename plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/{ModuleSpecifierTransformationDts.xtend => ModuleSpecifierTransformationDts.java} (69%) create mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/OverriddenAccessorsTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/OverriddenAccessorsTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ReturnTypeTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ReturnTypeTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ThisTypeTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ThisTypeTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TrimTransformationDts.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TrimTransformationDts.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.xtend delete mode 100644 plugins/org.eclipse.n4js.transpiler.dts/xtend-gen/.gitignore delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/IgnorePropertyChangeEvents.java delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/IgnorePropertyChangeEventsProcessor.xtend delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/PropertyChangeSupport.java delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/PropertyChangeSupportProcessor.xtend rename plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/{Collections2.xtend => Collections2.java} (56%) create mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Iterables2.java delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Iterables2.xtend create mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/nodemodel/NodeModelUtilsN4.java delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/nodemodel/NodeModelUtilsN4.xtend diff --git a/plugins/org.eclipse.n4js.transpiler.dts/.classpath b/plugins/org.eclipse.n4js.transpiler.dts/.classpath index 14dd6eb29b..e3378d07f0 100644 --- a/plugins/org.eclipse.n4js.transpiler.dts/.classpath +++ b/plugins/org.eclipse.n4js.transpiler.dts/.classpath @@ -1,7 +1,6 @@ - diff --git a/plugins/org.eclipse.n4js.transpiler.dts/build.properties b/plugins/org.eclipse.n4js.transpiler.dts/build.properties index aaedd5b241..17daa5b49c 100644 --- a/plugins/org.eclipse.n4js.transpiler.dts/build.properties +++ b/plugins/org.eclipse.n4js.transpiler.dts/build.properties @@ -1,5 +1,4 @@ -source.. = src/,\ - xtend-gen/ +source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ diff --git a/plugins/org.eclipse.n4js.transpiler.dts/pom.xml b/plugins/org.eclipse.n4js.transpiler.dts/pom.xml index 534ae5be08..f34548c912 100644 --- a/plugins/org.eclipse.n4js.transpiler.dts/pom.xml +++ b/plugins/org.eclipse.n4js.transpiler.dts/pom.xml @@ -34,11 +34,6 @@ Contributors: maven-resources-plugin ${maven-resources-plugin.version} - - org.eclipse.xtend - xtend-maven-plugin - - diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/CutOffTransformation.java b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/CutOffTransformation.java new file mode 100644 index 0000000000..396acfcec5 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/CutOffTransformation.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2021 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.transpiler.dts.transform; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.dts.utils.DtsUtils; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.Type; + +/** + * Remove from extends/implements clauses of classifiers all references to types that are not .d.ts exportable. + */ +public class CutOffTransformation extends Transformation { + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + for (N4ClassifierDeclaration decl : collectNodes(getState().im, N4ClassifierDeclaration.class, false)) { + cutOffReferencesInExtendsImplements(decl); + } + } + + private void cutOffReferencesInExtendsImplements(N4ClassifierDeclaration classifierDecl) { + List> toBeRemoved = new ArrayList<>(); + for (TypeReferenceNode superTypeRefNode : classifierDecl.getSuperClassifierRefs()) { + TypeRef superTypeRef = getState().info.getOriginalProcessedTypeRef(superTypeRefNode); + Type superDeclType = superTypeRef == null ? null : superTypeRef.getDeclaredType(); + if (!DtsUtils.isDtsExportableReference(superDeclType, getState())) { + toBeRemoved.add(superTypeRefNode); + } + } + for (TypeReferenceNode tbr : toBeRemoved) { + remove(tbr); + } + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/CutOffTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/CutOffTransformation.xtend deleted file mode 100644 index b047130b98..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/CutOffTransformation.xtend +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2021 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.transpiler.dts.transform - -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.dts.utils.DtsUtils - -/** - * Remove from extends/implements clauses of classifiers all references to types that are not .d.ts exportable. - */ -class CutOffTransformation extends Transformation { - - override assertPreConditions() { - } - - override assertPostConditions() { - } - - override analyze() { - // ignore - } - - override transform() { - collectNodes(state.im, N4ClassifierDeclaration, false).forEach[cutOffReferencesInExtendsImplements]; - } - - def private void cutOffReferencesInExtendsImplements(N4ClassifierDeclaration classifierDecl) { - val toBeRemoved = newArrayList; - for (superTypeRefNode : classifierDecl.superClassifierRefs) { - val superTypeRef = state.info.getOriginalProcessedTypeRef(superTypeRefNode); - val superDeclType = superTypeRef?.declaredType; - if (!DtsUtils.isDtsExportableReference(superDeclType, state)) { - toBeRemoved += superTypeRefNode; - } - } - - toBeRemoved.forEach[remove]; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/EnumAddMissingInitializersTransformation.java b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/EnumAddMissingInitializersTransformation.java new file mode 100644 index 0000000000..4198f7b195 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/EnumAddMissingInitializersTransformation.java @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2021 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.transpiler.dts.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteral; + +import org.eclipse.n4js.n4JS.ExportDeclaration; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.Literal; +import org.eclipse.n4js.n4JS.N4EnumDeclaration; +import org.eclipse.n4js.n4JS.N4EnumLiteral; +import org.eclipse.n4js.n4JS.ScriptElement; +import org.eclipse.n4js.n4JS.StringLiteral; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.transpiler.utils.TranspilerUtils; +import org.eclipse.n4js.ts.types.TEnumLiteral; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind; + +/** + * Transformer to add initializers to string-/number-based enums + */ +public class EnumAddMissingInitializersTransformation extends Transformation { + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + makeInferredTypesExplicit(); + } + + private void makeInferredTypesExplicit() { + for (ScriptElement rootElemRaw : getState().im.getScriptElements()) { + ScriptElement rootElem = (rootElemRaw instanceof ExportDeclaration) + ? ((ExportDeclaration) rootElemRaw).getExportedElement() + : rootElemRaw; + + if (rootElem instanceof N4EnumDeclaration) { + N4EnumDeclaration enumDecl = (N4EnumDeclaration) rootElem; + EnumKind enumKind = N4JSLanguageUtils.getEnumKind(enumDecl); + boolean isLiteralBased = enumKind != EnumKind.Normal; + boolean isPartiallyInitialized = false; + for (N4EnumLiteral literal : enumDecl.getLiterals()) { + Expression valueExpr = literal.getValueExpression(); + isPartiallyInitialized = isPartiallyInitialized + || (valueExpr != null && valueExpr instanceof StringLiteral); + + if (valueExpr == null) { + if (isPartiallyInitialized) { + literal.setValueExpression(_StringLiteral(literal.getName())); + } else if (isLiteralBased) { + SymbolTableEntry propSTE = getState().steCache.mapNamedElement_2_STE.get(literal); + TEnumLiteral tLiteral = (propSTE instanceof SymbolTableEntryOriginal) + ? (TEnumLiteral) ((SymbolTableEntryOriginal) propSTE).getOriginalTarget() + : null; + Literal newLit = TranspilerUtils.enumLiteralToNumericOrStringLiteral(tLiteral); + literal.setValueExpression(newLit); + } + } + } + } + } + } + +} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/EnumAddMissingInitializersTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/EnumAddMissingInitializersTransformation.xtend deleted file mode 100644 index 579d199ac0..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/EnumAddMissingInitializersTransformation.xtend +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright (c) 2021 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.transpiler.dts.transform - -import org.eclipse.n4js.n4JS.ExportDeclaration -import org.eclipse.n4js.n4JS.N4EnumDeclaration -import org.eclipse.n4js.n4JS.StringLiteral -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal -import org.eclipse.n4js.transpiler.utils.TranspilerUtils -import org.eclipse.n4js.ts.types.TEnumLiteral -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - * Transformer to add initializers to string-/number-based enums - */ -class EnumAddMissingInitializersTransformation extends Transformation { - - override assertPreConditions() { - } - - override assertPostConditions() { - } - - override analyze() { - // ignore - } - - override transform() { - makeInferredTypesExplicit(); - } - - def private void makeInferredTypesExplicit() { - for (rootElemRaw : state.im.scriptElements) { - val rootElem = if (rootElemRaw instanceof ExportDeclaration) rootElemRaw.exportedElement else rootElemRaw; - if (rootElem instanceof N4EnumDeclaration) { - - val enumKind = N4JSLanguageUtils.getEnumKind(rootElem); - val isLiteralBased = enumKind !== EnumKind.Normal; - var isPartiallyInitialized = false; - for (literal : rootElem.literals) { - isPartiallyInitialized = isPartiallyInitialized - || (literal.valueExpression !== null && literal.valueExpression instanceof StringLiteral); - - if (literal.valueExpression === null) { - if (isPartiallyInitialized) { - literal.valueExpression = _StringLiteral(literal.name); - } else if (isLiteralBased) { - val propSTE = state.steCache.mapNamedElement_2_STE.get(literal); - val tLiteral = if (propSTE instanceof SymbolTableEntryOriginal) propSTE.originalTarget as TEnumLiteral; - val newLit = TranspilerUtils.enumLiteralToNumericOrStringLiteral(tLiteral); - literal.valueExpression = newLit; - } - } - } - } - } - } - -} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ImplementedMemberTransformation.java b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ImplementedMemberTransformation.java new file mode 100644 index 0000000000..b075e9a645 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ImplementedMemberTransformation.java @@ -0,0 +1,299 @@ +/** + * Copyright (c) 2021 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.transpiler.dts.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Fpar; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._LiteralOrComputedPropertyName; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4FieldDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4GetterDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4MethodDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4SetterDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4TypeVariable; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._TypeReferenceNode; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.wrap; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.operator_plus; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4GetterDeclaration; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.N4MethodDeclaration; +import org.eclipse.n4js.n4JS.N4Modifier; +import org.eclipse.n4js.n4JS.N4SetterDeclaration; +import org.eclipse.n4js.n4JS.N4TypeVariable; +import org.eclipse.n4js.n4JS.TypedElement; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.im.TypeReferenceNode_IM; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.FieldAccessor; +import org.eclipse.n4js.ts.types.MemberAccessModifier; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.TSetter; +import org.eclipse.n4js.ts.types.TTypedElement; +import org.eclipse.n4js.ts.types.TypeVariable; +import org.eclipse.n4js.ts.types.util.NonSymetricMemberKey; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; + +import com.google.inject.Inject; + +/** + * To each class declaration in the intermediate module, this transformation adds a member declaration for all members + * of all directly or indirectly implemented interfaces, unless such a member is present in the class already (owned or + * inherited). + *

+ * In particular, this is necessary for two cases: + *

    + *
  1. TypeScript cannot cope with abstract(!) classes that implement an interface I but do not themselves declare all + * of I's members (at least as abstract). + *
  2. TypeScript does not know about default methods/getters/setters in interfaces; since implementing classes in N4JS + * won't have an implementation for such default members, we would not export a declaration for them without the below + * special handling. + *
+ */ +public class ImplementedMemberTransformation extends Transformation { + + @Inject + private N4JSTypeSystem ts; + + @Inject + private TypeSystemHelper tsh; + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + // empty + } + + @Override + public void transform() { + for (N4ClassDeclaration cd : collectNodes(getState().im, N4ClassDeclaration.class, false)) { + addMissingImplementedMembers(cd); + } + } + + private void addMissingImplementedMembers(N4ClassDeclaration classDecl) { + TClass tClass = getState().info.getOriginalDefinedType(classDecl); + if (tClass == null) { + // an earlier transformation created a synthetic class without setting its original defined type + throw new IllegalStateException( + "intermediate model contains a class declaration without original defined type"); + } + TClass tSuperClass = tClass.getSuperClass(); + + List membersFromSuperClass = (tSuperClass != null) + ? getState().memberCollector.allMembers(tSuperClass, false, true, true) + : new ArrayList<>(); + + Set membersOwnedAndFromSuperClassAsSet = new HashSet<>(); + for (TMember member : operator_plus(tClass.getOwnedMembers(), membersFromSuperClass)) { + if (!member.isStatic()) { + membersOwnedAndFromSuperClassAsSet.add(NonSymetricMemberKey.of(member)); + } + } + + List membersFromInterfaces = new ArrayList<>(); + for (TMember member : getState().memberCollector.membersOfImplementedInterfacesForConsumption(tClass)) { + if (!member.isStatic() + && member.getMemberAccessModifier() == MemberAccessModifier.PUBLIC) { + // non public interface members are not exported to .d.ts (cf. TrimForDtsTransformation) + membersFromInterfaces.add(member); + } + } + + Map membersToAmend = new LinkedHashMap<>(); + for (TMember memberFromIfc : membersFromInterfaces) { + NonSymetricMemberKey key = NonSymetricMemberKey.of(memberFromIfc); + if (!membersOwnedAndFromSuperClassAsSet.contains(key)) { + // note: in case of duplicates in list 'membersFromInterfaces' we want to use the *last* member, + // because it might be more specialized than the earlier ones; therefore we here overwrite earlier + // members with later ones if they have the same 'key': + membersToAmend.put(key, memberFromIfc); + } + } + + if (membersToAmend.isEmpty()) { + return; + } + + // for adjusting the types of members coming from interfaces, we prepare a rule environment + // with all implicit type variable bindings of tClass + RuleEnvironment G_tClass = wrap(getState().G); + for (ParameterizedTypeRef tRef : tClass.getSuperClassifierRefs()) { + tsh.addSubstitutions(G_tClass, tRef); + } + + for (TMember memberToAmend : membersToAmend.values()) { + N4MemberDeclaration memberNew = addMember(classDecl, memberToAmend, G_tClass); + + memberNew.getDeclaredModifiers().add(N4Modifier.PUBLIC); + boolean hasDefaultImpl = false; + if (memberToAmend instanceof TField) { + // small inconsistency in N4JS: fields in interfaces need not be re-declared in implementing classes + // even if they do not have an initializer expression; so in a sense they are all "default fields": + hasDefaultImpl = true; + // this would be more consistent: + // memberToAmend.hasExpression + } + if (memberToAmend instanceof FieldAccessor) { + hasDefaultImpl = !((FieldAccessor) memberToAmend).isHasNoBody(); + } + if (memberToAmend instanceof TMethod) { + hasDefaultImpl = !((TMethod) memberToAmend).isHasNoBody(); + } + if (!hasDefaultImpl) { + memberNew.getDeclaredModifiers().add(N4Modifier.ABSTRACT); + } + } + } + + private N4MemberDeclaration addMember(N4ClassDeclaration classDecl, TMember member, RuleEnvironment G_tClass) { + if (member instanceof TField) { + return addMember(classDecl, (TField) member, G_tClass); + } else if (member instanceof TGetter) { + return addMember(classDecl, (TGetter) member, G_tClass); + } else if (member instanceof TSetter) { + return addMember(classDecl, (TSetter) member, G_tClass); + } else if (member instanceof TMethod) { + return addMember(classDecl, (TMethod) member, G_tClass); + } + throw new IllegalArgumentException("Unhandled parameter types: " + + Arrays. asList(classDecl, member, G_tClass).toString()); + } + + private N4MemberDeclaration addMember(N4ClassDeclaration classDecl, TField fieldToAdd, RuleEnvironment G_tClass) { + N4FieldDeclaration fieldNew = _N4FieldDecl(false, fieldToAdd.getName(), null); + classDecl.getOwnedMembersRaw().add(fieldNew); + + setDeclaredTypeRef(fieldNew, fieldToAdd, G_tClass); + + return fieldNew; + } + + private N4MemberDeclaration addMember(N4ClassDeclaration classDecl, TGetter getterToAdd, RuleEnvironment G_tClass) { + N4GetterDeclaration getterNew = _N4GetterDecl(_LiteralOrComputedPropertyName(getterToAdd.getName()), null); + classDecl.getOwnedMembersRaw().add(getterNew); + + setDeclaredTypeRef(getterNew, getterToAdd.getTypeRef(), G_tClass); + + return getterNew; + } + + private N4MemberDeclaration addMember(N4ClassDeclaration classDecl, TSetter setterToAdd, RuleEnvironment G_tClass) { + FormalParameter fpar = _Fpar("value"); + N4SetterDeclaration setterNew = _N4SetterDecl(_LiteralOrComputedPropertyName(setterToAdd.getName()), fpar, + null); + classDecl.getOwnedMembersRaw().add(setterNew); + + setDeclaredTypeRef(fpar, setterToAdd.getTypeRef(), G_tClass); + + return setterNew; + } + + private N4MemberDeclaration addMember(N4ClassDeclaration classDecl, TMethod methodToAdd, RuleEnvironment G_tClass) { + N4MethodDeclaration methodNew = _N4MethodDecl(methodToAdd.getName()); + classDecl.getOwnedMembersRaw().add(methodNew); + + for (TypeVariable typeParam : methodToAdd.getTypeVars()) { + addTypeParameter(methodNew, typeParam, G_tClass); + } + + for (TFormalParameter fpar : methodToAdd.getFpars()) { + addFormalParameter(methodNew, fpar, G_tClass); + } + + setReturnTypeRef(methodNew, methodToAdd.getReturnTypeRef(), G_tClass); + + return methodNew; + } + + private void addTypeParameter(N4MethodDeclaration methodDecl, TypeVariable typeParamToAdd, + RuleEnvironment G_tClass) { + N4TypeVariable typeParamNew = _N4TypeVariable(typeParamToAdd.getName(), typeParamToAdd.isDeclaredCovariant(), + typeParamToAdd.isDeclaredContravariant()); + methodDecl.getTypeVars().add(typeParamNew); + + setDeclaredUpperBound(typeParamNew, typeParamToAdd.getDeclaredUpperBound(), G_tClass); + } + + private void addFormalParameter(N4MethodDeclaration methodDecl, TFormalParameter fparToAdd, + RuleEnvironment G_tClass) { + FormalParameter fparNew = _Fpar(fparToAdd.getName(), fparToAdd.isVariadic()); + fparNew.setHasInitializerAssignment(fparToAdd.isOptional()); + methodDecl.getFpars().add(fparNew); + + setDeclaredTypeRef(fparNew, fparToAdd, G_tClass); + } + + private void setDeclaredTypeRef(TypedElement elementInIM, TTypedElement elementInTModule, + RuleEnvironment G_tClass) { + TypeRef typeRef = elementInTModule.getTypeRef(); + setDeclaredTypeRef(elementInIM, typeRef, G_tClass); + } + + private void setDeclaredTypeRef(TypedElement elementInIM, TypeRef typeRef, RuleEnvironment G_tClass) { + if (typeRef != null) { + elementInIM.setDeclaredTypeRefNode(createLocalizedTypeRefNodeFor(typeRef, G_tClass)); + } + } + + private void setReturnTypeRef(FunctionDefinition funDef, TypeRef typeRef, RuleEnvironment G_tClass) { + if (typeRef != null) { + funDef.setDeclaredReturnTypeRefNode(createLocalizedTypeRefNodeFor(typeRef, G_tClass)); + } + } + + private void setDeclaredUpperBound(N4TypeVariable typeParam, TypeRef typeRef, RuleEnvironment G_tClass) { + if (typeRef != null) { + typeParam.setDeclaredUpperBoundNode(createLocalizedTypeRefNodeFor(typeRef, G_tClass)); + } + } + + /** + * Converts the given type reference to the context defined by rule environment 'ruleEnvForSubstituion' (which will + * usually contain type variable bindings representing the context inside the class declaration passed to method + * {@link #addMissingImplementedMembers(N4ClassDeclaration)}) and creates a new {@link TypeReferenceNode_IM} for it. + */ + private TypeReferenceNode_IM createLocalizedTypeRefNodeFor(TypeRef typeRef, + RuleEnvironment ruleEnvForSubstituion) { + TypeRef typeRefSubst = ts.substTypeVariables(ruleEnvForSubstituion, typeRef); + TypeRef typeRefSubstCpy = (typeRefSubst == typeRef) ? TypeUtils.copy(typeRefSubst) : typeRefSubst; + TypeReferenceNode_IM typeRefNode = _TypeReferenceNode(getState(), typeRefSubstCpy); + return typeRefNode; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ImplementedMemberTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ImplementedMemberTransformation.xtend deleted file mode 100644 index 9b00ca7eb2..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ImplementedMemberTransformation.xtend +++ /dev/null @@ -1,240 +0,0 @@ -/** - * Copyright (c) 2021 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.transpiler.dts.transform - -import com.google.inject.Inject -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.n4JS.N4MemberDeclaration -import org.eclipse.n4js.n4JS.N4MethodDeclaration -import org.eclipse.n4js.n4JS.N4Modifier -import org.eclipse.n4js.n4JS.N4TypeVariable -import org.eclipse.n4js.n4JS.TypedElement -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.im.TypeReferenceNode_IM -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.FieldAccessor -import org.eclipse.n4js.ts.types.MemberAccessModifier -import org.eclipse.n4js.ts.types.TField -import org.eclipse.n4js.ts.types.TFormalParameter -import org.eclipse.n4js.ts.types.TGetter -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.ts.types.TMemberWithAccessModifier -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.ts.types.TSetter -import org.eclipse.n4js.ts.types.TTypedElement -import org.eclipse.n4js.ts.types.TypeVariable -import org.eclipse.n4js.ts.types.util.NonSymetricMemberKey -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * To each class declaration in the intermediate module, this transformation adds a member declaration - * for all members of all directly or indirectly implemented interfaces, unless such a member is present - * in the class already (owned or inherited). - *

- * In particular, this is necessary for two cases: - *

    - *
  1. TypeScript cannot cope with abstract(!) classes that implement an interface I but do not themselves - * declare all of I's members (at least as abstract). - *
  2. TypeScript does not know about default methods/getters/setters in interfaces; since implementing - * classes in N4JS won't have an implementation for such default members, we would not export a declaration - * for them without the below special handling. - *
- */ -class ImplementedMemberTransformation extends Transformation { - - @Inject - private N4JSTypeSystem ts; - - @Inject - private TypeSystemHelper tsh; - - override assertPreConditions() { - } - - override assertPostConditions() { - } - - override analyze() { - } - - override transform() { - collectNodes(state.im, N4ClassDeclaration, false).forEach[addMissingImplementedMembers]; - } - - private def void addMissingImplementedMembers(N4ClassDeclaration classDecl) { - val tClass = state.info.getOriginalDefinedType(classDecl); - if (tClass === null) { - // an earlier transformation created a synthetic class without setting its original defined type - throw new IllegalStateException("intermediate model contains a class declaration without original defined type"); - } - val tSuperClass = tClass.superClass; - - val membersFromSuperClass = if (tSuperClass !== null) { - state.memberCollector.allMembers(tSuperClass, false, true, true) - } else { - #[] - }; - - val membersOwnedAndFromSuperClassAsSet = (tClass.ownedMembers + membersFromSuperClass) - .filter[!static] - .map[NonSymetricMemberKey.of(it)] - .toSet; - - val membersFromInterfaces = state.memberCollector.membersOfImplementedInterfacesForConsumption(tClass) - .filter[!static] - .filter[memberAccessModifier === MemberAccessModifier.PUBLIC] // non public interface members are not exported to .d.ts (cf. TrimForDtsTransformation) - .toList; - - val membersToAmend = newLinkedHashMap; - for (memberFromIfc : membersFromInterfaces) { - val key = NonSymetricMemberKey.of(memberFromIfc); - if (!membersOwnedAndFromSuperClassAsSet.contains(key)) { - // note: in case of duplicates in list 'membersFromInterfaces' we want to use the *last* member, - // because it might be more specialized than the earlier ones; therefore we here overwrite earlier - // members with later ones if they have the same 'key': - membersToAmend.put(key, memberFromIfc); - } - } - - if (membersToAmend.empty) { - return; - } - - // for adjusting the types of members coming from interfaces, we prepare a rule environment - // with all implicit type variable bindings of tClass - val G_tClass = state.G.wrap; - tClass.superClassifierRefs.forEach[tsh.addSubstitutions(G_tClass, it)]; - - for (TMember memberToAmend : membersToAmend.values) { - val memberNew = addMember(classDecl, memberToAmend as TMemberWithAccessModifier, G_tClass); - - memberNew.declaredModifiers += N4Modifier.PUBLIC; - val hasDefaultImpl = switch (memberToAmend) { - TField: { - // small inconsistency in N4JS: fields in interfaces need not be re-declared in implementing classes - // even if they do not have an initializer expression; so in a sense they are all "default fields": - true - // this would be more consistent: - // memberToAmend.hasExpression - } - FieldAccessor: !memberToAmend.hasNoBody - TMethod: !memberToAmend.hasNoBody - }; - if (!hasDefaultImpl) { - memberNew.declaredModifiers += N4Modifier.ABSTRACT; - } - } - } - - private def dispatch N4MemberDeclaration addMember(N4ClassDeclaration classDecl, TField fieldToAdd, RuleEnvironment G_tClass) { - val fieldNew = _N4FieldDecl(false, fieldToAdd.name, null); - classDecl.ownedMembersRaw += fieldNew; - - setDeclaredTypeRef(fieldNew, fieldToAdd, G_tClass); - - return fieldNew; - } - - private def dispatch N4MemberDeclaration addMember(N4ClassDeclaration classDecl, TGetter getterToAdd, RuleEnvironment G_tClass) { - val getterNew = _N4GetterDecl(_LiteralOrComputedPropertyName(getterToAdd.name), null); - classDecl.ownedMembersRaw += getterNew; - - setDeclaredTypeRef(getterNew, getterToAdd.typeRef, G_tClass); - - return getterNew; - } - - private def dispatch N4MemberDeclaration addMember(N4ClassDeclaration classDecl, TSetter setterToAdd, RuleEnvironment G_tClass) { - val fpar = _Fpar("value"); - val setterNew = _N4SetterDecl(_LiteralOrComputedPropertyName(setterToAdd.name), fpar, null); - classDecl.ownedMembersRaw += setterNew; - - setDeclaredTypeRef(fpar, setterToAdd.typeRef, G_tClass); - - return setterNew; - } - - private def dispatch N4MemberDeclaration addMember(N4ClassDeclaration classDecl, TMethod methodToAdd, RuleEnvironment G_tClass) { - val methodNew = _N4MethodDecl(methodToAdd.name); - classDecl.ownedMembersRaw += methodNew; - - for (TypeVariable typeParam : methodToAdd.typeVars) { - addTypeParameter(methodNew, typeParam, G_tClass); - } - - for (TFormalParameter fpar : methodToAdd.fpars) { - addFormalParameter(methodNew, fpar, G_tClass); - } - - setReturnTypeRef(methodNew, methodToAdd.returnTypeRef, G_tClass); - - return methodNew; - } - - private def void addTypeParameter(N4MethodDeclaration methodDecl, TypeVariable typeParamToAdd, RuleEnvironment G_tClass) { - val typeParamNew = _N4TypeVariable(typeParamToAdd.name, typeParamToAdd.isDeclaredCovariant, typeParamToAdd.isDeclaredContravariant); - methodDecl.typeVars += typeParamNew; - - setDeclaredUpperBound(typeParamNew, typeParamToAdd.declaredUpperBound, G_tClass); - } - - private def void addFormalParameter(N4MethodDeclaration methodDecl, TFormalParameter fparToAdd, RuleEnvironment G_tClass) { - val fparNew = _Fpar(fparToAdd.name, fparToAdd.variadic); - fparNew.hasInitializerAssignment = fparToAdd.optional; - methodDecl.fpars += fparNew; - - setDeclaredTypeRef(fparNew, fparToAdd, G_tClass); - } - - private def void setDeclaredTypeRef(TypedElement elementInIM, TTypedElement elementInTModule, RuleEnvironment G_tClass) { - val typeRef = elementInTModule.typeRef; - setDeclaredTypeRef(elementInIM, typeRef, G_tClass); - } - - private def void setDeclaredTypeRef(TypedElement elementInIM, TypeRef typeRef, RuleEnvironment G_tClass) { - if (typeRef !== null) { - elementInIM.declaredTypeRefNode = createLocalizedTypeRefNodeFor(typeRef, G_tClass); - } - } - - private def void setReturnTypeRef(FunctionDefinition funDef, TypeRef typeRef, RuleEnvironment G_tClass) { - if (typeRef !== null) { - funDef.declaredReturnTypeRefNode = createLocalizedTypeRefNodeFor(typeRef, G_tClass); - } - } - - private def void setDeclaredUpperBound(N4TypeVariable typeParam, TypeRef typeRef, RuleEnvironment G_tClass) { - if (typeRef !== null) { - typeParam.declaredUpperBoundNode = createLocalizedTypeRefNodeFor(typeRef, G_tClass); - } - } - - /** - * Converts the given type reference to the context defined by rule environment 'ruleEnvForSubstituion' - * (which will usually contain type variable bindings representing the context inside the class declaration - * passed to method {@link #addMissingImplementedMembers(N4ClassDeclaration)}) and creates a new - * {@link TypeReferenceNode_IM} for it. - */ - private def TypeReferenceNode_IM createLocalizedTypeRefNodeFor(TypeRef typeRef, RuleEnvironment ruleEnvForSubstituion) { - val typeRefSubst = ts.substTypeVariables(ruleEnvForSubstituion, typeRef); - val typeRefSubstCpy = if (typeRefSubst === typeRef) TypeUtils.copy(typeRefSubst) else typeRefSubst; - val typeRefNode = _TypeReferenceNode(state, typeRefSubstCpy); - return typeRefNode; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/InferredTypesTransformation.java b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/InferredTypesTransformation.java new file mode 100644 index 0000000000..92bb7131c7 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/InferredTypesTransformation.java @@ -0,0 +1,136 @@ +/** + * Copyright (c) 2021 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.transpiler.dts.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._TypeReferenceNode; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.anyTypeRef; + +import java.util.Collections; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.ExportDeclaration; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.FunctionDeclaration; +import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; +import org.eclipse.n4js.n4JS.ScriptElement; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.n4JS.TypedElement; +import org.eclipse.n4js.n4JS.VariableStatement; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.TypableElement; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.xtext.xbase.lib.IterableExtensions; + +import com.google.common.collect.Iterables; +import com.google.inject.Inject; + +/** + * Makes the inferred type of + *
    + *
  1. variables on top level, and + *
  2. fields of classes and interfaces + *
+ * explicit in the intermediate model, so that {@code PrettyPrinterDts} can handle them. + */ +public class InferredTypesTransformation extends Transformation { + + @Inject + private N4JSTypeSystem ts; + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + makeInferredTypesExplicit(); + } + + private void makeInferredTypesExplicit() { + for (ScriptElement rootElemRaw : getState().im.getScriptElements()) { + ScriptElement rootElem = (rootElemRaw instanceof ExportDeclaration) + ? ((ExportDeclaration) rootElemRaw).getExportedElement() + : rootElemRaw; + + // obtain those typed elements, that may have an inferred type + // (e.g. variables and fields, but not getters, setters) + Iterable typedElems = null; + if (rootElem instanceof VariableStatement) { + // note: returns also variable declarations that are arbitrarily nested in a destructure pattern + typedElems = ((VariableStatement) rootElem).getVarDecl(); + + } else if (rootElem instanceof N4ClassifierDeclaration) { + N4ClassifierDeclaration cd = (N4ClassifierDeclaration) rootElem; + typedElems = Iterables.concat( + cd.getOwnedFields(), + IterableExtensions.flatMap(cd.getOwnedMethods(), m -> m.getFpars()), + cd.getOwnedCtor() == null ? Collections.emptyList() : cd.getOwnedCtor().getFpars()); + + } else if (rootElem instanceof FunctionDeclaration) { + typedElems = ((FunctionDeclaration) rootElem).getFpars(); + } + + if (typedElems != null) { + for (TypedElement typedElem : typedElems) { + makeInferredTypeExplicit(typedElem); + } + } + } + } + + private void makeInferredTypeExplicit(TypedElement elemInIM) { + if (elemInIM.getDeclaredTypeRefNode() != null) { + // type already provided explicitly, so nothing to do here + return; + } + + // special handling for variadic fpars without declared type: + // the type system always gives us the fpar's actual type that here includes the implicit array (i.e. + // Array), + // but this would be inconsistent with the meaning of an explicitly declared type, so we simply use 'any' here + // ... + if (elemInIM instanceof FormalParameter) { + FormalParameter fPar = (FormalParameter) elemInIM; + + if (fPar.isVariadic()) { + fPar.setDeclaredTypeRefNode(_TypeReferenceNode(getState(), anyTypeRef(getState().G))); + return; + } + } + + EObject elemInAST = getState().tracer.getOriginalASTNode(elemInIM); + if (elemInAST instanceof TypableElement) { + TypeRef typeRef = ts.type(getState().G, (TypableElement) elemInAST); + if (typeRef != null) { + TypeRef typeRefCpy = TypeUtils.copy(typeRef); + TypeReferenceNode typeRefNode = _TypeReferenceNode(getState(), typeRefCpy); + elemInIM.setDeclaredTypeRefNode(typeRefNode); + } + } else if (elemInAST != null) { + throw new IllegalStateException( + "expected original AST node of typed element to be a typable element, but was: " + + elemInAST.eClass().getName()); + } + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/InferredTypesTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/InferredTypesTransformation.xtend deleted file mode 100644 index cd18e20196..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/InferredTypesTransformation.xtend +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright (c) 2021 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.transpiler.dts.transform - -import com.google.common.collect.Iterables -import com.google.inject.Inject -import java.util.Collections -import org.eclipse.n4js.n4JS.ExportDeclaration -import org.eclipse.n4js.n4JS.FormalParameter -import org.eclipse.n4js.n4JS.FunctionDeclaration -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.n4JS.TypedElement -import org.eclipse.n4js.n4JS.VariableStatement -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.ts.types.TypableElement -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * Makes the inferred type of - *
    - *
  1. variables on top level, and - *
  2. fields of classes and interfaces - *
- * explicit in the intermediate model, so that {@code PrettyPrinterDts} can handle them. - */ -class InferredTypesTransformation extends Transformation { - - @Inject - private N4JSTypeSystem ts; - - override assertPreConditions() { - } - - override assertPostConditions() { - } - - override analyze() { - // ignore - } - - override transform() { - makeInferredTypesExplicit(); - } - - def private void makeInferredTypesExplicit() { - for (rootElemRaw : state.im.scriptElements) { - val rootElem = if (rootElemRaw instanceof ExportDeclaration) rootElemRaw.exportedElement else rootElemRaw; - - // obtain those typed elements, that may have an inferred type - // (e.g. variables and fields, but not getters, setters) - val typedElems = switch (rootElem) { - VariableStatement: rootElem.varDecl // note: returns also variable declarations that are arbitrarily nested in a destructure pattern - N4ClassifierDeclaration: { - Iterables.concat( - rootElem.ownedFields, - rootElem.ownedMethods.flatMap[fpars], - rootElem.ownedCtor === null ? Collections.emptyList : rootElem.ownedCtor.fpars - ); - } - FunctionDeclaration: rootElem.fpars - }; - - if (typedElems !== null) { - for (typedElem : typedElems) { - makeInferredTypeExplicit(typedElem); - } - } - } - } - - def private void makeInferredTypeExplicit(TypedElement elemInIM) { - if (elemInIM.declaredTypeRefNode !== null) { - // type already provided explicitly, so nothing to do here - return; - } - - // special handling for variadic fpars without declared type: - // the type system always gives us the fpar's actual type that here includes the implicit array (i.e. Array), - // but this would be inconsistent with the meaning of an explicitly declared type, so we simply use 'any' here ... - if (elemInIM instanceof FormalParameter) { - if (elemInIM.variadic) { - elemInIM.declaredTypeRefNode = _TypeReferenceNode(state, state.G.anyTypeRef); - return; - } - } - - val elemInAST = state.tracer.getOriginalASTNode(elemInIM); - if (elemInAST instanceof TypableElement) { - val typeRef = ts.type(state.G, elemInAST); - if (typeRef !== null) { - val typeRefCpy = TypeUtils.copy(typeRef); - val typeRefNode = _TypeReferenceNode(state, typeRefCpy); - elemInIM.declaredTypeRefNode = typeRefNode; - } - } else if (elemInAST !== null) { - throw new IllegalStateException("expected original AST node of typed element to be a typable element, but was: " + elemInAST.eClass.name); - } - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ModuleSpecifierTransformationDts.xtend b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ModuleSpecifierTransformationDts.java similarity index 69% rename from plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ModuleSpecifierTransformationDts.xtend rename to plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ModuleSpecifierTransformationDts.java index 2c5e5dba58..702402640a 100644 --- a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ModuleSpecifierTransformationDts.xtend +++ b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ModuleSpecifierTransformationDts.java @@ -8,17 +8,18 @@ * Contributors: * NumberFour AG - Initial API and implementation */ -package org.eclipse.n4js.transpiler.dts.transform +package org.eclipse.n4js.transpiler.dts.transform; -import org.eclipse.n4js.transpiler.es.transform.ModuleSpecifierTransformation -import org.eclipse.n4js.ts.types.TModule +import org.eclipse.n4js.transpiler.es.transform.ModuleSpecifierTransformation; +import org.eclipse.n4js.ts.types.TModule; /** * Minor adjustments over {@link ModuleSpecifierTransformation} for .d.ts files. */ -class ModuleSpecifierTransformationDts extends ModuleSpecifierTransformation { +public class ModuleSpecifierTransformationDts extends ModuleSpecifierTransformation { - override protected String getActualFileExtension(TModule targetModule) { + @Override + protected String getActualFileExtension(TModule targetModule) { // file extensions are not required in module specifiers inside .d.ts files return null; } diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/OverriddenAccessorsTransformation.java b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/OverriddenAccessorsTransformation.java new file mode 100644 index 0000000000..dbfd26cc64 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/OverriddenAccessorsTransformation.java @@ -0,0 +1,179 @@ +/** + * Copyright (c) 2021 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.transpiler.dts.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Fpar; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4GetterDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4SetterDecl; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.operator_plus; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.n4JS.AnnotableN4MemberDeclaration; +import org.eclipse.n4js.n4JS.ExportDeclaration; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4GetterDeclaration; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.N4SetterDeclaration; +import org.eclipse.n4js.n4JS.ScriptElement; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.TransformationDependency.RequiresBefore; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TSetter; +import org.eclipse.n4js.ts.types.util.MemberList; + +import com.google.common.collect.Lists; + +/** + * Transformer to deal with the inability of JavaScript to overwrite class fields by getter/setter pairs and vice versa. + *

+ * Dependencies: + *

    + *
  • requires {@link InferredTypesTransformation} to run before, because the fields being converted to getters/setters + * by this transformation might have an inferred type that must be available in the IM at time of conversion. + *
+ */ +@RequiresBefore(InferredTypesTransformation.class) +public class OverriddenAccessorsTransformation extends Transformation { + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + // empty + } + + @Override + public void transform() { + omitOrConvertOverridingFieldsAndAccessors(); + } + + private void omitOrConvertOverridingFieldsAndAccessors() { + for (ScriptElement rootElemRaw : getState().im.getScriptElements()) { + ScriptElement rootElem = (rootElemRaw instanceof ExportDeclaration) + ? ((ExportDeclaration) rootElemRaw).getExportedElement() + : rootElemRaw; + + if (rootElem instanceof N4ClassDeclaration) { + N4ClassDeclaration classDecl = (N4ClassDeclaration) rootElem; + List removeMembers = new ArrayList<>(); + List addMembers = new ArrayList<>(); + Map addMembersToOriginal = new HashMap<>(); + + for (N4FieldDeclaration field : classDecl.getOwnedFields()) { + if (isOverriding(field)) { + List overriddenMembers = findOverriddenMembers(field); + if (overriddenMembers.isEmpty()) { + // cannot happen since field has no errors and @Override annotation + } else if (overriddenMembers.size() == 1) { + EObject origAstNodeField = getState().tracer.getOriginalASTNode(field); + TMember overriddenMember = overriddenMembers.get(0); + if (overriddenMember instanceof TGetter) { + // consequently there is no setter defined --> add setter instead of field + removeMembers.add(field); + FormalParameter fPar = _Fpar("value"); + fPar.setDeclaredTypeRefNode(field.getDeclaredTypeRefNode()); + N4SetterDeclaration setter = _N4SetterDecl(field.getDeclaredName(), fPar, null); + setter.getDeclaredModifiers().addAll(field.getDeclaredModifiers()); + addMembers.add(setter); + addMembersToOriginal.put(setter, origAstNodeField); + + } else if (overriddenMember instanceof TSetter) { + // consequently there is no getter defined --> add getter instead of field + removeMembers.add(field); + N4GetterDeclaration getter = _N4GetterDecl(field.getDeclaredName(), null); + getter.setDeclaredTypeRefNode(field.getDeclaredTypeRefNode()); + getter.getDeclaredModifiers().addAll(field.getDeclaredModifiers()); + addMembers.add(getter); + + getState().tracer.getOriginalASTNode(field); + addMembersToOriginal.put(getter, origAstNodeField); + } + + } else if (overriddenMembers.size() == 2) { + // omit + removeMembers.add(field); + } + } + } + + for (AnnotableN4MemberDeclaration accessor : operator_plus(classDecl.getOwnedGetters(), + classDecl.getOwnedSetters())) { + if (isOverriding(accessor)) { + List overriddenMembers = findOverriddenMembers(accessor); + if (overriddenMembers.isEmpty()) { + // cannot happen since field has no errors and @Override annotation + } else if (overriddenMembers.size() == 1) { + TMember overriddenMember = overriddenMembers.get(0); + if (overriddenMember instanceof TField) { + // omit + removeMembers.add(accessor); + } + } + } + } + + classDecl.getOwnedMembersRaw().removeAll(removeMembers); + classDecl.getOwnedMembersRaw().addAll(addMembers); + for (N4MemberDeclaration addMember : addMembers) { + // will cause JSDoc to appear at the getter + EObject origAstNodeField = addMembersToOriginal.get(addMember); + getState().tracer.setOriginalASTNode(addMember, origAstNodeField); + } + } + } + } + + private boolean isOverriding(AnnotableN4MemberDeclaration member) { + return AnnotationDefinition.OVERRIDE.hasAnnotation(member); + } + + /** Finds the overridden member using name comparison. */ + private List findOverriddenMembers(AnnotableN4MemberDeclaration member) { + N4ClassDeclaration clazz = (N4ClassDeclaration) member.eContainer(); + if (getState().steCache.mapNamedElement_2_STE.get(clazz) instanceof SymbolTableEntryOriginal) { + SymbolTableEntryOriginal steo = (SymbolTableEntryOriginal) getState().steCache.mapNamedElement_2_STE + .get(clazz); + if (steo.getOriginalTarget() instanceof TClass) { + TClass type = (TClass) steo.getOriginalTarget(); + MemberList inheritedMembers = getState().memberCollector.inheritedMembers(type); + Iterable overriddenMembers = filter(inheritedMembers, + m -> Objects.equals(m.getName(), member.getName())); + + return Lists.newArrayList(overriddenMembers); + } + } + + return Collections.emptyList(); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/OverriddenAccessorsTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/OverriddenAccessorsTransformation.xtend deleted file mode 100644 index 862eaba8b7..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/OverriddenAccessorsTransformation.xtend +++ /dev/null @@ -1,152 +0,0 @@ -/** - * Copyright (c) 2021 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.transpiler.dts.transform - -import com.google.common.collect.Lists -import java.util.ArrayList -import java.util.Collections -import java.util.HashMap -import java.util.List -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.AnnotableN4MemberDeclaration -import org.eclipse.n4js.n4JS.ExportDeclaration -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.TransformationDependency.RequiresBefore -import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.TField -import org.eclipse.n4js.ts.types.TGetter -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.ts.types.TSetter - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - * Transformer to deal with the inability of JavaScript to overwrite class fields by getter/setter pairs and vice versa. - *

- * Dependencies: - *

    - *
  • requires {@link InferredTypesTransformation} to run before, because the fields being converted to getters/setters - * by this transformation might have an inferred type that must be available in the IM at time of conversion. - *
- */ -@RequiresBefore(InferredTypesTransformation) -class OverriddenAccessorsTransformation extends Transformation { - - override assertPreConditions() { - } - - override assertPostConditions() { - } - - override analyze() { - } - - override transform() { - omitOrConvertOverridingFieldsAndAccessors(); - } - - def private void omitOrConvertOverridingFieldsAndAccessors() { - for (rootElemRaw : state.im.scriptElements) { - val rootElem = if (rootElemRaw instanceof ExportDeclaration) rootElemRaw.exportedElement else rootElemRaw; - - - if (rootElem instanceof N4ClassDeclaration) { - val removeMembers = new ArrayList(); - val addMembers = new ArrayList(); - val addMembersToOriginal = new HashMap(); - - for (field : rootElem.ownedFields) { - if (isOverriding(field)) { - val overriddenMembers = findOverriddenMembers(field); - if (overriddenMembers.isEmpty) { - // cannot happen since field has no errors and @Override annotation - } else if (overriddenMembers.size == 1) { - val origAstNodeField = state.tracer.getOriginalASTNode(field); - val overriddenMember = overriddenMembers.get(0); - if (overriddenMember instanceof TGetter) { - // consequently there is no setter defined --> add setter instead of field - removeMembers.add(field); - val fPar = _Fpar("value"); - fPar.declaredTypeRefNode = field.declaredTypeRefNode; - val setter = _N4SetterDecl(field.declaredName, fPar, null); - setter.declaredModifiers += field.declaredModifiers; - addMembers.add(setter); - addMembersToOriginal.put(setter, origAstNodeField); - - } else if (overriddenMember instanceof TSetter) { - // consequently there is no getter defined --> add getter instead of field - removeMembers.add(field); - val getter = _N4GetterDecl(field.declaredName, null); - getter.declaredTypeRefNode = field.declaredTypeRefNode; - getter.declaredModifiers += field.declaredModifiers; - addMembers.add(getter); - - state.tracer.getOriginalASTNode(field); - addMembersToOriginal.put(getter, origAstNodeField); - } - - } else if (overriddenMembers.size == 2) { - // omit - removeMembers.add(field); - } - } - } - - for (accessor : (rootElem.ownedGetters + rootElem.ownedSetters)) { - if (isOverriding(accessor)) { - val overriddenMembers = findOverriddenMembers(accessor); - if (overriddenMembers.isEmpty) { - // cannot happen since field has no errors and @Override annotation - } else if (overriddenMembers.size == 1) { - val overriddenMember = overriddenMembers.get(0); - if (overriddenMember instanceof TField) { - // omit - removeMembers.add(accessor); - } - } - } - } - - rootElem.ownedMembersRaw.removeAll(removeMembers); - rootElem.ownedMembersRaw.addAll(addMembers); - for (addMember : addMembers) { - // will cause JSDoc to appear at the getter - val origAstNodeField = addMembersToOriginal.get(addMember); - state.tracer.setOriginalASTNode(addMember, origAstNodeField); - } - } - } - } - - def private boolean isOverriding(AnnotableN4MemberDeclaration member) { - return AnnotationDefinition.OVERRIDE.hasAnnotation(member); - } - - /** Finds the overridden member using name comparison. */ - def private List findOverriddenMembers(AnnotableN4MemberDeclaration member) { - val clazz = member.eContainer() as N4ClassDeclaration; - if (state.steCache.mapNamedElement_2_STE.get(clazz) instanceof SymbolTableEntryOriginal) { - val steo = state.steCache.mapNamedElement_2_STE.get(clazz) as SymbolTableEntryOriginal; - if (steo.getOriginalTarget() instanceof TClass) { - val type = steo.getOriginalTarget() as TClass; - val inheritedMembers = state.memberCollector.inheritedMembers(type); - val overriddenMembers = IterableExtensions.filter(inheritedMembers, - [it.getName() == member.getName()]); - - return Lists.newArrayList(overriddenMembers); - } - } - - return Collections.emptyList(); - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ReturnTypeTransformation.java b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ReturnTypeTransformation.java new file mode 100644 index 0000000000..bb12377699 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ReturnTypeTransformation.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2021 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.transpiler.dts.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._TypeReferenceNode; + +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.assistants.TypeAssistant; +import org.eclipse.n4js.ts.typeRefs.TypeRef; + +import com.google.inject.Inject; + +/** + * Implicit return types are made explicit. + */ +public class ReturnTypeTransformation extends Transformation { + + @Inject + private TypeAssistant typeAssistant; + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + for (FunctionDefinition fDef : collectNodes(getState().im, FunctionDefinition.class, false)) { + makeReturnTypeExplicit(fDef); + } + } + + private void makeReturnTypeExplicit(FunctionDefinition funDef) { + if (funDef.getDeclaredReturnTypeRefNode() != null) { + // return type already provided explicitly, so nothing to do here + return; + } + + TypeRef returnTypeRef = typeAssistant.getReturnTypeRef(getState(), funDef); + TypeReferenceNode typeRefNode = _TypeReferenceNode(getState(), returnTypeRef); + funDef.setDeclaredReturnTypeRefNode(typeRefNode); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ReturnTypeTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ReturnTypeTransformation.xtend deleted file mode 100644 index 31dcb94759..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ReturnTypeTransformation.xtend +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2021 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.transpiler.dts.transform - -import com.google.inject.Inject -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.assistants.TypeAssistant - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - * Implicit return types are made explicit. - */ -class ReturnTypeTransformation extends Transformation { - - @Inject - private TypeAssistant typeAssistant; - - override assertPreConditions() { - } - - override assertPostConditions() { - } - - override analyze() { - // ignore - } - - override transform() { - collectNodes(state.im, FunctionDefinition, false).forEach[makeReturnTypeExplicit]; - } - - def private void makeReturnTypeExplicit(FunctionDefinition funDef) { - if (funDef.declaredReturnTypeRefNode !== null) { - // return type already provided explicitly, so nothing to do here - return; - } - - val returnTypeRef = typeAssistant.getReturnTypeRef(state, funDef); - val typeRefNode = _TypeReferenceNode(state, returnTypeRef); - funDef.declaredReturnTypeRefNode = typeRefNode; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ThisTypeTransformation.java b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ThisTypeTransformation.java new file mode 100644 index 0000000000..382e10712a --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ThisTypeTransformation.java @@ -0,0 +1,283 @@ +/** + * Copyright (c) 2021 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.transpiler.dts.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._FormalParameter; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4MethodDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._TypeReferenceNode; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.setThisBinding; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.wrap; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4MethodDeclaration; +import org.eclipse.n4js.n4JS.N4Modifier; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.ts.typeRefs.ThisTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; + +import com.google.common.base.Preconditions; +import com.google.inject.Inject; + +/** + * This transformation replaces some ThisTypeRefs by concrete type references iff they occur in static methods or + * constructors. This is true for the following cases: + *
    + *
  • replace spec parameter (this-type) of constructors by concrete type + *
  • add (missing) spec constructor iff superclass defines one + *
  • replace return this-type of static methods by concrete type + *
  • add method override for all static methods returning this-types to replace return type by concrete type + *
+ */ +public class ThisTypeTransformation extends Transformation { + + @Inject + private N4JSTypeSystem ts; + + @Inject + private TypeSystemHelper tsh; + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + transformThisTypeRefs(); + } + + private void transformThisTypeRefs() { + List classes = collectNodes(getState().im, true, N4ClassDeclaration.class); + + for (N4ClassDeclaration clazz : classes) { + N4ClassDeclaration clazzOrig = (N4ClassDeclaration) getState().tracer.getOriginalASTNode(clazz); + + List methods = collectNodes(clazz, false, N4MethodDeclaration.class); + Set methodNamesCurClass = new HashSet<>(); + N4MethodDeclaration ctor = null; + for (N4MethodDeclaration method : methods) { + if (method.isConstructor()) { + ctor = method; + } else if (method.isStatic()) { + methodNamesCurClass.add(method.getName()); + // special handling for return type 'this' of static methods + TypeRef retTR = getState().info.getOriginalProcessedTypeRef(method.getDeclaredReturnTypeRefNode()); + if (retTR instanceof ThisTypeRef) { + N4MethodDeclaration methodOrig = getState().tracer.getOriginalASTNodeOfSameType(method, false); + var typeRef = tsh.bindAndSubstituteThisTypeRef(getState().G, methodOrig, retTR); + typeRef = ts.upperBoundWithReopen(getState().G, typeRef); + if (typeRef.isGeneric()) { + typeRef = TypeUtils.copyIfContained(typeRef); + int newTypeArgsCount = typeRef.getDeclaredType().getTypeVars().size(); + typeRef.getDeclaredTypeArgs().clear(); // only 'any' allowed here by TypeScript + for (var i = 0; i < newTypeArgsCount; i++) { + typeRef.getDeclaredTypeArgs().add(TypeRefsFactory.eINSTANCE.createWildcard()); + } + } + getState().info.setOriginalProcessedTypeRef(method.getDeclaredReturnTypeRefNode(), typeRef); + } + } + } + + if (ctor != null) { + // special handling for constructor parameter @Spec ~i~this + FormalParameter specFPar = getSpecFPar(ctor); + if (specFPar != null) { + FormalParameter specFParOrig = getState().tracer.getOriginalASTNodeOfSameType(specFPar, false); + if (specFParOrig != null) { + var typeRef = getState().info.getOriginalProcessedTypeRef(specFPar.getDeclaredTypeRefNode()); + typeRef = tsh.bindAndSubstituteThisTypeRef(getState().G, specFParOrig, typeRef); + typeRef = ts.upperBoundWithReopen(getState().G, typeRef); + getState().info.setOriginalProcessedTypeRef(specFPar.getDeclaredTypeRefNode(), typeRef); + } + } + + } else { + // search spec constructor in superclass and put its signature here and replace return 'this' type by + // actual type + TMethod specConstructorOrig = findSpecConstructorInSuperclass(clazzOrig); + if (specConstructorOrig != null) { + addOverwritingSpecConstructor(specConstructorOrig, clazz); + } + } + + Collection staticMethodsReturingThisInSuperclasses = findStaticMethodsReturingThisInSuperclasses( + clazzOrig); + for (TMethod method : staticMethodsReturingThisInSuperclasses) { + if (!methodNamesCurClass.contains(method.getName())) { + // put signature here and replace return 'this' type by actual type + addOverwritingStaticMethod(method, clazz); + } + } + } + } + + private Collection findStaticMethodsReturingThisInSuperclasses(N4ClassDeclaration clazzOrig) { + Map name2method = new HashMap<>(); + TClass curClass = clazzOrig.getDefinedTypeAsClass(); + while (curClass.getSuperClass() != null) { + curClass = curClass.getSuperClass(); + for (TMember member : curClass.getOwnedMembers()) { + if (member instanceof TMethod) { + TMethod tMethod = (TMethod) member; + if (member.isStatic() && tMethod.getReturnTypeRef() instanceof ThisTypeRef) { + name2method.putIfAbsent(member.getName(), tMethod); + } + } + } + } + + return name2method.values(); + } + + private TMethod findSpecConstructorInSuperclass(N4ClassDeclaration clazzOrig) { + TClass curClass = clazzOrig.getDefinedTypeAsClass(); + do { + if (curClass.getSuperClass() == null) { + return null; + } + curClass = curClass.getSuperClass(); + TMethod ctor = curClass.getOwnedCtor(); + + if (isSpecConstructor(ctor)) { + return ctor; + } else if (ctor != null) { + return null; + } + } while (true); + } + + @SuppressWarnings("unused") + private N4MethodDeclaration getConstructor(N4ClassDeclaration clazz) { + EList methods = clazz.getOwnedMethods(); + for (N4MethodDeclaration method : methods) { + if (method.isConstructor()) { + return method; + } + } + return null; + } + + private FormalParameter getSpecFPar(N4MethodDeclaration method) { + if (method == null) { + return null; + } + if (!method.isConstructor()) { + return null; + } + if (method.getFpars().isEmpty()) { + return null; + } + for (FormalParameter fpar : method.getFpars()) { + if (AnnotationDefinition.SPEC.hasAnnotation(fpar)) { + return fpar; + } + } + return null; + } + + private boolean isSpecConstructor(TMethod method) { + if (method == null) { + return false; + } + if (!method.isConstructor()) { + return false; + } + if (method.getFpars().isEmpty()) { + return false; + } + for (TFormalParameter fpar : method.getFpars()) { + if (AnnotationDefinition.SPEC.hasAnnotation(fpar)) { + return true; + } + } + return false; + } + + private N4MethodDeclaration addOverwritingSpecConstructor(TMethod constructor, N4ClassDeclaration clazz) { + N4ClassDeclaration clazzOrig = (N4ClassDeclaration) getState().tracer.getOriginalASTNode(clazz); + N4MethodDeclaration newConstructor = _N4MethodDecl("constructor"); + clazz.getOwnedMembersRaw().add(newConstructor); + for (TFormalParameter fpar : constructor.getFpars()) { + FormalParameter newFPar = _FormalParameter(fpar.getName()); + newConstructor.getFpars().add(newFPar); + TypeRef typeRef = fpar.getTypeRef(); + if (AnnotationDefinition.SPEC.hasAnnotation(fpar)) { + TypeRef thisTypeRef = TypeUtils.createTypeRefWithParamsAsArgs(clazzOrig.getDefinedType()); + typeRef = getConcreteTypeRef(fpar.getTypeRef(), thisTypeRef); + } + + newFPar.setDeclaredTypeRefNode(_TypeReferenceNode(getState(), typeRef)); + getState().info.setOriginalProcessedTypeRef(newFPar.getDeclaredTypeRefNode(), typeRef); + } + return newConstructor; + } + + private N4MethodDeclaration addOverwritingStaticMethod(TMethod method, N4ClassDeclaration clazz) { + N4ClassDeclaration clazzOrig = (N4ClassDeclaration) getState().tracer.getOriginalASTNode(clazz); + N4MethodDeclaration newMethod = _N4MethodDecl(method.getName()); + newMethod.getDeclaredModifiers().add(N4Modifier.STATIC); + clazz.getOwnedMembersRaw().add(newMethod); + for (TFormalParameter fpar : method.getFpars()) { + FormalParameter newFPar = _FormalParameter(fpar.getName()); + newMethod.getFpars().add(newFPar); + TypeRef typeRef = fpar.getTypeRef(); + newFPar.setDeclaredTypeRefNode(_TypeReferenceNode(getState(), typeRef)); + getState().info.setOriginalProcessedTypeRef(newFPar.getDeclaredTypeRefNode(), typeRef); + } + + Preconditions.checkState(method.getReturnTypeRef() instanceof ThisTypeRef); + + TypeRef thisTypeRef = TypeUtils.createTypeRef(clazzOrig.getDefinedType(), clazzOrig.getTypingStrategy(), true); + TypeRef typeRef = getConcreteTypeRef(method.getReturnTypeRef(), thisTypeRef); + newMethod.setDeclaredReturnTypeRefNode(_TypeReferenceNode(getState(), typeRef)); + getState().info.setOriginalProcessedTypeRef(newMethod.getDeclaredReturnTypeRefNode(), typeRef); + + return newMethod; + } + + private TypeRef getConcreteTypeRef(TypeRef typeRef, TypeRef thisTypeRef) { + RuleEnvironment localG = wrap(getState().G); + setThisBinding(localG, thisTypeRef); + var concreteTypeRef = ts.substTypeVariables(localG, typeRef); + concreteTypeRef = ts.upperBoundWithReopen(getState().G, concreteTypeRef); + return concreteTypeRef; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ThisTypeTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ThisTypeTransformation.xtend deleted file mode 100644 index 9b72334c8e..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/ThisTypeTransformation.xtend +++ /dev/null @@ -1,263 +0,0 @@ -/** - * Copyright (c) 2021 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.transpiler.dts.transform - -import com.google.common.base.Preconditions -import com.google.inject.Inject -import java.util.ArrayList -import java.util.HashMap -import java.util.HashSet -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.FormalParameter -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.n4JS.N4MethodDeclaration -import org.eclipse.n4js.n4JS.N4Modifier -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.ts.typeRefs.ThisTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * This transformation replaces some ThisTypeRefs by concrete type references - * iff they occur in static methods or constructors. This is true for the following cases: - *
    - *
  • replace spec parameter (this-type) of constructors by concrete type - *
  • add (missing) spec constructor iff superclass defines one - *
  • replace return this-type of static methods by concrete type - *
  • add method override for all static methods returning this-types to replace return type by concrete type - *
- */ -class ThisTypeTransformation extends Transformation { - - @Inject - private N4JSTypeSystem ts; - - @Inject - private TypeSystemHelper tsh; - - - override assertPreConditions() { - } - - override assertPostConditions() { - } - - override analyze() { - // ignore - } - - override transform() { - transformThisTypeRefs(); - } - - def private void transformThisTypeRefs() { - val classes = collectNodes(state.im, true, N4ClassDeclaration); - - for (clazz : classes) { - val clazzOrig = state.tracer.getOriginalASTNode(clazz) as N4ClassDeclaration; - - val methods = collectNodes(clazz, false, N4MethodDeclaration); - val methodNamesCurClass = new HashSet(); - var N4MethodDeclaration ctor = null; - for (method : methods) { - if (method.isConstructor) { - ctor = method; - } else if (method.isStatic) { - methodNamesCurClass += method.name; - // special handling for return type 'this' of static methods - val retTR = state.info.getOriginalProcessedTypeRef(method.declaredReturnTypeRefNode); - if (retTR instanceof ThisTypeRef) { - val methodOrig = state.tracer.getOriginalASTNodeOfSameType(method, false); - var typeRef = tsh.bindAndSubstituteThisTypeRef(state.G, methodOrig, retTR); - typeRef = ts.upperBoundWithReopen(state.G, typeRef); - if (typeRef.generic) { - typeRef = TypeUtils.copyIfContained(typeRef); - val newTypeArgsCount = typeRef.declaredType.typeVars.size; - typeRef.declaredTypeArgs.clear; // only 'any' allowed here by TypeScript - for (var i = 0; i < newTypeArgsCount; i++) { - typeRef.declaredTypeArgs.add(TypeRefsFactory.eINSTANCE.createWildcard); - } - } - state.info.setOriginalProcessedTypeRef(method.declaredReturnTypeRefNode, typeRef); - } - } - } - - if (ctor !== null) { - // special handling for constructor parameter @Spec ~i~this - val specFPar = getSpecFPar(ctor); - if (specFPar !== null) { - val specFParOrig = state.tracer.getOriginalASTNodeOfSameType(specFPar, false); - if (specFParOrig !== null) { - var typeRef = state.info.getOriginalProcessedTypeRef(specFPar.declaredTypeRefNode); - typeRef = tsh.bindAndSubstituteThisTypeRef(state.G, specFParOrig, typeRef); - typeRef = ts.upperBoundWithReopen(state.G, typeRef); - state.info.setOriginalProcessedTypeRef(specFPar.declaredTypeRefNode, typeRef); - } - } - - } else { - // search spec constructor in superclass and put its signature here and replace return 'this' type by actual type - val specConstructorOrig = findSpecConstructorInSuperclass(clazzOrig); - if (specConstructorOrig !== null) { - addOverwritingSpecConstructor(specConstructorOrig, clazz); - } - } - - val staticMethodsReturingThisInSuperclasses = findStaticMethodsReturingThisInSuperclasses(clazzOrig); - for (method : staticMethodsReturingThisInSuperclasses) { - if (!methodNamesCurClass.contains(method.name)) { - // put signature here and replace return 'this' type by actual type - addOverwritingStaticMethod(method, clazz); - } - } - } - } - - def TMethod[] findStaticMethodsReturingThisInSuperclasses(N4ClassDeclaration clazzOrig) { - val name2method = new HashMap(); - var curClass = clazzOrig.definedTypeAsClass; - while (curClass.superClass !== null) { - curClass = curClass.superClass; - for (member : curClass.ownedMembers) { - if (member instanceof TMethod) { - if (member.isStatic && member.returnTypeRef instanceof ThisTypeRef) { - name2method.putIfAbsent(member.name, member); - } - } - } - } - - return name2method.values; - } - - def TMethod findSpecConstructorInSuperclass(N4ClassDeclaration clazzOrig) { - var curClass = clazzOrig.definedTypeAsClass; - do { - if (curClass.superClass === null) { - return null; - } - curClass = curClass.superClass; - val ctor = curClass.ownedCtor - - if (isSpecConstructor(ctor)) { - return ctor; - } else if (ctor !== null) { - return null; - } - } while (true); - } - - def N4MethodDeclaration getConstructor(N4ClassDeclaration clazz) { - val methods = clazz.ownedMethods; - for (method : methods) { - if (method.isConstructor) { - return method; - } - } - return null; - } - - def FormalParameter getSpecFPar(N4MethodDeclaration method) { - if (method === null) { - return null; - } - if (!method.isConstructor) { - return null; - } - if (method.fpars.empty) { - return null; - } - for (fpar : method.fpars) { - if (AnnotationDefinition.SPEC.hasAnnotation(fpar)) { - return fpar; - } - } - return null; - } - - def boolean isSpecConstructor(TMethod method) { - if (method === null) { - return false; - } - if (!method.isConstructor) { - return false; - } - if (method.fpars.empty) { - return false; - } - for (fpar : method.fpars) { - if (AnnotationDefinition.SPEC.hasAnnotation(fpar)) { - return true; - } - } - return false; - } - - def N4MethodDeclaration addOverwritingSpecConstructor(TMethod constructor, N4ClassDeclaration clazz) { - val clazzOrig = state.tracer.getOriginalASTNode(clazz) as N4ClassDeclaration; - val newConstructor = _N4MethodDecl("constructor", new ArrayList()); - clazz.ownedMembersRaw += newConstructor; - for (fpar: constructor.fpars) { - val newFPar = _FormalParameter(fpar.name); - newConstructor.fpars += newFPar; - var typeRef = fpar.typeRef; - if (AnnotationDefinition.SPEC.hasAnnotation(fpar)) { - val thisTypeRef = TypeUtils.createTypeRefWithParamsAsArgs(clazzOrig.definedType); - typeRef = getConcreteTypeRef(fpar.typeRef, thisTypeRef); - } - - newFPar.declaredTypeRefNode = _TypeReferenceNode(state, typeRef); - state.info.setOriginalProcessedTypeRef(newFPar.declaredTypeRefNode, typeRef); - } - return newConstructor; - } - - def N4MethodDeclaration addOverwritingStaticMethod(TMethod method, N4ClassDeclaration clazz) { - val clazzOrig = state.tracer.getOriginalASTNode(clazz) as N4ClassDeclaration; - val newMethod = _N4MethodDecl(method.name); - newMethod.declaredModifiers += N4Modifier.STATIC; - clazz.ownedMembersRaw += newMethod; - for (fpar: method.fpars) { - val newFPar = _FormalParameter(fpar.name); - newMethod.fpars += newFPar; - var typeRef = fpar.typeRef; - newFPar.declaredTypeRefNode = _TypeReferenceNode(state, typeRef); - state.info.setOriginalProcessedTypeRef(newFPar.declaredTypeRefNode, typeRef); - } - - - Preconditions.checkState(method.returnTypeRef instanceof ThisTypeRef); - - val thisTypeRef = TypeUtils.createTypeRef(clazzOrig.definedType, clazzOrig.typingStrategy, true); - val typeRef = getConcreteTypeRef(method.returnTypeRef, thisTypeRef); - newMethod.declaredReturnTypeRefNode = _TypeReferenceNode(state, typeRef); - state.info.setOriginalProcessedTypeRef(newMethod.declaredReturnTypeRefNode, typeRef); - - return newMethod; - } - - def private TypeRef getConcreteTypeRef(TypeRef typeRef, TypeRef thisTypeRef) { - val localG = state.G.wrap; - setThisBinding(localG, thisTypeRef); - var concreteTypeRef = ts.substTypeVariables(localG, typeRef); - concreteTypeRef = ts.upperBoundWithReopen(state.G, concreteTypeRef); - return concreteTypeRef; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TrimTransformationDts.java b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TrimTransformationDts.java new file mode 100644 index 0000000000..10afea981a --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TrimTransformationDts.java @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2021 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.transpiler.dts.transform; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.Block; +import org.eclipse.n4js.n4JS.ControlFlowElement; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.FunctionDeclaration; +import org.eclipse.n4js.n4JS.ModifierUtils; +import org.eclipse.n4js.n4JS.N4EnumLiteral; +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.ScriptElement; +import org.eclipse.n4js.n4JS.Statement; +import org.eclipse.n4js.n4JS.VariableBinding; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.VariableDeclarationOrBinding; +import org.eclipse.n4js.n4JS.VariableStatement; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.ts.types.MemberAccessModifier; +import org.eclipse.n4js.ts.types.TypeAccessModifier; + +/** + * Removes everything from the IM that is not required for .d.ts export. + */ +public class TrimTransformationDts extends Transformation { + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + List remove1 = new ArrayList<>(); + for (ScriptElement se : getState().im.getScriptElements()) { + if (isPureStatement(se)) { + remove1.add(se); + } + } + for (ScriptElement se : remove1) { + remove(se); + } + + List remove2 = new ArrayList<>(); + for (ControlFlowElement se : collectNodes(getState().im, false, Expression.class, Block.class)) { + if (!isValueOfEnum(se)) { + remove2.add(se); + } + } + for (ControlFlowElement se : remove2) { + remove(se); + } + + // remove all non-public members from interfaces + List remove3 = new ArrayList<>(); + for (N4InterfaceDeclaration intfDecl : collectNodes(getState().im, false, N4InterfaceDeclaration.class)) { + intfDecl.getOwnedMembers(); + for (N4MemberDeclaration member : intfDecl.getOwnedMembers()) { + if (!member.isStatic() && !isPublicMember(member)) { + remove3.add(member); + } + } + } + for (N4MemberDeclaration se : remove3) { + remove(se); + } + + // remove all destructuring patterns (and turn them into plain variable declarations) + for (VariableStatement vs : collectNodes(getState().im, false, VariableStatement.class)) { + convertDestructuringToOrdinaryVariableDeclarations(vs); + } + } + + private boolean isPureStatement(EObject obj) { + if (obj instanceof Statement) { + if (obj instanceof VariableStatement + || obj instanceof FunctionDeclaration) { + return false; + } + return true; + } + return false; + } + + private boolean isValueOfEnum(EObject obj) { + EObject parent = obj == null ? null : obj.eContainer(); + return parent instanceof N4EnumLiteral + && obj == ((N4EnumLiteral) parent).getValueExpression(); + } + + // TODO GH-2153 use reusable utility method for computing actual accessibility + private boolean isPublicMember(N4MemberDeclaration memberDecl) { + MemberAccessModifier declaredModifier = ModifierUtils + .convertToMemberAccessModifier(memberDecl.getDeclaredModifiers(), memberDecl.getAllAnnotations()); + if (declaredModifier == MemberAccessModifier.UNDEFINED) { + EObject parentDecl = memberDecl.eContainer(); + if (parentDecl instanceof N4InterfaceDeclaration) { + N4InterfaceDeclaration pInterfDecl = (N4InterfaceDeclaration) parentDecl; + TypeAccessModifier parentDeclModifier = ModifierUtils.convertToTypeAccessModifier( + pInterfDecl.getDeclaredModifiers(), pInterfDecl.getAllAnnotations()); + if (parentDeclModifier == TypeAccessModifier.PUBLIC) { + return true; + } + } + } + return declaredModifier == MemberAccessModifier.PUBLIC; + } + + private void convertDestructuringToOrdinaryVariableDeclarations(VariableStatement varStmnt) { + List varDeclsToBeMoved = new ArrayList<>(); + List varBindingToBeRemoved = new ArrayList<>(); + for (VariableDeclarationOrBinding root : varStmnt.getVarDeclsOrBindings()) { + if (root instanceof VariableDeclaration) { + // root is a variable declaration + // --> need not be moved + } else if (root instanceof VariableBinding) { + // root is a VariableBinding + // --> all contained variable declarations must be moved to the root level + varDeclsToBeMoved.addAll(root.getAllVariableDeclarations()); + varBindingToBeRemoved.add((VariableBinding) root); + } else { + throw new UnsupportedOperationException("unsupported subclass of " + + VariableDeclarationOrBinding.class.getSimpleName() + ": " + root.eClass().getName()); + } + } + + // move all variable declarations in 'varDeclsToBeMoved' to the root level + for (VariableDeclaration varDecl : varDeclsToBeMoved) { + varStmnt.getVarDeclsOrBindings().add(varDecl); // will be automatically removed from old location by EMF + } + + // remove all variable bindings + for (VariableBinding varBinding : varBindingToBeRemoved) { + remove(varBinding); + } + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TrimTransformationDts.xtend b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TrimTransformationDts.xtend deleted file mode 100644 index 9ed4106cce..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TrimTransformationDts.xtend +++ /dev/null @@ -1,125 +0,0 @@ -/** - * Copyright (c) 2021 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.transpiler.dts.transform - -import com.google.common.collect.Lists -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.Block -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.FunctionDeclaration -import org.eclipse.n4js.n4JS.ModifierUtils -import org.eclipse.n4js.n4JS.N4EnumLiteral -import org.eclipse.n4js.n4JS.N4InterfaceDeclaration -import org.eclipse.n4js.n4JS.N4MemberDeclaration -import org.eclipse.n4js.n4JS.Statement -import org.eclipse.n4js.n4JS.VariableBinding -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.n4JS.VariableDeclarationOrBinding -import org.eclipse.n4js.n4JS.VariableStatement -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.ts.types.MemberAccessModifier -import org.eclipse.n4js.ts.types.TypeAccessModifier - -/** - * Removes everything from the IM that is not required for .d.ts export. - */ -class TrimTransformationDts extends Transformation { - - override assertPreConditions() { - } - - override assertPostConditions() { - } - - override analyze() { - // ignore - } - - override transform() { - val toBeRemoved1 = Lists.newArrayList(state.im.scriptElements.filter[isPureStatement]); - toBeRemoved1.forEach[remove(it)]; - - val toBeRemoved2 = collectNodes(state.im, false, Expression, Block).filter[!isValueOfEnum(it)]; - toBeRemoved2.forEach[remove(it)]; - - // remove all non-public members from interfaces - val toBeRemoved3 = collectNodes(state.im, false, N4InterfaceDeclaration) - .flatMap[ownedMembers] - .filter[!static] - .filter[!isPublicMember(it)] - .toList; - toBeRemoved3.forEach[remove(it)]; - - // remove all destructuring patterns (and turn them into plain variable declarations) - collectNodes(state.im, false, VariableStatement) - .forEach[convertDestructuringToOrdinaryVariableDeclarations]; - } - - def private boolean isPureStatement(EObject obj) { - if (obj instanceof Statement) { - if (obj instanceof VariableStatement - || obj instanceof FunctionDeclaration) { - return false; - } - return true; - } - return false; - } - - def private boolean isValueOfEnum(EObject obj) { - val parent = obj?.eContainer(); - return parent instanceof N4EnumLiteral - && obj === (parent as N4EnumLiteral).valueExpression; - } - - // TODO GH-2153 use reusable utility method for computing actual accessibility - def private boolean isPublicMember(N4MemberDeclaration memberDecl) { - val declaredModifier = ModifierUtils.convertToMemberAccessModifier(memberDecl.declaredModifiers, memberDecl.allAnnotations); - if (declaredModifier === MemberAccessModifier.UNDEFINED) { - val parentDecl = memberDecl.eContainer; - if (parentDecl instanceof N4InterfaceDeclaration) { - val parentDeclModifier = ModifierUtils.convertToTypeAccessModifier(parentDecl.declaredModifiers, parentDecl.allAnnotations); - if (parentDeclModifier === TypeAccessModifier.PUBLIC) { - return true; - } - } - } - return declaredModifier === MemberAccessModifier.PUBLIC; - } - - def private void convertDestructuringToOrdinaryVariableDeclarations(VariableStatement varStmnt) { - val varDeclsToBeMoved = newArrayList; - val varBindingToBeRemoved = newArrayList; - for (root : varStmnt.varDeclsOrBindings) { - if (root instanceof VariableDeclaration) { - // root is a variable declaration - // --> need not be moved - } else if (root instanceof VariableBinding) { - // root is a VariableBinding - // --> all contained variable declarations must be moved to the root level - varDeclsToBeMoved += root.allVariableDeclarations; - varBindingToBeRemoved += root; - } else { - throw new UnsupportedOperationException("unsupported subclass of " + VariableDeclarationOrBinding.simpleName + ": " + root.eClass.name); - } - } - - // move all variable declarations in 'varDeclsToBeMoved' to the root level - for (varDecl : varDeclsToBeMoved) { - varStmnt.varDeclsOrBindings += varDecl; // will be automatically removed from old location by EMF - } - - // remove all variable bindings - for (varBinding : varBindingToBeRemoved) { - remove(varBinding); - } - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.java b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.java new file mode 100644 index 0000000000..92838a678b --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.java @@ -0,0 +1,709 @@ +/** + * Copyright (c) 2021 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.transpiler.dts.transform; + +import static org.eclipse.n4js.transpiler.utils.TranspilerUtils.isLegalIdentifier; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.intType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.isArrayN; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.iteratorEntryType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.objectType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.promiseType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.undefinedType; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Consumer; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.N4JSGlobals; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.scoping.builtin.N4Scheme; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.TranspilerState; +import org.eclipse.n4js.transpiler.assistants.TypeAssistant; +import org.eclipse.n4js.transpiler.dts.utils.DtsUtils; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.transpiler.im.TypeReferenceNode_IM; +import org.eclipse.n4js.ts.typeRefs.ComposedTypeRef; +import org.eclipse.n4js.ts.typeRefs.EnumLiteralTypeRef; +import org.eclipse.n4js.ts.typeRefs.ExistentialTypeRef; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeRef; +import org.eclipse.n4js.ts.typeRefs.IntersectionTypeExpression; +import org.eclipse.n4js.ts.typeRefs.LiteralTypeRef; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRefStructural; +import org.eclipse.n4js.ts.typeRefs.ThisTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeArgument; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeTypeRef; +import org.eclipse.n4js.ts.typeRefs.UnionTypeExpression; +import org.eclipse.n4js.ts.typeRefs.UnknownTypeRef; +import org.eclipse.n4js.ts.typeRefs.Wildcard; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.TEnum; +import org.eclipse.n4js.ts.types.TEnumLiteral; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.TSetter; +import org.eclipse.n4js.ts.types.TStructMember; +import org.eclipse.n4js.ts.types.TTypedElement; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind; +import org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot; +import org.eclipse.n4js.workspace.WorkspaceAccess; +import org.eclipse.xtext.EcoreUtil2; + +import com.google.common.base.Strings; +import com.google.common.collect.Lists; +import com.google.inject.Inject; + +/** + * For each {@link TypeReferenceNode_IM} in the intermediate model, this transformation will + *
    + *
  1. produce a string representation and store it in property {@link TypeReferenceNode_IM#getCodeToEmit() codeToEmit}, + * and + *
  2. record all types actually referenced by that string in property + * {@link TypeReferenceNode_IM#getRewiredReferences() rewiredReferences}. + *
+ */ +public class TypeReferenceTransformation extends Transformation { + + private TypeReferenceNode_IM currTypeRefNode = null; + private StringBuilder currStringBuilder = null; + + private final Map referenceCache = new HashMap<>(); + + @Inject + private TypeAssistant typeAssistant; + + @Inject + private WorkspaceAccess workspaceAccess; + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + for (TypeReferenceNode typeRefNode : collectNodes(getState().im, TypeReferenceNode.class, false)) { + // if you get a ClassCastException here, it means that not all TypeReferenceNodes were + // converted to TypeReferenceNode_IMs, which is an error + TypeReferenceNode_IM typeRefNodeCasted = (TypeReferenceNode_IM) typeRefNode; + + try { + currTypeRefNode = typeRefNodeCasted; + currStringBuilder = new StringBuilder(); + convertTypeRefNode(typeRefNodeCasted); + if (currStringBuilder.length() == 0) { + // we expect #convertTypeRefNode() to always produce some output code + // (if the type reference cannot be converted to TypeScript, 'any' or something similar should be + // emitted) + throw new IllegalStateException( + "converting the type reference of a TypeReferenceNode produced empty output code"); + } + typeRefNodeCasted.setCodeToEmit(currStringBuilder.toString()); + } finally { + currTypeRefNode = null; + currStringBuilder = null; + } + } + } + + private void convertTypeRefNode(TypeReferenceNode_IM typeRefNode) { + var typeRef = getState().info.getOriginalProcessedTypeRef(typeRefNode); + + // special handling for return types + boolean isReturnType = typeRefNode + .eContainmentFeature() == N4JSPackage.Literals.FUNCTION_DEFINITION__DECLARED_RETURN_TYPE_REF_NODE; + if (isReturnType) { + FunctionDefinition funDef = (FunctionDefinition) typeRefNode.eContainer(); + + // handle outer return type of asynchronous and/or generator functions + if ((funDef.isGenerator() || funDef.isAsync()) + && !N4JSLanguageUtils.hasExpectedSpecialReturnType(typeRef, funDef, getState().builtInTypeScope)) { + + TypeRef outerReturnTypeRef = typeAssistant.getReturnTypeRef(getState(), funDef); + typeRef = outerReturnTypeRef; + } + } + + Type declType = typeRef.getDeclaredType(); + boolean isExtendsClass = typeRefNode + .eContainmentFeature() == N4JSPackage.Literals.N4_CLASS_DEFINITION__SUPER_CLASS_REF; + if (isExtendsClass && isArrayN(getState().G, declType)) { + // special case: ArrayN in extends clause + String referenceStr = getReferenceToType(declType, getState()); + write(referenceStr); + convertTypeArguments((ParameterizedTypeRef) typeRef); + } else { + // standard case + convertTypeRef(typeRef); + } + + if (isReturnType) { + FunctionDefinition funDef = (FunctionDefinition) typeRefNode.eContainer(); + FunctionDefinition funDefInAST = getState().tracer.getOriginalASTNodeOfSameType(funDef, false); + if (funDefInAST != null) { + if (funDefInAST.isReturnValueOptional()) { + writeSuffixForReturnTypeOfFunctionWithOptionalReturnValue(true); + } + } + } + } + + private void convertDeclaredTypeRef(TTypedElement elem) { + TypeRef declaredTypeRef = elem.getTypeRef(); + if (declaredTypeRef != null) { + write(": "); + convertTypeRef(declaredTypeRef); + } + } + + private void convertTypeRef(TypeRef typeRefRaw) { + if (typeRefRaw == null) { + return; + } + + var typeRef = typeRefRaw; + + // if type aliases are used in the n4js[d] source code, we want the alias to show up in the .d.ts output, so we + // have to use the original alias type reference instead of the resolved alias type reference here: + if (typeRef.isAliasResolved()) { + TypeRef originalAliasTypeRef = typeRef.getOriginalAliasTypeRef(); + if (originalAliasTypeRef != null) { + typeRef = originalAliasTypeRef; + } + } + + if (typeRef instanceof ComposedTypeRef) { + convertComposedTypeRef((ComposedTypeRef) typeRef); + } else if (typeRef instanceof FunctionTypeExprOrRef) { + convertFunctionTypeExprOrRef((FunctionTypeExprOrRef) typeRef); + } else if (typeRef instanceof ParameterizedTypeRef) { + convertParameterizedTypeRef((ParameterizedTypeRef) typeRef); + } else if (typeRef instanceof ThisTypeRef) { + convertThisTypeRef((ThisTypeRef) typeRef); + } else if (typeRef instanceof ExistentialTypeRef) { + write("any"); // unsupported type reference + } else if (typeRef instanceof TypeTypeRef) { + write("any"); // unsupported type reference + } else if (typeRef instanceof LiteralTypeRef) { + convertLiteralTypeRef((LiteralTypeRef) typeRef); + } else if (typeRef instanceof UnknownTypeRef) { + write("any"); // unsupported type reference + } else { + throw new IllegalStateException( + "unknown subclass of " + TypeRef.class.getSimpleName() + ": " + typeRef.getClass().getSimpleName()); + } + } + + private void convertComposedTypeRef(ComposedTypeRef typeRef) { + char op; + if (typeRef instanceof UnionTypeExpression) { + op = '|'; + } else if (typeRef instanceof IntersectionTypeExpression) { + op = '&'; + } else { + throw new IllegalStateException("unknown subclass of " + ComposedTypeRef.class.getSimpleName() + ": " + + typeRef.getClass().getSimpleName()); + } + EList typeRefs = typeRef.getTypeRefs(); + write(typeRefs, tr -> convertMemberTypeRef(tr), " " + op + " "); + } + + /** Convert the member of a composed type reference. */ + private void convertMemberTypeRef(TypeRef memberTypeRef) { + boolean requiresParentheses = memberTypeRef instanceof ComposedTypeRef + || memberTypeRef instanceof FunctionTypeExprOrRef; + if (requiresParentheses) { + write("("); + } + convertTypeRef(memberTypeRef); + if (requiresParentheses) { + write(")"); + } + } + + private void convertFunctionTypeExprOrRef(FunctionTypeExprOrRef typeRef) { + EList fpars = typeRef.getFpars(); + TypeRef returnTypeRef = typeRef.getReturnTypeRef(); + write("("); + convertTFormalParameters(fpars); + write(")=>"); + if (returnTypeRef != null) { + convertTypeRef(returnTypeRef); + if (typeRef.isReturnValueOptional()) { + writeSuffixForReturnTypeOfFunctionWithOptionalReturnValue(false); + } + } else { + // TypeScript's default return type is 'any', so we need to emit 'void' in this case! + write("void"); + } + } + + private void convertParameterizedTypeRef(ParameterizedTypeRef typeRef) { + if (typeRef instanceof FunctionTypeRef) { + convertFunctionTypeExprOrRef((FunctionTypeRef) typeRef); + return; + } + Type declType = typeRef.getDeclaredType(); + + if (isArrayN(getState().G, declType)) { + convertTypeArguments(typeRef, "[", "]"); + return; + } + + boolean hasStructMembers = typeRef instanceof ParameterizedTypeRefStructural + && !typeRef.getStructuralMembers().isEmpty(); + boolean showDeclaredType = !hasStructMembers + || declType != objectType(getState().G); + + if (showDeclaredType && hasStructMembers) { + write("("); + } + + if (showDeclaredType) { + String referenceStr = (declType == null) ? null : getReferenceToType(declType, getState()); + if (referenceStr != null) { + String prependType = getStructuralTypeReplacements(typeRef); + write(prependType); + + write(referenceStr); + convertTypeArguments(typeRef); + + write(Strings.isNullOrEmpty(prependType) ? "" : ">"); + + } else { + write("any"); + } + } + + if (hasStructMembers) { + EList members = typeRef.getStructuralMembers(); + if (showDeclaredType) { + write(" & "); + } + write("{"); + write(members, m -> convertTMember(m), "; "); // ',' would also be allowed as separator + write("}"); + } + + if (showDeclaredType && hasStructMembers) { + write(")"); + } + } + + private void convertThisTypeRef(ThisTypeRef typeRef) { + String prependType = getStructuralTypeReplacements(typeRef); + write(prependType); + + write("this"); + + write(Strings.isNullOrEmpty(prependType) ? "" : ">"); + } + + private void convertLiteralTypeRef(LiteralTypeRef typeRef) { + if (typeRef instanceof EnumLiteralTypeRef) { + TEnum enumType = ((EnumLiteralTypeRef) typeRef).getEnumType(); + String referenceStr = (enumType == null) ? null : getReferenceToType(enumType, getState()); + if (referenceStr != null) { + write(referenceStr); + TEnumLiteral value = ((EnumLiteralTypeRef) typeRef).getValue(); + String enumLiteralName = value == null ? null : value.getName(); + EnumKind enumKind = N4JSLanguageUtils.getEnumKind(enumType); + if (enumLiteralName != null + && (enumKind == EnumKind.NumberBased || enumKind == EnumKind.StringBased)) { + write("."); + write(enumLiteralName); + } + } else { + write("any"); + } + } else { + write(typeRef.getTypeRefAsString()); + } + } + + private String getStructuralTypeReplacements(TypeRef typeRef) { + switch (typeRef.getTypingStrategy()) { + case STRUCTURAL_FIELDS: + return "StructuralFields<"; + case STRUCTURAL_READ_ONLY_FIELDS: + return "StructuralReadOnly<"; + case STRUCTURAL_WRITE_ONLY_FIELDS: + return "StructuralWriteOnly<"; + case STRUCTURAL_FIELD_INITIALIZER: + return "StructuralInititializers<"; + default: + return ""; + } + } + + private void convertTypeArguments(ParameterizedTypeRef typeRef) { + convertTypeArguments(typeRef, "<", ">"); + } + + private void convertTypeArguments(ParameterizedTypeRef typeRef, String prefix, String suffix) { + List typeArgs = typeRef.getDeclaredTypeArgs(); + if (typeArgs.isEmpty()) { + return; + } + + // special handling for certain types + Type declType = typeRef.getDeclaredType(); + if (declType == promiseType(getState().G) && typeArgs.size() > 1) { + // Promise in N4JS has more than one type parameter, whereas in TypeScript it has only one + typeArgs = Lists.newArrayList(typeArgs.get(0)); + } + + write(prefix); + write(typeArgs, ta -> convertTypeArgument(ta), ", "); + write(suffix); + } + + private void convertTypeArgument(TypeArgument typeArg) { + if (typeArg instanceof Wildcard) { + TypeRef upperBound = ((Wildcard) typeArg).getDeclaredOrImplicitUpperBound(); + if (upperBound != null) { + convertTypeArgument(upperBound); + } else { + write("any"); // TypeScript does not support lower bounds + } + return; + } + + TypeRef typeRef = (TypeRef) typeArg; + + // type 'undefined' used as type argument in N4JS, corresponds to 'void' in TypeScript: + if (typeRef.getDeclaredType() == undefinedType(getState().G)) { + // DISABLED (it leads to compile problems if an upper bound is in effect, because 'void' won't be a subtype + // of the upper bound, but 'undefined' will be; since we cannot easily find out whether an upper bound is in + // effect at this point in the code, we disable this special replacement with 'void' for now: + + // write("void"); + // return; + } + + convertTypeRef(typeRef); + } + + private void convertTFormalParameters(Iterable fpars) { + write(fpars, fp -> convertTFormalParameter(fp), ", "); + } + + private void convertTFormalParameter(TFormalParameter fpar) { + if (fpar.isVariadic()) { + write("..."); + } + String name = fpar.getName(); + if (name != null) { + write(name); + } else { + // Note: the name is mandatory in TypeScript; however, we create synthetic names for fpars in the types + // builder, so we should never reach this point: + throw new IllegalStateException("encountered a TFormalParameter without a (synthetic) name"); + } + if (!fpar.isVariadic() && fpar.isOptional()) { + write("?"); + } + TypeRef typeRef = fpar.getTypeRef(); + if (typeRef != null) { + write(": "); + convertTypeRef(typeRef); + if (fpar.isVariadic()) { + write("[]"); // TypeScript expect an array type + } + } + } + + private void convertTMember(TMember member) { + if (member instanceof TField) { + convertTMember((TField) member); + } else if (member instanceof TGetter) { + convertTMember((TGetter) member); + } else if (member instanceof TSetter) { + convertTMember((TSetter) member); + } else if (member instanceof TMethod) { + convertTMember((TMethod) member); + } else { + throw new IllegalStateException( + "unknown subclass of " + TMember.class.getSimpleName() + ": " + member.getClass().getSimpleName()); + } + } + + private void convertTMember(TField field) { + writeQuotedIfNonIdentifier(field.getName()); + convertDeclaredTypeRef(field); + } + + private void convertTMember(TGetter getter) { + write("get "); + writeQuotedIfNonIdentifier(getter.getName()); + write("(): "); + TypeRef typeRef = getter.getTypeRef(); + if (typeRef != null) { + convertTypeRef(typeRef); + } else { + write("any"); + } + } + + private void convertTMember(TSetter setter) { + write("set "); + writeQuotedIfNonIdentifier(setter.getName()); + write("("); + convertTFormalParameters(Collections.singletonList(setter.getFpar())); + write(")"); + } + + private void convertTMember(TMethod method) { + writeQuotedIfNonIdentifier(method.getName()); + write("("); + convertTFormalParameters(method.getFpars()); + write("): "); + TypeRef returnTypeRef = method.getReturnTypeRef(); + if (returnTypeRef != null) { + convertTypeRef(returnTypeRef); + } else { + // TypeScript's default return type is 'any', so we need to emit 'void' in this case! + write("void"); + } + } + + /** + * @param isReturnTypeOfActualFunction + * the caller should pass in {@code true} iff the return type to emit is for an "actual function", i.e. a + * declared function, a method, or a function expression (as opposed to the return type of a pure + * function type expression inside a type annotation). + */ + private void writeSuffixForReturnTypeOfFunctionWithOptionalReturnValue(boolean isReturnTypeOfActualFunction) { + // note: due to limitations in N4JS, the return type of a function with an optional return value cannot be a + // ComposedTypeRef, + // so we do not need to bother with parentheses around the actual return type reference + if (isReturnTypeOfActualFunction) { + write("|undefined"); + } else { + write("|void"); + } + } + + private void write(Iterable nodesInIM, Consumer processor, + String separator) { + + Iterator iter = nodesInIM.iterator(); + while (iter.hasNext()) { + processor.accept(iter.next()); + if (separator != null && iter.hasNext()) { + write(separator); + } + } + } + + private void write(CharSequence csq) { + currStringBuilder.append(csq); + } + + private void writeQuotedIfNonIdentifier(String csq) { + if (!isLegalIdentifier(csq)) { + write("'"); + write(csq); + write("'"); + } else { + write(csq); + } + } + + /** + * Returns the textual reference that can be used in the local file to refer to the given type (adding an import for + * the given type, if necessary), or null if the type cannot be referred to from the local file. + *

+ * The returned string is usually simply the local name of the given type, but includes, if required, also the name + * of a namespace and "." as separator. + */ + private String getReferenceToType(Type type, TranspilerState state) { + // note: map 'referenceCache' may contain 'null' as value! + if (referenceCache.containsKey(type)) { + return referenceCache.get(type); + } + String reference = computeReferenceToType(type, state); + referenceCache.put(type, reference); + return reference; + } + + private String computeReferenceToType(Type type, TranspilerState state) { + boolean isLocal = isFromSameFileOrStaticPolyfill(type); + + if (!isLocal) { + if (!DtsUtils.isDtsExportableReference(type, state)) { + // the type is from a project not available on the .d.ts side, so we cut off the .d.ts export at this + // reference + return null; + } + + boolean isBuiltInOrGlobal = isBuiltInOrGlobal(type); + if (isBuiltInOrGlobal) { + // simple case: the type reference points to a built-in type OR a type from a global module + // -> can simply use its name in output code, because they are global and available everywhere + if (type == intType(state.G)) { + return "number"; + } else if (type == iteratorEntryType(state.G)) { + return "IteratorReturnResult"; + } + TModule containingModule = type.getContainingModule(); + if (containingModule != null + && Objects.equals(containingModule.getSimpleName(), "IntlClasses") + && Objects.equals(containingModule.getPackageName(), + N4JSGlobals.N4JS_RUNTIME_ECMA402.getRawName())) { + return "Intl." + type.getName(); + } + return type.getName(); + } + } + + SymbolTableEntryOriginal ste = getSymbolTableEntryOriginal(type, true); + if (ste == null) { + return null; + } + + // is the type already available? + var isAvailable = isLocal || ste.getImportSpecifier() != null; + if (!isAvailable) { + // no, so try to import it! + + if (type.isExported() && isFromSameProjectOrDirectDependency(type)) { + // note: no need to check accessibility modifiers in addition to #isExported(), because on + // TypeScript-side we bump up the accessibility + + String alias = hasNameConflict(ste, ste.getName()) ? findConflictFreeName(ste) : null; + + // add a new named import for this type + addNamedImport(ste, alias); + + // Try to delete following 3 lines + // for (IdentifiableElement idElem : state.steCache.mapOriginal.keySet()) { + // idElem.getName(); // What is this for? + // } + + ImportSpecifier is = ste.getImportSpecifier(); + if (is instanceof NamedImportSpecifier) { + NamedImportSpecifier nis = (NamedImportSpecifier) is; + ste.setName( + Strings.isNullOrEmpty(nis.getAlias()) ? nis.getImportedElementAsText() : nis.getAlias()); + } + if (is instanceof NamespaceImportSpecifier) { + ste.setName(((NamespaceImportSpecifier) is).getAlias()); + } + isAvailable = ste.getImportSpecifier() != null; + } + } + + // is the type now available? + if (isAvailable) { + // yes, so ... + + // 1) record that 'currTypeRefNode' is actually referring to 'type' + recordReferenceToType(currTypeRefNode, ste); + + // 2) compute output code that correctly refers to 'type' from within current file (depending on how the + // type was imported) + var referenceStr = ""; + ImportSpecifier importSpec = ste.getImportSpecifier(); + if (importSpec instanceof NamespaceImportSpecifier) { + String namespaceName = ((NamespaceImportSpecifier) importSpec).getAlias(); + referenceStr = namespaceName + "." + ste.getName(); + } else { + referenceStr = ste.getName(); + } + + return referenceStr; + } + + // we tried our best, but this type is not available in the current file AND cannot be made available + return null; + } + + private boolean hasNameConflict(SymbolTableEntryOriginal ste, String name) { + for (IdentifiableElement id : getState().steCache.mapOriginal.keySet()) { + if (id != ste.getOriginalTarget() && Objects.equals(id.getName(), name)) { + return true; + } + } + return false; + } + + private String findConflictFreeName(SymbolTableEntryOriginal ste) { + var i = 2; + while (hasNameConflict(ste, ste.getName() + i)) { + i++; + } + return ste.getName() + i; + } + + private boolean isFromSameFileOrStaticPolyfill(Type type) { + Resource typeResource = type.eResource(); + if (typeResource == getState().resource) { + return true; + } + TModule module = getState().resource.getModule(); + if (module != null && module.isStaticPolyfillAware()) { + TModule typeModule = type.getContainingModule(); + return typeModule != null + && typeModule.isStaticPolyfillModule() + && Objects.equals(typeModule.getQualifiedName(), module.getQualifiedName()); + } + return false; + } + + /** True if the given type is located in the local project or a project we directly depend on. */ + private boolean isFromSameProjectOrDirectDependency(Type type) { + N4JSProjectConfigSnapshot containingProject = workspaceAccess.findProjectContaining(type); + return containingProject != null + && (containingProject == getState().project + || getState().project.getDependencies().contains(containingProject.getName())); + } + + private static boolean isBuiltInOrGlobal(Type type) { + if (N4Scheme.isFromResourceWithN4Scheme(type)) { + return true; + } + TModule module = EcoreUtil2.getContainerOfType(type, TModule.class); + return module != null && AnnotationDefinition.GLOBAL.hasAnnotation(module); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.xtend deleted file mode 100644 index 9b3fb6ca72..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.xtend +++ /dev/null @@ -1,654 +0,0 @@ -/** - * Copyright (c) 2021 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.transpiler.dts.transform - -import com.google.common.base.Strings -import com.google.common.collect.Lists -import com.google.inject.Inject -import java.util.Collections -import java.util.HashMap -import java.util.List -import java.util.Map -import java.util.Objects -import java.util.function.Consumer -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.N4JSGlobals -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.N4JSPackage -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.n4JS.TypeReferenceNode -import org.eclipse.n4js.scoping.builtin.N4Scheme -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.TranspilerState -import org.eclipse.n4js.transpiler.assistants.TypeAssistant -import org.eclipse.n4js.transpiler.dts.utils.DtsUtils -import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal -import org.eclipse.n4js.transpiler.im.TypeReferenceNode_IM -import org.eclipse.n4js.ts.typeRefs.ComposedTypeRef -import org.eclipse.n4js.ts.typeRefs.EnumLiteralTypeRef -import org.eclipse.n4js.ts.typeRefs.ExistentialTypeRef -import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef -import org.eclipse.n4js.ts.typeRefs.FunctionTypeRef -import org.eclipse.n4js.ts.typeRefs.IntersectionTypeExpression -import org.eclipse.n4js.ts.typeRefs.LiteralTypeRef -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRefStructural -import org.eclipse.n4js.ts.typeRefs.ThisTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeArgument -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.typeRefs.TypeTypeRef -import org.eclipse.n4js.ts.typeRefs.UnionTypeExpression -import org.eclipse.n4js.ts.typeRefs.UnknownTypeRef -import org.eclipse.n4js.ts.typeRefs.Wildcard -import org.eclipse.n4js.ts.types.TField -import org.eclipse.n4js.ts.types.TFormalParameter -import org.eclipse.n4js.ts.types.TGetter -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.ts.types.TSetter -import org.eclipse.n4js.ts.types.TTypedElement -import org.eclipse.n4js.ts.types.Type -import org.eclipse.n4js.ts.types.TypingStrategy -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind -import org.eclipse.n4js.workspace.WorkspaceAccess -import org.eclipse.xtext.EcoreUtil2 - -import static org.eclipse.n4js.transpiler.utils.TranspilerUtils.isLegalIdentifier - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * For each {@link TypeReferenceNode_IM} in the intermediate model, this transformation will - *

    - *
  1. produce a string representation and store it in property {@link TypeReferenceNode_IM#getCodeToEmit() codeToEmit}, and - *
  2. record all types actually referenced by that string in property {@link TypeReferenceNode_IM#getRewiredReferences() rewiredReferences}. - *
- */ -class TypeReferenceTransformation extends Transformation { - - private TypeReferenceNode_IM currTypeRefNode = null; - private StringBuilder currStringBuilder = null; - - private final Map referenceCache = new HashMap(); - - @Inject - private TypeAssistant typeAssistant; - - @Inject - private WorkspaceAccess workspaceAccess; - - override assertPreConditions() { - } - - override assertPostConditions() { - } - - override analyze() { - // ignore - } - - override transform() { - collectNodes(state.im, TypeReferenceNode, false).forEach[ typeRefNode | - // if you get a ClassCastException here, it means that not all TypeReferenceNodes were - // converted to TypeReferenceNode_IMs, which is an error - val typeRefNodeCasted = typeRefNode as TypeReferenceNode_IM; - - try { - currTypeRefNode = typeRefNodeCasted; - currStringBuilder = new StringBuilder(); - convertTypeRefNode(typeRefNodeCasted); - if (currStringBuilder.length === 0) { - // we expect #convertTypeRefNode() to always produce some output code - // (if the type reference cannot be converted to TypeScript, 'any' or something similar should be emitted) - throw new IllegalStateException("converting the type reference of a TypeReferenceNode produced empty output code"); - } - typeRefNodeCasted.codeToEmit = currStringBuilder.toString(); - } finally { - currTypeRefNode = null; - currStringBuilder = null; - } - ]; - } - - def private void convertTypeRefNode(TypeReferenceNode_IM typeRefNode) { - var typeRef = state.info.getOriginalProcessedTypeRef(typeRefNode); - - // special handling for return types - val isReturnType = typeRefNode.eContainmentFeature === N4JSPackage.Literals.FUNCTION_DEFINITION__DECLARED_RETURN_TYPE_REF_NODE; - if (isReturnType) { - val funDef = typeRefNode.eContainer as FunctionDefinition; - - // handle outer return type of asynchronous and/or generator functions - if ((funDef.isGenerator() || funDef.isAsync()) - && !N4JSLanguageUtils.hasExpectedSpecialReturnType(typeRef, funDef, state.builtInTypeScope)) { - - val outerReturnTypeRef = typeAssistant.getReturnTypeRef(state, funDef); - typeRef = outerReturnTypeRef; - } - } - - val declType = typeRef.getDeclaredType(); - val isExtendsClass = typeRefNode.eContainmentFeature === N4JSPackage.Literals.N4_CLASS_DEFINITION__SUPER_CLASS_REF; - if (isExtendsClass && state.G.isArrayN(declType)) { - // special case: ArrayN in extends clause - val referenceStr = getReferenceToType(declType, state); - write(referenceStr); - convertTypeArguments(typeRef as ParameterizedTypeRef); - } else { - // standard case - convertTypeRef(typeRef); - } - - if (isReturnType) { - val funDef = typeRefNode.eContainer as FunctionDefinition; - val funDefInAST = state.tracer.getOriginalASTNodeOfSameType(funDef, false); - if (funDefInAST !== null) { - if (funDefInAST.isReturnValueOptional) { - writeSuffixForReturnTypeOfFunctionWithOptionalReturnValue(true); - } - } - } - } - - def private void convertDeclaredTypeRef(TTypedElement elem) { - val declaredTypeRef = elem.getTypeRef(); - if (declaredTypeRef !== null) { - write(": "); - convertTypeRef(declaredTypeRef); - } - } - - def private void convertTypeRef(TypeRef typeRefRaw) { - if (typeRefRaw === null) { - return; - } - - var typeRef = typeRefRaw; - - // if type aliases are used in the n4js[d] source code, we want the alias to show up in the .d.ts output, so we - // have to use the original alias type reference instead of the resolved alias type reference here: - if (typeRef.isAliasResolved()) { - val originalAliasTypeRef = typeRef.getOriginalAliasTypeRef(); - if (originalAliasTypeRef !== null) { - typeRef = originalAliasTypeRef; - } - } - - if (typeRef instanceof ComposedTypeRef) { - convertComposedTypeRef(typeRef); - } else if (typeRef instanceof FunctionTypeExprOrRef) { - convertFunctionTypeExprOrRef(typeRef); - } else if (typeRef instanceof ParameterizedTypeRef) { - convertParameterizedTypeRef(typeRef); - } else if (typeRef instanceof ThisTypeRef) { - convertThisTypeRef(typeRef); - } else if (typeRef instanceof ExistentialTypeRef) { - write("any"); // unsupported type reference - } else if (typeRef instanceof TypeTypeRef) { - write("any"); // unsupported type reference - } else if (typeRef instanceof LiteralTypeRef) { - convertLiteralTypeRef(typeRef); - } else if (typeRef instanceof UnknownTypeRef) { - write("any"); // unsupported type reference - } else { - throw new IllegalStateException("unknown subclass of " + TypeRef.simpleName + ": " + typeRef.getClass.simpleName); - } - } - - def private void convertComposedTypeRef(ComposedTypeRef typeRef) { - var char op; - if (typeRef instanceof UnionTypeExpression) { - op = '|'; - } else if (typeRef instanceof IntersectionTypeExpression) { - op = '&'; - } else { - throw new IllegalStateException("unknown subclass of " + ComposedTypeRef.simpleName + ": " + typeRef.getClass.simpleName); - } - val typeRefs = typeRef.getTypeRefs(); - write(typeRefs, [convertMemberTypeRef], " " + op + " "); - } - - /** Convert the member of a composed type reference. */ - def private void convertMemberTypeRef(TypeRef memberTypeRef) { - val requiresParentheses = memberTypeRef instanceof ComposedTypeRef - || memberTypeRef instanceof FunctionTypeExprOrRef; - if (requiresParentheses) { - write('('); - } - convertTypeRef(memberTypeRef); - if (requiresParentheses) { - write(')'); - } - } - - def private void convertFunctionTypeExprOrRef(FunctionTypeExprOrRef typeRef) { - val fpars = typeRef.getFpars(); - val returnTypeRef = typeRef.getReturnTypeRef(); - write('('); - convertTFormalParameters(fpars); - write(")=>"); - if (returnTypeRef !== null) { - convertTypeRef(returnTypeRef); - if (typeRef.isReturnValueOptional) { - writeSuffixForReturnTypeOfFunctionWithOptionalReturnValue(false); - } - } else { - // TypeScript's default return type is 'any', so we need to emit 'void' in this case! - write("void"); - } - } - - def private void convertParameterizedTypeRef(ParameterizedTypeRef typeRef) { - if (typeRef instanceof FunctionTypeRef) { - convertFunctionTypeExprOrRef(typeRef); - return; - } - val declType = typeRef.getDeclaredType(); - - if (state.G.isArrayN(declType)) { - convertTypeArguments(typeRef, "[", "]"); - return; - } - - val hasStructMembers = typeRef instanceof ParameterizedTypeRefStructural - && !typeRef.getStructuralMembers().isEmpty(); - val showDeclaredType = !hasStructMembers - || declType !== state.G.objectType; - - if (showDeclaredType && hasStructMembers) { - write('('); - } - - if (showDeclaredType) { - val referenceStr = if (declType !== null) { - getReferenceToType(declType, state); - }; - if (referenceStr !== null) { - val prependType = getStructuralTypeReplacements(typeRef); - write(prependType); - - write(referenceStr); - convertTypeArguments(typeRef); - - write(prependType.isNullOrEmpty ? "" : ">"); - - } else { - write("any"); - } - } - - if (hasStructMembers) { - val members = typeRef.getStructuralMembers(); - if (showDeclaredType) { - write(" & "); - } - write("{"); - write(members, [convertTMember], "; "); // ',' would also be allowed as separator - write("}"); - } - - if (showDeclaredType && hasStructMembers) { - write(')'); - } - } - - def private void convertThisTypeRef(ThisTypeRef typeRef) { - val prependType = getStructuralTypeReplacements(typeRef); - write(prependType); - - write("this"); - - write(prependType.isNullOrEmpty ? "" : ">"); - } - - def private void convertLiteralTypeRef(LiteralTypeRef typeRef) { - if (typeRef instanceof EnumLiteralTypeRef) { - val enumType = typeRef.enumType; - val referenceStr = if (enumType !== null) getReferenceToType(enumType, state); - if (referenceStr !== null) { - write(referenceStr); - val enumLiteralName = typeRef.value?.name; - val enumKind = N4JSLanguageUtils.getEnumKind(enumType); - if (enumLiteralName !== null - && (enumKind === EnumKind.NumberBased || enumKind === EnumKind.StringBased)) { - write('.'); - write(enumLiteralName); - } - } else { - write("any"); - } - } else { - write(typeRef.getTypeRefAsString()); - } - } - - def private String getStructuralTypeReplacements(TypeRef typeRef) { - return switch (typeRef.getTypingStrategy()) { - case TypingStrategy.STRUCTURAL_FIELDS: "StructuralFields<" - case TypingStrategy.STRUCTURAL_READ_ONLY_FIELDS: "StructuralReadOnly<" - case TypingStrategy.STRUCTURAL_WRITE_ONLY_FIELDS: "StructuralWriteOnly<" - case TypingStrategy.STRUCTURAL_FIELD_INITIALIZER: "StructuralInititializers<" - default: "" - }; - } - - def private void convertTypeArguments(ParameterizedTypeRef typeRef) { - convertTypeArguments(typeRef, "<", ">"); - } - - def private void convertTypeArguments(ParameterizedTypeRef typeRef, String prefix, String suffix) { - var List typeArgs = typeRef.getDeclaredTypeArgs(); - if (typeArgs.isEmpty()) { - return; - } - - // special handling for certain types - val declType = typeRef.getDeclaredType(); - if (declType === state.G.promiseType && typeArgs.size() > 1) { - // Promise in N4JS has more than one type parameter, whereas in TypeScript it has only one - typeArgs = Lists.newArrayList(typeArgs.get(0)); - } - - write(prefix); - write(typeArgs, [convertTypeArgument], ", "); - write(suffix); - } - - def private void convertTypeArgument(TypeArgument typeArg) { - if (typeArg instanceof Wildcard) { - val upperBound = typeArg.getDeclaredOrImplicitUpperBound(); - if (upperBound !== null) { - convertTypeArgument(upperBound); - } else { - write("any"); // TypeScript does not support lower bounds - } - return; - } - - val typeRef = typeArg as TypeRef; - - // type 'undefined' used as type argument in N4JS, corresponds to 'void' in TypeScript: - if (typeRef.getDeclaredType() == state.G.undefinedType) { - // DISABLED (it leads to compile problems if an upper bound is in effect, because 'void' won't be a subtype - // of the upper bound, but 'undefined' will be; since we cannot easily find out whether an upper bound is in - // effect at this point in the code, we disable this special replacement with 'void' for now: - - // write("void"); - // return; - } - - convertTypeRef(typeRef); - } - - def private void convertTFormalParameters(Iterable fpars) { - write(fpars, [convertTFormalParameter], ", "); - } - - def private void convertTFormalParameter(TFormalParameter fpar) { - if (fpar.isVariadic()) { - write("..."); - } - val name = fpar.getName(); - if (name !== null) { - write(name); - } else { - // Note: the name is mandatory in TypeScript; however, we create synthetic names for fpars in the types - // builder, so we should never reach this point: - throw new IllegalStateException("encountered a TFormalParameter without a (synthetic) name"); - } - if (!fpar.isVariadic() && fpar.isOptional()) { - write('?'); - } - val typeRef = fpar.getTypeRef(); - if (typeRef !== null) { - write(": "); - convertTypeRef(typeRef); - if (fpar.isVariadic()) { - write("[]"); // TypeScript expect an array type - } - } - } - - def private dispatch void convertTMember(TMember member) { - throw new IllegalStateException("unknown subclass of " + TMember.simpleName + ": " + member.getClass.simpleName); - } - - def private dispatch void convertTMember(TField field) { - writeQuotedIfNonIdentifier(field.getName()); - convertDeclaredTypeRef(field); - } - - def private dispatch void convertTMember(TGetter getter) { - write("get "); - writeQuotedIfNonIdentifier(getter.getName()); - write("(): "); - val typeRef = getter.getTypeRef(); - if (typeRef !== null) { - convertTypeRef(typeRef); - } else { - write("any"); - } - } - - def private dispatch void convertTMember(TSetter setter) { - write("set "); - writeQuotedIfNonIdentifier(setter.getName()); - write("("); - convertTFormalParameters(Collections.singletonList(setter.getFpar())); - write(")"); - } - - def private dispatch void convertTMember(TMethod method) { - writeQuotedIfNonIdentifier(method.getName()); - write("("); - convertTFormalParameters(method.getFpars()); - write("): "); - val returnTypeRef = method.getReturnTypeRef(); - if (returnTypeRef !== null) { - convertTypeRef(returnTypeRef); - } else { - // TypeScript's default return type is 'any', so we need to emit 'void' in this case! - write("void"); - } - } - - /** - * @param isReturnTypeOfActualFunction the caller should pass in {@code true} iff the return type to emit is for an "actual function", - * i.e. a declared function, a method, or a function expression (as opposed to the return type of a pure function type expression inside - * a type annotation). - */ - def private void writeSuffixForReturnTypeOfFunctionWithOptionalReturnValue(boolean isReturnTypeOfActualFunction) { - // note: due to limitations in N4JS, the return type of a function with an optional return value cannot be a ComposedTypeRef, - // so we do not need to bother with parentheses around the actual return type reference - if (isReturnTypeOfActualFunction) { - write("|undefined"); - } else { - write("|void"); - } - } - - def private void write(Iterable nodesInIM, Consumer processor, String separator) { - val iter = nodesInIM.iterator(); - while (iter.hasNext()) { - processor.accept(iter.next()); - if (separator !== null && iter.hasNext()) { - write(separator); - } - } - } - - def private void write(CharSequence csq) { - currStringBuilder.append(csq); - } - - def private void writeQuotedIfNonIdentifier(String csq) { - if (!isLegalIdentifier(csq)) { - write("'"); - write(csq); - write("'"); - } else { - write(csq); - } - } - - - /** - * Returns the textual reference that can be used in the local file to refer to the given type (adding an import for - * the given type, if necessary), or null if the type cannot be referred to from the local file. - *

- * The returned string is usually simply the local name of the given type, but includes, if required, also the name - * of a namespace and "." as separator. - */ - def private String getReferenceToType(Type type, TranspilerState state) { - // note: map 'referenceCache' may contain 'null' as value! - if (referenceCache.containsKey(type)) { - return referenceCache.get(type); - } - val reference = computeReferenceToType(type, state); - referenceCache.put(type, reference); - return reference; - } - - def private String computeReferenceToType(Type type, TranspilerState state) { - val isLocal = isFromSameFileOrStaticPolyfill(type); - - if (!isLocal) { - - if (!DtsUtils.isDtsExportableReference(type, state)) { - // the type is from a project not available on the .d.ts side, so we cut off the .d.ts export at this reference - return null; - } - - val isBuiltInOrGlobal = isBuiltInOrGlobal(type); - if (isBuiltInOrGlobal) { - // simple case: the type reference points to a built-in type OR a type from a global module - // -> can simply use its name in output code, because they are global and available everywhere - if (type == state.G.intType) { - return "number"; - } else if (type == state.G.iteratorEntryType) { - return "IteratorReturnResult"; - } - val containingModule = type.containingModule; - if (containingModule !== null - && containingModule.simpleName == "IntlClasses" - && containingModule.packageName == N4JSGlobals.N4JS_RUNTIME_ECMA402.rawName) { - return "Intl." + type.name; - } - return type.name; - } - - } - - val ste = getSymbolTableEntryOriginal(type, true); - if (ste === null) { - return null; - } - - // is the type already available? - var isAvailable = isLocal || ste.importSpecifier !== null; - if (!isAvailable) { - // no, so try to import it! - - if (type.exported && isFromSameProjectOrDirectDependency(type)) { - // note: no need to check accessibility modifiers in addition to #isExported(), because on TypeScript-side we bump up the accessibility - - val alias = hasNameConflict(ste, ste.name)? findConflictFreeName(ste) : null; - - // add a new named import for this type - addNamedImport(ste, alias); - - - for (idElem : state.steCache.mapOriginal.keySet) { - idElem.name - } - - val is = ste.importSpecifier; - ste.name = switch (is) { - NamedImportSpecifier: Strings.isNullOrEmpty(is.alias) ? is.importedElementAsText : is.alias - NamespaceImportSpecifier: is.alias - } - isAvailable = ste.importSpecifier !== null; - } - } - - // is the type now available? - if (isAvailable) { - // yes, so ... - - // 1) record that 'currTypeRefNode' is actually referring to 'type' - recordReferenceToType(currTypeRefNode, ste); - - // 2) compute output code that correctly refers to 'type' from within current file (depending on how the type was imported) - var referenceStr = ""; - val importSpec = ste.getImportSpecifier(); - if (importSpec instanceof NamespaceImportSpecifier) { - val namespaceName = importSpec.getAlias(); - referenceStr = namespaceName + "." + ste.getName(); - } else { - referenceStr = ste.getName(); - } - - return referenceStr; - } - - // we tried our best, but this type is not available in the current file AND cannot be made available - return null; - } - - def private boolean hasNameConflict(SymbolTableEntryOriginal ste, String name) { - return state.steCache.mapOriginal.keySet.exists[ - it != ste.originalTarget && Objects.equals(it.name, name) - ]; - } - - def private String findConflictFreeName(SymbolTableEntryOriginal ste) { - var i = 2; - while (hasNameConflict(ste, ste.name + i)) { - i++; - } - return ste.name + i; - } - - def private boolean isFromSameFileOrStaticPolyfill(Type type) { - val typeResource = type.eResource; - if (typeResource === state.resource) { - return true; - } - val module = state.resource.module; - if (module !== null && module.isStaticPolyfillAware) { - val typeModule = type.containingModule; - return typeModule !== null - && typeModule.isStaticPolyfillModule - && typeModule.qualifiedName == module.qualifiedName; - } - return false; - } - - /** Tells whether the given type is located in the local project or a project we directly depend on. */ - def private boolean isFromSameProjectOrDirectDependency(Type type) { - val containingProject = workspaceAccess.findProjectContaining(type); - return containingProject !== null - && (containingProject === state.project - || state.project.dependencies.contains(containingProject.name)); - } - - def private static boolean isBuiltInOrGlobal(Type type) { - if (N4Scheme.isFromResourceWithN4Scheme(type)) { - return true; - } - val module = EcoreUtil2.getContainerOfType(type, TModule); - return module !== null && AnnotationDefinition.GLOBAL.hasAnnotation(module); - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.dts/xtend-gen/.gitignore b/plugins/org.eclipse.n4js.transpiler.dts/xtend-gen/.gitignore deleted file mode 100644 index c96a04f008..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.dts/xtend-gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/plugins/org.eclipse.n4js.utils/META-INF/MANIFEST.MF b/plugins/org.eclipse.n4js.utils/META-INF/MANIFEST.MF index 5c38c15b1a..ce9d5a4a97 100644 --- a/plugins/org.eclipse.n4js.utils/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.n4js.utils/META-INF/MANIFEST.MF @@ -23,7 +23,6 @@ Require-Bundle: org.eclipse.n4js.releng.utils;resolution:=optional, com.google.guava Export-Package: org.eclipse.n4js.fileextensions, org.eclipse.n4js.utils, - org.eclipse.n4js.utils.beans, org.eclipse.n4js.utils.collections, org.eclipse.n4js.utils.di.scopes, org.eclipse.n4js.utils.emf, diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/IgnorePropertyChangeEvents.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/IgnorePropertyChangeEvents.java deleted file mode 100644 index 2383e8311b..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/IgnorePropertyChangeEvents.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 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.utils.beans; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; - -import org.eclipse.xtend.lib.macro.Active; - -/** - * Annotation to exclude fields from property change support. - * - * @see PropertyChangeSupport - */ -@Target(ElementType.FIELD) -@Active(IgnorePropertyChangeEventsProcessor.class) -public @interface IgnorePropertyChangeEvents { - // just a marker annotation to enable validation -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/IgnorePropertyChangeEventsProcessor.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/IgnorePropertyChangeEventsProcessor.xtend deleted file mode 100644 index 61101f5ec1..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/IgnorePropertyChangeEventsProcessor.xtend +++ /dev/null @@ -1,49 +0,0 @@ -/** - * 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.utils.beans - -import org.eclipse.xtend.lib.macro.AbstractFieldProcessor -import org.eclipse.xtend.lib.macro.ValidationContext -import org.eclipse.xtend.lib.macro.declaration.FieldDeclaration - -/** - * Processor for validating all fields that are supposed to NOT participate in property change support. - */ -class IgnorePropertyChangeEventsProcessor extends AbstractFieldProcessor { - - override doValidate(FieldDeclaration field, extension ValidationContext context) { - - val clazz = field.declaringType; - - val annotations = clazz.annotations.filter[annotationTypeDeclaration.qualifiedName == PropertyChangeSupport.name]; - if (annotations.nullOrEmpty) { - field.addError('''Declaring type is not annotated with @«PropertyChangeSupport.simpleName».'''); - return; - } - - if (field.static) { - field.addError('''Cannot enable property change support on static field.'''); - return; - } - - if (field.final) { - field.addError('''Cannot enable property change support on final field.'''); - return; - } - - if (null !== field.type && field.type.inferred) { - field.addError('''Cannot enable property change support on fields with inferred types.'''); - return; - } - - } - -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/PropertyChangeSupport.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/PropertyChangeSupport.java deleted file mode 100644 index 307f248da1..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/PropertyChangeSupport.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * 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.utils.beans; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; - -import org.eclipse.xtend.lib.macro.Active; - -/** - * Active annotation for generating property change support code. - * - * @see IgnorePropertyChangeEvents - */ -@Active(PropertyChangeSupportProcessor.class) -@Target(ElementType.TYPE) -public @interface PropertyChangeSupport { - - /** - * If this flag is set to {@code true} then each property change will be logged, otherwise no. {@code false} by - * default. - * - * @return {@code true} if the property change events has to be logged, otherwise {@code false}. - */ - boolean verbose() default false; - -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/PropertyChangeSupportProcessor.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/PropertyChangeSupportProcessor.xtend deleted file mode 100644 index 3ccb46b33d..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/beans/PropertyChangeSupportProcessor.xtend +++ /dev/null @@ -1,257 +0,0 @@ -/** - * 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.utils.beans - -import com.google.common.base.CaseFormat -import java.beans.PropertyChangeListener -import java.beans.PropertyChangeSupport -import java.lang.annotation.Annotation -import java.lang.annotation.Repeatable -import java.util.ArrayList -import java.util.Collection -import org.apache.log4j.Logger -import org.eclipse.xtend.lib.annotations.AccessorsProcessor -import org.eclipse.xtend.lib.macro.AbstractClassProcessor -import org.eclipse.xtend.lib.macro.TransformationContext -import org.eclipse.xtend.lib.macro.declaration.AnnotationTarget -import org.eclipse.xtend.lib.macro.declaration.ClassDeclaration -import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration -import org.eclipse.xtend.lib.macro.declaration.Visibility - -/** - * Class transformation processor for generating {@link PropertyChangeSupport} for all - * non-final non-static fields within a class annotated with {@link org.eclipse.n4js.utils.beans.PropertyChangeSupport} annotation. - */ -class PropertyChangeSupportProcessor extends AbstractClassProcessor { - - override doTransform(MutableClassDeclaration clazz, extension TransformationContext context) { - - val annotations = clazz.annotations.filter[annotationTypeDeclaration.qualifiedName == org.eclipse.n4js.utils.beans.PropertyChangeSupport.name]; - - if (annotations.nullOrEmpty) { - return; - } - - if (annotations.size > 1) { - clazz.addError( - '''Duplicate annotation of non-repeatable type @«org.eclipse.n4js.utils.beans.PropertyChangeSupport.simpleName». - Only annotation types marked @«Repeatable.simpleName» can be used multiple times at one target.''') - return; - } - - val verbose = annotations.head.getBooleanValue('verbose'); - if (verbose) { - clazz.addField('PROPERTY_CHANGE_LOGGER') [ - visibility = Visibility.PRIVATE; - static = true; - final = true; - type = Logger.newTypeReference; - it.initializer = '''«Logger».getLogger(«clazz».class)'''; - ]; - } - - - val fields = clazz.declaredFields.filter[ - null !== type - && !final - && !static - && !hasAnnotation(IgnorePropertyChangeEvents) - ]; - - val inferredFields = fields.filter[type.inferred]; - if (!inferredFields.nullOrEmpty) { - inferredFields.forEach[addError('''The type of field must be explicitly declared to enable the property change support.''')]; - return; - } - - if (!hasSuperPropertyChangeSupportGetter(clazz, context)) { - clazz.addField('_propertyChangeSupport') [ - visibility = Visibility.PRIVATE; - static = false; - final = true; - type = PropertyChangeSupport.newTypeReference; - initializer = '''new «PropertyChangeSupport»(this)'''; - ]; - - clazz.addMethod('internalGetPropertyChangeSupport') [ - visibility = Visibility.PROTECTED; - static = false; - final = true; - returnType = PropertyChangeSupport.newTypeReference; - body = ''' - return this._propertyChangeSupport; - ''' - ]; - } - - if (!hasSuperAddPropertyChangeListener(clazz, context)) { - clazz.addMethod('addPropertyChangeListener') [ - returnType = primitiveVoid - val typeRef = context.newTypeReference(PropertyChangeListener) - val param = addParameter('listener', typeRef); - visibility = Visibility.PUBLIC; - static = false; - final = true; - body = ''' - internalGetPropertyChangeSupport().addPropertyChangeListener(«param.simpleName»); - ''' - ]; - } - - if (!hasSuperRemovePropertyChangeListener(clazz, context)) { - clazz.addMethod('removePropertyChangeListener') [ - returnType = primitiveVoid - val typeRef = context.newTypeReference(PropertyChangeListener) - val param = addParameter('listener', typeRef); - visibility = Visibility.PUBLIC; - static = false; - final = true; - body = ''' - internalGetPropertyChangeSupport().removePropertyChangeListener(«param.simpleName»); - ''' - ]; - } - - fields.forEach[ field | - - val propertyName = '''«CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, field.simpleName)»_PROPERTY'''; - val fieldTypeRef = if (null === field.type) object else field.type; - - // Generate constant property for the field. - clazz.addField(propertyName) [ - visibility = Visibility.PUBLIC; - static = true; - final = true; - type = string; - constantValueAsString = field.simpleName; - ]; - - // Generate common getter. - val accessorUtil = new AccessorsProcessor.Util(context); - if (accessorUtil.shouldAddGetter(field)) { - accessorUtil.addGetter(field, Visibility.PUBLIC); - } - - // Generate setter that invokes the property change support. - clazz.addMethod(accessorUtil.getSetterName(field)) [ - returnType = primitiveVoid - val param = addParameter(field.simpleName, fieldTypeRef); - val oldValue = if (context.newTypeReference(Collection).isAssignableFrom(fieldTypeRef)) { - '''new «ArrayList.name»(this.«field.simpleName»)'''; - } else { - '''this.«field.simpleName»'''; - } - body = ''' - internalGetPropertyChangeSupport().firePropertyChange(«propertyName», «oldValue», this.«field.simpleName» = «param.simpleName»); - '''; - it.visibility = Visibility.PUBLIC; - ]; - - if (context.newTypeReference(Collection).isAssignableFrom(fieldTypeRef)) { - - clazz.addMethod('''add«field.simpleName.toFirstUpper»''') [ - returnType = primitiveVoid - val typeRef = fieldTypeRef.actualTypeArguments.head?: object; - val param = addParameter('''element«field.simpleName.toFirstUpper»''', typeRef); - body = ''' - internalGetPropertyChangeSupport().firePropertyChange( - «propertyName», - new «ArrayList.name»(this.«field.simpleName»), - this.«field.simpleName».add(«param.simpleName») ? this.«field.simpleName» : this.«field.simpleName»); - '''; - it.visibility = Visibility.PUBLIC; - ]; - - clazz.addMethod('''remove«field.simpleName.toFirstUpper»''') [ - returnType = primitiveVoid - val typeRef = fieldTypeRef.actualTypeArguments.head?: object; - val param = addParameter('''element«field.simpleName.toFirstUpper»''', typeRef); - body = ''' - internalGetPropertyChangeSupport().firePropertyChange( - «propertyName», - new «ArrayList.name»(this.«field.simpleName»), - this.«field.simpleName».remove(«param.simpleName») ? this.«field.simpleName» : this.«field.simpleName»); - '''; - it.visibility = Visibility.PUBLIC; - ]; - - } - - ] - - } - - private def hasPropertyChangeSupportGetter(ClassDeclaration it, TransformationContext context) { - declaredMethods.exists [ - simpleName == 'internalGetPropertyChangeSupport' - && returnType == context.newTypeReference(PropertyChangeSupport) - && parameters.size == 0 - && (visibility === Visibility.PROTECTED || visibility === Visibility.PUBLIC) - ]; - } - - private def hasSuperPropertyChangeSupportGetter(ClassDeclaration cls, TransformationContext context) { - var superClass = (cls.extendedClass.type as ClassDeclaration) - while (null !== superClass) { - if (superClass.hasPropertyChangeSupportGetter(context)) { - return true; - } - superClass = superClass.extendedClass?.type as ClassDeclaration; - } - return false; - } - - private def hasAnnotation(AnnotationTarget it, Class annotation) { - annotations.exists[annotationTypeDeclaration.qualifiedName == annotation.name]; - } - - private def hasAddPropertyChangeListener(ClassDeclaration it, TransformationContext context) { - declaredMethods.exists [ - simpleName == 'addPropertyChangeListener' - && returnType == context.primitiveVoid - && parameters.size == 1 - && parameters.head.type == context.newTypeReference(PropertyChangeListener) - ]; - } - - private def boolean hasSuperAddPropertyChangeListener(ClassDeclaration cls, TransformationContext context) { - var superClass = (cls.extendedClass.type as ClassDeclaration) - while (null !== superClass) { - if (superClass.hasAddPropertyChangeListener(context)) { - return true; - } - superClass = superClass.extendedClass?.type as ClassDeclaration; - } - return false; - } - - private def hasRemovePropertyChangeListener(ClassDeclaration it, TransformationContext context) { - declaredMethods.exists [ - simpleName == 'removePropertyChangeListener' - && returnType == context.primitiveVoid - && parameters.size == 1 - && parameters.head.type == context.newTypeReference(PropertyChangeListener) - ]; - } - - private def boolean hasSuperRemovePropertyChangeListener(ClassDeclaration cls, TransformationContext context) { - var superClass = (cls.extendedClass.type as ClassDeclaration) - while (null !== superClass) { - if (superClass.hasRemovePropertyChangeListener(context)) { - return true; - } - superClass = superClass.extendedClass?.type as ClassDeclaration; - } - return false; - } - - -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Collections2.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Collections2.java similarity index 56% rename from plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Collections2.xtend rename to plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Collections2.java index f5719eb80d..8467303a39 100644 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Collections2.xtend +++ b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Collections2.java @@ -8,42 +8,47 @@ * Contributors: * NumberFour AG - Initial API and implementation */ -package org.eclipse.n4js.utils.collections +package org.eclipse.n4js.utils.collections; -import java.util.ArrayList -import java.util.Collection -import java.util.Comparator -import java.util.HashMap -import java.util.HashSet -import java.util.LinkedHashMap -import java.util.LinkedHashSet -import java.util.LinkedList -import java.util.List -import java.util.Objects -import java.util.Set -import java.util.TreeMap -import java.util.TreeSet -import java.util.stream.Stream +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.stream.Stream; + +import org.eclipse.xtext.xbase.lib.CollectionLiterals; +import org.eclipse.xtext.xbase.lib.Pair; /** * Utility functions for collections */ -class Collections2 { +public class Collections2 { /** * Private constructor to prevent instantiation. */ - private new() { + private Collections2() { } /** * Creates a new linked list containing the given elements. This just delegates to * {@link CollectionLiterals#newLinkedList}. * - * @param initial the initial elements of the list + * @param initial + * the initial elements of the list * * @return the newly created linked list */ - def static LinkedList newLinkedList(T... initial) { + @SafeVarargs + public static LinkedList newLinkedList(T... initial) { return CollectionLiterals.newLinkedList(initial); } @@ -51,11 +56,13 @@ def static LinkedList newLinkedList(T... initial) { * Creates a new array-backed list containing the given elements. This just delegates to * {@link CollectionLiterals#newArrayList}. * - * @param initial the initial elements of the list + * @param initial + * the initial elements of the list * * @return the newly created array-backed list */ - def static ArrayList newArrayList(T... initial) { + @SafeVarargs + public static ArrayList newArrayList(T... initial) { return CollectionLiterals.newArrayList(initial); } @@ -63,11 +70,13 @@ def static ArrayList newArrayList(T... initial) { * Creates a new hash set containing the given elements. This just delegates to * {@link CollectionLiterals#newHashSet}. * - * @param initial the initial elements of the set + * @param initial + * the initial elements of the set * * @return the newly created hash set */ - def static HashSet newHashSet(T... initial) { + @SafeVarargs + public static HashSet newHashSet(T... initial) { return CollectionLiterals.newHashSet(initial); } @@ -75,11 +84,13 @@ def static HashSet newHashSet(T... initial) { * Creates a new linked hash set containing the given elements. This just delegates to * {@link CollectionLiterals#newLinkedHashSet}. * - * @param initial the initial elements of the set + * @param initial + * the initial elements of the set * * @return the newly created linked hash set */ - def static LinkedHashSet newLinkedHashSet(T... initial) { + @SafeVarargs + public static LinkedHashSet newLinkedHashSet(T... initial) { return CollectionLiterals.newLinkedHashSet(initial); } @@ -87,12 +98,15 @@ def static LinkedHashSet newLinkedHashSet(T... initial) { * Creates a new tree set containing the given elements. This just delegates to * {@link CollectionLiterals#newTreeSet}. * - * @param comparator the comparator to use - * @param initial the initial elements of the set + * @param comparator + * the comparator to use + * @param initial + * the initial elements of the set * * @return the newly created tree set */ - def static TreeSet newTreeSet(Comparator comparator, T... initial) { + @SafeVarargs + public static TreeSet newTreeSet(Comparator comparator, T... initial) { return CollectionLiterals.newTreeSet(comparator, initial); } @@ -100,23 +114,27 @@ def static TreeSet newTreeSet(Comparator comparator, T... init * Creates a new hash set containing the given elements. This just delegates to * {@link CollectionLiterals#newHashMap}. * - * @param initial the initial elements of the map + * @param initial + * the initial elements of the map * * @return the newly created hash map */ - def static HashMap newHashMap(Pair... initial) { + @SafeVarargs + public static HashMap newHashMap(Pair... initial) { return CollectionLiterals.newHashMap(initial); } /** * Creates a new linked hash set containing the given elements. This just delegates to - * {@link CollectionLiterals#newLinkedHashMasp}. + * {@link CollectionLiterals#newLinkedHashMap}. * - * @param initial the initial elements of the map + * @param initial + * the initial elements of the map * * @return the newly created linked hash map */ - def static LinkedHashMap newLinkedHashMap(Pair... initial) { + @SafeVarargs + public static LinkedHashMap newLinkedHashMap(Pair... initial) { return CollectionLiterals.newLinkedHashMap(initial); } @@ -124,11 +142,14 @@ def static LinkedHashMap newLinkedHashMap(Pair TreeMap newTreeMap(Comparator comparator, Pair... initial) { + @SafeVarargs + public static TreeMap newTreeMap(Comparator comparator, + Pair... initial) { return CollectionLiterals.newTreeMap(comparator, initial); } @@ -141,25 +162,21 @@ def static TreeMap newTreeMap(Comparator comparator, Pair< * the second list, must not be null * @return the unique concatenation of the given lists */ - def static List concatUnique(List listA, List listB) { + public static List concatUnique(List listA, List listB) { Objects.requireNonNull(listA); Objects.requireNonNull(listB); - val Set result = newLinkedHashSet(listA); + Set result = new LinkedHashSet<>(listA); result.addAll(listB); - return newLinkedList(result); + return new LinkedList<>(result); } - - /** + + /** * Returns a stream of all pairs that can be formed with the elements of the given collection. - * + * * Example: [1,2,3] -> (1,1), (1,2), (1,3), (2,1), (2,2), (2,3), (3,1), (3,2), (3,3) */ - def static Stream> pairs(Collection collection) { - return collection.stream.flatMap[ e1 | - collection.stream.map[ e2 | - return e1 -> e2; - ] - ] + public static Stream> pairs(Collection collection) { + return collection.stream().flatMap(e1 -> collection.stream().map(e2 -> Pair.of(e1, e2))); } } diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Iterables2.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Iterables2.java new file mode 100644 index 0000000000..12f5fe5d97 --- /dev/null +++ b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Iterables2.java @@ -0,0 +1,127 @@ +/** + * 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.utils.collections; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.function.Function; + +import org.eclipse.xtext.xbase.lib.IterableExtensions; +import org.eclipse.xtext.xbase.lib.Pair; + +import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; + +/** + * Extension for {@link Iterable iterable}s. + */ +public class Iterables2 { + + /** + * Like {@link #skipDuplicates(Function, Iterable[])}, using the elements themselves as keys, i.e. a later element + * is deemed a duplicate of an earlier element iff the two elements are {@link Object#equals(Object) equal}. + */ + @SafeVarargs + public static Iterable skipDuplicates(Iterable... inputs) { + return skipDuplicates(Function.identity(), inputs); + } + + /** + * Returns a view of the concatenation of the given {@link Iterable}s that hides all duplicate elements. A later + * element is deemed a duplicate of an earlier element iff the given key supplier returns + * {@link Object#equals(Object) equal} keys for the two elements. + */ + @SafeVarargs + public static Iterable skipDuplicates(Function keySupplier, Iterable... inputs) { + Set keySet = new HashSet<>(); + Predicate recordingFilter = (elem) -> { + K key = keySupplier.apply(elem); + return keySet.add(key); + }; + int len = inputs.length; + @SuppressWarnings("unchecked") + Iterable[] inputsWrapped = new Iterable[len]; + for (int i = 0; i < len; i++) { + inputsWrapped[i] = Iterables.filter(inputs[i], recordingFilter); + } + return Iterables.concat(inputsWrapped); + } + + /** + * Creates a chain of the elements with the following rules: + *

    + *
  • Throws a NPE if the {@code elements} argument is {@code null}.
  • + *
  • Throws a IAE if the {@code elements} argument does not contain the {@code ref} argument.
  • + *
  • Returns with a new list which first and last element element will be the {@code ref}.
  • + *
      + *
    • If the {@code ref} argument contained multiple times in the list, then the first occurrence will be used. + *
    • + *
    + *
  • Creates a new list with the {@code ref}. Then finds the {@code ref} argument in the {@code elements} iterable + * and simply gets the rest of the elements from {@code elements} argument and appends it after the {@code ref}, + * then gets all the elements before the {@code ref} in the original {@code elements} and appends to the new list. + * Finally appends the {@code ref} to the very end of the new list. + *
+ * + * For instance: + * + *
+	 * #[1, 2, 3, 4, 5].chainOf(3) === #[3, 4, 5, 1, 2, 3];
+	 * #[1, -1, 3, -1, 4, 5].chainOf(-1) === #[-1, 3, -1, 4, 5, 1, -1];
+	 * 
+ * + */ + public static List chainOf(Iterable elements, T ref) { + List copy = IterableExtensions.toList(Preconditions.checkNotNull(elements)); + int indexOf = copy.indexOf(ref); + checkArgument(0 <= indexOf, "Element " + ref + " does not contained in " + elements + "."); + List result = new ArrayList<>(); + result.addAll(copy.subList(indexOf, copy.size())); + result.addAll(copy.subList(0, indexOf)); + result.add(ref); + return result; + } + + /** + * Returns an {@link Iterable} which aligns values of iterable1 and iterable2 by their indices. + * + * The size of the resulting iterable is the minimum of iterable1.size and iterable2.size. + */ + public static Iterable> align(Iterable iterable1, Iterable iterable2) { + return new Iterable<>() { + Iterator it1 = iterable1.iterator(); + Iterator it2 = iterable2.iterator(); + + @Override + public Iterator> iterator() { + return new Iterator<>() { + + @Override + public boolean hasNext() { + return it1.hasNext() && it2.hasNext(); + } + + @Override + public Pair next() { + return Pair.of(it1.next(), it2.next()); + } + }; + } + }; + } + +} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Iterables2.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Iterables2.xtend deleted file mode 100644 index e099658af3..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/collections/Iterables2.xtend +++ /dev/null @@ -1,111 +0,0 @@ -/** - * 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.utils.collections - -import com.google.common.base.Predicate -import com.google.common.collect.Iterables -import java.util.Iterator -import java.util.List -import java.util.function.Function - -import static com.google.common.collect.Sets.newHashSet -import static java.util.Collections.singletonList - -import static extension com.google.common.base.Preconditions.* - -/** - * Extension for {@link Iterable iterable}s. - */ -class Iterables2 { - - /** - * Like {@link #skipDuplicates(Function, Iterable[])}, using the elements themselves as keys, i.e. a later element is - * deemed a duplicate of an earlier element iff the two elements are {@link Object#equals(Object) equal}. - */ - @SafeVarargs - def static Iterable skipDuplicates(Iterable... inputs) { - return skipDuplicates(Function.identity, inputs); - } - - /** - * Returns a view of the concatenation of the given {@link Iterable}s that hides all duplicate elements. A later element - * is deemed a duplicate of an earlier element iff the given key supplier returns {@link Object#equals(Object) equal} keys - * for the two elements. - */ - @SafeVarargs - def static Iterable skipDuplicates(Function keySupplier, Iterable... inputs) { - val keySet = newHashSet; - val Predicate recordingFilter = [ elem | - val key = keySupplier.apply(elem); - return keySet.add(key); - ]; - val len = inputs.length; - val inputsWrapped = newArrayOfSize(len); - for (var int i = 0; i < len; i++) { - inputsWrapped.set(i, Iterables.filter(inputs.get(i), recordingFilter)); - } - return Iterables.concat(inputsWrapped); - } - - /** - * Creates a chain of the elements with the following rules: - *
    - *
  • Throws a NPE if the {@code elements} argument is {@code null}.
  • - *
  • Throws a IAE if the {@code elements} argument does not contain the {@code ref} argument.
  • - *
  • Returns with a new list which first and last element element will be the {@code ref}.
  • - *
      - *
    • If the {@code ref} argument contained multiple times in the list, then the first occurrence will be used. - *
    • - *
    - *
  • Creates a new list with the {@code ref}. Then finds the {@code ref} argument in the {@code elements} iterable - * and simply gets the rest of the elements from {@code elements} argument and appends it after the {@code ref}, - * then gets all the elements before the {@code ref} in the original {@code elements} and appends to the new list. - * Finally appends the {@code ref} to the very end of the new list. - *
- * - * For instance: - *
-	 * #[1, 2, 3, 4, 5].chainOf(3) === #[3, 4, 5, 1, 2, 3];
-	 * #[1, -1, 3, -1, 4, 5].chainOf(-1) === #[-1, 3, -1, 4, 5, 1, -1];
-	 * 
- * - */ - def static List chainOf(Iterable elements, T ref) { - val copy = elements.checkNotNull.toList; - val indexOf = copy.indexOf(ref); - checkArgument(0 <= indexOf, '''Element «ref» does not contained in «elements».'''); - return (copy.subList(indexOf, copy.size) + copy.subList(0, indexOf) + singletonList(ref)).toList; - } - /** - * Returns an {@link Iterable} which aligns values of iterable1 and iterable2 by their indices. - * - * The size of the resulting iterable is the minimum of iterable1.size and iterable2.size. - */ - def static Iterable> align(Iterable iterable1, Iterable iterable2) { - return [ - val it1 = iterable1.iterator; - val it2 = iterable2.iterator; - - return new Iterator>() { - - override hasNext() { - return it1.hasNext && it2.hasNext; - } - - override next() { - return it1.next -> it2.next - } - - } - ] - } - -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/nodemodel/NodeModelUtilsN4.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/nodemodel/NodeModelUtilsN4.java new file mode 100644 index 0000000000..d5880274f3 --- /dev/null +++ b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/nodemodel/NodeModelUtilsN4.java @@ -0,0 +1,185 @@ +/** + * Copyright (c) 2018 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.utils.nodemodel; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.findFirst; + +import java.util.Iterator; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.xtext.Keyword; +import org.eclipse.xtext.nodemodel.BidiIterable; +import org.eclipse.xtext.nodemodel.BidiTreeIterator; +import org.eclipse.xtext.nodemodel.ICompositeNode; +import org.eclipse.xtext.nodemodel.ILeafNode; +import org.eclipse.xtext.nodemodel.INode; +import org.eclipse.xtext.nodemodel.util.NodeModelUtils; +import org.eclipse.xtext.util.ITextRegion; +import org.eclipse.xtext.util.TextRegion; + +/** + * Utility methods for dealing with the parse tree, in addition to those in {@link NodeModelUtils}. + */ +public class NodeModelUtilsN4 { + + /** + * Computation of a node's length with {@link INode#getLength()} does not work properly with the automatic semicolon + * insertion (ASI) in N4JS: + *
    + *
  • if an optional ';' is given in the N4JS source code, then the length returned will only include code up to + * (including) the semicolon. This is the desired behavior. + *
  • if the optional ';' is omitted in the N4JS source code, then the length returned will include all following + * white space and comments up to (excluding) the beginning of the following statement, declaration, etc. + *
+ * In contrast, this method will always return the actual length (including the semicolon, if given) without + * including any following white space or comments. + *

+ * This method should always be used when computing the length or region of an AST element which may include an + * optional semicolon at the end (e.g. {@code ImportDeclaration}, {@code ExpressionStatement}) but not for AST + * elements that never include a semicolon (e.g. {@code N4ClassDeclaration}). + */ + public static int getNodeLengthWithASISupport(INode node) { + BidiTreeIterator iterator = node.getAsTreeIterable().iterator(); + boolean done = false; + int end = node.getEndOffset(); + boolean foundSemi = false; + while (!done && iterator.hasPrevious()) { + INode prev = iterator.previous(); + if (prev instanceof ILeafNode) { + boolean hiddenOrIgnored = ((ILeafNode) prev).isHidden() || prev.getText().trim().isEmpty(); + if (!hiddenOrIgnored) { + done = true; + end = prev.getEndOffset(); + foundSemi = ";".equals(prev.getText()); + } + } + } + + // Sometimes an actually present semicolon is not part of the node + // returned by NodeModelUtils#findActualNodeFor(), therefore we have + // to do some additional work: + if (!foundSemi) { + INode next = node.getNextSibling(); + if (next != null && isHiddenTokensFollowedBySemi(next)) { + end = next.getEndOffset(); + } + } + + int offset = node.getOffset(); + return end - offset; + } + + private static boolean isHiddenTokensFollowedBySemi(INode node) { + BidiTreeIterator iterator = node.getAsTreeIterable().iterator(); + while (iterator.hasNext()) { + INode next = iterator.next(); + if (next instanceof ILeafNode) { + if (!((ILeafNode) next).isHidden()) { + if (";".equals(next.getText())) { + // consume remaining non-leafs + while (iterator.hasNext()) { + if (iterator.next() instanceof ILeafNode) { + return false; + } + } + return true; + } else { + // non-hidden leaf other than ';' + return false; + } + } + } + } + // no ';' found + return false; + } + + /** + * Finds recursively a node in the node tree which stands for a keyword (starting from the parentNode) + * + * @param parentNode + * The node from which the recursive search begins + * @param keyword + * Searched keyword + * @returns keywordNode if exists; null otherwise + */ + public static INode findKeywordNode(ICompositeNode parentNode, String keyword) { + BidiIterable children = parentNode.getChildren(); + INode rs = findFirst(children, c -> isKeyword(c, keyword)); + if (rs != null) { + return rs; + } + for (INode iNode : children) { + if (iNode instanceof ICompositeNode) { + INode retValOfRecursion = findKeywordNode((ICompositeNode) iNode, keyword); + if (retValOfRecursion != null) { + return retValOfRecursion; + } + } + } + return null; + } + + public static ITextRegion findRegionOfKeywordWithOptionalBlock(ICompositeNode parentNode, String keyword) { + INode keywordNode = findFirst(parentNode.getChildren(), child -> isKeyword(child, keyword)); + if (keywordNode != null) { + Iterator siblingsIter = new SiblingIterable(keywordNode.getNextSibling()).iterator(); + if (siblingsIter.hasNext()) { + INode nextNode = siblingsIter.next(); + if (isKeyword(nextNode, "{")) { + INode closingNode = findFirst(siblingsIter, sibl -> isKeyword(sibl, "}")); + if (closingNode != null) { + return new TextRegion(keywordNode.getOffset(), + (closingNode.getOffset() + closingNode.getLength()) - keywordNode.getOffset()); + } + } + } + return new TextRegion(keywordNode.getOffset(), keywordNode.getLength()); + } + return null; + } + + public static boolean isKeyword(INode node, String keyword) { + EObject ge = node.getGrammarElement(); + return (ge instanceof Keyword) ? keyword.equalsIgnoreCase(((Keyword) ge).getValue()) : false; + } + + /** + * This method converts a node to text. + * + * Only hidden tokens (whitespaces/comments) before and after non-hidden tokens are deleted. + * + * See {@link NodeModelUtils#getTokenText(INode node)} + */ + public static String getTokenTextWithHiddenTokens(INode node) { + if (node instanceof ILeafNode) { + return node.getText(); + } else { + StringBuilder builder = new StringBuilder(Math.max(node.getTotalLength(), 1)); + StringBuilder tmpBuilder = new StringBuilder(Math.max(node.getTotalLength(), 1)); + boolean nonHiddenSeen = false; + for (ILeafNode leaf : node.getLeafNodes()) { + if (!leaf.isHidden()) { + builder.append(tmpBuilder); + tmpBuilder.delete(0, tmpBuilder.length()); + builder.append(leaf.getText()); + nonHiddenSeen = true; + } else { + if (nonHiddenSeen) { + tmpBuilder.append(leaf.getText()); + } + } + } + return builder.toString(); + } + } +} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/nodemodel/NodeModelUtilsN4.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/nodemodel/NodeModelUtilsN4.xtend deleted file mode 100644 index e7765ea886..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/nodemodel/NodeModelUtilsN4.xtend +++ /dev/null @@ -1,176 +0,0 @@ -/** - * Copyright (c) 2018 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.utils.nodemodel - -import org.eclipse.xtext.Keyword -import org.eclipse.xtext.nodemodel.BidiTreeIterator -import org.eclipse.xtext.nodemodel.ICompositeNode -import org.eclipse.xtext.nodemodel.ILeafNode -import org.eclipse.xtext.nodemodel.INode -import org.eclipse.xtext.nodemodel.util.NodeModelUtils -import org.eclipse.xtext.util.ITextRegion -import org.eclipse.xtext.util.TextRegion - -/** - * Utility methods for dealing with the parse tree, in addition to those in {@link NodeModelUtils}. - */ -class NodeModelUtilsN4 { - - /** - * Computation of a node's length with {@link INode#getLength()} does not work properly with the - * automatic semicolon insertion (ASI) in N4JS: - *

    - *
  • if an optional ';' is given in the N4JS source code, then the length returned will only include code - * up to (including) the semicolon. This is the desired behavior. - *
  • if the optional ';' is omitted in the N4JS source code, then the length returned will include all - * following white space and comments up to (excluding) the beginning of the following statement, - * declaration, etc. - *
- * In contrast, this method will always return the actual length (including the semicolon, if given) - * without including any following white space or comments. - *

- * This method should always be used when computing the length or region of an AST element which - * may include an optional semicolon at the end (e.g. {@code ImportDeclaration}, {@code ExpressionStatement}) - * but not for AST elements that never include a semicolon (e.g. {@code N4ClassDeclaration}). - */ - def public static int getNodeLengthWithASISupport(INode node) { - val BidiTreeIterator iterator = node.getAsTreeIterable().iterator(); - var done = false; - var end = node.endOffset; - var foundSemi = false; - while (!done && iterator.hasPrevious()) { - val INode prev = iterator.previous(); - if (prev instanceof ILeafNode) { - val hiddenOrIgnored = prev.isHidden() || prev.getText().trim().isEmpty(); - if (!hiddenOrIgnored) { - done = true; - end = prev.endOffset; - foundSemi = ';'.equals(prev.text); - } - } - } - - // Sometimes an actually present semicolon is not part of the node - // returned by NodeModelUtils#findActualNodeFor(), therefore we have - // to do some additional work: - if (!foundSemi) { - val next = node.nextSibling; - if (next !== null && isHiddenTokensFollowedBySemi(next)) { - end = next.getEndOffset(); - } - } - - val offset = node.getOffset(); - return end - offset; - } - - def private static boolean isHiddenTokensFollowedBySemi(INode node) { - val BidiTreeIterator iterator = node.getAsTreeIterable().iterator(); - while (iterator.hasNext) { - val INode next = iterator.next(); - if (next instanceof ILeafNode) { - if (!next.isHidden()) { - if (';'.equals(next.text)) { - // consume remaining non-leafs - while (iterator.hasNext) { - if (iterator.next() instanceof ILeafNode) { - return false; - } - } - return true; - } else { - // non-hidden leaf other than ';' - return false; - } - } - } - } - // no ';' found - return false; - } - - /** - * Finds recursively a node in the node tree which stands for a keyword (starting from the parentNode) - * @param parentNode The node from which the recursive search begins - * @param keyword Searched keyword - * @returns keywordNode if exists; null otherwise - */ - def public static INode findKeywordNode(ICompositeNode parentNode, String keyword) { - val children = parentNode.children; - val rs = children.findFirst[c|c.isKeyword(keyword)]; - if (rs !== null) { - return rs; - } - for (INode iNode: children) { - if (iNode instanceof ICompositeNode) { - val retValOfRecursion = findKeywordNode(iNode, keyword); - if (retValOfRecursion !== null) { - return retValOfRecursion; - } - } - } - return null; - } - - def public static ITextRegion findRegionOfKeywordWithOptionalBlock(ICompositeNode parentNode, String keyword) { - val INode keywordNode = parentNode.children.findFirst[isKeyword(keyword)]; - if (keywordNode !== null) { - val siblingsIter = new SiblingIterable(keywordNode.nextSibling).iterator; - if (siblingsIter.hasNext) { - val INode nextNode = siblingsIter.next; - if (nextNode.isKeyword("{")) { - val INode closingNode = siblingsIter.findFirst[isKeyword("}")]; - if (closingNode !== null) { - return new TextRegion(keywordNode.offset, - (closingNode.offset + closingNode.length) - keywordNode.offset); - } - } - } - return new TextRegion(keywordNode.offset, keywordNode.length); - } - return null; - } - - def public static boolean isKeyword(INode node, String keyword) { - val ge = node.grammarElement; - return if (ge instanceof Keyword) keyword.equalsIgnoreCase(ge.value) else false; - } - - /** - * This method converts a node to text. - * - * Only hidden tokens (whitespaces/comments) before and after non-hidden tokens are deleted. - * - * See {@link NodeModelUtils#getTokenText(INode node)} - */ - def public static String getTokenTextWithHiddenTokens(INode node) { - if (node instanceof ILeafNode) { - return node.getText(); - } else { - val builder = new StringBuilder(Math.max(node.getTotalLength(), 1)); - val tmpBuilder = new StringBuilder(Math.max(node.getTotalLength(), 1)); - var nonHiddenSeen = false; - for (ILeafNode leaf : node.getLeafNodes()) { - if (!leaf.isHidden()) { - builder.append(tmpBuilder); - tmpBuilder.delete(0, tmpBuilder.length); - builder.append(leaf.getText()); - nonHiddenSeen = true; - } else { - if (nonHiddenSeen) { - tmpBuilder.append(leaf.getText); - } - } - } - return builder.toString(); - } - } -} From 5c8b24efa1ec19ebc864b0f9025a611b4e770511 Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Tue, 21 Nov 2023 16:25:39 +0100 Subject: [PATCH 03/26] GH-2575: Optionality on fields in object literals gets lost in d.ts output (#2577) * extend test * fix --- .../dts/transform/TypeReferenceTransformation.java | 3 +++ .../xt-tests/dts-export/OptionalMembers.n4js.xt | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.java b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.java index 92838a678b..60942a671e 100644 --- a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.java +++ b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.java @@ -470,6 +470,9 @@ private void convertTMember(TMember member) { private void convertTMember(TField field) { writeQuotedIfNonIdentifier(field.getName()); + if (field.isOptional()) { + write("?"); + } convertDeclaredTypeRef(field); } diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/OptionalMembers.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/OptionalMembers.n4js.xt index 6830589994..3c756c331b 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/OptionalMembers.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/OptionalMembers.n4js.xt @@ -35,6 +35,12 @@ export default class C { set optionalSetterWithJSDoc?(value : number) { } } +export const K: ~Object with { + optionalField?: number, + // in TypeScript methods can be optional too + get optionalGetter?():number, + set optionalSetter?(val: number) +} = null; /* XPECT generated_dts --- export default class C { @@ -54,4 +60,5 @@ export default class C { // *\/ // set optionalSetterWithJSDoc?(value: number); // optional setter omitted } +export const K: {optionalField?: number; get optionalGetter(): number; set optionalSetter(val: number)}; --- */ From 55f98a734ee25fffd5b38943abac3bbfa676a930 Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Thu, 23 Nov 2023 17:30:37 +0100 Subject: [PATCH 04/26] GH-2576: TypeScript's meta type language has issues with circular type structures (#2578) * add test * improve test * fix * improve test * use newer version of TypeScript * fix * improve test * fix * improve tests * fix * more fixes --- .../TypeReferenceTransformation.java | 144 ++++++++++++++---- .../ide/tests/helper/server/xt/XtIdeTest.java | 6 +- ...onlyStructuralTypes_TS_circularity.n4js.xt | 82 ++++++++++ ...nlyStructuralTypes_TS_circularity.n4jsd.xt | 48 ++++++ 4 files changed, 249 insertions(+), 31 deletions(-) create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/ReadonlyStructuralTypes_TS_circularity.n4js.xt create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/ReadonlyStructuralTypes_TS_circularity.n4jsd.xt diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.java b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.java index 60942a671e..f2f5a8b721 100644 --- a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.java +++ b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/transform/TypeReferenceTransformation.java @@ -31,9 +31,13 @@ import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.n4js.AnnotationDefinition; import org.eclipse.n4js.N4JSGlobals; +import org.eclipse.n4js.n4JS.FormalParameter; import org.eclipse.n4js.n4JS.FunctionDefinition; import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.N4MethodDeclaration; +import org.eclipse.n4js.n4JS.N4TypeDeclaration; import org.eclipse.n4js.n4JS.NamedImportSpecifier; import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; import org.eclipse.n4js.n4JS.TypeReferenceNode; @@ -66,12 +70,14 @@ import org.eclipse.n4js.ts.types.TField; import org.eclipse.n4js.ts.types.TFormalParameter; import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TInterface; import org.eclipse.n4js.ts.types.TMember; import org.eclipse.n4js.ts.types.TMethod; import org.eclipse.n4js.ts.types.TModule; import org.eclipse.n4js.ts.types.TSetter; +import org.eclipse.n4js.ts.types.TStructField; import org.eclipse.n4js.ts.types.TStructMember; -import org.eclipse.n4js.ts.types.TTypedElement; +import org.eclipse.n4js.ts.types.TStructuralType; import org.eclipse.n4js.ts.types.Type; import org.eclipse.n4js.utils.N4JSLanguageUtils; import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind; @@ -171,10 +177,10 @@ private void convertTypeRefNode(TypeReferenceNode_IM typeRefNode) { // special case: ArrayN in extends clause String referenceStr = getReferenceToType(declType, getState()); write(referenceStr); - convertTypeArguments((ParameterizedTypeRef) typeRef); + convertTypeArguments(typeRefNode, (ParameterizedTypeRef) typeRef); } else { // standard case - convertTypeRef(typeRef); + convertTypeRef(typeRefNode, typeRef); } if (isReturnType) { @@ -188,15 +194,11 @@ private void convertTypeRefNode(TypeReferenceNode_IM typeRefNode) { } } - private void convertDeclaredTypeRef(TTypedElement elem) { - TypeRef declaredTypeRef = elem.getTypeRef(); - if (declaredTypeRef != null) { - write(": "); - convertTypeRef(declaredTypeRef); - } + private void convertTypeRef(TypeRef typeRefRaw) { + convertTypeRef(null, typeRefRaw); } - private void convertTypeRef(TypeRef typeRefRaw) { + private void convertTypeRef(TypeReferenceNode_IM typeRefNode, TypeRef typeRefRaw) { if (typeRefRaw == null) { return; } @@ -217,7 +219,7 @@ private void convertTypeRef(TypeRef typeRefRaw) { } else if (typeRef instanceof FunctionTypeExprOrRef) { convertFunctionTypeExprOrRef((FunctionTypeExprOrRef) typeRef); } else if (typeRef instanceof ParameterizedTypeRef) { - convertParameterizedTypeRef((ParameterizedTypeRef) typeRef); + convertParameterizedTypeRef(typeRefNode, (ParameterizedTypeRef) typeRef); } else if (typeRef instanceof ThisTypeRef) { convertThisTypeRef((ThisTypeRef) typeRef); } else if (typeRef instanceof ExistentialTypeRef) { @@ -278,7 +280,7 @@ private void convertFunctionTypeExprOrRef(FunctionTypeExprOrRef typeRef) { } } - private void convertParameterizedTypeRef(ParameterizedTypeRef typeRef) { + private void convertParameterizedTypeRef(TypeReferenceNode_IM typeRefNode, ParameterizedTypeRef typeRef) { if (typeRef instanceof FunctionTypeRef) { convertFunctionTypeExprOrRef((FunctionTypeRef) typeRef); return; @@ -286,7 +288,7 @@ private void convertParameterizedTypeRef(ParameterizedTypeRef typeRef) { Type declType = typeRef.getDeclaredType(); if (isArrayN(getState().G, declType)) { - convertTypeArguments(typeRef, "[", "]"); + convertTypeArguments(typeRefNode, typeRef, "[", "]"); return; } @@ -302,11 +304,11 @@ private void convertParameterizedTypeRef(ParameterizedTypeRef typeRef) { if (showDeclaredType) { String referenceStr = (declType == null) ? null : getReferenceToType(declType, getState()); if (referenceStr != null) { - String prependType = getStructuralTypeReplacements(typeRef); + String prependType = getStructuralTypeReplacements(typeRefNode, typeRef); write(prependType); write(referenceStr); - convertTypeArguments(typeRef); + convertTypeArguments(typeRefNode, typeRef); write(Strings.isNullOrEmpty(prependType) ? "" : ">"); @@ -321,7 +323,7 @@ private void convertParameterizedTypeRef(ParameterizedTypeRef typeRef) { write(" & "); } write("{"); - write(members, m -> convertTMember(m), "; "); // ',' would also be allowed as separator + write(members, m -> convertTMember(typeRefNode, m), "; "); // ',' would also be allowed as separator write("}"); } @@ -331,7 +333,7 @@ private void convertParameterizedTypeRef(ParameterizedTypeRef typeRef) { } private void convertThisTypeRef(ThisTypeRef typeRef) { - String prependType = getStructuralTypeReplacements(typeRef); + String prependType = getStructuralTypeReplacements(null, typeRef); write(prependType); write("this"); @@ -361,7 +363,19 @@ private void convertLiteralTypeRef(LiteralTypeRef typeRef) { } } - private String getStructuralTypeReplacements(TypeRef typeRef) { + private String getStructuralTypeReplacements(TypeReferenceNode_IM typeRefNode, TypeRef typeRef) { + if (isCaseOfTypeScriptCircularityIssue(typeRefNode, typeRef)) { + switch (typeRef.getTypingStrategy()) { + case STRUCTURAL_READ_ONLY_FIELDS: + case STRUCTURAL_FIELD_INITIALIZER: + return "Readonly<"; + case STRUCTURAL_FIELDS: + case STRUCTURAL_WRITE_ONLY_FIELDS: + default: + return ""; + } + } + switch (typeRef.getTypingStrategy()) { case STRUCTURAL_FIELDS: return "StructuralFields<"; @@ -376,11 +390,79 @@ private String getStructuralTypeReplacements(TypeRef typeRef) { } } - private void convertTypeArguments(ParameterizedTypeRef typeRef) { - convertTypeArguments(typeRef, "<", ">"); + /** + * Mitigates TypeScript issue occurring on circular type references. Details see here: + * ReadonlyStructuralTypes_TS_circularity.n4js.xt + */ + private boolean isCaseOfTypeScriptCircularityIssue(TypeReferenceNode_IM typeRefNode, TypeRef typeRef) { + if (typeRef instanceof ParameterizedTypeRefStructural + && typeRef.eContainer() instanceof ParameterizedTypeRefStructural) { + + EObject trTmp = typeRef; + while (trTmp instanceof TypeRef) { + trTmp = trTmp.eContainer(); + } + if (trTmp instanceof TStructField) { + // case for fields type aliases + ParameterizedTypeRefStructural propTypeRef = (ParameterizedTypeRefStructural) typeRef.eContainer(); + TStructuralType propType = propTypeRef.getStructuralType(); + + if (propType == trTmp.eContainer()) { + return true; + } + } + if (trTmp instanceof TFormalParameter && trTmp.eContainer() != null) { + // case for formal parameters in type aliases + ParameterizedTypeRefStructural paramTypeRef = (ParameterizedTypeRefStructural) typeRef.eContainer(); + TStructuralType paramType = paramTypeRef.getStructuralType(); + + if (paramType == trTmp.eContainer().eContainer()) { + return true; + } + } + } + + if (typeRefNode != null + && typeRefNode.eContainer() instanceof N4FieldDeclaration + && typeRefNode.eContainer().eContainer() instanceof N4TypeDeclaration) { + + // case for interfaces and classes + Type referencedType = typeRef.getDeclaredType(); + N4TypeDeclaration containingTDecl = (N4TypeDeclaration) typeRefNode.eContainer().eContainer(); + Type containingType = getState().info.getOriginalDefinedType(containingTDecl); + + if (referencedType == containingType) { + return true; + } + } + + if (typeRefNode != null + && typeRefNode.eContainer() instanceof FormalParameter + && typeRefNode.eContainer().eContainer() instanceof N4MethodDeclaration + && typeRefNode.eContainer().eContainer().eContainer() instanceof N4TypeDeclaration) { + + // case for formal parameters + Type referencedType = typeRef.getDeclaredType(); + N4MethodDeclaration method = (N4MethodDeclaration) typeRefNode.eContainer().eContainer(); + N4TypeDeclaration containingTDecl = (N4TypeDeclaration) typeRefNode.eContainer().eContainer().eContainer(); + Type containingType = getState().info.getOriginalDefinedType(containingTDecl); + + if (referencedType == containingType && !method.isConstructor()) { + if (containingType instanceof TInterface) { + return !method.isConstructSignature(); + } + return !method.isConstructor(); + } + } + return false; + } + + private void convertTypeArguments(TypeReferenceNode_IM typeRefNode, ParameterizedTypeRef typeRef) { + convertTypeArguments(typeRefNode, typeRef, "<", ">"); } - private void convertTypeArguments(ParameterizedTypeRef typeRef, String prefix, String suffix) { + private void convertTypeArguments(TypeReferenceNode_IM typeRefNode, ParameterizedTypeRef typeRef, String prefix, + String suffix) { List typeArgs = typeRef.getDeclaredTypeArgs(); if (typeArgs.isEmpty()) { return; @@ -394,15 +476,15 @@ private void convertTypeArguments(ParameterizedTypeRef typeRef, String prefix, S } write(prefix); - write(typeArgs, ta -> convertTypeArgument(ta), ", "); + write(typeArgs, ta -> convertTypeArgument(typeRefNode, ta), ", "); write(suffix); } - private void convertTypeArgument(TypeArgument typeArg) { + private void convertTypeArgument(TypeReferenceNode_IM typeRefNode, TypeArgument typeArg) { if (typeArg instanceof Wildcard) { TypeRef upperBound = ((Wildcard) typeArg).getDeclaredOrImplicitUpperBound(); if (upperBound != null) { - convertTypeArgument(upperBound); + convertTypeArgument(typeRefNode, upperBound); } else { write("any"); // TypeScript does not support lower bounds } @@ -421,7 +503,7 @@ private void convertTypeArgument(TypeArgument typeArg) { // return; } - convertTypeRef(typeRef); + convertTypeRef(typeRefNode, typeRef); } private void convertTFormalParameters(Iterable fpars) { @@ -453,9 +535,9 @@ private void convertTFormalParameter(TFormalParameter fpar) { } } - private void convertTMember(TMember member) { + private void convertTMember(TypeReferenceNode_IM typeRefNode, TMember member) { if (member instanceof TField) { - convertTMember((TField) member); + convertTMember(typeRefNode, (TField) member); } else if (member instanceof TGetter) { convertTMember((TGetter) member); } else if (member instanceof TSetter) { @@ -468,12 +550,16 @@ private void convertTMember(TMember member) { } } - private void convertTMember(TField field) { + private void convertTMember(TypeReferenceNode_IM typeRefNode, TField field) { writeQuotedIfNonIdentifier(field.getName()); if (field.isOptional()) { write("?"); } - convertDeclaredTypeRef(field); + TypeRef declaredTypeRef = field.getTypeRef(); + if (declaredTypeRef != null) { + write(": "); + convertTypeRef(typeRefNode, declaredTypeRef); + } } private void convertTMember(TGetter getter) { diff --git a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtIdeTest.java b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtIdeTest.java index 78a2a386e2..d4912189fb 100644 --- a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtIdeTest.java +++ b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtIdeTest.java @@ -81,6 +81,7 @@ */ public class XtIdeTest extends AbstractIdeTest { + static final String TSC_VERSION = "5.3.2"; static final File TSC_PROVIDER = new File("test-tscProvider"); static final File TSC2 = new File(TSC_PROVIDER, N4JSGlobals.NODE_MODULES + "/.bin/tsc"); @@ -802,8 +803,9 @@ private void ensureTSC(CliTools cliTools) { } TSC_PROVIDER.mkdirs(); - // npm install --prefix . typescript@4.3.2 - ProcessResult result = cliTools.npmRun(TSC_PROVIDER.toPath(), "install", "--prefix", ".", "typescript@4.3.2"); + // npm install --prefix . typescript@ + ProcessResult result = cliTools.npmRun(TSC_PROVIDER.toPath(), "install", "--prefix", ".", + "typescript@" + TSC_VERSION); assertEquals(0, result.getExitCode()); } diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/ReadonlyStructuralTypes_TS_circularity.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/ReadonlyStructuralTypes_TS_circularity.n4js.xt new file mode 100644 index 0000000000..6ecada0d27 --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/ReadonlyStructuralTypes_TS_circularity.n4js.xt @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest + GENERATE_DTS + END_SETUP + */ + + + +/* + * Background is GH-2576: + * TypeScript cannot handle recursive types when used with type meta language (a.k.a. utitlity types). + * We use the utility types (e.g. StructuralReadOnly) to mimic N4JS structural type strategies (e.g. ~r~) when generating d.ts files. + * Those utility types we use are defined in n4jsglobals.d.ts. + * They rely on the TypeScript meta language feature: [K in keyof T]: T[K] extends Function ? K : never. + * However, this feature is not compatible with recursive types, i.e. types that have members of the same type. + * As a fallback in those situations, we use the utility type Readonly instead to avoid errors by the TypeScript compiler. + */ + +export public interface CircularProblem1 { + field_f: ~~CircularProblem1; + field_r: ~r~CircularProblem1; + field_w: ~w~CircularProblem1; + array_r1: ~r~CircularProblem1[]; + array_r2: Array<~r~CircularProblem1>; + field_i: ~Object with {prop: ~i~CircularProblem1}; + method(arg: ~r~CircularProblem1): ~r~CircularProblem1; // method returns are fine +} + +export public class CircularProblem2 { + constructor(spec: ~i~CircularProblem2) {} + field_f: ~~CircularProblem2; + field_r: ~r~CircularProblem2; + field_w: ~w~CircularProblem2; + array_r1: ~r~CircularProblem2[]; + array_r2: Array<~r~CircularProblem2>; + field_i: ~Object with {prop: ~i~CircularProblem2}; + method(arg: ~r~CircularProblem2): ~r~CircularProblem2 { return null; } // method returns are fine +} + +export public type CircularProblem3 = ~Object with { + field_f: ~~CircularProblem3; + field_r: ~r~CircularProblem3; + field_w: ~w~CircularProblem3; + array_r1: ~r~CircularProblem3[]; + array_r2: Array<~r~CircularProblem3>; + field_i: ~Object with {prop: ~i~CircularProblem3}; + method(arg: ~r~CircularProblem3): ~r~CircularProblem3; // method returns are fine +} + + +/* XPECT generated_dts --- +export interface CircularProblem1 { + field_f: CircularProblem1; + field_r: Readonly; + field_w: CircularProblem1; + array_r1: Array>; + array_r2: Array>; + field_i: {prop: Readonly}; + method(arg: Readonly): StructuralReadOnly; +} +export class CircularProblem2 { + constructor(spec: StructuralInititializers); + field_f: CircularProblem2; + field_r: Readonly; + field_w: CircularProblem2; + array_r1: Array>; + array_r2: Array>; + field_i: {prop: Readonly}; + method(arg: Readonly): StructuralReadOnly; +} +export type CircularProblem3 = {field_f: CircularProblem3; field_r: Readonly; field_w: CircularProblem3; array_r1: Array>; array_r2: Array>; field_i: {prop: StructuralInititializers}; method(arg: Readonly): StructuralReadOnly}; +--- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/ReadonlyStructuralTypes_TS_circularity.n4jsd.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/ReadonlyStructuralTypes_TS_circularity.n4jsd.xt new file mode 100644 index 0000000000..b537078033 --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/ReadonlyStructuralTypes_TS_circularity.n4jsd.xt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest + GENERATE_DTS + END_SETUP + */ + + + +/* + * Background is GH-2576: + * TypeScript cannot handle recursive types when used with type meta language (a.k.a. utitlity types). + * We use the utility types (e.g. StructuralReadOnly) to mimic N4JS structural type strategies (e.g. ~r~) when generating d.ts files. + * Those utility types we use are defined in n4jsglobals.d.ts. + * They rely on the TypeScript meta language feature: [K in keyof T]: T[K] extends Function ? K : never. + * However, this feature is not compatible with recursive types, i.e. types that have members of the same type. + * As a fallback in those situations, we use the utility type Readonly instead to avoid errors by the TypeScript compiler. + */ + +export public interface ~CircularProblem1 { + new(spec: ~i~CircularProblem1): ~r~CircularProblem1; + field_f: ~~CircularProblem1; + field_r: ~r~CircularProblem1[]; + field_w: Array<~w~CircularProblem1>; + field_i: ~Object with {prop: ~i~CircularProblem1}; + method(arg: ~r~CircularProblem1): ~r~CircularProblem1; // method returns are fine +} + + +/* XPECT generated_dts --- +export interface CircularProblem1 { + new(spec: StructuralInititializers): StructuralReadOnly; + field_f: CircularProblem1; + field_r: Array>; + field_w: Array; + field_i: {prop: Readonly}; + method(arg: Readonly): StructuralReadOnly; +} +--- */ From 04e37644d8106c0c10cd4ec3465167d4ead4ace8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean=20Andr=C3=A9=20Gauthier?= Date: Fri, 1 Dec 2023 08:03:22 +0100 Subject: [PATCH 05/26] Replace fireTestRunStarted/Finished by fireTestSuiteStarted/Finished in XtFileRunner (#2581) * Replace testRunStarted/Finished by testSuiteStarted/Finished in XtFileRunner * Add suite description to testSuiteStarted/Finished events in AbstractXtParentRunnerTest --- .../ide/tests/helper/server/xt/XtFileRunner.java | 4 ++-- .../server/xt/tests/AbstractXtParentRunnerTest.java | 9 ++++----- .../server/xt/tests/BeforeAfterInvocationTest.java | 13 ++++++------- .../helper/server/xt/tests/DefinitionTest.java | 7 ++++--- .../helper/server/xt/tests/ElementKeywordTest.java | 9 +++++---- .../server/xt/tests/IgnoreWrongRunnerTest.java | 5 +++-- .../server/xt/tests/IssueConfigurationTest.java | 7 ++++--- .../tests/helper/server/xt/tests/ModifiersTest.java | 13 +++++++------ .../server/xt/tests/SuppressedIssuesTest.java | 9 +++++---- 9 files changed, 40 insertions(+), 36 deletions(-) diff --git a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtFileRunner.java b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtFileRunner.java index 26a81d73a1..f71bbbff41 100644 --- a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtFileRunner.java +++ b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtFileRunner.java @@ -89,7 +89,7 @@ public void run(RunNotifier notifier) { } try { - notifier.fireTestRunStarted(getDescription()); + notifier.fireTestSuiteStarted(getDescription()); parent.invokeBeforeMethods(ideTest); @@ -126,7 +126,7 @@ public void run(RunNotifier notifier) { try { parent.invokeAfterMethods(ideTest); - notifier.fireTestRunFinished(new Result()); + notifier.fireTestSuiteFinished(getDescription()); } catch (Throwable t) { notifier.fireTestFailure(new Failure(getDescription(), t)); } diff --git a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/AbstractXtParentRunnerTest.java b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/AbstractXtParentRunnerTest.java index 88b763d7c0..95707133ec 100644 --- a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/AbstractXtParentRunnerTest.java +++ b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/AbstractXtParentRunnerTest.java @@ -20,7 +20,6 @@ import org.junit.After; import org.junit.Assert; import org.junit.runner.Description; -import org.junit.runner.Result; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; @@ -58,13 +57,13 @@ protected XtParentRunner createParentRunner() throws InitializationError { } @Override - public void testRunStarted(Description description) throws Exception { - events.put("testRunStarted", description); + public void testSuiteStarted(Description description) throws Exception { + events.put("testSuiteStarted - " + description.getDisplayName(), description); } @Override - public void testRunFinished(Result result) throws Exception { - events.put("testRunFinished", result); + public void testSuiteFinished(Description description) throws Exception { + events.put("testSuiteFinished - " + description.getDisplayName(), description); } @Override diff --git a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/BeforeAfterInvocationTest.java b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/BeforeAfterInvocationTest.java index ac763aa89d..f4b8553978 100644 --- a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/BeforeAfterInvocationTest.java +++ b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/BeforeAfterInvocationTest.java @@ -37,25 +37,26 @@ public class BeforeAfterInvocationTest extends AbstractXtParentRunnerTest { private static List invocationRecorder = null; - @Test public void test() throws Exception { assertNull(invocationRecorder); invocationRecorder = new ArrayList<>(); run(new BeforeAfterTestRunSimulator(), "probands/BeforeAfterInvocation"); - assertEventNames("testRunStarted\n" + assertEventNames("testSuiteStarted - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup\n" + + "testSuiteStarted - BeforeAfterInvocation1.n4js.xt: probands/BeforeAfterInvocation\n" + "testStarted\n" + "testFinished\n" + "testStarted\n" + "testFinished\n" - + "testRunFinished\n" - + "testRunStarted\n" + + "testSuiteFinished - BeforeAfterInvocation1.n4js.xt: probands/BeforeAfterInvocation\n" + + "testSuiteStarted - BeforeAfterInvocation2.n4js.xt: probands/BeforeAfterInvocation\n" + "testStarted\n" + "testFinished\n" + "testStarted\n" + "testFinished\n" - + "testRunFinished"); + + "testSuiteFinished - BeforeAfterInvocation2.n4js.xt: probands/BeforeAfterInvocation\n" + + "testSuiteFinished - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup"); assertResults("Passed: noerrors~0: 〔probands/BeforeAfterInvocation/BeforeAfterInvocation1.n4js.xt〕\n" + "Passed: noerrors~1: 〔probands/BeforeAfterInvocation/BeforeAfterInvocation1.n4js.xt〕\n" + "Passed: noerrors~0: 〔probands/BeforeAfterInvocation/BeforeAfterInvocation2.n4js.xt〕\n" @@ -91,7 +92,6 @@ public void test() throws Exception { invocationRecorder = null; } - public static class SuperBeforeAfterXtIdeTest extends XtIdeTest { @BeforeClass @@ -125,7 +125,6 @@ public static void someAfterClassMethod() { } } - public static class SubBeforeAfterXtIdeTest extends SuperBeforeAfterXtIdeTest { @BeforeClass diff --git a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/DefinitionTest.java b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/DefinitionTest.java index b293ee7f9b..86067cc85c 100644 --- a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/DefinitionTest.java +++ b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/DefinitionTest.java @@ -19,16 +19,17 @@ */ public class DefinitionTest extends AbstractXtParentRunnerTest { - @Test public void test() throws Exception { run("probands/Definition"); - assertEventNames("testRunStarted\n" + assertEventNames("testSuiteStarted - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup\n" + + "testSuiteStarted - Definition.n4js.xt: probands/Definition\n" + "testStarted\n" + "testFinished\n" + "testStarted\n" + "testFailure\n" - + "testRunFinished"); + + "testSuiteFinished - Definition.n4js.xt: probands/Definition\n" + + "testSuiteFinished - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup"); assertResults( "Passed: definition~0: test-1 〔probands/Definition/Definition.n4js.xt〕\n" + "Failed: definition~1: test-2 〔probands/Definition/Definition.n4js.xt〕. expected:<[wrong expectation]> but was:<[(test-project/src/Definition.n4js, [21:4 - 21:6])]>"); diff --git a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/ElementKeywordTest.java b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/ElementKeywordTest.java index 8f3d51d323..88aa98e20a 100644 --- a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/ElementKeywordTest.java +++ b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/ElementKeywordTest.java @@ -10,8 +10,8 @@ */ package org.eclipse.n4js.ide.tests.helper.server.xt.tests; -import org.eclipse.n4js.ide.tests.helper.server.xt.XtMethodData; import org.eclipse.n4js.ide.tests.helper.server.xt.XtIdeTest; +import org.eclipse.n4js.ide.tests.helper.server.xt.XtMethodData; import org.junit.Test; /** @@ -19,16 +19,17 @@ */ public class ElementKeywordTest extends AbstractXtParentRunnerTest { - @Test public void test() throws Exception { run("probands/ElementKeyword"); - assertEventNames("testRunStarted\n" + assertEventNames("testSuiteStarted - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup\n" + + "testSuiteStarted - ElementKeyword.n4js.xt: probands/ElementKeyword\n" + "testStarted\n" + "testFinished\n" + "testStarted\n" + "testFailure\n" - + "testRunFinished"); + + "testSuiteFinished - ElementKeyword.n4js.xt: probands/ElementKeyword\n" + + "testSuiteFinished - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup"); assertResults( "Passed: elementKeyword~0: test-1 〔probands/ElementKeyword/ElementKeyword.n4js.xt〕\n" + "Failed: elementKeyword~1: test-2 〔probands/ElementKeyword/ElementKeyword.n4js.xt〕. expected:<[wrong expectation]> but was:<[method]>"); diff --git a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/IgnoreWrongRunnerTest.java b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/IgnoreWrongRunnerTest.java index 5851d9924a..40c7549d08 100644 --- a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/IgnoreWrongRunnerTest.java +++ b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/IgnoreWrongRunnerTest.java @@ -17,13 +17,14 @@ */ public class IgnoreWrongRunnerTest extends AbstractXtParentRunnerTest { - @Test public void test() throws Exception { run("probands/IgnoreWrongRunner"); assertTestStructure("org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup\n" + " + IgnoreWrongRunner.n4js.xt: probands/IgnoreWrongRunner: Specified runner does not match current runner"); - assertEventNames("testIgnored"); + assertEventNames("testSuiteStarted - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup\n" + + "testIgnored\n" + + "testSuiteFinished - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup"); } } diff --git a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/IssueConfigurationTest.java b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/IssueConfigurationTest.java index 1fa19eba52..4d3b1e0793 100644 --- a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/IssueConfigurationTest.java +++ b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/IssueConfigurationTest.java @@ -24,7 +24,6 @@ */ public class IssueConfigurationTest extends AbstractXtParentRunnerTest { - @Test public void test() throws Exception { @@ -37,7 +36,8 @@ public void test() throws Exception { assertFalse(suppressed.contains(IssueCodes.CLF_NAME_DOES_NOT_START_LOWERCASE)); run("probands/IssueConfiguration", suppressed); - assertEventNames("testRunStarted\n" + assertEventNames("testSuiteStarted - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup\n" + + "testSuiteStarted - IssueConfiguration.n4js.xt: probands/IssueConfiguration\n" + "testStarted\n" + "testFinished\n" + "testStarted\n" @@ -46,7 +46,8 @@ public void test() throws Exception { + "testFinished\n" + "testStarted\n" + "testFinished\n" - + "testRunFinished"); + + "testSuiteFinished - IssueConfiguration.n4js.xt: probands/IssueConfiguration\n" + + "testSuiteFinished - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup"); assertResults("Passed: nowarnings~0: 〔probands/IssueConfiguration/IssueConfiguration.n4js.xt〕\n" + "Passed: warnings~0: 〔probands/IssueConfiguration/IssueConfiguration.n4js.xt〕\n" + "Passed: warnings~1: 〔probands/IssueConfiguration/IssueConfiguration.n4js.xt〕\n" diff --git a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/ModifiersTest.java b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/ModifiersTest.java index 617889abf1..b2dd66bbb3 100644 --- a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/ModifiersTest.java +++ b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/ModifiersTest.java @@ -10,8 +10,8 @@ */ package org.eclipse.n4js.ide.tests.helper.server.xt.tests; -import org.eclipse.n4js.ide.tests.helper.server.xt.XtMethodData; import org.eclipse.n4js.ide.tests.helper.server.xt.XtIdeTest; +import org.eclipse.n4js.ide.tests.helper.server.xt.XtMethodData; import org.junit.Test; /** @@ -19,20 +19,21 @@ */ public class ModifiersTest extends AbstractXtParentRunnerTest { - @Test public void test() throws Exception { run("probands/Modifiers"); - assertEventNames("testRunStarted\n" + assertEventNames("testSuiteStarted - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup\n" + + "testSuiteStarted - FIXME.n4js.xt: probands/Modifiers\n" + "testStarted\n" + "testFailure\n" + "testStarted\n" + "testFinished\n" - + "testRunFinished\n" - + "testRunStarted\n" + + "testSuiteFinished - FIXME.n4js.xt: probands/Modifiers\n" + + "testSuiteStarted - IGNORE.n4js.xt: probands/Modifiers\n" + "testIgnored\n" + "testIgnored\n" - + "testRunFinished"); + + "testSuiteFinished - IGNORE.n4js.xt: probands/Modifiers\n" + + "testSuiteFinished - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup"); assertResults( "Failed: definition~0: FIXME test-1 〔probands/Modifiers/FIXME.n4js.xt〕. Test fixed!\n" + "Passed: definition~1: FIXME test-2 〔probands/Modifiers/FIXME.n4js.xt〕\n" diff --git a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/SuppressedIssuesTest.java b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/SuppressedIssuesTest.java index b7d5682c3a..5ee638515e 100644 --- a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/SuppressedIssuesTest.java +++ b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/SuppressedIssuesTest.java @@ -11,8 +11,8 @@ package org.eclipse.n4js.ide.tests.helper.server.xt.tests; import org.eclipse.n4js.N4JSLanguageConstants; -import org.eclipse.n4js.ide.tests.helper.server.xt.XtMethodData; import org.eclipse.n4js.ide.tests.helper.server.xt.XtIdeTest; +import org.eclipse.n4js.ide.tests.helper.server.xt.XtMethodData; import org.junit.Test; /** @@ -20,14 +20,15 @@ */ public class SuppressedIssuesTest extends AbstractXtParentRunnerTest { - @Test public void test() throws Exception { run("probands/SuppressedIssues", N4JSLanguageConstants.DEFAULT_SUPPRESSED_ISSUE_CODES_FOR_TESTS); - assertEventNames("testRunStarted\n" + assertEventNames("testSuiteStarted - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup\n" + + "testSuiteStarted - SuppressedIssues.n4js.xt: probands/SuppressedIssues\n" + "testStarted\n" + "testFinished\n" - + "testRunFinished"); + + "testSuiteFinished - SuppressedIssues.n4js.xt: probands/SuppressedIssues\n" + + "testSuiteFinished - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup"); assertResults("Passed: nowarnings~0: 〔probands/SuppressedIssues/SuppressedIssues.n4js.xt〕"); } From ec2941d97346089388cf234e12750dfa7b4dc65f Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Fri, 1 Dec 2023 09:18:05 +0100 Subject: [PATCH 06/26] GH-2579: As a smith I want to replace annotation NLS (#2580) * migrate from NLS to enum * remove xtend nature * migrate from NLS to enum (bundle JSON) * fixes * adjust issue messages * adjust issue message * towards enum * many adjustments * more adjustments * several adjustments * more adjustments * several adjustments * more adjustments * lots of adjustments * some fixes * adjust test expectations * more fixes * lots of fixes * remove obsolete xtend files * migrate two xtend files * remove xtend from n4js.utils * use IssueCodes instead of string literal * adjust issue code messages --- n4js-libs/yarn.lock | 108 - .../n4js/ide/server/codeActions/Fix.java | 10 +- .../codeActions/N4JSCodeActionService.java | 12 +- .../codeActions/N4JSQuickfixProvider.java | 2 +- .../conversion/JSONDoubleValueConverter.java | 6 +- .../n4js/json/validation/JSONIssueCodes.java | 64 + .../n4js/json/validation/JSONIssueCodes.xtend | 6 - .../json/validation/JSONIssueSeverities.java | 2 +- .../n4js/json/validation/JSONValidator.java | 13 +- .../n4js/json/validation/messages.properties | 18 - plugins/org.eclipse.n4js.semver/.classpath | 5 - .../META-INF/MANIFEST.MF | 3 +- .../org.eclipse.n4js.semver/build.properties | 3 +- plugins/org.eclipse.n4js.semver/pom.xml | 5 - .../semver/validation/SemverIssueCodes.java | 60 + .../semver/validation/SemverIssueCodes.xtend | 6 - .../validation/SemverIssueSeverities.java | 2 +- .../semver/validation/SemverValidator.java | 8 +- .../semver/validation/messages.properties | 7 - .../xtend-gen/.gitignore | 2 - plugins/org.eclipse.n4js.utils/.classpath | 5 - .../org.eclipse.n4js.utils/build.properties | 1 - plugins/org.eclipse.n4js.utils/pom.xml | 5 - .../n4js/utils/AbstractNLSProcessor.xtend | 281 -- .../org/eclipse/n4js/utils/AndFunction1.java | 71 + .../org/eclipse/n4js/utils/AndFunction1.xtend | 69 - .../n4js/utils/CompilerProcessor.xtend | 86 - .../src/org/eclipse/n4js/utils/Diff.xtend | 86 - .../org/eclipse/n4js/utils/DiffBuilder.xtend | 143 - .../eclipse/n4js/utils/FunctionDelegate.xtend | 34 - .../src/org/eclipse/n4js/utils/Log.java | 25 + .../org/eclipse/n4js/utils/LogProcessor.java | 52 + .../org/eclipse/n4js/utils/LogProcessor.xtend | 50 - .../n4js/utils/NLSMessagesProcessor.xtend | 77 - .../org/eclipse/n4js/utils/NLSProcessor.xtend | 181 - .../src/org/eclipse/n4js/utils/Strings.java | 17 + .../org/eclipse/n4js/utils/XtextUtilN4.xtend | 73 - .../xtend-gen/.gitignore | 2 - .../.settings/org.eclipse.jdt.core.prefs | 15 + .../eclipse/n4js/N4JSLanguageConstants.java | 6 +- .../PropertyNameAwareElementFactory.java | 5 +- .../AbstractN4JSStringValueConverter.java | 8 +- .../conversion/BinaryIntValueConverter.java | 19 +- .../conversion/DoubleValueConverter.java | 15 +- .../conversion/HexIntValueConverter.java | 19 +- .../conversion/IdentifierValueConverter.java | 12 +- .../JSXIdentifierValueConverter.java | 12 +- .../LegacyOctalIntValueConverter.java | 23 +- .../conversion/N4JSStringValueConverter.java | 8 +- .../N4JSValueConverterException.java | 7 +- .../N4JSValueConverterWithValueException.java | 9 +- ...titutionTemplateSegmentValueConverter.java | 7 +- .../conversion/OctalIntValueConverter.java | 19 +- .../conversion/RegExLiteralConverter.java | 28 +- .../ScientificIntValueConverter.java | 15 +- .../conversion/TemplateEndValueConverter.java | 8 +- .../TemplateHeadValueConverter.java | 7 +- .../TemplateMiddleValueConverter.java | 7 +- .../eclipse/n4js/resource/N4JSResource.java | 9 +- .../ContextAwareTypeScope.java | 8 +- .../HollowTypeOrValueDescription.java | 4 +- .../InvalidStaticWriteAccessDescription.java | 16 +- .../InvisibleMemberDescription.java | 4 +- .../InvisibleTypeOrVariableDescription.java | 15 +- .../NonExportedElementDescription.java | 4 +- ...N4JSScopingConsumableMethodsDiagnosis.java | 4 +- ...copingInstanceOfPrimitivTypeDiagnosis.java | 4 +- .../scoping/diagnosing/ScopingDiagnosis.java | 2 +- .../imports/AmbiguousImportDescription.java | 12 +- .../ImportedElementsScopingHelper.xtend | 4 +- ...PlainAccessOfAliasedImportDescription.java | 4 +- ...inAccessOfNamespacedImportDescription.java | 4 +- .../ComposedMemberDescriptionWithError.java | 4 +- ...ntersectionMemberDescriptionWithError.java | 13 +- .../PolyfillMemberConflictDescription.java | 9 +- .../UnionMemberDescriptionWithError.java | 30 +- .../WrongTypingStrategyDescription.java | 12 +- .../utils/ProjectImportEnablingScope.java | 2 +- .../utils/RestrictedUsageDescription.java | 7 +- .../utils/UnsatisfiedRWAccessDescription.java | 4 +- .../utils/WrongStaticAccessDescription.java | 11 +- .../utils/WrongWriteAccessDescription.java | 9 +- .../ContextAwareTypeScopeValidator.java | 8 +- .../scoping/validation/VeeScopeValidator.java | 4 +- .../VisibilityAwareCtorScopeValidator.java | 5 +- .../ImportStateCalculator.xtend | 2 +- .../n4js/typesystem/SubtypeJudgment.java | 20 +- .../utils/StructuralTypingComputer.xtend | 9 +- .../validation/ASTStructureValidator.xtend | 3390 ++++++++--------- .../AbstractN4JSDeclarativeValidator.xtend | 53 +- .../eclipse/n4js/validation/IssueCodes.java | 2137 +++++++++++ .../eclipse/n4js/validation/IssueCodes.xtend | 21 - .../eclipse/n4js/validation/IssueItem.java | 45 + .../n4js/validation/N4JSIssueSeverities.java | 2 +- .../validation/N4JSResourceValidator.java | 14 +- .../helper/FunctionValidationHelper.java | 25 +- .../n4js/validation/messages.properties | 1221 ------ .../validators/IDEBUGValidator.xtend | 12 +- .../N4JSAccessModifierValidator.xtend | 50 +- .../validators/N4JSAnnotationValidator.xtend | 104 +- .../validators/N4JSClassValidator.xtend | 90 +- .../validators/N4JSClassifierValidator.xtend | 34 +- .../N4JSDeclaredNameValidator.xtend | 117 +- .../N4JSDependencyInjectionValidator.xtend | 74 +- .../validators/N4JSDestructureValidator.xtend | 39 +- .../validators/N4JSEnumValidator.java | 32 +- .../validators/N4JSExpressionValidator.xtend | 230 +- .../validators/N4JSExternalValidator.xtend | 81 +- .../validators/N4JSFunctionValidator.xtend | 67 +- .../validators/N4JSImportValidator.xtend | 93 +- .../N4JSInjectorCallsitesValidator.xtend | 12 +- .../validators/N4JSInterfaceValidator.xtend | 38 +- .../validators/N4JSLambdaValidator.java | 3 +- .../N4JSMemberRedefinitionValidator.java | 194 +- .../validators/N4JSMemberValidator.xtend | 88 +- .../validators/N4JSModuleValidator.xtend | 19 +- .../validators/N4JSNameValidator.java | 86 +- .../validators/N4JSStatementValidator.java | 14 +- .../validators/N4JSSuperValidator.xtend | 45 +- .../validators/N4JSSyntaxValidator.java | 64 +- .../validators/N4JSTypeAliasValidator.java | 27 +- .../validators/N4JSTypeValidator.xtend | 89 +- .../validators/N4JSVariableValidator.xtend | 9 +- .../validators/N4JSXValidator.xtend | 79 +- .../validators/PolyfillValidatorFragment.java | 105 +- .../RuntimeDependencyValidator.xtend | 24 +- .../StaticPolyfillValidatorExtension.xtend | 23 +- .../validators/ThirdPartyValidator.xtend | 4 +- .../UnsupportedFeatureValidator.xtend | 8 +- .../flowgraphs/DeadCodeValidator.java | 9 +- .../MissingReturnOrThrowValidator.java | 3 +- .../flowgraphs/NullUndefinedValidator.java | 8 +- .../UsedBeforeDeclaredValidator.java | 3 +- ...AbstractPackageJSONValidatorExtension.java | 18 +- ...JSProjectSetupJsonValidatorExtension.xtend | 111 +- .../PackageJsonValidatorExtension.java | 179 +- .../tests/helper/server/AbstractIdeTest.java | 3 +- .../server/AbstractOrganizeImportsTest.java | 16 +- .../src/org/eclipse/n4js/N4JSParseHelper.java | 12 +- .../src/org/eclipse/n4js/N4JSTestHelper.java | 3 +- .../n4js/N4JSValidationTestHelper.java | 15 +- ..._0267_thisTypeInFunctionTEofFields.n4js.xt | 2 +- ...HOLD_0021_InstanceOfPrimitiveTypes.n4js.xt | 8 +- .../IDEBUG_0279_functionTypeBounds.n4js.xt | 2 +- .../matrix/Class_x_This/01_in_methods.n4js.xt | 4 +- .../matrix/Role_x_This/01_in_methods.n4js.xt | 2 +- .../xt/tests/IssueConfigurationTest.java | 8 +- ...xceptionInCaseOfSemverSyntaxErrorTest.java | 4 +- .../IncrementalBuilderReexportTest.java | 2 +- ...ncrementalBuilderWorkspaceChangesTest.java | 8 +- .../builder/YarnDifferentPackageNames.java | 2 +- .../jsdoc2spec/adoc/JSDoc2AdocFullTest.java | 2 +- .../xt-tests/validation/DuplicateKeys.json.xt | 2 +- .../lang/tests/parser/JSXParserTest.java | 6 +- .../builtin/BuiltInTypesDefinitionTest.java | 3 +- .../n4js/tests/parser/N4_SyntaxErrorTest.java | 6 +- .../parser/regex/RegexInN4JSParserTest.java | 16 +- .../n4js/tests/scoping/AT_084_Test.java | 87 +- .../scoping/AT_556_MemberAccessTest.java | 12 +- ...ExportDefinitionInCyclicResourcesTest.java | 3 +- .../tests/scoping/ExportDefinitionTest.java | 4 +- .../n4js/tests/scoping/StaticScopingTest.java | 8 +- ...ortOnlyOnFirstUsageOfConcreteTypeTest.java | 44 +- .../validation/AutomaticCancelationTest.java | 2 +- .../tests/validation/N4JSValidatorTest.java | 16 +- .../typesystem/AbstractScriptAssembler.java | 9 +- .../AbstractTypeSystemHelperTests.java | 9 +- .../JoinComputer_IntersectionTypesTest.java | 8 +- .../JoinComputer_UnionTypesTest.java | 15 +- .../MeetComputer_UnionTypesTest.java | 8 +- .../TypeRefsToVariablesAssembler.java | 15 +- ...mHelper_SimplifyIntersectionTypesTest.java | 4 +- ...peSystemHelper_SimplifyUnionTypesTest.java | 4 +- ...N6_1_22_CommaExpressionTypesystemTest.java | 6 +- .../xpect/tests/PackageJsonXtTest.java | 4 +- .../missing-implementation-id/package.json.xt | 2 +- .../package.json.xt | 2 +- .../dependencies/mandatory1/package.json.xt | 2 +- .../dependencies/mandatory2/package.json.xt | 2 +- .../xpect-xt/duplicates/package.json.xt | 18 +- .../library-project/package.json.xt | 8 +- .../xpect-xt/module-filters/package.json.xt | 2 +- .../npmScopes/@/MyProject/package.json.xt | 2 +- .../@_invalidScope/MyProject/package.json.xt | 2 +- .../_InvalidProject/package.json.xt | 4 +- .../@myScope/MyProject/package.json.xt | 4 +- .../@myScope/_InvalidProject/package.json.xt | 2 +- .../npmScopes/MyProject/package.json.xt | 2 +- .../xpect-xt/project-name/package.json.xt | 2 +- .../test.01/package.json.xt | 2 +- .../test.03/package.json.xt | 2 +- .../test.04/package.json.xt | 2 +- .../test.13/package.json.xt | 2 +- .../xpect-xt/projectName/package.json.xt | 2 +- .../invalidExample/package.json.xt | 2 +- .../validExample/package.json.xt | 2 +- .../as-dependency/client/package.json.xt | 2 +- .../package.json.xt | 4 +- .../nested-containers/package.json.xt | 4 +- .../non-top-level/package.json.xt | 10 +- .../structure/overall/package.json.xt | 2 +- .../structure/sources-section/package.json.xt | 2 +- .../as-dependency/tests/package.json.xt | 2 +- .../package.json.xt | 6 +- .../PackageVersionNumber/package.json.xt | 4 +- .../xpect-xt/version/error/package.json.xt | 4 +- .../Req13_LegalUsesOfVoid.n4js.xt | 40 +- .../VoidUndefined_asTypeArgument.n4js.xt | 40 +- .../LegalAndIllegalUseOfSymbol.n4js.xt | 4 +- ...Req25_UnionType_AnyTypeDiscouraged.n4js.xt | 2 +- .../AT-IDE0785_No_Constructor_This.n4js.xt | 2 +- ...-IDE0785_ThisType_in_static_return.n4js.xt | 2 +- ...tance-return-type_in_static_method.n4js.xt | 4 +- ...his_type_as_typearg_in_return_type.n4js.xt | 2 +- .../Ch04_12__ThisType/Req37_ThisType.n4js.xt | 8 +- .../Req41_NumberBasedEnums_Usage.n4js.xt | 4 +- .../Req41_StringBasedEnums_Usage.n4js.xt | 4 +- ...TypeAlias_destructuring_validation.n4js.xt | 4 +- ...alidation_extendsImplementsClauses.n4js.xt | 4 +- .../01_SuperClassMustBeAClass.n4js.xt | 6 +- ...oThisInFieldInitializerOfInterface.n4js.xt | 4 +- ...q50_Warning_In_DefinitionProjects.n4jsd.xt | 4 +- .../Req59_3_SpecParameterCorrectType.n4js.xt | 2 +- .../Req62_ConstDataFields.n4js.xt | 4 +- .../Req64_FieldAccessors.n4js.xt | 4 +- .../Req76_3_StructuralAndInstanceof.n4js.xt | 6 +- .../generators-throw-next-return.n4js.xt | 8 +- .../generators-yield-star.n4js.xt | 4 +- ...o_This_In_Top_Level_Arrow_Function.n4js.xt | 2 +- .../Promisify_useCases.n4js.xt | 8 +- .../Req88_PromisifableCombinations.n4js.xt | 4 +- ...Req173_ValidLocationForThisLiteral.n4js.xt | 14 +- ...nForThisLiteralAndArrowExpressions.n4js.xt | 8 +- .../CallExpressionValidTarget.n4js.xt | 4 +- .../Equality_Classes.n4js.xt | 2 +- ...ExportSeparateFromDecl03_asDefault.n4js.xt | 1 + ...l05_cannotImportNonExportedElement.n4js.xt | 1 + ...rateFromDecl06_exportFromNamespace.n4js.xt | 1 + ...estructTS_Object_propMustBeVisible.n4js.xt | 4 +- .../DestructTS_Object_propMustExist.n4js.xt | 18 +- ...S_Object_propUnionIntersectionType.n4js.xt | 4 +- .../AbstractCanLoadFromDescriptionTest.java | 2 +- .../n4js/tests/realworld/ListBaseIdeTest.java | 2 +- .../eclipse/n4js/utils/DiffBuilderTest2.java | 246 -- ..._ternay_expression_object_literals.n4js.xt | 2 +- ...bject_new_expression_final_nominal.n4js.xt | 2 +- ...28_this_type_in_functionexpression.n4js.xt | 8 +- .../IDE_657_external/ExternalInN4JS.n4js.xt | 4 +- .../validation/IDE_784_external/Enum.n4js.xt | 6 +- .../validation/IDE_784_external/Funs.n4js.xt | 10 +- .../NullUndefined_SpecialExpressions.n4js.xt | 2 +- ...EBUG_155_functions_UnionReturnType.n4js.xt | 2 +- .../validation/super/arrowExpression.n4js.xt | 2 +- .../validation/super/useStrict.n4js.xt | 2 +- .../AT_538_ThisTypeAllowedOccurences.n4js.xt | 8 +- .../ExtendsVsImplements.n4js.xt | 6 +- 256 files changed, 5820 insertions(+), 6494 deletions(-) create mode 100644 plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/JSONIssueCodes.java delete mode 100644 plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/JSONIssueCodes.xtend delete mode 100644 plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/messages.properties create mode 100644 plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/SemverIssueCodes.java delete mode 100644 plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/SemverIssueCodes.xtend delete mode 100644 plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/messages.properties delete mode 100644 plugins/org.eclipse.n4js.semver/xtend-gen/.gitignore delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/AbstractNLSProcessor.xtend create mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/AndFunction1.java delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/AndFunction1.xtend delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/CompilerProcessor.xtend delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/Diff.xtend delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/DiffBuilder.xtend delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/FunctionDelegate.xtend create mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/Log.java create mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/LogProcessor.java delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/LogProcessor.xtend delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/NLSMessagesProcessor.xtend delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/NLSProcessor.xtend delete mode 100644 plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/XtextUtilN4.xtend delete mode 100644 plugins/org.eclipse.n4js.utils/xtend-gen/.gitignore create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueItem.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/messages.properties delete mode 100644 tests/org.eclipse.n4js.utils.tests/src/org/eclipse/n4js/utils/DiffBuilderTest2.java diff --git a/n4js-libs/yarn.lock b/n4js-libs/yarn.lock index 7b63e27175..059bc7a59e 100644 --- a/n4js-libs/yarn.lock +++ b/n4js-libs/yarn.lock @@ -1509,114 +1509,6 @@ es6-weak-map@^2.0.3: es6-iterator "^2.0.3" es6-symbol "^3.1.1" -esbuild-android-arm64@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.3.tgz#f0fc0a892dd6f2f42baf68f9ac24c9bfcfdaba20" - integrity sha512-v/vdnGJiSGWOAXzg422T9qb4S+P3tOaYtc5n3FDR27Bh3/xQDS7PdYz/yY7HhOlVp0eGwWNbPHEi8FcEhXjsuw== - -esbuild-darwin-64@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.3.tgz#074268b97df08dc2ea60ddd3c29b05fd93ff63d3" - integrity sha512-swY5OtEg6cfWdgc/XEjkBP7wXSyXXeZHEsWMdh1bDiN1D6GmRphk9SgKFKTj+P3ZHhOGIcC1+UdIwHk5bUcOig== - -esbuild-darwin-arm64@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.3.tgz#72a62c7e5c58a2321f0bb839f1368878d4a5a814" - integrity sha512-6i9dXPk8oT87wF6VHmwzSad76eMRU2Rt+GXrwF3Y4DCJgnPssJbabNQ9gurkuEX8M0YnEyJF0d1cR7rpTzcEiA== - -esbuild-freebsd-64@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.3.tgz#63f507254f41ccbab97bb6dce655e7dbc127f351" - integrity sha512-WDY5ENsmyceeE+95U3eI+FM8yARY5akWkf21M/x/+v2P5OVsYqCYELglSeAI5Y7bhteCVV3g4i2fRqtkmprdSA== - -esbuild-freebsd-arm64@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.3.tgz#6520f6c8339df943633586d0d597ac2ee1f1958d" - integrity sha512-4BEEGcP0wBzg04pCCWXlgaPuksQHHfwHvYgCIsi+7IsuB17ykt6MHhTkHR5b5pjI/jNtRhPfMsDODUyftQJgvw== - -esbuild-linux-32@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.3.tgz#813d7baf2d33675c9264a07b09a26c39d588abb2" - integrity sha512-8yhsnjLG/GwCA1RAIndjmCHWViRB2Ol0XeOh2fCXS9qF8tlVrJB7qAiHZpm2vXx+yjOA/bFLTxzU+5pMKqkn5A== - -esbuild-linux-64@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.3.tgz#6356ff2d2c6ec978eb6e794a8891cc5cfadab3f1" - integrity sha512-eNq4aixfbwXHIJq4bQDe+XaSNV1grxqpZYs/zHbp0HGHf6SBNlTI02uyTbYGpIzlXmCEPS9tpPCi7BTU45kcJQ== - -esbuild-linux-arm64@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.3.tgz#a289bb67a5207e021d1ac8cae3532771eda473a6" - integrity sha512-wPLyRoqoV/tEMQ7M24DpAmCMyKqBmtgZY35w2tXM8X5O5b2Ohi7fkPSmd6ZgLIxZIApWt88toA8RT0S7qoxcOA== - -esbuild-linux-arm@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.3.tgz#b193de64458d4829be18206e58d127296367c189" - integrity sha512-YcMvJHAQnWrWKb+eLxN9e/iWUC/3w01UF/RXuMknqOW3prX8UQ63QknWz9/RI8BY/sdrdgPEbSmsTU2jy2cayQ== - -esbuild-linux-mips64le@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.3.tgz#d3c826fc746f1cbf3aea696017b001625ea28b59" - integrity sha512-DdmfM5rcuoqjQL3px5MbquAjZWnySB5LdTrg52SSapp0gXMnGcsM6GY2WVta02CMKn5qi7WPVG4WbqTWE++tJw== - -esbuild-linux-ppc64le@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.3.tgz#483974c92555eefe86d623145ff5f328074b6c9b" - integrity sha512-ujdqryj0m135Ms9yaNDVFAcLeRtyftM/v2v7Osji5zElf2TivSMdFxdrYnYICuHfkm8c8gHg1ncwqitL0r+nnA== - -esbuild-netbsd-64@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.3.tgz#76442f9d2d6e6dc796d18eb321256ccdc68ead53" - integrity sha512-Z/UB9OUdwo1KDJCSGnVueDuKowRZRkduLvRMegHtDBHC3lS5LfZ3RdM1i+4MMN9iafyk8Q9FNcqIXI178ZujvA== - -esbuild-openbsd-64@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.3.tgz#13b0adfd39e165f0dfd30af3e629c601b1b5fa36" - integrity sha512-9I1uoMDeogq3zQuTe3qygmXYjImnvc6rBn51LLbLniQDlfvqHPBMnAZ/5KshwtXXIIMkCwByytDZdiuzRRlTvQ== - -esbuild-sunos-64@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.3.tgz#f8ce1a0c6f165b82d589c7f3de01baf094587fd2" - integrity sha512-pldqx/Adxl4V4ymiyKxOOyJmHn6nUIo3wqk2xBx07iDgmL2XTcDDQd7N4U4QGu9LnYN4ZF+8IdOYa3oRRpbjtg== - -esbuild-windows-32@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.3.tgz#f555cbf0fca5974c3c303d9d9ff0d39e08f26916" - integrity sha512-AqzvA/KbkC2m3kTXGpljLin3EttRbtoPTfBn6w6n2m9MWkTEbhQbE1ONoOBxhO5tExmyJdL/6B87TJJD5jEFBQ== - -esbuild-windows-64@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.3.tgz#02c9804f9ca5e587ccb8b18e46a00f9237e54689" - integrity sha512-HGg3C6113zLGB5hN41PROTnBuoh/arG2lQdOird6xFl9giff1cAfMQOUJUfODKD57dDqHjQ1YGW8gOkg0/IrWw== - -esbuild-windows-arm64@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.3.tgz#8bcf737feddde3ccf4d2d6d581b2422b45a9b6e2" - integrity sha512-qB2izYu4VpigGnOrAN2Yv7ICYLZWY/AojZtwFfteViDnHgW4jXPYkHQIXTISJbRz25H2cYiv+MfRQYK31RNjlw== - -esbuild@0.14.3: - version "0.14.3" - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.14.3.tgz#38db1d26aaeccc43f478225974538e2c4de9d6b1" - integrity sha512-zyEC5hkguW2oieXRXp8VJzQdcO/1FxCS5GjzqOHItRlojXnx/cTavsrkxdWvBH9li2lUq0bN+LeeVEmyCwiR/Q== - optionalDependencies: - esbuild-android-arm64 "0.14.3" - esbuild-darwin-64 "0.14.3" - esbuild-darwin-arm64 "0.14.3" - esbuild-freebsd-64 "0.14.3" - esbuild-freebsd-arm64 "0.14.3" - esbuild-linux-32 "0.14.3" - esbuild-linux-64 "0.14.3" - esbuild-linux-arm "0.14.3" - esbuild-linux-arm64 "0.14.3" - esbuild-linux-mips64le "0.14.3" - esbuild-linux-ppc64le "0.14.3" - esbuild-netbsd-64 "0.14.3" - esbuild-openbsd-64 "0.14.3" - esbuild-sunos-64 "0.14.3" - esbuild-windows-32 "0.14.3" - esbuild-windows-64 "0.14.3" - esbuild-windows-arm64 "0.14.3" - escalade@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" diff --git a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/Fix.java b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/Fix.java index 62d651f2cb..589f065cba 100644 --- a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/Fix.java +++ b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/Fix.java @@ -16,6 +16,8 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.eclipse.n4js.validation.IssueCodes; + /** * Annotation for quick-fix methods. *

@@ -33,7 +35,13 @@ /** * The issue code that is about the be resolved. The annotated method will potentially produce a fix for this code. */ - String value(); + IssueCodes value(); + + /** + * Only evaluated if {@link #value()} equals to {@link IssueCodes#INVALID_ISSUE_CODE}. Will be used instead of + * {@link #value()}. + */ + String valueName() default ""; /** Returns true if the implemented fix is a multi fix. */ boolean multiFix() default true; diff --git a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/N4JSCodeActionService.java b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/N4JSCodeActionService.java index 7a07de0f87..4b537da109 100644 --- a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/N4JSCodeActionService.java +++ b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/N4JSCodeActionService.java @@ -32,6 +32,7 @@ import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.n4js.ide.server.commands.N4JSCommandService; import org.eclipse.n4js.resource.N4JSResource; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot; import org.eclipse.n4js.workspace.N4JSWorkspaceConfigSnapshot; import org.eclipse.n4js.xtext.ide.server.ResourceTaskManager; @@ -48,7 +49,6 @@ import org.eclipse.xtext.util.IFileSystemScanner; import org.eclipse.xtext.validation.Issue; -import com.google.common.base.Strings; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.google.inject.Inject; @@ -251,10 +251,14 @@ public void init(Injector injector) { } private void acceptFix(Fix fix, Object instance, Method method) { - String issueCode = fix.value(); - if (!Strings.isNullOrEmpty(issueCode)) { + IssueCodes issueCode = fix.value(); + String issueCodeName = issueCode.name(); + if (issueCode == IssueCodes.INVALID_ISSUE_CODE) { + issueCodeName = fix.valueName(); + } + if (issueCodeName != null) { QuickFixImplementation impl = new QuickFixImplementation(instance, method, fix.multiFix()); - quickfixMap.put(issueCode, impl); + quickfixMap.put(issueCodeName, impl); } } diff --git a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/N4JSQuickfixProvider.java b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/N4JSQuickfixProvider.java index f89ab87c9d..36d3e577f7 100644 --- a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/N4JSQuickfixProvider.java +++ b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/N4JSQuickfixProvider.java @@ -63,7 +63,7 @@ public class N4JSQuickfixProvider { /** * Resolves missing import statements by re-using content assist and {@link ImportsAwareReferenceProposalCreator} */ - @Fix(value = org.eclipse.xtext.diagnostics.Diagnostic.LINKING_DIAGNOSTIC, multiFix = false) + @Fix(value = IssueCodes.INVALID_ISSUE_CODE, valueName = org.eclipse.xtext.diagnostics.Diagnostic.LINKING_DIAGNOSTIC, multiFix = false) public void addImportForUnresolvedReference(QuickfixContext context, ICodeActionAcceptor acceptor) { Script script = context.resource.getScriptResolved(); Document doc = context.options.getDocument(); diff --git a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/conversion/JSONDoubleValueConverter.java b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/conversion/JSONDoubleValueConverter.java index f765a5856f..3317e0b183 100644 --- a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/conversion/JSONDoubleValueConverter.java +++ b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/conversion/JSONDoubleValueConverter.java @@ -22,19 +22,19 @@ protected String toEscapedString(BigDecimal value) { protected void assertValidValue(BigDecimal value) { super.assertValidValue(value); if (value.signum() == -1) - throw new ValueConverterException(JSONIssueCodes.getMessageForJSON_INVALID_DOUBLE_VALUE(), + throw new ValueConverterException(JSONIssueCodes.JSON_INVALID_DOUBLE_VALUE.getMessage(), null, null); } @Override public BigDecimal toValue(String string, INode node) { if (Strings.isEmpty(string)) - throw new ValueConverterException(JSONIssueCodes.getMessageForJSON_INVALID_DOUBLE_VALUE(), + throw new ValueConverterException(JSONIssueCodes.JSON_INVALID_DOUBLE_VALUE.getMessage(), node, null); try { return new BigDecimal(string); } catch (NumberFormatException e) { - throw new ValueConverterException(JSONIssueCodes.getMessageForJSON_INVALID_DOUBLE_VALUE(), + throw new ValueConverterException(JSONIssueCodes.JSON_INVALID_DOUBLE_VALUE.getMessage(), node, null); } } diff --git a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/JSONIssueCodes.java b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/JSONIssueCodes.java new file mode 100644 index 0000000000..cceb11ec76 --- /dev/null +++ b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/JSONIssueCodes.java @@ -0,0 +1,64 @@ +package org.eclipse.n4js.json.validation; + +import static org.eclipse.xtext.diagnostics.Severity.ERROR; +import static org.eclipse.xtext.diagnostics.Severity.WARNING; + +import org.eclipse.xtext.diagnostics.Severity; + +/** + * Enum contains all issues + */ +@SuppressWarnings("javadoc") +public enum JSONIssueCodes { + + /** 0: Property Name, 1: Line of original definition */ + JSON_DUPLICATE_KEY(WARNING, "Duplicate property %s (line %s)."), + + /** No parameters */ + JSON_COMMENT_UNSUPPORTED(WARNING, "Comments are not a valid JSON construct."), + + /** No parameters */ + JSON_TRAILING_COMMAS_UNSUPPORTED(WARNING, "Trailing commas are not allowed in JSON."), + + /** No parameters */ + JSON_INVALID_DOUBLE_VALUE(ERROR, "Invalid decimal number value."), + + /** 0: expected JSON value type, 1: actual JSON value type, 2: location clause (e.g. for property 'name') */ + JSON_EXPECTED_DIFFERENT_VALUE_TYPE(ERROR, "Expected %s instead of %s %s."), + + /** 0: mandatory key name */ + JSON_MISSING_PROPERTY(ERROR, "Missing mandatory property %s."), + + /** 0: property name */ + JSON_EMPTY_STRING(ERROR, "Value for property '%s' must not be empty.") + + ; + + public final Severity severity; + private final String msgTemplate; + + JSONIssueCodes(Severity severity, String msgTemplate) { + this.severity = severity; + this.msgTemplate = msgTemplate; + } + + public String getMessage(Object... values) { + if (values == null) { + return msgTemplate; + } + for (int i = 0; i < values.length; i++) { + if (!(values[i] instanceof String)) { + values[i] = values[i].toString(); + } + } + return msgTemplate.formatted(values); + } + + static public Severity getSeverityForName(String issueName) { + try { + return valueOf(issueName).severity; + } catch (Exception e) { + return null; + } + } +} diff --git a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/JSONIssueCodes.xtend b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/JSONIssueCodes.xtend deleted file mode 100644 index a12ca64465..0000000000 --- a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/JSONIssueCodes.xtend +++ /dev/null @@ -1,6 +0,0 @@ -package org.eclipse.n4js.json.validation - -import org.eclipse.n4js.utils.NLS - -@NLS(propertyFileName="messages") -class JSONIssueCodes {} diff --git a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/JSONIssueSeverities.java b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/JSONIssueSeverities.java index ca0a0c7aa1..9d0d927418 100644 --- a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/JSONIssueSeverities.java +++ b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/JSONIssueSeverities.java @@ -42,7 +42,7 @@ public JSONIssueSeverities(IPreferenceValues preferenceValues, Map n instanceof HiddenLeafNode) .filter(n -> isCommentNode(n)) .forEach(n -> { - addIssue(JSONIssueCodes.getMessageForJSON_COMMENT_UNSUPPORTED(), document, n.getOffset(), - n.getLength(), JSONIssueCodes.JSON_COMMENT_UNSUPPORTED); + addIssue(JSONIssueCodes.JSON_COMMENT_UNSUPPORTED.getMessage(), document, n.getOffset(), + n.getLength(), JSONIssueCodes.JSON_COMMENT_UNSUPPORTED.name()); }); } @@ -147,8 +147,9 @@ private void internalCheckDocumentForTrailingCommas(JSONValue value, String... e if (Objects.equals(keyword.getValue(), expectedKeywords.get(0))) { expectedKeywords.remove(0); if (expectedKeywords.isEmpty()) { - addIssue(JSONIssueCodes.getMessageForJSON_TRAILING_COMMAS_UNSUPPORTED(), value, - node.getOffset(), node.getLength(), JSONIssueCodes.JSON_TRAILING_COMMAS_UNSUPPORTED); + addIssue(JSONIssueCodes.JSON_TRAILING_COMMAS_UNSUPPORTED.getMessage(), value, + node.getOffset(), node.getLength(), + JSONIssueCodes.JSON_TRAILING_COMMAS_UNSUPPORTED.name()); return; } } diff --git a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/messages.properties b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/messages.properties deleted file mode 100644 index b86b0c1846..0000000000 --- a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/validation/messages.properties +++ /dev/null @@ -1,18 +0,0 @@ -# see NLSProcessor for description of value format -# If you change anything here, manually trigger re-compilation of IssueCodes - - -# 0: Property Name, 1: Line of original definition -JSON_DUPLICATE_KEY=warning;;;Property {0} duplicates property {0} (line {1}). -# No parameters -JSON_COMMENT_UNSUPPORTED=warning;;;Comments are not a valid JSON construct. -# No parameters -JSON_TRAILING_COMMAS_UNSUPPORTED=warning;;;Trailing commas are not allowed in JSON. -# No parameters -JSON_INVALID_DOUBLE_VALUE=error;;;Invalid decimal number value. -# 0: expected JSON value type, 1: actual JSON value type, 2: location clause (e.g. for property 'name') -JSON_EXPECTED_DIFFERENT_VALUE_TYPE=error;;;Expected {0} instead of {1} {2}. -# 0: mandatory key name -JSON_MISSING_PROPERTY=error;;;Missing mandatory property {0}. -# 0: property name -JSON_EMPTY_STRING=error;;;Value for property "{0}" must not be empty. \ No newline at end of file diff --git a/plugins/org.eclipse.n4js.semver/.classpath b/plugins/org.eclipse.n4js.semver/.classpath index 4305a21582..7f20dda608 100644 --- a/plugins/org.eclipse.n4js.semver/.classpath +++ b/plugins/org.eclipse.n4js.semver/.classpath @@ -6,11 +6,6 @@ - - - - - diff --git a/plugins/org.eclipse.n4js.semver/META-INF/MANIFEST.MF b/plugins/org.eclipse.n4js.semver/META-INF/MANIFEST.MF index 1695cdd19c..533113ffae 100644 --- a/plugins/org.eclipse.n4js.semver/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.n4js.semver/META-INF/MANIFEST.MF @@ -5,7 +5,8 @@ Bundle-Vendor: org.eclipse.n4js Bundle-Version: 0.0.1.qualifier Bundle-SymbolicName: org.eclipse.n4js.semver; singleton:=true Bundle-ActivationPolicy: lazy -Require-Bundle: org.eclipse.xtext.xbase, +Require-Bundle: org.eclipse.xtext, + org.eclipse.xtext.xbase, org.eclipse.emf.mwe2.launch, org.eclipse.n4js.semver.model, org.eclipse.osgi, diff --git a/plugins/org.eclipse.n4js.semver/build.properties b/plugins/org.eclipse.n4js.semver/build.properties index cd11d169b9..10905486e4 100644 --- a/plugins/org.eclipse.n4js.semver/build.properties +++ b/plugins/org.eclipse.n4js.semver/build.properties @@ -1,6 +1,5 @@ source.. = src/,\ - src-gen/,\ - xtend-gen/ + src-gen/ bin.includes = .,\ META-INF/ bin.excludes = **/*.mwe2,\ diff --git a/plugins/org.eclipse.n4js.semver/pom.xml b/plugins/org.eclipse.n4js.semver/pom.xml index 018877648b..6a766e9447 100644 --- a/plugins/org.eclipse.n4js.semver/pom.xml +++ b/plugins/org.eclipse.n4js.semver/pom.xml @@ -78,11 +78,6 @@ Contributors: - - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/SemverIssueCodes.java b/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/SemverIssueCodes.java new file mode 100644 index 0000000000..6225dcfa37 --- /dev/null +++ b/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/SemverIssueCodes.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2023 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.semver.validation; + +import static org.eclipse.xtext.diagnostics.Severity.ERROR; + +import org.eclipse.xtext.diagnostics.Severity; + +/** + * Enum contains all issues + */ +@SuppressWarnings("javadoc") +public enum SemverIssueCodes { + + /** No parameters */ + SEMVER_TOO_MANY_NUMBERS(ERROR, + "Too many version parts. Semantic versions consist only of major, minor and patch."), + + /** No parameters */ + SEMVER_TOO_MANY_COMPARATORS(ERROR, + "Only zero or one comparator allowed.") + + ; + + public final Severity severity; + private final String msgTemplate; + + SemverIssueCodes(Severity severity, String msgTemplate) { + this.severity = severity; + this.msgTemplate = msgTemplate; + } + + public String getMessage(Object... values) { + if (values == null) { + return msgTemplate; + } + for (int i = 0; i < values.length; i++) { + if (!(values[i] instanceof String)) { + values[i] = values[i].toString(); + } + } + return msgTemplate.formatted(values); + } + + static public Severity getSeverityForName(String issueName) { + try { + return valueOf(issueName).severity; + } catch (Exception e) { + return null; + } + } +} diff --git a/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/SemverIssueCodes.xtend b/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/SemverIssueCodes.xtend deleted file mode 100644 index 23f78040c5..0000000000 --- a/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/SemverIssueCodes.xtend +++ /dev/null @@ -1,6 +0,0 @@ -package org.eclipse.n4js.semver.validation - -import org.eclipse.n4js.utils.NLS - -@NLS(propertyFileName="messages") -class SemverIssueCodes {} diff --git a/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/SemverIssueSeverities.java b/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/SemverIssueSeverities.java index 31ebcdc085..f8c9da2017 100644 --- a/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/SemverIssueSeverities.java +++ b/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/SemverIssueSeverities.java @@ -42,7 +42,7 @@ public SemverIssueSeverities(IPreferenceValues preferenceValues, Map extended = versionNumber.getExtended(); if (extended != null && !extended.isEmpty()) { - String msg = SemverIssueCodes.getMessageForSEMVER_TOO_MANY_NUMBERS(); + String msg = SemverIssueCodes.SEMVER_TOO_MANY_NUMBERS.getMessage(); addIssue(msg, versionNumber, SemverPackage.Literals.VERSION_NUMBER__EXTENDED, - SemverIssueCodes.SEMVER_TOO_MANY_NUMBERS); + SemverIssueCodes.SEMVER_TOO_MANY_NUMBERS.name()); } } @@ -40,9 +40,9 @@ public void checkNoAdditionalParts(VersionNumber versionNumber) { public void checkNoMultipleComparators(SimpleVersion simpleVersion) { EList comparators = simpleVersion.getComparators(); if (comparators.size() > 1) { - String msg = SemverIssueCodes.getMessageForSEMVER_TOO_MANY_COMPARATORS(); + String msg = SemverIssueCodes.SEMVER_TOO_MANY_COMPARATORS.getMessage(); addIssue(msg, simpleVersion, SemverPackage.Literals.SIMPLE_VERSION__COMPARATORS, - SemverIssueCodes.SEMVER_TOO_MANY_COMPARATORS); + SemverIssueCodes.SEMVER_TOO_MANY_COMPARATORS.name()); } } diff --git a/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/messages.properties b/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/messages.properties deleted file mode 100644 index 6ddd79545e..0000000000 --- a/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/validation/messages.properties +++ /dev/null @@ -1,7 +0,0 @@ -# see NLSProcessor for description of value format -# If you change anything here, manually trigger re-compilation of IssueCodes - - -# No parameters -SEMVER_TOO_MANY_NUMBERS=error;;;Too many version parts. Semantic versions consist only of major, minor and patch. -SEMVER_TOO_MANY_COMPARATORS=error;;;Only zero or one comparator allowed. diff --git a/plugins/org.eclipse.n4js.semver/xtend-gen/.gitignore b/plugins/org.eclipse.n4js.semver/xtend-gen/.gitignore deleted file mode 100644 index d6b7ef32c8..0000000000 --- a/plugins/org.eclipse.n4js.semver/xtend-gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/plugins/org.eclipse.n4js.utils/.classpath b/plugins/org.eclipse.n4js.utils/.classpath index be8b36f3c4..af27bdbd59 100644 --- a/plugins/org.eclipse.n4js.utils/.classpath +++ b/plugins/org.eclipse.n4js.utils/.classpath @@ -6,11 +6,6 @@ - - - - - diff --git a/plugins/org.eclipse.n4js.utils/build.properties b/plugins/org.eclipse.n4js.utils/build.properties index 0a51997ce5..02052fb1a7 100644 --- a/plugins/org.eclipse.n4js.utils/build.properties +++ b/plugins/org.eclipse.n4js.utils/build.properties @@ -1,5 +1,4 @@ source.. = src/,\ - xtend-gen/,\ emf-gen output.. = bin/ bin.includes = META-INF/,\ diff --git a/plugins/org.eclipse.n4js.utils/pom.xml b/plugins/org.eclipse.n4js.utils/pom.xml index 28a4c66c97..16e57623ed 100644 --- a/plugins/org.eclipse.n4js.utils/pom.xml +++ b/plugins/org.eclipse.n4js.utils/pom.xml @@ -37,11 +37,6 @@ Contributors: maven-resources-plugin ${maven-resources-plugin.version} - - org.eclipse.xtend - xtend-maven-plugin - - diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/AbstractNLSProcessor.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/AbstractNLSProcessor.xtend deleted file mode 100644 index 0c2f3cbde5..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/AbstractNLSProcessor.xtend +++ /dev/null @@ -1,281 +0,0 @@ -/** - * 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.utils - -import java.io.IOException -import java.io.InputStream -import java.lang.reflect.InvocationTargetException -import java.util.Map -import java.util.MissingResourceException -import java.util.Properties -import java.util.ResourceBundle -import java.util.regex.Pattern -import org.eclipse.xtend.lib.macro.AbstractClassProcessor -import org.eclipse.xtend.lib.macro.TransformationContext -import org.eclipse.xtend.lib.macro.declaration.AnnotationReference -import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration -import org.eclipse.xtend.lib.macro.declaration.Visibility -import org.eclipse.xtext.xbase.lib.Functions.Function0 -import org.eclipse.xtext.xbase.lib.util.ReflectExtensions - -/** - * Base class for active annotations which parses NLS properties files and - * generates helper methods in NLS message class to create messages with correct number of parameters. - * - * For each key in the properties file, the annotation generates - *

    - *
  • static final String constant field with same name and same value - *
  • a get message method having Object parameters of same count as of unique occurrences of wild cards (e.g. first parameter then - * maps to "{0}") - *
- * - * Additional usage notes: - *
    - *
  • To apply changes from the properties file to the xtend NLS class you have to - * make the xtend class dirty (resp. make a fake change). If there are mistakes - * in the properties file (e.g. missing severity in value), the NLS annotation - * will get an error marker pointing you to the cause of the problem - *
  • With CTRL + left mouse click you can navigate from a message.properties entry to one of its current usages. - *
  • The message properties are sorted alphabetically, in order to simplify finding of entries, and to - * avoid problems of differently sorted sets due to different Java versions.

    - *
- */ - -/** See annotation NLS */ -public abstract class AbstractNLSProcessor extends AbstractClassProcessor { - protected extension ReflectExtensions reflExt = new ReflectExtensions - - protected static final String BUNDLE_NAME_FIELD = "BUNDLE_NAME" - protected static final String RESOURCE_BUNDLE_FIELD = "RESOURCE_BUNDLE" - protected static final String nlsClass = "org.eclipse.osgi.util.NLS" - - abstract protected def Class getAnnotationType(); - - def String getAnnotationName() { - return annotationType.simpleName; - } - - override doTransform(MutableClassDeclaration annotatedClass, extension TransformationContext context) { - val nlsAnnotation = annotatedClass.getNLSAnnotation(context) - if (nlsAnnotation===null) { - throw new NullPointerException("Unable to retrieve the annotation") - } - if (findTypeGlobally(nlsClass) === null) { - nlsAnnotation.addError(nlsClass + " isn't on the classpath.") - } - val propertyFileNameValue = nlsAnnotation.getNLSAnnotationPropertyValue(context) - val propertiesFileInputStream = annotatedClass.getPropertiesFile(context, propertyFileNameValue, nlsAnnotation) - val properties = propertiesFileInputStream.loadPropertiesFile(context, nlsAnnotation) - - addMembers(annotatedClass, nlsAnnotation, context, propertyFileNameValue); - - properties.entrySet.sortBy[String.valueOf(key)].forEach [ - addField(annotatedClass, nlsAnnotation, context) - addMethod(annotatedClass, nlsAnnotation, context) - ] - } - - /** - * May be overridden by sub classes to add or remove members which are to be created. - */ - def protected void addMembers( - MutableClassDeclaration annotatedClass, - AnnotationReference nlsAnnotation, - TransformationContext context, - String propertyFileNameValue - ) { - addBundleNameField(annotatedClass, nlsAnnotation, context, propertyFileNameValue) - addResourceBundleField(annotatedClass, nlsAnnotation, context) - addStaticBlock(annotatedClass, nlsAnnotation, context) - addGetStringMethod(annotatedClass, nlsAnnotation, context) - } - - - - def protected void addStaticBlock(MutableClassDeclaration annotatedClass, AnnotationReference nlsAnnotation, - extension TransformationContext context) { - val fieldName = "INITIALIZER"; - checkForExistentField(annotatedClass, fieldName, context, nlsAnnotation) - annotatedClass.addField(fieldName) [ - visibility = Visibility.PRIVATE - static = true - final = true - type = string - initializer = ''' - new «Function0»<«String»>() { - public «string» apply() { - «nlsClass».initializeMessages(«annotatedClass.findDeclaredField( - BUNDLE_NAME_FIELD).simpleName», «annotatedClass.newTypeReference».class); - return ""; - } - }.apply(); - ''' - ] - } - - def protected void addBundleNameField(MutableClassDeclaration annotatedClass, AnnotationReference nlsAnnotation, - extension TransformationContext context, String propertyFileName) { - checkForExistentField(annotatedClass, BUNDLE_NAME_FIELD, context, nlsAnnotation) - annotatedClass.addField(BUNDLE_NAME_FIELD) [ - visibility = Visibility.PRIVATE - static = true - final = true - type = string - initializer = '''«annotatedClass.newTypeReference».class.getPackage().getName() + ".«propertyFileName.replace(".properties", "")»"''' - ] - } - - def protected void addResourceBundleField(MutableClassDeclaration annotatedClass, - AnnotationReference nlsAnnotation, extension TransformationContext context) { - checkForExistentField(annotatedClass, RESOURCE_BUNDLE_FIELD, context, nlsAnnotation) - annotatedClass.addField(RESOURCE_BUNDLE_FIELD) [ - visibility = Visibility.PRIVATE - static = true - final = true - type = ResourceBundle.newTypeReference - initializer = '''«ResourceBundle».getBundle(«annotatedClass.findDeclaredField(BUNDLE_NAME_FIELD).simpleName»)''' - ] - } - - def protected void addGetStringMethod(MutableClassDeclaration annotatedClass, AnnotationReference nlsAnnotation, - extension TransformationContext context) { - val methodName = "getString" - checkForExistentMethod(annotatedClass, methodName, context, nlsAnnotation, 1) - annotatedClass.addMethod(methodName) [ - visibility = Visibility.PRIVATE - static = true - returnType = string - addParameter("key", string) - body = ''' - try { - «string» value = «annotatedClass.findDeclaredField(RESOURCE_BUNDLE_FIELD).simpleName».getString(key); - return value; - } catch («MissingResourceException» e) { - return '!' + key + '!'; - } - ''' - ] - } - - - def protected void addField(Map.Entry entry, MutableClassDeclaration annotatedClass, - AnnotationReference nlsAnnotation, extension TransformationContext context) { - val fieldName = entry.key as String - checkForExistentField(annotatedClass, fieldName, context, nlsAnnotation) - annotatedClass.addField(fieldName) [ - visibility = Visibility.PUBLIC - static = true - final = true - type = string - initializer = '''"«entry.key»"''' - // remove when https://bugs.eclipse.org/bugs/show_bug.cgi?id=444333 is fixed - try { - val delegate = it.invoke("getDelegate") - delegate.invoke("setConstant", true) - } catch (NoSuchFieldException exc) { - throw new RuntimeException(exc) - } catch (IllegalAccessException exc) { - throw new RuntimeException(exc) - } catch (NoSuchMethodException exc) { - throw new RuntimeException(exc) - } catch (InvocationTargetException exc) { - throw new RuntimeException(exc) - } - ] - } - - def protected void checkForExistentField(MutableClassDeclaration annotatedClass, String fieldName, - extension TransformationContext context, AnnotationReference nlsAnnotation) { - if (annotatedClass.findDeclaredField(fieldName) !== null) { - nlsAnnotation.addError("Field " + fieldName + " already present in class.") - } - } - - def protected void addMethod(Map.Entry entry, MutableClassDeclaration annotatedClass, - AnnotationReference nlsAnnotation, extension TransformationContext context) { - val message = entry.value as String - val wildcardCount = message.getWildcardCount - val params = if (wildcardCount > 0) (0 .. wildcardCount - 1).map["param" + it] else newArrayList - val msgMethodName = "msg" + entry.key - checkForExistentMethod(annotatedClass, msgMethodName, context, nlsAnnotation, params.size) - annotatedClass.addMethod(msgMethodName) [ - visibility = Visibility.PUBLIC - static = true - returnType = context.string - params.forEach(param|addParameter(param, object)) - docComment = message - body = '''return «nlsClass».bind(getString(«entry.key»), new Object [] { «params.join(", ")» });''' - ] - } - - def protected void checkForExistentMethod(MutableClassDeclaration annotatedClass, String methodName, - extension TransformationContext context, AnnotationReference nlsAnnotation, int parameterListSize) { - val existentMethod = annotatedClass.findDeclaredMethod(methodName) - if (existentMethod !== null) { - if (existentMethod.parameters.size == parameterListSize) { - nlsAnnotation.addError("Method " + methodName + "/" + parameterListSize + " already present in class.") - } - } - } - - def protected getWildcardCount(String unboundMessage) { - val pattern = Pattern.compile("\\{\\d*\\}") - val matcher = pattern.matcher(unboundMessage); - val matches = newHashSet - while (matcher.find) { - val matchResult = matcher.toMatchResult - matches.add(matchResult.group()) - } - matches.size - } - - def private getNLSAnnotation(MutableClassDeclaration annotatedClass, extension TransformationContext context) { - annotatedClass.findAnnotation(annotationType.newTypeReference.type) - } - - - - def private getNLSAnnotationPropertyValue(AnnotationReference nlsAnnotation, - extension TransformationContext context) { - val value = nlsAnnotation.getValue('propertyFileName') as String - if (value.nullOrEmpty) { - nlsAnnotation.addError(getAnnotationName() + " requires non empty propertyFileName property value.") - } - value - } - - def private getPropertiesFile(MutableClassDeclaration annotatedClass, extension TransformationContext context, - String propertyFileName, AnnotationReference nlsAnnotation) { - val folder = annotatedClass.compilationUnit.filePath?.parent - if (folder === null || !folder.exists) { - nlsAnnotation.addError("Cannot find folder for class " + annotatedClass.qualifiedName + ": " + folder) - throw new IllegalArgumentException( - "Cannot find folder for class " + annotatedClass.qualifiedName + ": " + folder) - } - val propertiesFilePath = folder.append( - propertyFileName + (if (!propertyFileName.endsWith(".properties")) ".properties" else "")) - if (!propertiesFilePath.exists) { - nlsAnnotation.addError(propertiesFilePath.lastSegment + " doesn't exist.") - } - propertiesFilePath.getContentsAsStream - } - - def private loadPropertiesFile(InputStream propertiesFile, extension TransformationContext transformationContext, - AnnotationReference nlsAnnotation) { - val properties = new Properties - try { - properties.load(propertiesFile) - } catch (IOException ioe) { - nlsAnnotation.addError("Cannot load properties file: " + ioe.message) - } - properties - } -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/AndFunction1.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/AndFunction1.java new file mode 100644 index 0000000000..88ff40020b --- /dev/null +++ b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/AndFunction1.java @@ -0,0 +1,71 @@ +/** + * 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.utils; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Lists.asList; + +import java.util.List; + +import org.eclipse.xtext.xbase.lib.Functions.Function1; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +/** + * A predicate like {@link Function1 function} implementation with logical conjunction capabilities. In other words the + * current AND function will be evaluated to {@code true} if all wrapped functions are evaluated to {@code true}. + * Otherwise it will be evaluated to {@code false}. + */ +public class AndFunction1 implements Function1 { + + final List> functions; + + /** + * Creates a new function instance that will represent a logical conjunction. + */ + @SuppressWarnings("unchecked") + static public AndFunction1 conjunctionOf(Function1 first, + Function1... others) { + + return new AndFunction1<>( + asList( + checkNotNull(first, "first"), + checkNotNull(others, "others"))); + } + + /** + * Creates a new logical AND predicate function with the iterable of wrapped functions. + */ + protected AndFunction1(Iterable> toAdd) { + checkNotNull(toAdd, "others"); + functions = ImmutableList.> builder().addAll(toAdd).build(); + } + + @Override + public Boolean apply(F p) { + for (Function1 f : functions) { + if (!f.apply(p)) { + return false; + } + } + return true; + } + + /** + * Returns with a new AND function instance by copying the current instance and appending the argument to to it. + */ + @SuppressWarnings("unchecked") + public AndFunction1 and(Function1... toAdd) { + return (toAdd == null || toAdd.length == 0) ? this : new AndFunction1<>(Lists.asList(this, toAdd)); + } + +} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/AndFunction1.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/AndFunction1.xtend deleted file mode 100644 index 7d3048167a..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/AndFunction1.xtend +++ /dev/null @@ -1,69 +0,0 @@ -/** - * 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.utils - -import com.google.common.collect.ImmutableList -import java.util.List -import org.eclipse.xtext.xbase.lib.Functions.Function1 - -import static com.google.common.collect.Lists.asList - -import static extension com.google.common.base.Preconditions.checkNotNull -import com.google.common.collect.Lists - -/** - * A predicate like {@link Function1 function} implementation with logical conjunction capabilities. - * In other words the current AND function will be evaluated to {@code true} if all wrapped functions - * are evaluated to {@code true}. Otherwise it will be evaluated to {@code false}. - */ -class AndFunction1 implements Function1 { - - val List> functions; - - /** - * Creates a new function instance that will represent a logical conjunction. - */ - def static conjunctionOf(Function1 first, Function1... others) { - new AndFunction1( - asList( - first.checkNotNull('first'), - others.checkNotNull('others') - ) - ); - } - - /** - * Creates a new logical AND predicate function with the iterable of wrapped functions. - */ - protected new(Iterable> toAdd) { - functions = ImmutableList.builder - .addAll(toAdd.checkNotNull('others')) - .build; - } - - override apply(F p) { - for (f : functions) { - if (!f.apply(p)) { - return false; - } - } - return true; - } - - /** - * Returns with a new AND function instance by copying the current instance and appending the argument - * to to it. - */ - def AndFunction1 and(Function1... toAdd) { - return if (toAdd.nullOrEmpty) this else new AndFunction1(Lists.asList(this, toAdd)) - } - -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/CompilerProcessor.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/CompilerProcessor.xtend deleted file mode 100644 index be2080381a..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/CompilerProcessor.xtend +++ /dev/null @@ -1,86 +0,0 @@ -/** - * 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.utils - -import java.lang.annotation.ElementType -import java.lang.annotation.Target -import org.eclipse.xtend.lib.macro.AbstractFieldProcessor -import org.eclipse.xtend.lib.macro.Active -import org.eclipse.xtend.lib.macro.TransformationContext -import org.eclipse.xtend.lib.macro.declaration.FieldDeclaration -import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration -import org.eclipse.xtend.lib.macro.declaration.ClassDeclaration -import org.eclipse.xtend.lib.macro.declaration.InterfaceDeclaration - -/** - */ -@Target(ElementType::FIELD) -@Active(typeof(CompilerProcessor)) -annotation Compiler { -} - -class CompilerProcessor extends AbstractFieldProcessor { - - override doTransform(MutableFieldDeclaration annotatedField, extension TransformationContext context) { - if(annotatedField.type === string) { - annotatedField.addError("Annotated field must be of type String.") - } else { - val value = getInitializerAsString(annotatedField, context) - if (value !== null) { - val resolvedType = findTypeGlobally(value) - if (resolvedType === null) { - annotatedField.initializer.addError(value + " isn't on the classpath.") - } else { - if(!(resolvedType instanceof ClassDeclaration)) { - annotatedField.initializer.addError(value + " have to resolve to a class on the classpath.") - } else { - val clazz = resolvedType as ClassDeclaration - val subGeneratorInterface = "org.eclipse.n4js.generator.ISubGenerator" - if(!clazz.implementsInterface(subGeneratorInterface)) { - annotatedField.initializer.addError("The class " + value + " have to implement the interface " + subGeneratorInterface + ", but only implements " + clazz.implementedInterfaces.map[name]) - } - } - } - } - } - } - - def private boolean implementsInterface(ClassDeclaration clazz, String expectedInterface) { - if(clazz.implementedInterfaces.exists[name.equals(expectedInterface)]) { - return true; - } - if(clazz.implementedInterfaces.exists[(type as InterfaceDeclaration).extendsInterface(expectedInterface)]) { - return true; - } - if(clazz.extendedClass !== null) { - return implementsInterface(clazz.extendedClass.type as ClassDeclaration, expectedInterface) - } - return false; - } - - def private boolean extendsInterface(InterfaceDeclaration interf, String expectedInterface) { - if(interf.extendedInterfaces.exists[name.equals(expectedInterface)]) { - return true; - } - return false; - } - - def getInitializerAsString(FieldDeclaration f, extension TransformationContext context) { - val string = f.initializer?.toString - if(string === null) { - f.addError("A value have to be assigned to this annotated field.") - } else if(!(string.startsWith("\"") && string.endsWith("\""))) { - f.addError("A quoted string value have to be assigned to this annotated field.") - } else { - return string.substring(1, string.length - 1) - } - } -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/Diff.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/Diff.xtend deleted file mode 100644 index 5022ef7d57..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/Diff.xtend +++ /dev/null @@ -1,86 +0,0 @@ -/** - * 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.utils - -import com.google.common.collect.Iterables -import java.util.Arrays -import java.util.Map -import org.eclipse.xtend.lib.annotations.Data - -/** - * Simple POJO for representing a difference. - */ -@Data -class Diff { - - /** - * The initial, ordered state of the relevant items. - */ - val T[] oldItems; - - /** - * The initial, ordered state of all items. - */ - val T[] oldAllItems; - - /** - * The items that have been added. - */ - val T[] addedItems; - - /** - * The removed items. - */ - val T[] deletedItems; - - /** - * Map of edited items. Keys are old state, values are the new state. - */ - val Map editedItems; - - /** - * The final, ordered state of the relevant items. - */ - val T[] newItems; - - /** - * The final, ordered state of all items. - */ - val T[] newAllItems; - - /** - * Returns with {@code true} if the diff contains no addition, deletion and no edition - * and the state of all and relevant items equals with the new state of all and relevant items. - * Otherwise returns with {@code false}. - */ - def isEmpty() { - return addedItems.empty - && deletedItems.empty - && editedItems.empty - && Arrays.equals(newItems, oldItems) - && Arrays.equals(newAllItems, oldAllItems) - } - - override toString() { - '''Diff: - ----------------------------- - Old items: «Iterables.toString(oldItems)» - Old all items: «Iterables.toString(oldAllItems)» - Added items: «Iterables.toString(addedItems)» - Deleted items: «Iterables.toString(deletedItems)» - Edited items: «editedItems» - New items: «Iterables.toString(newItems)» - New all items: «Iterables.toString(newAllItems)» - ----------------------------- - '''; - } - -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/DiffBuilder.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/DiffBuilder.xtend deleted file mode 100644 index 9a14a50be9..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/DiffBuilder.xtend +++ /dev/null @@ -1,143 +0,0 @@ -/** - * 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.utils - -import com.google.common.base.Preconditions -import com.google.common.collect.BiMap -import com.google.common.collect.HashBiMap -import java.util.List -import java.util.function.Function -import com.google.common.annotations.VisibleForTesting - -/** - * Builder for creating a {@link Diff} via a fluent API. The fields are declared as protected only for debug purposes. - */ -abstract class DiffBuilder { - - /** - * The initial, ordered state of the relevant items. - */ - @VisibleForTesting - protected val List oldItems; - - /** - * The initial, ordered state of all items. - */ - @VisibleForTesting - protected val List oldAllItems; - - /** - * The items that have been added. - */ - @VisibleForTesting - protected val List addedItems; - - /** - * The removed items. - */ - @VisibleForTesting - protected val List deletedItems; - - /** - * Map of edited items. Keys are old state, values are the new state. - */ - @VisibleForTesting - protected val BiMap editedItems; - - val F input; - - new(F input) { - this.input = input; - oldItems = oldItemsFunction.apply(this.input); - oldAllItems = allOldItemsFunction.apply(this.input); - Preconditions.checkState( - oldAllItems.containsAll(oldItems), - '''Not all old items is not a subset of all old items. Old items: «oldItems». All old items: «oldAllItems».''' - ); - addedItems = newArrayList(); - deletedItems = newArrayList(); - editedItems = HashBiMap.create(); - } - - /** - * Adds a new item into the diff. - */ - def add(T item) { - if (!oldAllItems.contains(item) && !addedItems.contains(item)) { - addedItems.add(item); - } - deletedItems.remove(item); - return this; - } - - /** - * Deletes an item from the diff. - */ - def delete(T item) { - val index = addedItems.indexOf(item); - if (index >= 0) { - addedItems.remove(index); - } else { - // Original state before the edition - val originalItem = editedItems.inverse.remove(item); - deletedItems.add(originalItem); - } - return this; - } - - /** - * Updates an item in the diff. - */ - def edit(T oldState, T newState) { - val index = addedItems.indexOf(oldState); - if (index >= 0) { - addedItems.remove(index); - addedItems.add(index, newState); - } else { - // check if oldState already is the outcome of an edit operation - val originalState = editedItems.inverse.get(oldState); - - // if so, override previous edit - if (null !== originalState) { - editedItems.put(originalState, newState); - } else { - // otherwise simply add a new edit operation - editedItems.put(oldState, newState); - } - } - return this; - } - - /** - * Builds the diff instance using latest item states. - */ - def Diff build(T[] newItems, T[] newAllItems) { - return new Diff(oldItems, oldAllItems, addedItems, deletedItems, editedItems, newItems, newAllItems); - } - - /** - * Returns with the input. - */ - protected def F getInput() { - return input; - } - - /** - * Function from extracting the initial, ordered state of the relevant from the subject. - */ - protected def abstract Function getOldItemsFunction(); - - /** - * Function from extracting the initial, ordered state of all items from the subject. - */ - protected def abstract Function getAllOldItemsFunction(); - -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/FunctionDelegate.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/FunctionDelegate.xtend deleted file mode 100644 index 1eb2bdac94..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/FunctionDelegate.xtend +++ /dev/null @@ -1,34 +0,0 @@ -/** - * 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.utils - -import com.google.common.base.Function -import org.eclipse.xtext.xbase.lib.Functions.Function1 - -import static extension com.google.common.base.Preconditions.checkNotNull - -/** - * Sugar for converting a {@link Function1 Xtext function} it into a {@link Function Guava function}. - */ -class FunctionDelegate implements Function { - - val Function1 delegate - - /** Creates a new function instance with the delegate. */ - new(Function1 delegate) { - this.delegate = delegate.checkNotNull; - } - - override apply(F input) { - delegate.apply(input); - } - -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/Log.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/Log.java new file mode 100644 index 0000000000..b9f6cdd710 --- /dev/null +++ b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/Log.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2023 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.utils; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +import org.eclipse.xtend.lib.macro.Active; + +/** + * + */ +@Target(ElementType.TYPE) +@Active(LogProcessor.class) +public @interface Log { + // empty +} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/LogProcessor.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/LogProcessor.java new file mode 100644 index 0000000000..7958cd2a40 --- /dev/null +++ b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/LogProcessor.java @@ -0,0 +1,52 @@ +/** + * 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.utils; + +import org.apache.log4j.Logger; +import org.eclipse.xtend.lib.macro.AbstractClassProcessor; +import org.eclipse.xtend.lib.macro.TransformationContext; +import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration; +import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration; +import org.eclipse.xtend.lib.macro.declaration.Visibility; +import org.eclipse.xtend2.lib.StringConcatenationClient; + +/** + * Adds logger declaration (field name "logger") to annotated class. Manual definition: + * + *
+ * private final static Logger logger = Logger.getLogger(TYPE.class);
+ * 
+ */ +public class LogProcessor extends AbstractClassProcessor { + + @Override + public void doTransform(MutableClassDeclaration annotatedClass, TransformationContext context) { + addLoggerDeclaration(annotatedClass, context); + } + + public void addLoggerDeclaration(MutableClassDeclaration cdecl, TransformationContext context) { + cdecl.addField("logger", (MutableFieldDeclaration field) -> { + field.setStatic(true); + field.setFinal(true); + field.setVisibility(Visibility.PRIVATE); + field.setType(context.newTypeReference(Logger.class)); + field.setInitializer(new StringConcatenationClient() { + @Override + protected void appendTo(StringConcatenationClient.TargetStringConcatenation tsc) { + tsc.append(Logger.class); + tsc.append(".getLogger("); + tsc.append(cdecl); + tsc.append(".class)"); + } + }); + }); + } +} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/LogProcessor.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/LogProcessor.xtend deleted file mode 100644 index ba37e92bb3..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/LogProcessor.xtend +++ /dev/null @@ -1,50 +0,0 @@ -/** - * 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.utils - -import org.eclipse.xtend.lib.macro.AbstractClassProcessor -import java.lang.annotation.Target -import java.lang.annotation.ElementType -import org.eclipse.xtend.lib.macro.Active -import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration -import org.eclipse.xtend.lib.macro.TransformationContext -import org.eclipse.xtend.lib.macro.declaration.Visibility -import org.apache.log4j.Logger - - -@Target(ElementType.TYPE) -@Active(LogProcessor) -annotation Log {} - -/** - * Adds logger declaration (field name "logger") to annotated class. - * Manual definition: - *
- * private final static Logger logger = Logger.getLogger(TYPE.class);
- * 
- */ -class LogProcessor extends AbstractClassProcessor { - - override doTransform(MutableClassDeclaration annotatedClass, extension TransformationContext context) { - addLoggerDeclaration(annotatedClass, context); - } - - - def addLoggerDeclaration(MutableClassDeclaration cdecl, TransformationContext context) { - cdecl.addField("logger") [ - static=true; - final=true; - visibility=Visibility.PRIVATE; - type= context.newTypeReference(Logger); - initializer = '''«Logger».getLogger(«cdecl».class)''' - ] - } -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/NLSMessagesProcessor.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/NLSMessagesProcessor.xtend deleted file mode 100644 index 6a07ad910a..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/NLSMessagesProcessor.xtend +++ /dev/null @@ -1,77 +0,0 @@ -/** - * 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.utils - -import java.lang.annotation.ElementType -import java.lang.annotation.Target -import org.eclipse.xtend.lib.macro.Active - -/** - * Active annotation which parses NLS message properties files and generates helper methods in NLS message class to - * create messages with correct number of parameters. - * - * The value of properties have to follow the following pattern: - *
    - *
  • comment in the first line, stating the description of all required wildcards - *
  • issue ID: all in upper case, no whitespaces allowed - use underscore - * instead, if sensible, use the encoded short cuts from above to indicate - * place and domain of the issue followed by a few additional meaningful words - *
  • the issue message with wildcards - *
- * - * For each key in the properties file, the annotation generates - *
    - *
  • static final String constant field with same name and same value - *
  • method {@code msg[ISSUE_ID]} having Object parameters of same count as of unique occurrences of wild cards (e.g. first parameter then - * maps to "{0}") - *
- * - * Example: - *
- * # 0: type or variable, 1: type name, 2: comma separated list of types - the sources of the imports
- * IMP_AMBIGUOUS=The {0} {1} is ambiguously imported from {2}.
- * 
- * - * From that, the following members are created in the NLS class: - *
- * public final static String IMP_AMBIGUOUS = "IMP_AMBIGUOUS";
- *
- * public static String getMessageIMP_AMBIGUOUS(final Object param0, final Object param1, final Object param2) {
- *   return org.eclipse.osgi.util.NLS.bind(getString(IMP_AMBIGUOUS), new Object [] { param0, param1, param2 });
- * }
- * 
- * - * Additional usage notes: - *
    - *
  • To apply changes from the properties file to the xtend NLS class you have to - * make the xtend class dirty (resp. make a fake change). If there are mistakes - * in the properties file (e.g. missing severity in value), the NLS annotation - * will get an error marker pointing you to the cause of the problem - *
  • With CTRL + left mouse click you can navigate from a message.properties entry to one of its current usages. - *
  • The message properties are sorted alphabetically, in order to simplify finding of entries, and to - * avoid problems of differently sorted sets due to different Java versions.

    - *
- * - * @see NLSProcessor - */ -@Target(ElementType::TYPE) -@Active(typeof(NLSMessagesProcessor)) -public annotation NLSMessages { - String propertyFileName -} - -/** See annotation NLSMessages */ -public class NLSMessagesProcessor extends AbstractNLSProcessor { - - override Class getAnnotationType() { - return NLSMessages; - } -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/NLSProcessor.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/NLSProcessor.xtend deleted file mode 100644 index e1dc2456ff..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/NLSProcessor.xtend +++ /dev/null @@ -1,181 +0,0 @@ -/** - * 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.utils - -import java.lang.annotation.ElementType -import java.lang.annotation.Target -import java.util.List -import java.util.Map -import java.util.MissingResourceException -import org.eclipse.xtend.lib.macro.Active -import org.eclipse.xtend.lib.macro.TransformationContext -import org.eclipse.xtend.lib.macro.declaration.AnnotationReference -import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration -import org.eclipse.xtend.lib.macro.declaration.Visibility -import org.eclipse.xtext.diagnostics.Severity - -/** - * Active annotation which parses NLS properties files and generates helper methods in NLS message class to - * create messages with correct number of parameters. - * - * The value of properties have to follow the following pattern: - *
    - *
  • comment in the first line, stating the description of all required wildcards - *
  • issue ID: all in upper case, no whitespaces allowed - use underscore - * instead, if sensible, use the encoded short cuts from above to indicate - * place and domain of the issue followed by a few additional meaningful words - *
  • default severity: the severity to use, if there is no other severity - * provided by the issue code provider (see explanation above) - *
  • separator: ";;;" is used to separate default severity and issue message - *
  • the issue message with wildcards - *
- * - * For each key in the properties file, the annotation generates - *
    - *
  • static final String constant field with same name and same value - *
  • method {@code getMessageFor[ISSUE_ID]} having Object parameters of same count as of unique occurrences of wild cards (e.g. first parameter then - * maps to "{0}") - *
- * - * Additionally, a general helper method is generated: - *
    - *
  • {@code getDefaultSeverity(String)} returns the default severity for the given issue ID (= key in properties file) - *
- * - * Example: - *
- * # 0: type or variable, 1: type name, 2: comma separated list of types - the sources of the imports
- * IMP_AMBIGUOUS=error;;;The {0} {1} is ambiguously imported from {2}.
- * 
- * - * From that, the following members are created in the NLS class: - *
- * public final static String IMP_AMBIGUOUS = "IMP_AMBIGUOUS";
- *
- * public static String getMessageIMP_AMBIGUOUS(final Object param0, final Object param1, final Object param2) {
- *   return org.eclipse.osgi.util.NLS.bind(getString(IMP_AMBIGUOUS), new Object [] { param0, param1, param2 });
- * }
- * 
- * - * Additional usage notes: - *
    - *
  • To apply changes from the properties file to the xtend NLS class you have to - * make the xtend class dirty (resp. make a fake change). If there are mistakes - * in the properties file (e.g. missing severity in value), the NLS annotation - * will get an error marker pointing you to the cause of the problem - *
  • With CTRL + left mouse click you can navigate from a message.properties entry to one of its current usages. - *
  • The message properties are sorted alphabetically, in order to simplify finding of entries, and to - * avoid problems of differently sorted sets due to different Java versions.

    - *
- */ -@Target(ElementType::TYPE) -@Active(typeof(NLSProcessor)) -public annotation NLS { - String propertyFileName -} - -/** See annotation NLS */ -public class NLSProcessor extends AbstractNLSProcessor { - - private static List SEVERITIES = #["error", "warning", "info", "ignore"] - - override Class getAnnotationType() { - return NLS; - } - - - override void addMembers( - MutableClassDeclaration annotatedClass, - AnnotationReference nlsAnnotation, - TransformationContext context, - String propertyFileNameValue - ) { - super.addMembers(annotatedClass, nlsAnnotation, context, propertyFileNameValue); - addGetDefaultSeverityMethod(annotatedClass, nlsAnnotation, context) - } - - override void addGetStringMethod(MutableClassDeclaration annotatedClass, AnnotationReference nlsAnnotation, - extension TransformationContext context) { - val methodName = "getString" - checkForExistentMethod(annotatedClass, methodName, context, nlsAnnotation, 1) - annotatedClass.addMethod(methodName) [ - visibility = Visibility.PRIVATE - static = true - returnType = string - addParameter("key", string) - body = ''' - try { - «string» value = «annotatedClass.findDeclaredField(RESOURCE_BUNDLE_FIELD).simpleName».getString(key); - «string»[] parts = value.split(";;;"); - return parts[1]; - } catch («MissingResourceException» e) { - return '!' + key + '!'; - } - ''' - ] - } - - - def private void addGetDefaultSeverityMethod(MutableClassDeclaration annotatedClass, - AnnotationReference nlsAnnotation, extension TransformationContext context) { - val methodName = "getDefaultSeverity" - checkForExistentMethod(annotatedClass, methodName, context, nlsAnnotation, 1) - annotatedClass.addMethod(methodName) [ - visibility = Visibility.PUBLIC - static = true - returnType = Severity.newTypeReference - addParameter("key", string) - body = ''' - try { - «string» value = «annotatedClass.findDeclaredField(RESOURCE_BUNDLE_FIELD).simpleName».getString(key); - «string»[] parts = value.split(";;;"); - «string» defaultSeverity = parts[0]; - return «Severity».valueOf(defaultSeverity.toUpperCase()); - } catch («MissingResourceException» e) { - return null; - } - ''' - ] - } - - override void addMethod(Map.Entry entry, MutableClassDeclaration annotatedClass, - AnnotationReference nlsAnnotation, extension TransformationContext context) { - val value = entry.value as String - val parts = value.split(";;;") - if (parts.length != 2) { - nlsAnnotation.addError( - "Value for " + entry.key + " in properties file doesn't follow pattern 'defaultSeverity;;;message'") - return - } - val defaultSeverity = parts.get(0) - if (!SEVERITIES.contains(defaultSeverity)) { - nlsAnnotation.addError( - defaultSeverity + " is not a valid severity (which would be " + SEVERITIES.join(", ") + ").") - return - } - val message = parts.get(1) - val wildcardCount = message.getWildcardCount - val params = if (wildcardCount > 0) (0 .. wildcardCount - 1).map["param" + it] else newArrayList - val getMessageForMethodName = "getMessageFor" + entry.key - checkForExistentMethod(annotatedClass, getMessageForMethodName, context, nlsAnnotation, params.size) - annotatedClass.addMethod(getMessageForMethodName) [ - visibility = Visibility.PUBLIC - static = true - returnType = context.string - params.forEach(param|addParameter(param, object)) - docComment = message - body = '''return «nlsClass».bind(getString(«entry.key»), new Object [] { «params.join(", ")» });''' - ] - } - - - -} diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/Strings.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/Strings.java index 582d3b658b..8a7dc0aeee 100644 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/Strings.java +++ b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/Strings.java @@ -288,4 +288,21 @@ public static String stripAllTrailing(String str) { } return Strings.join("\n", (Object[]) lines); } + + public static int count(String str, String pattern) { + if (str == null || str.isEmpty()) { + return 0; + } + + int count = 0; + int idx = 0; + idx = str.indexOf(pattern, idx); + while (idx > 0) { + idx++; + count++; + idx = str.indexOf(pattern, idx); + } + + return count; + } } diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/XtextUtilN4.xtend b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/XtextUtilN4.xtend deleted file mode 100644 index c005138279..0000000000 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/XtextUtilN4.xtend +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright (c) 2017 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.utils - -import com.google.inject.Inject -import com.google.inject.Singleton -import java.util.List -import org.eclipse.emf.ecore.EClass -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.resource.Resource -import org.eclipse.xtext.resource.IContainer -import org.eclipse.xtext.resource.IEObjectDescription -import org.eclipse.xtext.resource.IResourceDescription -import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider - -/** - * This class contains helper methods for working with Xtext. - */ - @Singleton -class XtextUtilN4 { - @Inject IContainer.Manager containerManager; - @Inject ResourceDescriptionsProvider resourceDescriptionsProvider; - @Inject IResourceDescription.Manager descriptionManager; - - /** - * Return all EObjectDescriptions in the index that are visible from an EObject. - * @param o - * the EObject - *

- * See Lorenzo's book page 260. - */ - def Iterable getVisibleEObjectDescriptions(EObject o) { - o.visibleContainers.map [ container | container.exportedObjects ].flatten; - } - - /** - * Return all EObjectDescriptions of a certain type in the index that are visible from an EObject. - * @param o - * the EObject. - * @param type - * the type of EObjectDescriptions to filter. - *

- * See Lorenzo's book page 260. - */ - def Iterable getVisibleEObjectDescriptions(EObject o, EClass type) { - o.visibleContainers.map [ container | container.getExportedObjectsByType(type) ].flatten; - } - - /** - * Return all visible containers from within a given resource. - * @param resource - * the resource - */ - def List getVisibleContainers(Resource resource) { - val index = resourceDescriptionsProvider.getResourceDescriptions(resource.getResourceSet()); - val resourceDescription = descriptionManager.getResourceDescription(resource); - return containerManager.getVisibleContainers(resourceDescription, index); - } - - def private List getVisibleContainers(EObject o) { - val index = resourceDescriptionsProvider.getResourceDescriptions((o.eResource)); - val resourceDescription = index.getResourceDescription(o.eResource.URI) - containerManager.getVisibleContainers(resourceDescription, index); - } -} diff --git a/plugins/org.eclipse.n4js.utils/xtend-gen/.gitignore b/plugins/org.eclipse.n4js.utils/xtend-gen/.gitignore deleted file mode 100644 index c96a04f008..0000000000 --- a/plugins/org.eclipse.n4js.utils/xtend-gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/plugins/org.eclipse.n4js/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.n4js/.settings/org.eclipse.jdt.core.prefs index f22022d1bb..f8f455c60f 100644 --- a/plugins/org.eclipse.n4js/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.eclipse.n4js/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,5 @@ eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.annotationPath.allLocations=disabled org.eclipse.jdt.core.builder.cleanOutputFolder=clean org.eclipse.jdt.core.builder.duplicateResourceTask=warning org.eclipse.jdt.core.builder.invalidClasspath=abort @@ -21,8 +22,11 @@ org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore org.eclipse.jdt.core.compiler.annotation.nonnull=javax.annotation.Nonnull +org.eclipse.jdt.core.compiler.annotation.nonnull.secondary= org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=javax.annotation.ParametersAreNonnullByDefault +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary= org.eclipse.jdt.core.compiler.annotation.nullable=javax.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullable.secondary= org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate @@ -34,6 +38,8 @@ org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.doc.comment.support=enabled org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.APILeak=warning +org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated=info org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.autoboxing=ignore @@ -84,12 +90,14 @@ org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning org.eclipse.jdt.core.compiler.problem.nullReference=error org.eclipse.jdt.core.compiler.problem.nullSpecViolation=warning org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning @@ -104,21 +112,28 @@ org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=enabled org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.suppressWarningsNotFullyAnalysed=info org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning +org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled +org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=warning org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedImport=warning org.eclipse.jdt.core.compiler.problem.unusedLabel=warning org.eclipse.jdt.core.compiler.problem.unusedLocal=warning diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/N4JSLanguageConstants.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/N4JSLanguageConstants.java index 69f0140585..7551825239 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/N4JSLanguageConstants.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/N4JSLanguageConstants.java @@ -61,9 +61,9 @@ public abstract class N4JSLanguageConstants { * or {@code SuppressIssuesSetup} to configure Xpect tests for issue suppression. */ public static final Set DEFAULT_SUPPRESSED_ISSUE_CODES_FOR_TESTS = unmodifiableSet(newHashSet( - IssueCodes.CFG_LOCAL_VAR_UNUSED, - IssueCodes.DFG_NULL_DEREFERENCE, - JSONIssueCodes.JSON_COMMENT_UNSUPPORTED + IssueCodes.CFG_LOCAL_VAR_UNUSED.name(), + IssueCodes.DFG_NULL_DEREFERENCE.name(), + JSONIssueCodes.JSON_COMMENT_UNSUPPORTED.name() )); //@formatter:on diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/PropertyNameAwareElementFactory.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/PropertyNameAwareElementFactory.java index c63f86fa34..2d79d4b3ed 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/PropertyNameAwareElementFactory.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/PropertyNameAwareElementFactory.java @@ -89,7 +89,7 @@ public void set(EObject object, String feature, Object value, String ruleName, I } catch (ValueConverterException e) { throw e; } catch (NullPointerException e) { - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_NPE(), IssueCodes.VCO_NPE, node, e); + throw new N4JSValueConverterException(IssueCodes.VCO_NPE.getMessage(), IssueCodes.VCO_NPE.name(), node, e); } catch (Exception e) { throw new ValueConverterException(null, node, e); } @@ -142,7 +142,8 @@ private Object getTokenValue(Object tokenOrValue, String ruleName, INode node) t private void checkNullForPrimitiveFeatures(EStructuralFeature structuralFeature, Object tokenValue, INode node) { if (tokenValue == null && structuralFeature.getEType().getInstanceClass().isPrimitive()) { throw new N4JSValueConverterException( - IssueCodes.getMessageForVCO_NULL_FEATURE(structuralFeature.getName()), IssueCodes.VCO_NULL_FEATURE, + IssueCodes.VCO_NULL_FEATURE.getMessage(structuralFeature.getName()), + IssueCodes.VCO_NULL_FEATURE.name(), node, null); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/AbstractN4JSStringValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/AbstractN4JSStringValueConverter.java index 2d76c2beab..4bc8ad5f84 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/AbstractN4JSStringValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/AbstractN4JSStringValueConverter.java @@ -79,11 +79,11 @@ public static String convertFromN4JSString(String n4jsString, INode node, boolea null); if (validate) { if (result.hasError()) { - throw new BadEscapementException(IssueCodes.getMessageForVCO_STRING_BAD_ESCAPE_ERROR(), - IssueCodes.VCO_STRING_BAD_ESCAPE_ERROR, node, result.getValue(), true); + throw new BadEscapementException(IssueCodes.VCO_STRING_BAD_ESCAPE_ERROR.getMessage(), + IssueCodes.VCO_STRING_BAD_ESCAPE_ERROR.name(), node, result.getValue(), true); } else if (result.hasWarning()) { - throw new BadEscapementException(IssueCodes.getMessageForVCO_STRING_BAD_ESCAPE_WARN(), - IssueCodes.VCO_STRING_BAD_ESCAPE_WARN, node, result.getValue(), false); + throw new BadEscapementException(IssueCodes.VCO_STRING_BAD_ESCAPE_WARN.getMessage(), + IssueCodes.VCO_STRING_BAD_ESCAPE_WARN.name(), node, result.getValue(), false); } } return result.getValue(); diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/BinaryIntValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/BinaryIntValueConverter.java index 41e2bc6455..dc7f57a6f1 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/BinaryIntValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/BinaryIntValueConverter.java @@ -13,12 +13,11 @@ import java.math.BigDecimal; import java.math.BigInteger; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.util.Strings; -import org.eclipse.n4js.validation.IssueCodes; - /** * A value converter that properly converts hexadecimal JS numbers to {@link BigDecimal}. */ @@ -33,26 +32,26 @@ protected String toEscapedString(BigDecimal value) { protected void assertValidValue(BigDecimal value) { super.assertValidValue(value); if (value.signum() == -1) - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_BINARYINT_NEGATIVE(getRuleName(), value), - IssueCodes.VCO_BINARYINT_NEGATIVE, null, null); + throw new N4JSValueConverterException(IssueCodes.VCO_BINARYINT_NEGATIVE.getMessage(getRuleName(), value), + IssueCodes.VCO_BINARYINT_NEGATIVE.name(), null, null); } @Override public BigDecimal toValue(String string, INode node) { if (Strings.isEmpty(string)) - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_BINARYINT_CONVERT_EMPTY_STR(), - IssueCodes.VCO_BINARYINT_CONVERT_EMPTY_STR, node, null); + throw new N4JSValueConverterException(IssueCodes.VCO_BINARYINT_CONVERT_EMPTY_STR.getMessage(), + IssueCodes.VCO_BINARYINT_CONVERT_EMPTY_STR.name(), node, null); if (string.length() <= 2) { throw new N4JSValueConverterWithValueException( - IssueCodes.getMessageForVCO_BINARYINT_CONVERT_TOO_SHORT(string), - IssueCodes.VCO_BINARYINT_CONVERT_TOO_SHORT, node, + IssueCodes.VCO_BINARYINT_CONVERT_TOO_SHORT.getMessage(string), + IssueCodes.VCO_BINARYINT_CONVERT_TOO_SHORT.name(), node, BigDecimal.ZERO, null); } try { return new BigDecimal(new BigInteger(string.substring(2), 2)); } catch (NumberFormatException e) { - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_HEXINT_CONVERT_STR(string), - IssueCodes.VCO_HEXINT_CONVERT_STR, node, null); + throw new N4JSValueConverterException(IssueCodes.VCO_HEXINT_CONVERT_STR.getMessage(string), + IssueCodes.VCO_HEXINT_CONVERT_STR.name(), node, null); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/DoubleValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/DoubleValueConverter.java index ac3c38b82a..c528b5b581 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/DoubleValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/DoubleValueConverter.java @@ -12,12 +12,11 @@ import java.math.BigDecimal; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.util.Strings; -import org.eclipse.n4js.validation.IssueCodes; - /** * A value converter that properly converts floating point JS numbers to {@link BigDecimal}. */ @@ -32,20 +31,20 @@ protected String toEscapedString(BigDecimal value) { protected void assertValidValue(BigDecimal value) { super.assertValidValue(value); if (value.signum() == -1) - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_DOUBLE_NEGATIVE(getRuleName(), value), - IssueCodes.VCO_DOUBLE_NEGATIVE, null, null); + throw new N4JSValueConverterException(IssueCodes.VCO_DOUBLE_NEGATIVE.getMessage(getRuleName(), value), + IssueCodes.VCO_DOUBLE_NEGATIVE.name(), null, null); } @Override public BigDecimal toValue(String string, INode node) { if (Strings.isEmpty(string)) - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_DOUBLE_CONVERT_EMPTY_STR(), - IssueCodes.VCO_DOUBLE_CONVERT_EMPTY_STR, node, null); + throw new N4JSValueConverterException(IssueCodes.VCO_DOUBLE_CONVERT_EMPTY_STR.getMessage(), + IssueCodes.VCO_DOUBLE_CONVERT_EMPTY_STR.name(), node, null); try { return new BigDecimal(string); } catch (NumberFormatException e) { - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_DOUBLE_CONVERT_STR(string), - IssueCodes.VCO_DOUBLE_CONVERT_STR, node, null); + throw new N4JSValueConverterException(IssueCodes.VCO_DOUBLE_CONVERT_STR.getMessage(string), + IssueCodes.VCO_DOUBLE_CONVERT_STR.name(), node, null); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/HexIntValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/HexIntValueConverter.java index 1da5ec4a5d..ff77c492cf 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/HexIntValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/HexIntValueConverter.java @@ -13,12 +13,11 @@ import java.math.BigDecimal; import java.math.BigInteger; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.util.Strings; -import org.eclipse.n4js.validation.IssueCodes; - /** * A value converter that properly converts hexadecimal JS numbers to {@link BigDecimal}. */ @@ -33,26 +32,26 @@ protected String toEscapedString(BigDecimal value) { protected void assertValidValue(BigDecimal value) { super.assertValidValue(value); if (value.signum() == -1) - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_HEXINT_NEGATIVE(getRuleName(), value), - IssueCodes.VCO_HEXINT_NEGATIVE, null, null); + throw new N4JSValueConverterException(IssueCodes.VCO_HEXINT_NEGATIVE.getMessage(getRuleName(), value), + IssueCodes.VCO_HEXINT_NEGATIVE.name(), null, null); } @Override public BigDecimal toValue(String string, INode node) { if (Strings.isEmpty(string)) - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_HEXINT_CONVERT_EMPTY_STR(), - IssueCodes.VCO_HEXINT_CONVERT_EMPTY_STR, node, null); + throw new N4JSValueConverterException(IssueCodes.VCO_HEXINT_CONVERT_EMPTY_STR.getMessage(), + IssueCodes.VCO_HEXINT_CONVERT_EMPTY_STR.name(), node, null); if (string.length() <= 2) { throw new N4JSValueConverterWithValueException( - IssueCodes.getMessageForVCO_HEXINT_CONVERT_TOO_SHORT(string), - IssueCodes.VCO_HEXINT_CONVERT_TOO_SHORT, node, + IssueCodes.VCO_HEXINT_CONVERT_TOO_SHORT.getMessage(string), + IssueCodes.VCO_HEXINT_CONVERT_TOO_SHORT.name(), node, BigDecimal.ZERO, null); } try { return new BigDecimal(new BigInteger(string.substring(2), 16)); } catch (NumberFormatException e) { - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_HEXINT_CONVERT_STR(string), - IssueCodes.VCO_HEXINT_CONVERT_STR, node, null); + throw new N4JSValueConverterException(IssueCodes.VCO_HEXINT_CONVERT_STR.getMessage(string), + IssueCodes.VCO_HEXINT_CONVERT_STR.name(), node, null); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/IdentifierValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/IdentifierValueConverter.java index 38460212f6..9727971157 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/IdentifierValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/IdentifierValueConverter.java @@ -63,21 +63,21 @@ public static String convertFromN4JSIdentifier(String jsString, INode node) { validityChecker); if (result.hasError()) { throw new N4JSValueConverterWithValueException( - IssueCodes.getMessageForVCO_IDENT_ESCAPE_SEQ(jsString, result.getErrorOffset()), - IssueCodes.VCO_IDENT_ESCAPE_SEQ, + IssueCodes.VCO_IDENT_ESCAPE_SEQ.getMessage(jsString, result.getErrorOffset()), + IssueCodes.VCO_IDENT_ESCAPE_SEQ.name(), node, result.getValue(), null); } if (result.hasInvalidChar()) { if (result.getValue().length() != 0) throw new N4JSValueConverterWithValueException( - IssueCodes.getMessageForVCO_IDENT_ILLEGAL_CHAR_WITH_RESULT(result.getValue(), jsString, + IssueCodes.VCO_IDENT_ILLEGAL_CHAR_WITH_RESULT.getMessage(result.getValue(), jsString, result.getInvalidCharOffset()), - IssueCodes.VCO_IDENT_ILLEGAL_CHAR_WITH_RESULT, + IssueCodes.VCO_IDENT_ILLEGAL_CHAR_WITH_RESULT.name(), node, result.getValue(), null); else - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_IDENT_ILLEGAL_CHAR( + throw new N4JSValueConverterException(IssueCodes.VCO_IDENT_ILLEGAL_CHAR.getMessage( jsString, result.getInvalidCharOffset()), - IssueCodes.VCO_IDENT_ILLEGAL_CHAR, + IssueCodes.VCO_IDENT_ILLEGAL_CHAR.name(), node, null); } return result.getValue(); diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/JSXIdentifierValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/JSXIdentifierValueConverter.java index 8f09fddd0a..527bf9aa16 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/JSXIdentifierValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/JSXIdentifierValueConverter.java @@ -48,8 +48,8 @@ public String toValue(String string, INode node) throws ValueConverterException int idx = disallowedChar.indexIn(string); if (idx != -1) { throw new N4JSValueConverterWithValueException( - IssueCodes.getMessageForVCO_IDENT_ILLEGAL_CHAR_WITH_RESULT(string, string.charAt(idx), idx), - IssueCodes.VCO_IDENT_ILLEGAL_CHAR_WITH_RESULT, node, string.substring(0, idx), null); + IssueCodes.VCO_IDENT_ILLEGAL_CHAR_WITH_RESULT.getMessage(string, string.charAt(idx), idx), + IssueCodes.VCO_IDENT_ILLEGAL_CHAR_WITH_RESULT.name(), node, string.substring(0, idx), null); } } return string; @@ -63,16 +63,16 @@ private void validate(String value, int firstOffset, ILeafNode leaf) { if (leaf.isHidden()) { int idx = leaf.getTotalOffset() - firstOffset; throw new N4JSValueConverterWithValueException( - IssueCodes.getMessageForVCO_JSXIDENT_WHITESPACE_COMMENT(), - IssueCodes.VCO_JSXIDENT_WHITESPACE_COMMENT, leaf, value.substring(0, idx), null); + IssueCodes.VCO_JSXIDENT_WHITESPACE_COMMENT.getMessage(), + IssueCodes.VCO_JSXIDENT_WHITESPACE_COMMENT.name(), leaf, value.substring(0, idx), null); } else { int escapeSequence = leaf.getText().indexOf("\\"); if (escapeSequence >= 0) { int idx = leaf.getTotalOffset() - firstOffset + escapeSequence; throw new N4JSValueConverterWithValueException( - IssueCodes.getMessageForVCO_IDENT_ILLEGAL_CHAR_WITH_RESULT(value, + IssueCodes.VCO_IDENT_ILLEGAL_CHAR_WITH_RESULT.getMessage(value, leaf.getText().charAt(escapeSequence), idx), - IssueCodes.VCO_IDENT_ILLEGAL_CHAR_WITH_RESULT, leaf, value.substring(0, idx), null); + IssueCodes.VCO_IDENT_ILLEGAL_CHAR_WITH_RESULT.name(), leaf, value.substring(0, idx), null); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/LegacyOctalIntValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/LegacyOctalIntValueConverter.java index 32dbb7ad60..19d894b05d 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/LegacyOctalIntValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/LegacyOctalIntValueConverter.java @@ -13,12 +13,11 @@ import java.math.BigDecimal; import java.math.BigInteger; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.util.Strings; -import org.eclipse.n4js.validation.IssueCodes; - /** * A value converter that properly converts octal JS numbers to {@link BigDecimal}. */ @@ -54,19 +53,19 @@ protected String toEscapedString(BigDecimal value) { protected void assertValidValue(BigDecimal value) { super.assertValidValue(value); if (value.signum() == -1) - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_OCTALINT_NEGATIVE(getRuleName(), value), - IssueCodes.VCO_OCTALINT_NEGATIVE, null, null); + throw new N4JSValueConverterException(IssueCodes.VCO_OCTALINT_NEGATIVE.getMessage(getRuleName(), value), + IssueCodes.VCO_OCTALINT_NEGATIVE.name(), null, null); } @Override public BigDecimal toValue(String string, INode node) { if (Strings.isEmpty(string)) - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_OCTALINT_CONVERT_EMPTY_STR(), - IssueCodes.VCO_OCTALINT_CONVERT_EMPTY_STR, node, null); + throw new N4JSValueConverterException(IssueCodes.VCO_OCTALINT_CONVERT_EMPTY_STR.getMessage(), + IssueCodes.VCO_OCTALINT_CONVERT_EMPTY_STR.name(), node, null); if (string.length() <= 1) { throw new N4JSValueConverterWithValueException( - IssueCodes.getMessageForVCO_OCTALINT_CONVERT_TOO_SHORT(string), - IssueCodes.VCO_OCTALINT_CONVERT_TOO_SHORT, node, + IssueCodes.VCO_OCTALINT_CONVERT_TOO_SHORT.getMessage(string), + IssueCodes.VCO_OCTALINT_CONVERT_TOO_SHORT.name(), node, BigDecimal.ZERO, null); } try { @@ -74,11 +73,11 @@ public BigDecimal toValue(String string, INode node) { } catch (NumberFormatException e) { try { BigDecimal result = new BigDecimal(new BigInteger(string, 10)); - throw new LeadingZerosException(IssueCodes.getMessageForVCO_OCTALINT_LEADING_ZEROS(string), - IssueCodes.VCO_OCTALINT_LEADING_ZEROS, node, result); + throw new LeadingZerosException(IssueCodes.VCO_OCTALINT_LEADING_ZEROS.getMessage(string), + IssueCodes.VCO_OCTALINT_LEADING_ZEROS.name(), node, result); } catch (NumberFormatException again) { - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_OCTALINT_CONVERT_STR(string), - IssueCodes.VCO_OCTALINT_CONVERT_STR, node, null); + throw new N4JSValueConverterException(IssueCodes.VCO_OCTALINT_CONVERT_STR.getMessage(string), + IssueCodes.VCO_OCTALINT_CONVERT_STR.name(), node, null); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/N4JSStringValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/N4JSStringValueConverter.java index 3771a790bf..b721443ae4 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/N4JSStringValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/N4JSStringValueConverter.java @@ -63,10 +63,10 @@ public String toValue(String string, INode node) { */ protected N4JSValueConverterWithValueException newN4JSValueConverterException(char c, INode node, String value) { if (c == '"') - return new N4JSValueConverterWithValueException(IssueCodes.getMessageForVCO_STRING_DOUBLE_QUOTE(), - IssueCodes.VCO_STRING_DOUBLE_QUOTE, node, value, null); + return new N4JSValueConverterWithValueException(IssueCodes.VCO_STRING_DOUBLE_QUOTE.getMessage(), + IssueCodes.VCO_STRING_DOUBLE_QUOTE.name(), node, value, null); else - return new N4JSValueConverterWithValueException(IssueCodes.getMessageForVCO_STRING_QUOTE(), - IssueCodes.VCO_STRING_QUOTE, node, value, null); + return new N4JSValueConverterWithValueException(IssueCodes.VCO_STRING_QUOTE.getMessage(), + IssueCodes.VCO_STRING_QUOTE.name(), node, value, null); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/N4JSValueConverterException.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/N4JSValueConverterException.java index b32930c2f8..8ed69bc91a 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/N4JSValueConverterException.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/N4JSValueConverterException.java @@ -10,14 +10,13 @@ */ package org.eclipse.n4js.parser.conversion; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.conversion.ValueConverterException; import org.eclipse.xtext.diagnostics.Severity; import org.eclipse.xtext.nodemodel.INode; -import org.eclipse.n4js.validation.IssueCodes; - /** - * Extende value converter exception to hold issue code and message later to use by Xtext diagnostic producer. + * Extends value converter exception to hold issue code and message later to use by Xtext diagnostic producer. */ public class N4JSValueConverterException extends ValueConverterException { private final String issueCode; @@ -37,7 +36,7 @@ public N4JSValueConverterException(final String message, final String issueCode, final Exception cause) { super(message, node, cause); this.issueCode = issueCode; - this.severity = IssueCodes.getDefaultSeverity(issueCode); + this.severity = IssueCodes.getSeverityForName(issueCode); } /** diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/N4JSValueConverterWithValueException.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/N4JSValueConverterWithValueException.java index 11593a9201..d1221ff79a 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/N4JSValueConverterWithValueException.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/N4JSValueConverterWithValueException.java @@ -10,14 +10,13 @@ */ package org.eclipse.n4js.parser.conversion; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.conversion.ValueConverterWithValueException; import org.eclipse.xtext.diagnostics.Severity; import org.eclipse.xtext.nodemodel.INode; -import org.eclipse.n4js.validation.IssueCodes; - /** - * Extende value converter with value exception to hold issue code and message later to use by Xtext diagnostic + * Extends value converter with value exception to hold issue code and message later to use by Xtext diagnostic * producer. */ public class N4JSValueConverterWithValueException extends ValueConverterWithValueException { @@ -43,7 +42,7 @@ public N4JSValueConverterWithValueException(final String message, final String i super(message, node, value, cause); this.hasRange = false; this.issueCode = issueCode; - this.severity = IssueCodes.getDefaultSeverity(issueCode); + this.severity = IssueCodes.getSeverityForName(issueCode); } /** @@ -69,7 +68,7 @@ public N4JSValueConverterWithValueException(final String message, final String i super(message, node, value, offset, length, cause); this.hasRange = true; this.issueCode = issueCode; - this.severity = IssueCodes.getDefaultSeverity(issueCode); + this.severity = IssueCodes.getSeverityForName(issueCode); } @Override diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/NoSubstitutionTemplateSegmentValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/NoSubstitutionTemplateSegmentValueConverter.java index 751b315139..7b20ca8537 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/NoSubstitutionTemplateSegmentValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/NoSubstitutionTemplateSegmentValueConverter.java @@ -10,9 +10,8 @@ */ package org.eclipse.n4js.parser.conversion; -import org.eclipse.xtext.nodemodel.INode; - import org.eclipse.n4js.validation.IssueCodes; +import org.eclipse.xtext.nodemodel.INode; /** */ @@ -33,8 +32,8 @@ protected String getLeftDelimiter() { */ @Override protected N4JSValueConverterWithValueException newN4JSValueConverterException(INode node, String value) { - return new N4JSValueConverterWithValueException(IssueCodes.getMessageForVCO_TEMPLATE_QUOTE(), - IssueCodes.VCO_TEMPLATE_QUOTE, node, value, null); + return new N4JSValueConverterWithValueException(IssueCodes.VCO_TEMPLATE_QUOTE.getMessage(), + IssueCodes.VCO_TEMPLATE_QUOTE.name(), node, value, null); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/OctalIntValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/OctalIntValueConverter.java index 55582a179e..9b835daede 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/OctalIntValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/OctalIntValueConverter.java @@ -13,12 +13,11 @@ import java.math.BigDecimal; import java.math.BigInteger; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.util.Strings; -import org.eclipse.n4js.validation.IssueCodes; - /** * A value converter that properly converts hexadecimal JS numbers to {@link BigDecimal}. */ @@ -33,26 +32,26 @@ protected String toEscapedString(BigDecimal value) { protected void assertValidValue(BigDecimal value) { super.assertValidValue(value); if (value.signum() == -1) - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_HEXINT_NEGATIVE(getRuleName(), value), - IssueCodes.VCO_OCTALINT_NEGATIVE, null, null); + throw new N4JSValueConverterException(IssueCodes.VCO_HEXINT_NEGATIVE.getMessage(getRuleName(), value), + IssueCodes.VCO_OCTALINT_NEGATIVE.name(), null, null); } @Override public BigDecimal toValue(String string, INode node) { if (Strings.isEmpty(string)) - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_OCTALINT_CONVERT_EMPTY_STR(), - IssueCodes.VCO_OCTALINT_CONVERT_EMPTY_STR, node, null); + throw new N4JSValueConverterException(IssueCodes.VCO_OCTALINT_CONVERT_EMPTY_STR.getMessage(), + IssueCodes.VCO_OCTALINT_CONVERT_EMPTY_STR.name(), node, null); if (string.length() <= 2) { throw new N4JSValueConverterWithValueException( - IssueCodes.getMessageForVCO_OCTALINT_CONVERT_TOO_SHORT(string), - IssueCodes.VCO_OCTALINT_CONVERT_TOO_SHORT, node, + IssueCodes.VCO_OCTALINT_CONVERT_TOO_SHORT.getMessage(string), + IssueCodes.VCO_OCTALINT_CONVERT_TOO_SHORT.name(), node, BigDecimal.ZERO, null); } try { return new BigDecimal(new BigInteger(string.substring(2), 8)); } catch (NumberFormatException e) { - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_OCTALINT_CONVERT_STR(string), - IssueCodes.VCO_OCTALINT_CONVERT_STR, node, null); + throw new N4JSValueConverterException(IssueCodes.VCO_OCTALINT_CONVERT_STR.getMessage(string), + IssueCodes.VCO_OCTALINT_CONVERT_STR.name(), node, null); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/RegExLiteralConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/RegExLiteralConverter.java index 9ee809ea7d..9581b8bc4c 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/RegExLiteralConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/RegExLiteralConverter.java @@ -112,8 +112,8 @@ public String toValue(String string, INode node) { offsetFixup = node.getOffset() - node.getTotalOffset(); } N4JSValueConverterWithValueException mainError = new N4JSValueConverterWithValueException( - IssueCodes.getMessageForVCO_REGEX_INVALID(), - IssueCodes.VCO_REGEX_INVALID, node, + IssueCodes.VCO_REGEX_INVALID.getMessage(), + IssueCodes.VCO_REGEX_INVALID.name(), node, stringConverterResult.getSourceOffset(localOffset) + offsetFixup, syntaxError.getLength(), string, null); @@ -139,8 +139,8 @@ public String toValue(String string, INode node) { if (offsetFixup == -1) { offsetFixup = node.getOffset() - node.getTotalOffset(); } - errors.add(new N4JSValueConverterWithValueException(IssueCodes.getMessageForVCO_REGEX_INVALID(), - IssueCodes.VCO_REGEX_INVALID, node, + errors.add(new N4JSValueConverterWithValueException(IssueCodes.VCO_REGEX_INVALID.getMessage(), + IssueCodes.VCO_REGEX_INVALID.name(), node, stringConverterResult.getSourceOffset(nodeForElement.getOffset()) + offsetFixup, nodeForElement.getLength(), string, null)); @@ -152,8 +152,8 @@ public String toValue(String string, INode node) { if (offsetFixup == -1) { offsetFixup = node.getOffset() - node.getTotalOffset(); } - errors.add(new N4JSValueConverterWithValueException(IssueCodes.getMessageForVCO_REGEX_INVALID(), - IssueCodes.VCO_REGEX_INVALID, node, + errors.add(new N4JSValueConverterWithValueException(IssueCodes.VCO_REGEX_INVALID.getMessage(), + IssueCodes.VCO_REGEX_INVALID.name(), node, stringConverterResult.getSourceOffset(featureNode.getOffset()) + offsetFixup, featureNode.getLength(), string, null)); @@ -165,8 +165,8 @@ public String toValue(String string, INode node) { if (offsetFixup == -1) { offsetFixup = node.getOffset() - node.getTotalOffset(); } - errors.add(new N4JSValueConverterWithValueException(IssueCodes.getMessageForVCO_REGEX_INVALID(), - IssueCodes.VCO_REGEX_INVALID, node, + errors.add(new N4JSValueConverterWithValueException(IssueCodes.VCO_REGEX_INVALID.getMessage(), + IssueCodes.VCO_REGEX_INVALID.name(), node, stringConverterResult.getSourceOffset(nodeForElement.getOffset()) + offsetFixup, nodeForElement.getLength(), string, null)); } @@ -175,8 +175,8 @@ public String toValue(String string, INode node) { if (offsetFixup == -1) { offsetFixup = node.getOffset() - node.getTotalOffset(); } - errors.add(new N4JSValueConverterWithValueException(IssueCodes.getMessageForVCO_REGEX_INVALID(), - IssueCodes.VCO_REGEX_INVALID, node, + errors.add(new N4JSValueConverterWithValueException(IssueCodes.VCO_REGEX_INVALID.getMessage(), + IssueCodes.VCO_REGEX_INVALID.name(), node, stringConverterResult.getSourceOffset(nodeForElement.getOffset()) + offsetFixup, nodeForElement.getLength(), string, null)); } @@ -191,8 +191,8 @@ public String toValue(String string, INode node) { if (offsetFixup == -1) { offsetFixup = node.getOffset() - node.getTotalOffset(); } - errors.add(new N4JSValueConverterWithValueException(IssueCodes.getMessageForVCO_REGEX_NAMED_GROUP(), - IssueCodes.VCO_REGEX_NAMED_GROUP, node, + errors.add(new N4JSValueConverterWithValueException(IssueCodes.VCO_REGEX_NAMED_GROUP.getMessage(), + IssueCodes.VCO_REGEX_NAMED_GROUP.name(), node, stringConverterResult.getSourceOffset(nameNode.getOffset()) + offsetFixup, nameNode.getLength(), string, null)); @@ -214,8 +214,8 @@ private static StringConverterResult convertFromJS(String jsString, INode node) if (result.hasError()) { int offsetFixup = node.getOffset() - node.getTotalOffset(); throw new N4JSValueConverterWithValueException( - IssueCodes.getMessageForVCO_REGEX_ILLEGAL_ESCAPE(jsString), - IssueCodes.VCO_REGEX_ILLEGAL_ESCAPE, node, result.getErrorOffset() + offsetFixup, 1, + IssueCodes.VCO_REGEX_ILLEGAL_ESCAPE.getMessage(jsString), + IssueCodes.VCO_REGEX_ILLEGAL_ESCAPE.name(), node, result.getErrorOffset() + offsetFixup, 1, result.getValue(), null); } return result; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/ScientificIntValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/ScientificIntValueConverter.java index f3a14d3654..a99c959bcd 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/ScientificIntValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/ScientificIntValueConverter.java @@ -12,12 +12,11 @@ import java.math.BigDecimal; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.util.Strings; -import org.eclipse.n4js.validation.IssueCodes; - /** * A value converter that properly converts JS numbers in scientific notation to {@link BigDecimal}. */ @@ -32,20 +31,20 @@ protected String toEscapedString(BigDecimal value) { protected void assertValidValue(BigDecimal value) { super.assertValidValue(value); if (value.signum() == -1) - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_SCIINT_NEGATIVE(getRuleName(), value), - IssueCodes.VCO_SCIINT_NEGATIVE, null, null); + throw new N4JSValueConverterException(IssueCodes.VCO_SCIINT_NEGATIVE.getMessage(getRuleName(), value), + IssueCodes.VCO_SCIINT_NEGATIVE.name(), null, null); } @Override public BigDecimal toValue(String string, INode node) { if (Strings.isEmpty(string)) - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_SCIINT_CONVERT_EMPTY_STR(), - IssueCodes.VCO_SCIINT_CONVERT_EMPTY_STR, node, null); + throw new N4JSValueConverterException(IssueCodes.VCO_SCIINT_CONVERT_EMPTY_STR.getMessage(), + IssueCodes.VCO_SCIINT_CONVERT_EMPTY_STR.name(), node, null); try { return new BigDecimal(string); } catch (NumberFormatException e) { - throw new N4JSValueConverterException(IssueCodes.getMessageForVCO_SCIINT_CONVERT_STR(string), - IssueCodes.VCO_SCIINT_CONVERT_STR, node, null); + throw new N4JSValueConverterException(IssueCodes.VCO_SCIINT_CONVERT_STR.getMessage(string), + IssueCodes.VCO_SCIINT_CONVERT_STR.name(), node, null); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/TemplateEndValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/TemplateEndValueConverter.java index 1a5098adfc..7a8aafeba8 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/TemplateEndValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/TemplateEndValueConverter.java @@ -10,12 +10,11 @@ */ package org.eclipse.n4js.parser.conversion; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.AbstractRule; import org.eclipse.xtext.RuleCall; import org.eclipse.xtext.nodemodel.INode; -import org.eclipse.n4js.validation.IssueCodes; - /** */ public class TemplateEndValueConverter extends AbstractTemplateSegmentValueConverter { @@ -40,8 +39,9 @@ public String toValue(String string, INode node) { @Override protected N4JSValueConverterWithValueException newN4JSValueConverterException(INode node, String value) { - return new N4JSValueConverterWithValueException(IssueCodes.getMessageForVCO_TEMPLATE_QUOTE(), - IssueCodes.VCO_TEMPLATE_QUOTE, node, -1 /* offset relative to node */, value.length() + 1, value, null); + return new N4JSValueConverterWithValueException(IssueCodes.VCO_TEMPLATE_QUOTE.getMessage(), + IssueCodes.VCO_TEMPLATE_QUOTE.name(), node, -1 /* offset relative to node */, value.length() + 1, value, + null); } @Override diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/TemplateHeadValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/TemplateHeadValueConverter.java index 679514f6de..182c0b0209 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/TemplateHeadValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/TemplateHeadValueConverter.java @@ -10,9 +10,8 @@ */ package org.eclipse.n4js.parser.conversion; -import org.eclipse.xtext.nodemodel.INode; - import org.eclipse.n4js.validation.IssueCodes; +import org.eclipse.xtext.nodemodel.INode; /** */ @@ -30,8 +29,8 @@ protected String getLeftDelimiter() { @Override protected N4JSValueConverterWithValueException newN4JSValueConverterException(INode node, String value) { - return new N4JSValueConverterWithValueException(IssueCodes.getMessageForVCO_TEMPLATE_QUOTE(), - IssueCodes.VCO_TEMPLATE_MIDDLE, node, value, null); + return new N4JSValueConverterWithValueException(IssueCodes.VCO_TEMPLATE_QUOTE.getMessage(), + IssueCodes.VCO_TEMPLATE_MIDDLE.name(), node, value, null); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/TemplateMiddleValueConverter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/TemplateMiddleValueConverter.java index 8a067a633c..380cb4b824 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/TemplateMiddleValueConverter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/parser/conversion/TemplateMiddleValueConverter.java @@ -10,12 +10,11 @@ */ package org.eclipse.n4js.parser.conversion; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.AbstractRule; import org.eclipse.xtext.RuleCall; import org.eclipse.xtext.nodemodel.INode; -import org.eclipse.n4js.validation.IssueCodes; - /** */ public class TemplateMiddleValueConverter extends AbstractTemplateSegmentValueConverter { @@ -32,8 +31,8 @@ protected String getLeftDelimiter() { @Override protected N4JSValueConverterWithValueException newN4JSValueConverterException(INode node, String value) { - return new N4JSValueConverterWithValueException(IssueCodes.getMessageForVCO_TEMPLATE_QUOTE(), - IssueCodes.VCO_TEMPLATE_MIDDLE, node, value, null); + return new N4JSValueConverterWithValueException(IssueCodes.VCO_TEMPLATE_QUOTE.getMessage(), + IssueCodes.VCO_TEMPLATE_MIDDLE.name(), node, value, null); } @Override diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSResource.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSResource.java index eae9d11a3b..33cca2ff63 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSResource.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSResource.java @@ -1548,7 +1548,7 @@ protected void addSyntaxErrors() { for (INode error : getParseResult().getSyntaxErrors()) { processSyntaxDiagnostic(error, diagnostic -> { String code = diagnostic.getCode(); - Severity severity = IssueCodes.getDefaultSeverity(code); + Severity severity = IssueCodes.getSeverityForName(code); if (AbstractN4JSStringValueConverter.WARN_ISSUE_CODE.equals(code) || RegExLiteralConverter.ISSUE_CODE.equals(code) || LegacyOctalIntValueConverter.ISSUE_CODE.equals(code) @@ -1630,9 +1630,10 @@ private boolean isRangeBased(SyntaxErrorMessage syntaxErrorMessage) { String issueCode = syntaxErrorMessage.getIssueCode(); return SYNTAX_DIAGNOSTIC_WITH_RANGE.equals(issueCode) || RegExLiteralConverter.ISSUE_CODE.equals(issueCode) - || IssueCodes.VCO_REGEX_NAMED_GROUP.equals(issueCode) - || IssueCodes.VCO_REGEX_ILLEGAL_ESCAPE.equals(issueCode) - || (IssueCodes.VCO_TEMPLATE_QUOTE.equals(issueCode) && syntaxErrorMessage.getIssueData() != null); + || IssueCodes.VCO_REGEX_NAMED_GROUP.name().equals(issueCode) + || IssueCodes.VCO_REGEX_ILLEGAL_ESCAPE.name().equals(issueCode) + || (IssueCodes.VCO_TEMPLATE_QUOTE.name().equals(issueCode) + && syntaxErrorMessage.getIssueData() != null); } // FIXME the following method should no longer be required once TypingASTWalker is fully functional diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/ContextAwareTypeScope.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/ContextAwareTypeScope.java index 38023f72f5..7ae956be3b 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/ContextAwareTypeScope.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/ContextAwareTypeScope.java @@ -86,13 +86,13 @@ protected IEObjectDescriptionWithError wrapFilteredDescription(IEObjectDescripti } if (!isValidLocationForVoid && eClass == TypesPackage.Literals.VOID_TYPE) { return new DisallowedTypeDescription(originalDescr, - IssueCodes.getMessageForTYS_VOID_AT_WRONG_LOCATION(), - IssueCodes.TYS_VOID_AT_WRONG_LOCATION); + IssueCodes.TYS_VOID_AT_WRONG_LOCATION.getMessage(), + IssueCodes.TYS_VOID_AT_WRONG_LOCATION.name()); } if (!isValidLocationForFunctionType && TypesPackage.Literals.TFUNCTION.isSuperTypeOf(eClass)) { return new DisallowedTypeDescription(originalDescr, - IssueCodes.getMessageForTYS_FUNCTION_DISALLOWED_AS_TYPE(), - IssueCodes.TYS_FUNCTION_DISALLOWED_AS_TYPE); + IssueCodes.TYS_FUNCTION_DISALLOWED_AS_TYPE.getMessage(), + IssueCodes.TYS_FUNCTION_DISALLOWED_AS_TYPE.name()); } return null; // should never happen, because #isAccepted() has returned true } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/HollowTypeOrValueDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/HollowTypeOrValueDescription.java index e83624b583..7126e79c16 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/HollowTypeOrValueDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/HollowTypeOrValueDescription.java @@ -34,12 +34,12 @@ public HollowTypeOrValueDescription(IEObjectDescription delegate, String expecta @Override public String getMessage() { String name = getName().getLastSegment(); - return IssueCodes.getMessageForAST_ELEMENT_MISUSED_AS_VALUE_OR_TYPE(name, expectation); + return IssueCodes.AST_ELEMENT_MISUSED_AS_VALUE_OR_TYPE.getMessage(name, expectation); } @Override public String getIssueCode() { - return IssueCodes.AST_ELEMENT_MISUSED_AS_VALUE_OR_TYPE; + return IssueCodes.AST_ELEMENT_MISUSED_AS_VALUE_OR_TYPE.name(); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/InvalidStaticWriteAccessDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/InvalidStaticWriteAccessDescription.java index 4b0bae15a2..9cd8da605a 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/InvalidStaticWriteAccessDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/InvalidStaticWriteAccessDescription.java @@ -10,11 +10,10 @@ */ package org.eclipse.n4js.scoping.accessModifiers; -import org.eclipse.xtext.naming.QualifiedName; -import org.eclipse.xtext.resource.IEObjectDescription; - import org.eclipse.n4js.scoping.utils.AbstractDescriptionWithError; import org.eclipse.n4js.validation.IssueCodes; +import org.eclipse.xtext.naming.QualifiedName; +import org.eclipse.xtext.resource.IEObjectDescription; /** * Description marking invalid write access to static member via subtype or other expression. @@ -46,16 +45,15 @@ public String getMessage() { QualifiedName qualifiedName = getName(); String memberName = qualifiedName.getLastSegment(); return aliasOfMemberDefiningType == null - ? IssueCodes.getMessageForVIS_ILLEGAL_STATIC_MEMBER_WRITE_ACCESS(memberDefTypeName, memberName) - : IssueCodes.getMessageForVIS_ILLEGAL_STATIC_MEMBER_WRITE_ACCESS_WITH_ALIAS(memberDefTypeName, - memberName, - aliasOfMemberDefiningType); + ? IssueCodes.VIS_ILLEGAL_STATIC_MEMBER_WRITE_ACCESS.getMessage(memberDefTypeName, memberName) + : IssueCodes.VIS_ILLEGAL_STATIC_MEMBER_WRITE_ACCESS_WITH_ALIAS.getMessage(memberDefTypeName, + memberName, aliasOfMemberDefiningType); } @Override public String getIssueCode() { - return aliasOfMemberDefiningType == null ? IssueCodes.VIS_ILLEGAL_STATIC_MEMBER_WRITE_ACCESS - : IssueCodes.VIS_ILLEGAL_STATIC_MEMBER_WRITE_ACCESS_WITH_ALIAS; + return aliasOfMemberDefiningType == null ? IssueCodes.VIS_ILLEGAL_STATIC_MEMBER_WRITE_ACCESS.name() + : IssueCodes.VIS_ILLEGAL_STATIC_MEMBER_WRITE_ACCESS_WITH_ALIAS.name(); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/InvisibleMemberDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/InvisibleMemberDescription.java index 0b0860fe88..2d2d655ba9 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/InvisibleMemberDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/InvisibleMemberDescription.java @@ -51,12 +51,12 @@ public String getMessage() { // here, because error message refers not to the member available in the type but to the missing member accessed // by the source code. String memberName = getName().getLastSegment(); - return IssueCodes.getMessageForVIS_ILLEGAL_MEMBER_ACCESS(memberTypeName, memberName); + return IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS.getMessage(memberTypeName, memberName); } @Override public String getIssueCode() { - return IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS; + return IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS.name(); } @Override diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/InvisibleTypeOrVariableDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/InvisibleTypeOrVariableDescription.java index d972196266..055aab1561 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/InvisibleTypeOrVariableDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/InvisibleTypeOrVariableDescription.java @@ -11,14 +11,13 @@ package org.eclipse.n4js.scoping.accessModifiers; import org.eclipse.emf.ecore.EObject; -import org.eclipse.xtext.resource.IEObjectDescription; - import org.eclipse.n4js.scoping.utils.AbstractDescriptionWithError; import org.eclipse.n4js.ts.types.TFunction; import org.eclipse.n4js.ts.types.Type; import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.n4js.validation.IssueUserDataKeys.VIS_ILLEGAL_TYPE_ACCESS; import org.eclipse.n4js.validation.IssueUserDataKeys.VIS_ILLEGAL_VARIABLE_ACCESS; +import org.eclipse.xtext.resource.IEObjectDescription; /** * This description wraps an invisible type or variable. @@ -63,22 +62,22 @@ public String getMessage() { EObject objectOrProxy = getEObjectOrProxy(); String name = getName().getLastSegment(); if (objectOrProxy instanceof TFunction) { - return IssueCodes.getMessageForVIS_ILLEGAL_FUN_ACCESS(name); + return IssueCodes.VIS_ILLEGAL_FUN_ACCESS.getMessage(name); } else if (objectOrProxy instanceof Type) { - return IssueCodes.getMessageForVIS_ILLEGAL_TYPE_ACCESS(name); + return IssueCodes.VIS_ILLEGAL_TYPE_ACCESS.getMessage(name); } - return IssueCodes.getMessageForVIS_ILLEGAL_VARIABLE_ACCESS(name); + return IssueCodes.VIS_ILLEGAL_VARIABLE_ACCESS.getMessage(name); } @Override public String getIssueCode() { EObject objectOrProxy = getEObjectOrProxy(); if (objectOrProxy instanceof TFunction) { - return IssueCodes.VIS_ILLEGAL_FUN_ACCESS; + return IssueCodes.VIS_ILLEGAL_FUN_ACCESS.name(); } else if (objectOrProxy instanceof Type) { - return IssueCodes.VIS_ILLEGAL_TYPE_ACCESS; + return IssueCodes.VIS_ILLEGAL_TYPE_ACCESS.name(); } - return IssueCodes.VIS_ILLEGAL_VARIABLE_ACCESS; + return IssueCodes.VIS_ILLEGAL_VARIABLE_ACCESS.name(); } /* diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/NonExportedElementDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/NonExportedElementDescription.java index f7e0d468da..a5ea132301 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/NonExportedElementDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/accessModifiers/NonExportedElementDescription.java @@ -32,12 +32,12 @@ public NonExportedElementDescription(IEObjectDescription delegate) { @Override public String getMessage() { String name = getName().getLastSegment(); - return IssueCodes.getMessageForIMP_NOT_EXPORTED(name); + return IssueCodes.IMP_NOT_EXPORTED.getMessage(name); } @Override public String getIssueCode() { - return IssueCodes.IMP_NOT_EXPORTED; + return IssueCodes.IMP_NOT_EXPORTED.name(); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingConsumableMethodsDiagnosis.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingConsumableMethodsDiagnosis.java index 200f19015b..d85f38ca0a 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingConsumableMethodsDiagnosis.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingConsumableMethodsDiagnosis.java @@ -57,8 +57,8 @@ DiagnosticMessage diagnose(QualifiedName name, ParameterizedPropertyAccessExpres .anyMatch(m -> m.getName().equals(name.toString())); if (hasMethod) { - return createMessage(IssueCodes.CLF_CANNOT_REFER_TO_DEFAULT_METHOD_WITH_SUPER, - IssueCodes.getMessageForCLF_CANNOT_REFER_TO_DEFAULT_METHOD_WITH_SUPER()); + return createMessage(IssueCodes.CLF_CANNOT_REFER_TO_DEFAULT_METHOD_WITH_SUPER.name(), + IssueCodes.CLF_CANNOT_REFER_TO_DEFAULT_METHOD_WITH_SUPER.getMessage()); } } return null; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingInstanceOfPrimitivTypeDiagnosis.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingInstanceOfPrimitivTypeDiagnosis.java index 05d0865af5..9a68581a64 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingInstanceOfPrimitivTypeDiagnosis.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingInstanceOfPrimitivTypeDiagnosis.java @@ -59,8 +59,8 @@ DiagnosticMessage diagnose(QualifiedName name, RelationalExpression expression) // if we can find a primitive type for the qualified name if (singleElement.getEClass().getClassifierID() == TypesPackage.Literals.PRIMITIVE_TYPE.getClassifierID()) { // create special error message - return createMessage(IssueCodes.TYS_INSTANCEOF_NOT_SUPPORTED_FOR_PRIMITIVE_TYPES, - IssueCodes.getMessageForTYS_INSTANCEOF_NOT_SUPPORTED_FOR_PRIMITIVE_TYPES()); + return createMessage(IssueCodes.TYS_INSTANCEOF_NOT_SUPPORTED_FOR_PRIMITIVE_TYPES.name(), + IssueCodes.TYS_INSTANCEOF_NOT_SUPPORTED_FOR_PRIMITIVE_TYPES.getMessage()); } else { // the found element is not a primitive type, diagnosis not applicable return null; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/ScopingDiagnosis.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/ScopingDiagnosis.java index 8d65fe116c..7a0e7fb731 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/ScopingDiagnosis.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/ScopingDiagnosis.java @@ -36,7 +36,7 @@ public abstract class ScopingDiagnosis { * See {@link IssueCodes} for valid issue codes. */ protected DiagnosticMessage createMessage(String issueCode, String message) { - return new DiagnosticMessage(message, IssueCodes.getDefaultSeverity(issueCode), issueCode); + return new DiagnosticMessage(message, IssueCodes.getSeverityForName(issueCode), issueCode); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/AmbiguousImportDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/AmbiguousImportDescription.java index dcc2e5ee69..bfa9301648 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/AmbiguousImportDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/AmbiguousImportDescription.java @@ -84,12 +84,12 @@ public String getMessage() { typeListStr.append(((TNamespace) container).getName()); } } - if (this.issueCode == IssueCodes.IMP_AMBIGUOUS_WILDCARD) { - return IssueCodes.getMessageForIMP_AMBIGUOUS_WILDCARD(typeIdent, getName(), typeListStr.toString()); - } else if (this.issueCode == IssueCodes.IMP_AMBIGUOUS) { - return IssueCodes.getMessageForIMP_AMBIGUOUS(typeIdent, getName(), typeListStr.toString()); - } else if (this.issueCode == IssueCodes.IMP_DUPLICATE_NAMESPACE) { - return IssueCodes.getMessageForIMP_DUPLICATE_NAMESPACE("stub", getName(), "stub"); + if (this.issueCode == IssueCodes.IMP_AMBIGUOUS_WILDCARD.name()) { + return IssueCodes.IMP_AMBIGUOUS_WILDCARD.getMessage(typeIdent, getName(), typeListStr.toString()); + } else if (this.issueCode == IssueCodes.IMP_AMBIGUOUS.name()) { + return IssueCodes.IMP_AMBIGUOUS.getMessage(typeIdent, getName(), typeListStr.toString()); + } else if (this.issueCode == IssueCodes.IMP_DUPLICATE_NAMESPACE.name()) { + return IssueCodes.IMP_DUPLICATE_NAMESPACE.getMessage("stub", getName(), "stub"); } return "Unknown ambiguous import issue: " + this.issueCode + " for " + context + "."; } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/ImportedElementsScopingHelper.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/ImportedElementsScopingHelper.xtend index 1dcad98348..9f40a9b446 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/ImportedElementsScopingHelper.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/ImportedElementsScopingHelper.xtend @@ -235,7 +235,7 @@ class ImportedElementsScopingHelper { private def void addNamedImports(NamedImportSpecifier specifier, TExportableElement element, QualifiedName importedName, IEODesc2ISpec originatorMap, ImportedElementsMap validImports) { - val ieod = validImports.putOrError(element, importedName, IssueCodes.IMP_AMBIGUOUS); + val ieod = validImports.putOrError(element, importedName, IssueCodes.IMP_AMBIGUOUS.name); originatorMap.putWithOrigin(ieod, specifier) } @@ -284,7 +284,7 @@ class ImportedElementsScopingHelper { LOGGER.error("namespaceType not found\n" + sb.toString); return; } - val ieodx = validImports.putOrError(namespaceType, namespaceQName, IssueCodes.IMP_AMBIGUOUS) + val ieodx = validImports.putOrError(namespaceType, namespaceQName, IssueCodes.IMP_AMBIGUOUS.name) originatorMap.putWithOrigin(ieodx, specifier) if (includeValueOnlyElements) { diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/PlainAccessOfAliasedImportDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/PlainAccessOfAliasedImportDescription.java index 4ccf6c1978..d3b58dfb8c 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/PlainAccessOfAliasedImportDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/PlainAccessOfAliasedImportDescription.java @@ -39,12 +39,12 @@ public String getAlias() { @Override public String getMessage() { - return IssueCodes.getMessageForIMP_PLAIN_ACCESS_OF_ALIASED_TYPE(getName(), alias); + return IssueCodes.IMP_PLAIN_ACCESS_OF_ALIASED_TYPE.getMessage(getName(), alias); } @Override public String getIssueCode() { - return IssueCodes.IMP_PLAIN_ACCESS_OF_ALIASED_TYPE; + return IssueCodes.IMP_PLAIN_ACCESS_OF_ALIASED_TYPE.name(); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/PlainAccessOfNamespacedImportDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/PlainAccessOfNamespacedImportDescription.java index fd6685c959..593ba633b8 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/PlainAccessOfNamespacedImportDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/PlainAccessOfNamespacedImportDescription.java @@ -33,12 +33,12 @@ public PlainAccessOfNamespacedImportDescription(IEObjectDescription delegate, Qu @Override public String getMessage() { - return IssueCodes.getMessageForIMP_PLAIN_ACCESS_OF_NAMESPACED_TYPE(getName(), namespacedName); + return IssueCodes.IMP_PLAIN_ACCESS_OF_NAMESPACED_TYPE.getMessage(getName(), namespacedName); } @Override public String getIssueCode() { - return IssueCodes.IMP_PLAIN_ACCESS_OF_NAMESPACED_TYPE; + return IssueCodes.IMP_PLAIN_ACCESS_OF_NAMESPACED_TYPE.name(); } /** diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/ComposedMemberDescriptionWithError.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/ComposedMemberDescriptionWithError.java index 7ae62e6a41..a8f4253812 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/ComposedMemberDescriptionWithError.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/ComposedMemberDescriptionWithError.java @@ -197,7 +197,7 @@ protected boolean initSubMessages(IEObjectDescription[] descriptions, MapOfIndex if (submessage.endsWith(".")) { submessage = submessage.substring(0, submessage.length() - 1); } - completeSubMessage = IssueCodes.getMessageForCOMP_SUBMESSAGES(allScopeNames, submessage); + completeSubMessage = IssueCodes.COMP_SUBMESSAGES.getMessage(allScopeNames, submessage); } if (strb.length() > 0) { strb.append(" "); @@ -205,7 +205,7 @@ protected boolean initSubMessages(IEObjectDescription[] descriptions, MapOfIndex strb.append(completeSubMessage); } message = strb.toString(); - code = IssueCodes.COMP_SUBMESSAGES; + code = IssueCodes.COMP_SUBMESSAGES.name(); return true; } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/IntersectionMemberDescriptionWithError.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/IntersectionMemberDescriptionWithError.java index cfeacfd91a..65075917b1 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/IntersectionMemberDescriptionWithError.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/IntersectionMemberDescriptionWithError.java @@ -12,13 +12,12 @@ import java.util.List; +import org.eclipse.n4js.ts.typeRefs.ComposedTypeRef; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.naming.QualifiedName; import org.eclipse.xtext.resource.IEObjectDescription; import org.eclipse.xtext.scoping.IScope; -import org.eclipse.n4js.ts.typeRefs.ComposedTypeRef; -import org.eclipse.n4js.validation.IssueCodes; - /** * This description wraps a member of a union type that is not present in all contained types or is somehow incompatible * so that it cannot be composed into a single valid composed member. @@ -58,8 +57,8 @@ private boolean initMemberTypeConflict(MapOfIndexes indexesPerMemberType strb.append(memberTypeName + " in " + foundScopes); } final String memberName = getName().getLastSegment(); - message = IssueCodes.getMessageForINTER_MEMBER_TYPE_CONFLICT(memberName, strb); - code = IssueCodes.INTER_MEMBER_TYPE_CONFLICT; + message = IssueCodes.INTER_MEMBER_TYPE_CONFLICT.getMessage(memberName, strb); + code = IssueCodes.INTER_MEMBER_TYPE_CONFLICT.name(); return true; } return false; @@ -67,8 +66,8 @@ private boolean initMemberTypeConflict(MapOfIndexes indexesPerMemberType private boolean initDefault() { final String memberName = getName().getLastSegment(); - message = IssueCodes.getMessageForINTER_UNCOMMON(memberName); - code = IssueCodes.INTER_UNCOMMON; + message = IssueCodes.INTER_UNCOMMON.getMessage(memberName); + code = IssueCodes.INTER_UNCOMMON.name(); return true; } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/PolyfillMemberConflictDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/PolyfillMemberConflictDescription.java index 1c48bd9bc2..4561852d2b 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/PolyfillMemberConflictDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/PolyfillMemberConflictDescription.java @@ -12,13 +12,12 @@ import java.util.Collection; +import org.eclipse.n4js.scoping.utils.AbstractDescriptionWithError; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.resource.IEObjectDescription; import com.google.common.base.Joiner; -import org.eclipse.n4js.scoping.utils.AbstractDescriptionWithError; -import org.eclipse.n4js.validation.IssueCodes; - /** * Creates a description for error code {@link IssueCodes#CLF_POLYFILL_MULTIPOLYFILLS_MEMBER_CONFLICT}. */ @@ -45,13 +44,13 @@ public PolyfillMemberConflictDescription(IEObjectDescription delegate, String me @Override public String getMessage() { - return IssueCodes.getMessageForCLF_POLYFILL_MULTIPOLYFILLS_MEMBER_CONFLICT( + return IssueCodes.CLF_POLYFILL_MULTIPOLYFILLS_MEMBER_CONFLICT.getMessage( Joiner.on(", ").join(conflictingModuleNames), memberName); } @Override public String getIssueCode() { - return IssueCodes.CLF_POLYFILL_MULTIPOLYFILLS_MEMBER_CONFLICT; + return IssueCodes.CLF_POLYFILL_MULTIPOLYFILLS_MEMBER_CONFLICT.name(); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/UnionMemberDescriptionWithError.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/UnionMemberDescriptionWithError.java index e86265ac8b..e7ddfd09f1 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/UnionMemberDescriptionWithError.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/UnionMemberDescriptionWithError.java @@ -55,8 +55,8 @@ private boolean initInvalidCombination(MapOfIndexes indexesPerMemberType // check for three special cases of error 'multipleKinds' that require a more informative message if (numberOfFields + indexesPerMemberType.numberOf("getter") == max) { if (writeAccess) { - message = IssueCodes.getMessageForUNI_INVALID_COMBINATION("getters", name, "read-only"); - code = IssueCodes.UNI_INVALID_COMBINATION; + message = IssueCodes.UNI_INVALID_COMBINATION.getMessage("getters", name, "read-only"); + code = IssueCodes.UNI_INVALID_COMBINATION.name(); return true; } else { return false; // access would be ok, there must be another reason @@ -65,11 +65,11 @@ private boolean initInvalidCombination(MapOfIndexes indexesPerMemberType if (numberOfFields + indexesPerMemberType.numberOf("setter") == max) { if (writeAccess) { if (readOnlyField) { - message = IssueCodes.getMessageForUNI_INVALID_COMBINATION_SETTER_VS_READ_ONLY_FIELD(name); - code = IssueCodes.UNI_INVALID_COMBINATION_SETTER_VS_READ_ONLY_FIELD; + message = IssueCodes.UNI_INVALID_COMBINATION_SETTER_VS_READ_ONLY_FIELD.getMessage(name); + code = IssueCodes.UNI_INVALID_COMBINATION_SETTER_VS_READ_ONLY_FIELD.name(); } else { - message = IssueCodes.getMessageForUNI_INVALID_COMBINATION("setters", name, "write-only"); - code = IssueCodes.UNI_INVALID_COMBINATION; + message = IssueCodes.UNI_INVALID_COMBINATION.getMessage("setters", name, "write-only"); + code = IssueCodes.UNI_INVALID_COMBINATION.name(); } return true; } @@ -79,9 +79,9 @@ private boolean initInvalidCombination(MapOfIndexes indexesPerMemberType } // invalid special case - if (indexesPerCode.containsKey(IssueCodes.VIS_WRONG_STATIC_ACCESSOR)) { - message = IssueCodes.getMessageForVIS_WRONG_STATIC_ACCESSOR("static", name, "non-static"); - code = IssueCodes.VIS_WRONG_STATIC_ACCESSOR; + if (indexesPerCode.containsKey(IssueCodes.VIS_WRONG_STATIC_ACCESSOR.name())) { + message = IssueCodes.VIS_WRONG_STATIC_ACCESSOR.getMessage("static", name, "non-static"); + code = IssueCodes.VIS_WRONG_STATIC_ACCESSOR.name(); return true; } @@ -94,8 +94,8 @@ private boolean initInvalidCombination(MapOfIndexes indexesPerMemberType } strb.append(memberTypeName + " in " + foundScopes); } - message = IssueCodes.getMessageForUNI_MULTIPLE_KINDS(name, strb.toString()); - code = IssueCodes.UNI_MULTIPLE_KINDS; + message = IssueCodes.UNI_MULTIPLE_KINDS.getMessage(name, strb.toString()); + code = IssueCodes.UNI_MULTIPLE_KINDS.name(); return true; } return false; @@ -103,9 +103,9 @@ private boolean initInvalidCombination(MapOfIndexes indexesPerMemberType private boolean initMissingFrom(List missingFrom) { if (!missingFrom.isEmpty()) { - message = IssueCodes.getMessageForUNI_MISSING(getName().getLastSegment(), + message = IssueCodes.UNI_MISSING.getMessage(getName().getLastSegment(), Joiner.on(", ").join(missingFrom)); - code = IssueCodes.UNI_MISSING; + code = IssueCodes.UNI_MISSING.name(); return true; } else { return false; @@ -114,8 +114,8 @@ private boolean initMissingFrom(List missingFrom) { private boolean initDefault() { final String memberName = getName().getLastSegment(); - message = IssueCodes.getMessageForUNI_UNCOMMON(memberName); - code = IssueCodes.UNI_UNCOMMON; + message = IssueCodes.UNI_UNCOMMON.getMessage(memberName); + code = IssueCodes.UNI_UNCOMMON.name(); return true; } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/WrongTypingStrategyDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/WrongTypingStrategyDescription.java index 7c8e4acd71..5743a01973 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/WrongTypingStrategyDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/WrongTypingStrategyDescription.java @@ -38,14 +38,14 @@ public String getMessage() { // by the source code. String typeName = receiverTypeName; if (fields) { - return IssueCodes.getMessageForTYS_MEMBER_NOT_IN_STRUCTURAL_FIELDS_TYPE_USE_SITE(memberTypeName, + return IssueCodes.TYS_MEMBER_NOT_IN_STRUCTURAL_FIELDS_TYPE_USE_SITE.getMessage(memberTypeName, memberName, typeName); } if (useSite) { - return IssueCodes.getMessageForTYS_MEMBER_NOT_IN_STRUCTURAL_TYPE_USE_SITE(memberTypeName, memberName, + return IssueCodes.TYS_MEMBER_NOT_IN_STRUCTURAL_TYPE_USE_SITE.getMessage(memberTypeName, memberName, typeName); } else { - return IssueCodes.getMessageForTYS_MEMBER_NOT_IN_STRUCTURAL_TYPE_DEF_SITE(memberTypeName, memberName, + return IssueCodes.TYS_MEMBER_NOT_IN_STRUCTURAL_TYPE_DEF_SITE.getMessage(memberTypeName, memberName, typeName); } } @@ -53,12 +53,12 @@ public String getMessage() { @Override public String getIssueCode() { if (fields) { - return IssueCodes.TYS_MEMBER_NOT_IN_STRUCTURAL_FIELDS_TYPE_USE_SITE; + return IssueCodes.TYS_MEMBER_NOT_IN_STRUCTURAL_FIELDS_TYPE_USE_SITE.name(); } if (useSite) { - return IssueCodes.TYS_MEMBER_NOT_IN_STRUCTURAL_TYPE_USE_SITE; + return IssueCodes.TYS_MEMBER_NOT_IN_STRUCTURAL_TYPE_USE_SITE.name(); } - return IssueCodes.TYS_MEMBER_NOT_IN_STRUCTURAL_TYPE_DEF_SITE; + return IssueCodes.TYS_MEMBER_NOT_IN_STRUCTURAL_TYPE_DEF_SITE.name(); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ProjectImportEnablingScope.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ProjectImportEnablingScope.java index 36fc859ec1..f28a78dfa1 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ProjectImportEnablingScope.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ProjectImportEnablingScope.java @@ -275,7 +275,7 @@ public IEObjectDescription getSingleElement(QualifiedName name) { final EObject originalProxy = (EObject) this.importOrExportDecl.get() .eGet(N4JSPackage.eINSTANCE.getModuleRef_Module(), false); return new IssueCodeBasedEObjectDescription(EObjectDescription.create("impDecl", originalProxy), - sbErrrorMessage.toString(), IssueCodes.IMP_UNRESOLVED); + sbErrrorMessage.toString(), IssueCodes.IMP_UNRESOLVED.name()); } /** diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/RestrictedUsageDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/RestrictedUsageDescription.java index 36130bd96d..d330e1fed4 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/RestrictedUsageDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/RestrictedUsageDescription.java @@ -10,9 +10,8 @@ */ package org.eclipse.n4js.scoping.utils; -import org.eclipse.xtext.resource.IEObjectDescription; - import org.eclipse.n4js.validation.IssueCodes; +import org.eclipse.xtext.resource.IEObjectDescription; /** * This description wraps an invisible member. @@ -38,11 +37,11 @@ public RestrictedUsageDescription(IEObjectDescription delegate, String jsVariant @Override public String getMessage() { String memberName = getName().getLastSegment(); - return IssueCodes.getMessageForVIS_RESTRITCTED_USAGE(memberName, jsVariant); + return IssueCodes.VIS_RESTRITCTED_USAGE.getMessage(memberName, jsVariant); } @Override public String getIssueCode() { - return IssueCodes.VIS_RESTRITCTED_USAGE; + return IssueCodes.VIS_RESTRITCTED_USAGE.name(); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/UnsatisfiedRWAccessDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/UnsatisfiedRWAccessDescription.java index e6aeca2ea9..5c7e14d6be 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/UnsatisfiedRWAccessDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/UnsatisfiedRWAccessDescription.java @@ -34,13 +34,13 @@ public UnsatisfiedRWAccessDescription(IEObjectDescription delegate, boolean isRe @Override public String getMessage() { String available = (isReadMissing ? "write-access" : "read-access"); - return IssueCodes.getMessageForVIS_WRONG_READ_WRITE_ACCESS( + return IssueCodes.VIS_WRONG_READ_WRITE_ACCESS.getMessage( "operation", "requires both read and write access, but only " + available, "available"); } @Override public String getIssueCode() { - return IssueCodes.VIS_WRONG_READ_WRITE_ACCESS; + return IssueCodes.VIS_WRONG_READ_WRITE_ACCESS.name(); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/WrongStaticAccessDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/WrongStaticAccessDescription.java index 53d8c76b89..576df9ed74 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/WrongStaticAccessDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/WrongStaticAccessDescription.java @@ -10,11 +10,10 @@ */ package org.eclipse.n4js.scoping.utils; -import org.eclipse.xtext.resource.IEObjectDescription; - import org.eclipse.n4js.scoping.members.MemberScope; import org.eclipse.n4js.ts.types.TypesPackage; import org.eclipse.n4js.validation.IssueCodes; +import org.eclipse.xtext.resource.IEObjectDescription; /** * If the {@link MemberScope} finds a static accessor in a wrong context, this descriptor is used to bound the reference @@ -52,22 +51,22 @@ public WrongStaticAccessDescription(IEObjectDescription delegate, boolean static public String getMessage() { if (getEClass() == TypesPackage.eINSTANCE.getTypeVariable()) { // special case for TypeVariables (because the generic error message does not fit here): - return IssueCodes.getMessageForVIS_WRONG_TYPE_VARIABLE_ACCESSOR(getName()); + return IssueCodes.VIS_WRONG_TYPE_VARIABLE_ACCESSOR.getMessage(getName()); } // standard case: String[] staticNonStatic = { "static", "non-static" }; String staticMemberStr = staticNonStatic[staticAccess ? 1 : 0]; String staticContextStr = staticNonStatic[staticAccess ? 0 : 1]; - return IssueCodes.getMessageForVIS_WRONG_STATIC_ACCESSOR(staticMemberStr, getName(), staticContextStr); + return IssueCodes.VIS_WRONG_STATIC_ACCESSOR.getMessage(staticMemberStr, getName(), staticContextStr); } @Override public String getIssueCode() { if (getEClass() == TypesPackage.eINSTANCE.getTypeVariable()) { // special case: - return IssueCodes.VIS_WRONG_TYPE_VARIABLE_ACCESSOR; + return IssueCodes.VIS_WRONG_TYPE_VARIABLE_ACCESSOR.name(); } // standard case: - return IssueCodes.VIS_WRONG_STATIC_ACCESSOR; + return IssueCodes.VIS_WRONG_STATIC_ACCESSOR.name(); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/WrongWriteAccessDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/WrongWriteAccessDescription.java index 7192b8b03c..2b9978fd18 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/WrongWriteAccessDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/WrongWriteAccessDescription.java @@ -46,19 +46,18 @@ public WrongWriteAccessDescription(IEObjectDescription delegate, boolean accessF @Override public String getMessage() { if (isAssignmentToFinalFieldInCtor) { - return IssueCodes.getMessageForCLF_FIELD_FINAL_REINIT_IN_CTOR( - getName()); + return IssueCodes.CLF_FIELD_FINAL_REINIT_IN_CTOR.getMessage(getName()); } - return IssueCodes.getMessageForVIS_WRONG_READ_WRITE_ACCESS( + return IssueCodes.VIS_WRONG_READ_WRITE_ACCESS.getMessage( getKeyword(), getName(), accessForWriteOperation ? "read-only" : "write-only"); } @Override public String getIssueCode() { if (isAssignmentToFinalFieldInCtor) { - return IssueCodes.CLF_FIELD_FINAL_REINIT_IN_CTOR; + return IssueCodes.CLF_FIELD_FINAL_REINIT_IN_CTOR.name(); } - return IssueCodes.VIS_WRONG_READ_WRITE_ACCESS; + return IssueCodes.VIS_WRONG_READ_WRITE_ACCESS.name(); } private String getKeyword() { diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/validation/ContextAwareTypeScopeValidator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/validation/ContextAwareTypeScopeValidator.java index 62d35e178f..6911817a67 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/validation/ContextAwareTypeScopeValidator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/validation/ContextAwareTypeScopeValidator.java @@ -85,13 +85,13 @@ public ScopeElementIssue getIssue(IEObjectDescription originalDescr) { } if (!isValidLocationForVoid && eClass == TypesPackage.Literals.VOID_TYPE) { return new ScopeElementIssue(originalDescr, - IssueCodes.TYS_VOID_AT_WRONG_LOCATION, - IssueCodes.getMessageForTYS_VOID_AT_WRONG_LOCATION()); + IssueCodes.TYS_VOID_AT_WRONG_LOCATION.name(), + IssueCodes.TYS_VOID_AT_WRONG_LOCATION.getMessage()); } if (!isValidLocationForFunctionType && TypesPackage.Literals.TFUNCTION.isSuperTypeOf(eClass)) { return new ScopeElementIssue(originalDescr, - IssueCodes.TYS_FUNCTION_DISALLOWED_AS_TYPE, - IssueCodes.getMessageForTYS_FUNCTION_DISALLOWED_AS_TYPE()); + IssueCodes.TYS_FUNCTION_DISALLOWED_AS_TYPE.name(), + IssueCodes.TYS_FUNCTION_DISALLOWED_AS_TYPE.getMessage()); } return null; // should never happen, because #isAccepted() has returned true } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/validation/VeeScopeValidator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/validation/VeeScopeValidator.java index 4a017418ae..fb7c83410b 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/validation/VeeScopeValidator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/validation/VeeScopeValidator.java @@ -74,8 +74,8 @@ public ScopeElementIssue getIssue(IEObjectDescription originalDescr) { } QualifiedName name = originalDescr.getName(); return new ScopeElementIssue(originalDescr, - IssueCodes.AST_ELEMENT_MISUSED_AS_VALUE_OR_TYPE, - IssueCodes.getMessageForAST_ELEMENT_MISUSED_AS_VALUE_OR_TYPE(name.toString(), "value")); + IssueCodes.AST_ELEMENT_MISUSED_AS_VALUE_OR_TYPE.name(), + IssueCodes.AST_ELEMENT_MISUSED_AS_VALUE_OR_TYPE.getMessage(name.toString(), "value")); } @Override diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/validation/VisibilityAwareCtorScopeValidator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/validation/VisibilityAwareCtorScopeValidator.java index 6099e3ead0..ad993f214c 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/validation/VisibilityAwareCtorScopeValidator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/validation/VisibilityAwareCtorScopeValidator.java @@ -72,10 +72,11 @@ public ScopeElementIssue getIssue(IEObjectDescription objDescr) { TClassifier ctorClassifier = (TClassifier) proxyOrInstance; String containerName = ctorClassifier.getTypeAsString(); - String message = IssueCodes.getMessageForVIS_NEW_CANNOT_INSTANTIATE_INVISIBLE_CONSTRUCTOR("constructor", + String message = IssueCodes.VIS_NEW_CANNOT_INSTANTIATE_INVISIBLE_CONSTRUCTOR.getMessage("constructor", containerName); - return new ScopeElementIssue(objDescr, IssueCodes.VIS_NEW_CANNOT_INSTANTIATE_INVISIBLE_CONSTRUCTOR, message); + return new ScopeElementIssue(objDescr, IssueCodes.VIS_NEW_CANNOT_INSTANTIATE_INVISIBLE_CONSTRUCTOR.name(), + message); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportStateCalculator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportStateCalculator.xtend index 39c4c345b7..85aa1e7a16 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportStateCalculator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportStateCalculator.xtend @@ -238,6 +238,6 @@ class ImportStateCalculator { private static def boolean isNamedImportOfNonExportedElement(ImportSpecifier importSpec, ASTMetaInfoCache astMetaInfoCache) { return astMetaInfoCache.getLinkingIssueCodes(importSpec, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER__IMPORTED_ELEMENT) - .contains(IssueCodes.IMP_NOT_EXPORTED); + .contains(IssueCodes.IMP_NOT_EXPORTED.name()); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/SubtypeJudgment.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/SubtypeJudgment.java index 05dd7aa70e..70e17eab95 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/SubtypeJudgment.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/SubtypeJudgment.java @@ -37,6 +37,7 @@ import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.stringType; import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.undefinedType; import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.wrap; +import static org.eclipse.n4js.validation.IssueCodes.TYS_NO_SUBTYPE; import java.math.BigDecimal; import java.util.Iterator; @@ -107,7 +108,7 @@ public Result apply(RuleEnvironment G, TypeArgument leftArg, TypeArgument rightA // set default failure message final String leftMsg = leftArg != null ? leftArg.getTypeRefAsString() : ""; final String rightMsg = rightArg != null ? rightArg.getTypeRefAsString() : ""; - return result.setDefaultFailureMessage(leftMsg + " is not a subtype of " + rightMsg); + return result.setDefaultFailureMessage(TYS_NO_SUBTYPE.getMessage(leftMsg, rightMsg)); } return result; } @@ -504,8 +505,11 @@ private Result applyParameterizedTypeRef(RuleEnvironment G, ParameterizedTypeRef if ((left.isUseSiteStructuralTyping() || left.isDefSiteStructuralTyping()) && !(rightDeclType == objectType(G) && leftDeclType instanceof TClassifier) && !(leftDeclType instanceof PrimitiveType)) { - return failure("Structural type " + left.getTypeRefAsString() - + " is not a subtype of non-structural type " + right.getTypeRefAsString()); + + String msg = TYS_NO_SUBTYPE.getMessage( + "Structural type " + left.getTypeRefAsString(), + "non-structural type " + right.getTypeRefAsString()); + return failure(msg); } // nominal typing (the default behavior) if (leftDeclType instanceof TypeVariable || rightDeclType instanceof TypeVariable) { @@ -856,10 +860,12 @@ private Result checkTypeArgumentCompatibility(RuleEnvironment G, if (tempResult.isFailure()) { if (tempResult.isOrIsCausedByPriority()) { // fail with a custom message including the nested custom failure message: - return failure(leftContainingTypeRef.getTypeRefAsString() - + " is not a subtype of " + rightContainingTypeRef.getTypeRefAsString() - + " due to incompatible type arguments: " - + tempResult.getPriorityFailureMessage()); + String msg = TYS_NO_SUBTYPE.getMessage( + leftContainingTypeRef.getTypeRefAsString(), + rightContainingTypeRef.getTypeRefAsString() + + " due to incompatible type arguments: " + + tempResult.getPriorityFailureMessage()); + return failure(msg); } else { // fail with our default message: return failure(); diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/StructuralTypingComputer.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/StructuralTypingComputer.xtend index beabfefdb3..b45f7802c7 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/StructuralTypingComputer.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/StructuralTypingComputer.xtend @@ -51,6 +51,7 @@ import static org.eclipse.n4js.utils.StructuralMembersPredicates.* import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* import static extension org.eclipse.n4js.utils.N4JSLanguageUtils.* +import static org.eclipse.n4js.validation.IssueCodes.TYS_NO_SUBTYPE /** */ @@ -147,12 +148,12 @@ class StructuralTypingComputer extends TypeSystemHelperStrategy { val leftIsPrimitive = left.declaredType instanceof PrimitiveType // primitive type on the right and non-primitive on the left - if (rightIsPrimitive && !leftIsPrimitive) { - return failure(leftRaw.typeRefAsString + " is not a subtype of " + right.typeRefAsString); + if (rightIsPrimitive && !leftIsPrimitive) { + return failure(TYS_NO_SUBTYPE.getMessage(leftRaw.typeRefAsString, right.typeRefAsString)); } // primitive type on the left and non-primitive on the right else if (leftIsPrimitive && !rightIsPrimitive) { - return failure(leftRaw.typeRefAsString + " is not a subtype of " + right.typeRefAsString); + return failure(TYS_NO_SUBTYPE.getMessage(leftRaw.typeRefAsString, right.typeRefAsString)); } // primitive types on both sides else if (leftIsPrimitive && rightIsPrimitive) { @@ -160,7 +161,7 @@ class StructuralTypingComputer extends TypeSystemHelperStrategy { return if (left.declaredType === right.declaredType) { success(); } else { - failure(leftRaw.typeRefAsString + " is not a subtype of " + right.typeRefAsString); + failure(TYS_NO_SUBTYPE.getMessage(leftRaw.typeRefAsString, right.typeRefAsString)); } } // neither left nor right is primitive diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/ASTStructureValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/ASTStructureValidator.xtend index d9308d9262..b62de0146e 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/ASTStructureValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/ASTStructureValidator.xtend @@ -121,1754 +121,1652 @@ import static extension org.eclipse.n4js.parser.conversion.AbstractN4JSStringVal */ class ASTStructureValidator { - @Inject - private WorkspaceAccess workspaceAccess; - - @Inject - private N4JSGrammarAccess grammarAccess; - - @Inject - private N4JSLanguageHelper languageHelper; - - @Inject - private JavaScriptVariantHelper jsVariantHelper; - - @ToString - protected static class Constraints { - static val BUILT_IN_TYPE_DEFINITION = 1 - static val STRICT = BUILT_IN_TYPE_DEFINITION << 1 - static val N4JS = STRICT << 1 - static val EXTERNAL = N4JS << 1 - static val ALLOW_NESTED_FUNCTION_DECLARATION = EXTERNAL << 1 - static val ALLOW_RETURN = ALLOW_NESTED_FUNCTION_DECLARATION << 1 - static val ALLOW_CONTINUE = ALLOW_RETURN << 1 - static val ALLOW_BREAK = ALLOW_CONTINUE << 1 // whether we are in "break-allowed-with/without-label" (for||while||switch-case||labelled-block) area - static val ALLOW_BREAK_WITHOUT_LABEL = ALLOW_BREAK << 1 // whether we are in (for||while||switch-case) area - static val ALLOW_VAR_WITHOUT_INITIALIZER = ALLOW_BREAK_WITHOUT_LABEL << 1 - static val ALLOW_YIELD_EXPRESSION = ALLOW_VAR_WITHOUT_INITIALIZER << 1 - static val ALLOW_SUPER = ALLOW_YIELD_EXPRESSION << 1 - static val ALLOW_SUPER_CALL = ALLOW_SUPER << 1 - static val IN_FUNCTION_DECLARATION = ALLOW_SUPER_CALL << 1 - - val int bits - - def private static getIf(int value, boolean b) { - if (b) value else 0 - } - - new(boolean builtInTypeDefinition, boolean n4js, boolean external) { - this( - BUILT_IN_TYPE_DEFINITION.getIf(builtInTypeDefinition).bitwiseOr( - N4JS.getIf(n4js).bitwiseOr( - EXTERNAL.getIf(external).bitwiseOr( - ALLOW_VAR_WITHOUT_INITIALIZER.bitwiseOr( - ALLOW_YIELD_EXPRESSION - ) - ) - ) - ) - ) - } - - new(int bits) { - this.bits = bits - } - - def private is(int bit) { - return this.bits.bitwiseAnd(bit) !== 0 - } - - def boolean isBuiltInTypeDefinition() { - return is(BUILT_IN_TYPE_DEFINITION) - } - - def boolean isN4JS() { - return is(N4JS) - } - - def boolean isStrict() { - return is(N4JS) || is(STRICT) - } - - def boolean isExternal() { - return is(EXTERNAL) - } - - def boolean isNestedFunctionAllowed() { - return is(ALLOW_NESTED_FUNCTION_DECLARATION) - } - - def boolean isInFunctionDeclaration() { - return is(IN_FUNCTION_DECLARATION) - } - - def boolean isReturnAllowed() { - return is(ALLOW_RETURN) - } - - def boolean isBreakAllowed() { - return is(ALLOW_BREAK) - } - - def boolean isBreakAllowedWithoutLabel() { - return is(ALLOW_BREAK_WITHOUT_LABEL) - } - - def boolean isContinueAllowed() { - return is(ALLOW_CONTINUE) - } - - def boolean isVarInitializerRequired() { - return !is(ALLOW_VAR_WITHOUT_INITIALIZER) - } - - def boolean isYieldExpressionAllowed() { - return is(ALLOW_YIELD_EXPRESSION) - } - - def boolean isSuperLiteralAllowed() { - return is(ALLOW_SUPER) - } - - def boolean isSuperCallAllowed() { - return is(ALLOW_SUPER_CALL) - } - - def Constraints with(int bit, boolean set) { - val newBits = if (set) { - this.bits.bitwiseOr(bit) - } else { - this.bits.bitwiseAnd(bit.bitwiseNot) - } - if (newBits === this.bits) { - return this - } - return new Constraints(newBits) - } - - def Constraints strict(boolean strict) { - with(STRICT, strict) - } - - def Constraints allowNestedFunctions(boolean allow) { - with(ALLOW_NESTED_FUNCTION_DECLARATION, allow) - } - - def Constraints allowBreak(boolean allow) { - with(ALLOW_BREAK, allow) - } - - def Constraints allowBreakWithoutLabel(boolean allow) { - with(ALLOW_BREAK_WITHOUT_LABEL, allow) - } - - def Constraints allowContinue(boolean allow) { - with(ALLOW_CONTINUE, allow) - } - - def Constraints allowReturn(boolean allow) { - with(ALLOW_RETURN, allow) - } - - def Constraints allowVarWithoutInitializer(boolean allow) { - with(ALLOW_VAR_WITHOUT_INITIALIZER, allow) - } - - def Constraints allowYieldExpression(boolean allow) { - with(ALLOW_YIELD_EXPRESSION, allow) - } - - def Constraints allowSuperLiteral(boolean allow) { - if (!allow) { - allowSuperCall(false).with(ALLOW_SUPER, allow) - } else { - with(ALLOW_SUPER, allow) - } - } - - def Constraints allowSuperCall(boolean allow) { - with(ALLOW_SUPER_CALL, allow) - } - - def Constraints enterFunctionDeclaration() { - with(IN_FUNCTION_DECLARATION, true) - } - - } - - def void validate(EObject model, IDiagnosticConsumer consumer) { - val resource = model?.eResource; - if(resource !== null && !workspaceAccess.isNoValidate(resource, resource.getURI())) { - val producer = new ASTStructureDiagnosticProducer(consumer); - validateASTStructure(model, producer, Sets.newHashSetWithExpectedSize(2), - new Constraints( - N4Scheme.isResourceWithN4Scheme(resource), - jsVariantHelper.isN4JSMode(model), - jsVariantHelper.isExternalMode(model)) - ); - } - } - - def private void recursiveValidateASTStructure( - EObject model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - val content = model.eContents.iterator - var newStrict = constraints.isStrict - var first = true - while (content.hasNext()) { - val next = content.next(); - - // TODO this looks wrong: "strict mode" must be defined as first statement only! - // see IDE-163, also see JavaScriptVariant - // SZ: "use strict" must not be the first entry in the prolog, see test/language/directive-prologue/14.1-5gs.js - newStrict = newStrict || (first && isUseStrictProlog(model, next)) - first = first && isProlog(next) - if (next instanceof StrictModeRelevant) { - next.setStrictMode(newStrict) - } - validateASTStructure( - next, - producer, - validLabels, - constraints.strict(newStrict) - ) - } - } - - def private isProlog(EObject object) { - if (object instanceof ExpressionStatement) { - return object.expression instanceof StringLiteral - } - return false - } - - def private isUseStrictProlog(EObject model, EObject next) { - if (model instanceof Script || model instanceof Block && model.eContainer instanceof FunctionDefinition) { - switch (next) { - ExpressionStatement: { - switch it: next.expression { - StringLiteral: { - return BaseJavaScriptVariantHelper.STRICT_MODE_LITERAL_VALUE == value - } - } - } - } - } - return false - } - - def private dispatch void validateASTStructure( - EObject model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - Script model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints.strict(false).allowNestedFunctions(true).allowReturn(false).allowContinue(false).allowBreak(false).allowBreakWithoutLabel(false) - ); - } - - def private dispatch void validateASTStructure( - CoalesceExpression model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - val container = model.eContainer - if (container instanceof BinaryLogicalExpression) { - val target = NodeModelUtils.findActualNodeFor(model) - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_INVALID_COALESCE_PARENT(container.op.literal), - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_COALESCE_PARENT), IssueCodes.AST_INVALID_COALESCE_PARENT)) - } else if (model.expression instanceof BinaryLogicalExpression) { - val target = NodeModelUtils.findActualNodeFor(model.expression) - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_INVALID_COALESCE_CHILD((model.expression as BinaryLogicalExpression).op.literal), - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_COALESCE_CHILD), IssueCodes.AST_INVALID_COALESCE_CHILD)) - } else if (model.defaultExpression instanceof BinaryLogicalExpression) { - val target = NodeModelUtils.findActualNodeFor(model.defaultExpression) - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_INVALID_COALESCE_CHILD((model.defaultExpression as BinaryLogicalExpression).op.literal), - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_COALESCE_CHILD), IssueCodes.AST_INVALID_COALESCE_CHILD)) - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - N4ClassifierDefinition model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (model instanceof N4ClassifierDeclaration) { - if(model.name===null && !model.isExportedAsDefault) { - val target = NodeModelUtils.findActualNodeFor(model) - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_TYPE_DECL_MISSING_NAME, - IssueCodes.getDefaultSeverity(IssueCodes.AST_TYPE_DECL_MISSING_NAME), IssueCodes.AST_TYPE_DECL_MISSING_NAME)) - } - } - - recursiveValidateASTStructure( - model, - producer, - validLabels, - // according to ecma6 spec, class bodies are always strict - constraints.strict(true).allowNestedFunctions(true).allowReturn(false).allowContinue(false).allowBreak(false).allowBreakWithoutLabel(false) - ) - } - - def private dispatch void validateASTStructure( - N4EnumDeclaration model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if(model.name===null && !model.isExportedAsDefault) { - val target = NodeModelUtils.findActualNodeFor(model) - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_TYPE_DECL_MISSING_NAME, - IssueCodes.getDefaultSeverity(IssueCodes.AST_TYPE_DECL_MISSING_NAME), IssueCodes.AST_TYPE_DECL_MISSING_NAME)) - } - - if (model.literals.isEmpty) { - val target = NodeModelUtils.findActualNodeFor(model) - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForENM_WITHOUT_LITERALS, - IssueCodes.getDefaultSeverity(IssueCodes.ENM_WITHOUT_LITERALS), IssueCodes.ENM_WITHOUT_LITERALS)) - } - - recursiveValidateASTStructure( - model, - producer, - validLabels, - // according to ecma6 spec, class bodies are always strict - constraints.strict(true).allowNestedFunctions(true).allowReturn(false).allowContinue(false).allowBreak(false).allowBreakWithoutLabel(false) - ) - } - - def private dispatch void validateASTStructure( - N4EnumLiteral model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (!N4JSLanguageUtils.isEnumLiteralValueExpressionValid(model)) { - val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.eINSTANCE.n4EnumLiteral_ValueExpression); - producer.node = nodes.head; - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForENM_INVALID_VALUE_EXPRESSION, - IssueCodes.getDefaultSeverity(IssueCodes.ENM_INVALID_VALUE_EXPRESSION), IssueCodes.ENM_INVALID_VALUE_EXPRESSION)) - } - - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - LegacyOctalIntLiteral model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (constraints.isStrict) { - val target = NodeModelUtils.findActualNodeFor(model) - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_STR_NO_OCTALS, - IssueCodes.getDefaultSeverity(IssueCodes.AST_STR_NO_OCTALS), IssueCodes.AST_STR_NO_OCTALS)) - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - NumericLiteralTypeRef model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (constraints.isStrict) { - val node = NodeModelUtils.findNodesForFeature(model, TypeRefsPackage.Literals.LITERAL_TYPE_REF__AST_VALUE).head; - if (node !== null) { - val text = NodeModelUtils.getTokenText(node); - if (text.length() >= 2 && text.startsWith("0") && Character.isDigit(text.charAt(1))) { - producer.node = node; - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_STR_NO_OCTALS, - IssueCodes.getDefaultSeverity(IssueCodes.AST_STR_NO_OCTALS), IssueCodes.AST_STR_NO_OCTALS)); - } - } - } - - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - StringLiteral model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (constraints.isStrict) { - addErrorForOctalEscapeSequence(model.rawValue, model, N4JSPackage.Literals.STRING_LITERAL__VALUE, producer); - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - TemplateSegment model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - addErrorForOctalEscapeSequence(model.rawValue, model, N4JSPackage.Literals.TEMPLATE_SEGMENT__VALUE, producer); - - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - StringLiteralTypeRef model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - val node = NodeModelUtils.findNodesForFeature(model, TypeRefsPackage.Literals.LITERAL_TYPE_REF__AST_VALUE).head; - if (node !== null) { - val text = NodeModelUtils.getTokenText(node); - addErrorForOctalEscapeSequence(text, model, TypeRefsPackage.Literals.LITERAL_TYPE_REF__AST_VALUE, producer); - } - - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private addErrorForOctalEscapeSequence(String rawValue, EObject model, EAttribute valueEAttribute, ASTStructureDiagnosticProducer producer) { - val nodes = NodeModelUtils.findNodesForFeature(model, valueEAttribute); - val target = nodes.head; - val syntaxError = target.syntaxErrorMessage; - if ((syntaxError === null || syntaxError.issueCode == WARN_ISSUE_CODE || syntaxError.issueCode == InternalSemicolonInjectingParser.SEMICOLON_INSERTED) && rawValue.hasOctalEscapeSequence) { - producer.node = target; - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_STR_NO_OCTALS, - IssueCodes.getDefaultSeverity(IssueCodes.AST_STR_NO_OCTALS), IssueCodes.AST_STR_NO_OCTALS)); - } - } - - def private dispatch void validateASTStructure( - PostfixExpression model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - val child = model.expression - if (!child.isValidSimpleAssignmentTarget) { - val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.POSTFIX_EXPRESSION__EXPRESSION) - val target = nodes.head - producer.node = target - val operand = if (model.op == PostfixOperator.DEC) 'decrement' else 'increment' - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_INVALID_OPERAND(operand), - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_OPERAND), IssueCodes.AST_INVALID_OPERAND)) - } - } - - def private dispatch void validateASTStructure( - UnaryExpression model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - if (model.op == UnaryOperator.DEC || model.op == UnaryOperator.INC) { - val child = model.expression - if (child!==null && !child.isValidSimpleAssignmentTarget) { - val nodes = NodeModelUtils.findNodesForFeature(model, - N4JSPackage.Literals.POSTFIX_EXPRESSION__EXPRESSION) - val target = nodes.head - producer.node = target - val operand = if (model.op == UnaryOperator.DEC) 'decrement' else 'increment' - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_INVALID_OPERAND(operand), - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_OPERAND), IssueCodes.AST_INVALID_OPERAND)) - } - } - } - - def private dispatch void validateASTStructure( - YieldExpression model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (!constraints.isYieldExpressionAllowed) { - val target = NodeModelUtils.findActualNodeFor(model) - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_INVALID_YIELD_EXPRESSION, - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_YIELD_EXPRESSION), IssueCodes.AST_INVALID_YIELD_EXPRESSION)) - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - AssignmentExpression model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - // first validate the children to make sure strictMode flag was set - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - if (model.lhs !== null && !N4JSLanguageUtils.hasValidLHS(model)) { - val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.ASSIGNMENT_EXPRESSION__LHS) - val target = nodes.head - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_EXP_INVALID_LHS_ASS, - IssueCodes.getDefaultSeverity(IssueCodes.AST_EXP_INVALID_LHS_ASS), - IssueCodes.AST_EXP_INVALID_LHS_ASS)) - } - } - - def private dispatch void validateASTStructure( - ParameterizedCallExpression model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (N4JSLanguageUtils.isDynamicImportCall(model)) { - if (!model.arguments.empty && model.arguments.get(0).isSpread) { - val target = NodeModelUtils.findActualNodeFor(model.arguments.get(0)); - producer.node = target; - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_IMPORT_CALL_SPREAD, - IssueCodes.getDefaultSeverity(IssueCodes.AST_IMPORT_CALL_SPREAD), IssueCodes.AST_IMPORT_CALL_SPREAD)); - } - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - IdentifierRef model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - val name = model.idAsText - if (name !== null) { - if (constraints.isStrict && (RESERVED_WORDS_IN_STRICT_MODE.contains(name))) { - if (name == IMPORT_KEYWORD && model.eContainingFeature === N4JSPackage.Literals.EXPRESSION_WITH_TARGET__TARGET) { - // allow use of 'import' here - } else { - issueNameDiagnostic(model, producer, name, N4JSPackage.Literals.IDENTIFIER_REF__ID, Severity.ERROR) - } - } - if (model.eContainingFeature === N4JSPackage.Literals.NAMED_EXPORT_SPECIFIER__EXPORTED_ELEMENT - && name == N4JSLanguageConstants.EXPORT_DEFAULT_NAME) { - val grandParent = model.eContainer?.eContainer; - if (grandParent instanceof ExportDeclaration) { - if (grandParent.exportedElement === null && !grandParent.isReexport) { - val target = NodeModelUtils.findActualNodeFor(model); - producer.node = target; - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_SEPARATE_DEFAULT_EXPORT_WITHOUT_FROM, - IssueCodes.getDefaultSeverity(IssueCodes.AST_SEPARATE_DEFAULT_EXPORT_WITHOUT_FROM), IssueCodes.AST_SEPARATE_DEFAULT_EXPORT_WITHOUT_FROM)); - } - } - } - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - AbstractVariable model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - val name = model.name - if (name !== null) { - if (name == LOCAL_ARGUMENTS_VARIABLE_NAME) { - val isFparInN4jsd = constraints.isExternal // here: isExternal <==> file extension is ".n4jsd" - && (model instanceof FormalParameter); - if (!isFparInN4jsd) { - issueArgumentsError(model, name, constraints.isStrict, producer) - } - } else { - if (name != YIELD_KEYWORD && (languageHelper.getECMAKeywords.contains(name) - || 'enum'.equals(name) || 'await'.equals(name) - || 'true'.equals(name) || 'false'.equals(name) || 'null'.equals(name))) { - - if (constraints.isBuiltInTypeDefinition() && 'import'.equals(name)) { - // ignore - } else { - issueNameDiagnostic(model, producer, name) - } - } else if (constraints.isStrict) { - if (RESERVED_WORDS_IN_STRICT_MODE.contains(name) || name == EVAL_NAME) { - issueNameDiagnostic(model, producer, name) - model.name = null; // do not pollute scope - } - } - } - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - WithStatement model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (constraints.isStrict) { - val node = NodeModelUtils.findActualNodeFor(model).leafNodes.findFirst[ grammarElement == grammarAccess.withStatementAccess.withKeyword_0 ] - producer.node = node - if(node !== null) { - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_STR_NO_WITH_STMT, - IssueCodes.getDefaultSeverity(IssueCodes.AST_STR_NO_WITH_STMT), - IssueCodes.AST_STR_NO_WITH_STMT)) - } - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - LabelledStatement model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - val name = model.name - if (name !== null) { - if (constraints.isStrict && (RESERVED_WORDS_IN_STRICT_MODE.contains(name))) { - issueNameDiagnostic(model, producer, name) - model.name = null; // do not pollute scope - } - } - try { - validLabels.add(model) - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints.allowNestedFunctions(!constraints.isStrict).allowBreak(true) - ) - } finally { - validLabels.remove(model) - } - } - - def private dispatch void validateASTStructure( - Block model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - validateBlockStructure( - model.eContainer, - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateBlockStructure( - IfStatement container, - Block model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateBlockStructure( - IterationStatement container, - Block model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints.allowNestedFunctions(!constraints.isStrict && !constraints.isInFunctionDeclaration) - ) - } - - def private dispatch void validateBlockStructure( - FunctionDefinition container, - Block model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints.allowNestedFunctions(true) - ) - } - - def private dispatch void validateBlockStructure( - CatchBlock container, - Block model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints.allowNestedFunctions(true) - ) - } - - def private dispatch void validateBlockStructure( - EObject container, - Block model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints.allowNestedFunctions(!constraints.isStrict) - ) - } - - def private dispatch void validateASTStructure( - IfStatement model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints.allowNestedFunctions(!constraints.isStrict && !constraints.isInFunctionDeclaration) - ) - } - - def private dispatch void validateASTStructure( - AbstractCaseClause model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints.allowBreak(true).allowBreakWithoutLabel(true) - ) - } - - def private dispatch void validateASTStructure( - ForStatement model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (model.isAwait && !model.isForOf) { - val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.FOR_STATEMENT__AWAIT); - val target = nodes.head ?: NodeModelUtils.findActualNodeFor(model); - if (target !== null) { - producer.node = target; - producer.addDiagnostic(new DiagnosticMessage(IssueCodes.messageForAST_INVALID_FOR_AWAIT, - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_FOR_AWAIT), IssueCodes.AST_INVALID_FOR_AWAIT)); - } - } - if (!model.isForPlain) { - if (! model.varDeclsOrBindings.empty) { - model.varDecl.forEach[ varDecl | - if (varDecl.expression !== null && !(varDecl.eContainer instanceof BindingElement) && (constraints.isStrict || model.varStmtKeyword === VariableStatementKeyword.LET)) { - val nodes = NodeModelUtils.findNodesForFeature(varDecl, N4JSPackage.Literals.VARIABLE_DECLARATION__EXPRESSION) - val target = nodes.head ?: NodeModelUtils.findActualNodeFor(varDecl) - producer.node = target - if(target !== null) { - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_VAR_DECL_IN_FOR_INVALID_INIT, - if (constraints.isStrict || model.isForIn) IssueCodes.getDefaultSeverity(IssueCodes.AST_VAR_DECL_IN_FOR_INVALID_INIT) else Severity.WARNING, - IssueCodes.AST_VAR_DECL_IN_FOR_INVALID_INIT)) - } - } else if (model.varStmtKeyword === VariableStatementKeyword.LET && varDecl.name == 'let') { - val nodes = NodeModelUtils.findNodesForFeature(varDecl, N4JSPackage.Literals.ABSTRACT_VARIABLE__NAME) - val target = nodes.head ?: NodeModelUtils.findActualNodeFor(varDecl) - producer.node = target - if(target !== null) { - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_RESERVED_IDENTIFIER(varDecl.name), - IssueCodes.getDefaultSeverity(IssueCodes.AST_RESERVED_IDENTIFIER), - IssueCodes.AST_RESERVED_IDENTIFIER)) - } - } - ] - } else if (model.initExpr!==null) { - val initExpr = model.initExpr; - if (initExpr instanceof AssignmentExpression) { - val nodes = NodeModelUtils.findNodesForFeature(initExpr, - TypesPackage.Literals.IDENTIFIABLE_ELEMENT__NAME) - val target = nodes.head ?: NodeModelUtils.findActualNodeFor(initExpr) - producer.node = target - if (target !== null) { - producer.addDiagnostic( - new DiagnosticMessage( - IssueCodes.getMessageForAST_VAR_DECL_IN_FOR_INVALID_INIT(), - IssueCodes.getDefaultSeverity(IssueCodes.AST_VAR_DECL_IN_FOR_INVALID_INIT), - IssueCodes.AST_VAR_DECL_IN_FOR_INVALID_INIT)) - } - } else if(!initExpr.isValidSimpleAssignmentTarget && !model.isTopOfDestructuringForStatement) { - val nodes = NodeModelUtils.findNodesForFeature(model, - N4JSPackage.Literals.FOR_STATEMENT__INIT_EXPR) - val target = nodes.head ?: NodeModelUtils.findActualNodeFor(initExpr) - producer.node = target - if (target !== null) { - producer.addDiagnostic( - new DiagnosticMessage( - IssueCodes.getMessageForAST_EXP_INVALID_LHS_ASS, - IssueCodes.getDefaultSeverity(IssueCodes.AST_EXP_INVALID_LHS_ASS), - IssueCodes.AST_EXP_INVALID_LHS_ASS)) - } - } - } - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints.allowNestedFunctions(!constraints.isStrict && !constraints.isInFunctionDeclaration).allowBreak(true).allowContinue(true).allowBreakWithoutLabel(true) - ) - } - - def private dispatch void validateASTStructure( - IterationStatement model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints.allowNestedFunctions(!constraints.isStrict && !constraints.isInFunctionDeclaration).allowBreak(true).allowContinue(true).allowBreakWithoutLabel(true) - ) - } - - def private dispatch void validateASTStructure( - FormalParameter model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - val container = model.eContainer - var allowYieldInInit = false - if (container instanceof FunctionDefinition) { - allowYieldInInit = !container.isGenerator - - val issueConsumer = [String msg, String id, EObject eObj | - producer.node = NodeModelUtils.findActualNodeFor(eObj); - producer.addDiagnostic(new DiagnosticMessage(msg, IssueCodes.getDefaultSeverity(id), id)); - ]; - internalCheckFormalParameter( - container.fpars, - model, - [variadic], - [hasInitializerAssignment], - issueConsumer - ); - } - - _validateASTStructure( - model as AbstractVariable, - producer, - validLabels, - constraints.allowYieldExpression(allowYieldInInit) - ) - } - - def private dispatch void validateASTStructure( - NewTarget model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (EcoreUtil2.getContainerOfType(model, FunctionDefinition) === null) { - val target = NodeModelUtils.findActualNodeFor(model) - if(target !== null) { - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_INVALID_NEW_TARGET, - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_NEW_TARGET), - IssueCodes.AST_INVALID_NEW_TARGET)) - } - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - SuperLiteral model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (model.isInvalidSuperLiteral(constraints)) { - - val target = NodeModelUtils.findActualNodeFor(model) - if(target !== null) { - producer.node = target - if (model.eContainingFeature === N4JSPackage.Literals.EXPRESSION_WITH_TARGET__TARGET && model.eContainer instanceof ParameterizedCallExpression) { - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForKEY_SUP_CTOR_INVALID_LOC, - IssueCodes.getDefaultSeverity(IssueCodes.KEY_SUP_CTOR_INVALID_LOC), - IssueCodes.KEY_SUP_CTOR_INVALID_LOC)) - } else if (EcoreUtil2.getContainerOfType(model, N4MethodDeclaration) === null) { - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForKEY_SUP_ACCESS_INVALID_LOC, - IssueCodes.getDefaultSeverity(IssueCodes.KEY_SUP_ACCESS_INVALID_LOC), - IssueCodes.KEY_SUP_ACCESS_INVALID_LOC)) - } else { - val containingClass = EcoreUtil2.getContainerOfType(model, N4ClassifierDeclaration) - if (containingClass instanceof N4InterfaceDeclaration) { - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForKEY_SUP_ACCESS_INVALID_LOC_INTERFACE, - IssueCodes.getDefaultSeverity(IssueCodes.KEY_SUP_ACCESS_INVALID_LOC_INTERFACE), - IssueCodes.KEY_SUP_ACCESS_INVALID_LOC_INTERFACE)) - } else if (containingClass !== null) { - if (!constraints.isN4JS) { // implicit super type only available in n4js - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForKEY_SUP_ACCESS_NO_EXTENDS, - IssueCodes.getDefaultSeverity(IssueCodes.KEY_SUP_ACCESS_NO_EXTENDS), - IssueCodes.KEY_SUP_ACCESS_NO_EXTENDS)) - } - } else { - throw new IllegalStateException('a') - } - } - } - - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private boolean isInvalidSuperLiteral(SuperLiteral model, Constraints constraints) { - if (!model.isValidContainment) { - return true - } - if (!constraints.isSuperLiteralAllowed) { - return true - } - if (!constraints.isSuperCallAllowed) { - return model.eContainer instanceof ParameterizedCallExpression - } - return false - } - - def private boolean isValidContainment(SuperLiteral literal) { - val container = literal.eContainer - return container instanceof IndexedAccessExpression || container instanceof ParameterizedCallExpression || container instanceof ParameterizedPropertyAccessExpression - } - - def private dispatch void validateASTStructure( - FunctionDeclaration model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - validateFunctionDefinition( - model, - N4JSPackage.Literals.FUNCTION_DECLARATION__NAME, - constraints.enterFunctionDeclaration, - model.name, - producer, - validLabels - ) - } - - def private dispatch void validateASTStructure( - FunctionExpression model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - val name = model.name - if (name !== null) { - if (name == LOCAL_ARGUMENTS_VARIABLE_NAME) { - issueArgumentsError(model, name, constraints.isStrict, producer) - } else if (constraints.isStrict()) { - if (RESERVED_WORDS_IN_STRICT_MODE.contains(name) || name == EVAL_NAME) { - issueNameDiagnostic(model, producer, name) - model.name = null; // do not pollute scope - } - } - } - recursiveValidateASTStructure( - model, - producer, - Sets.newHashSetWithExpectedSize(2), - constraints.allowNestedFunctions(true).allowReturn(true).allowBreak(false).allowContinue(false).allowBreakWithoutLabel(false) - ) - } - - def private void validateFunctionDefinition( - FunctionDefinition model, - EAttribute attribute, - Constraints constraints, - String name, - ASTStructureDiagnosticProducer producer, - Set validLabels - ) { - if (!constraints.isNestedFunctionAllowed) { - val nodes = NodeModelUtils.findNodesForFeature(model, attribute) - val target = nodes.head ?: NodeModelUtils.findActualNodeFor(model) - producer.node = target - - // TODO improve error message - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_STR_FUN_NOT_NESTED(), - IssueCodes.getDefaultSeverity(IssueCodes.AST_STR_FUN_NOT_NESTED), IssueCodes.AST_STR_FUN_NOT_NESTED)) - } else if (name !== null) { - if (name == LOCAL_ARGUMENTS_VARIABLE_NAME) { - issueArgumentsError(model, name, constraints.isStrict, producer) - } else if (constraints.isStrict()) { - if (RESERVED_WORDS_IN_STRICT_MODE.contains(name) || name == EVAL_NAME) { - issueNameDiagnostic(model, producer, name) - } - } - } - recursiveValidateASTStructure( - model, - producer, - Sets.newHashSetWithExpectedSize(2), - constraints.allowNestedFunctions(true).allowReturn(true).allowContinue(false).allowBreak(false).allowYieldExpression(true).allowBreakWithoutLabel(false) - ) - } - - def private void validateName(PropertyNameOwner model, Constraints constraints, ASTStructureDiagnosticProducer producer) { - val name = model.name - if (name !== null) { - if (!model.isValidName - && !constraints.isBuiltInTypeDefinition) { - issueNameDiagnostic(model, producer, name) - } else { - if (constraints.isN4JS) { - if (RESERVED_WORDS_IN_STRICT_MODE.contains(name)) { - issueNameDiagnostic(model, producer, name) - } - } else if (constraints.isStrict) { - if (RESERVED_WORDS_IN_STRICT_MODE.contains(name)) { - issueNameDiagnostic(model, producer, name, getNameFeature(model), Severity.WARNING) - } - } - } - } - } - - def private void issueArgumentsError(EObject model, String name, boolean strict, ASTStructureDiagnosticProducer producer) { - issueNameDiagnostic(model, producer, name, getNameFeature(model), if (strict) Severity.ERROR else Severity.WARNING); - } - - def private void issueNameDiagnostic(EObject model, ASTStructureDiagnosticProducer producer, String name) { - issueNameDiagnostic(model, producer, name, getNameFeature(model), IssueCodes.getDefaultSeverity(IssueCodes.AST_RESERVED_IDENTIFIER)) - } - - def private void issueNameDiagnostic(EObject model, ASTStructureDiagnosticProducer producer, String name, EStructuralFeature feature, Severity severity) { - val nodes = NodeModelUtils.findNodesForFeature(model, feature) - val target = nodes.head ?: NodeModelUtils.findActualNodeFor(model) - producer.node = target - if(target !== null) { - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_RESERVED_IDENTIFIER(name), - severity, - IssueCodes.AST_RESERVED_IDENTIFIER)) - } - } - - def private EStructuralFeature getNameFeature(EObject model) { - return model.eClass.getEStructuralFeature('name') ?: model.eClass.getEStructuralFeature('declaredName'); - } - - def private dispatch void validateASTStructure( - N4FieldAccessor model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - model.validateName(constraints, producer) - recursiveValidateASTStructure( - model, - producer, - Sets.newHashSetWithExpectedSize(2), - constraints.allowReturn(true).allowSuperLiteral(true).allowSuperCall(false) - ) - } - - def private dispatch void validateASTStructure( - MethodDeclaration model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - model.validateName(constraints, producer) - recursiveValidateASTStructure( - model, - producer, - Sets.newHashSetWithExpectedSize(2), - constraints.allowReturn(true).allowSuperLiteral(true).allowSuperCall(model.name == 'constructor' && !model.isStatic && model.canCallSuperConstructor(constraints)) - ) - } - - def private boolean canCallSuperConstructor(MethodDeclaration declaration, Constraints constraints) { - val container = declaration.eContainer - if (container instanceof N4ClassDefinition) { - if (constraints.isN4JS) { - return true - } - return container.superClassRef !== null || container.superClassExpression !== null - } - return false - } - - def private dispatch void validateASTStructure( - FieldAccessor model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - model.validateName(constraints, producer) - recursiveValidateASTStructure( - model, - producer, - Sets.newHashSetWithExpectedSize(2), - constraints.allowReturn(true).allowSuperLiteral(true).allowSuperCall(false) - ) - } - - def private dispatch void validateASTStructure( - PropertyAssignment model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - Sets.newHashSetWithExpectedSize(2), - constraints.allowNestedFunctions(false).allowReturn(true).allowContinue(false).allowBreak(false).allowYieldExpression(true).allowBreakWithoutLabel(false) - ) - } - - def private dispatch void validateASTStructure( - ReturnStatement model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (!constraints.isReturnAllowed) { - val target = NodeModelUtils.findActualNodeFor(model) - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_INVALID_RETURN, - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_RETURN), IssueCodes.AST_INVALID_RETURN)) - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - ContinueStatement model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (!constraints.isContinueAllowed) { - val target = NodeModelUtils.findActualNodeFor(model) - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_INVALID_CONTINUE, - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_CONTINUE), IssueCodes.AST_INVALID_CONTINUE)) - } else { - validateLabelRef(model, producer, validLabels) - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - BreakStatement model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (!constraints.isBreakAllowed - || (!validateLabelRef(model, producer, validLabels) && !constraints.isBreakAllowedWithoutLabel) - ) { - val target = NodeModelUtils.findActualNodeFor(model) - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_INVALID_BREAK, - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_BREAK), IssueCodes.AST_INVALID_BREAK)) - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } + @Inject + private WorkspaceAccess workspaceAccess; + + @Inject + private N4JSGrammarAccess grammarAccess; + + @Inject + private N4JSLanguageHelper languageHelper; + + @Inject + private JavaScriptVariantHelper jsVariantHelper; + + @ToString + protected static class Constraints { + static val BUILT_IN_TYPE_DEFINITION = 1 + static val STRICT = BUILT_IN_TYPE_DEFINITION << 1 + static val N4JS = STRICT << 1 + static val EXTERNAL = N4JS << 1 + static val ALLOW_NESTED_FUNCTION_DECLARATION = EXTERNAL << 1 + static val ALLOW_RETURN = ALLOW_NESTED_FUNCTION_DECLARATION << 1 + static val ALLOW_CONTINUE = ALLOW_RETURN << 1 + static val ALLOW_BREAK = ALLOW_CONTINUE << 1 // whether we are in "break-allowed-with/without-label" (for||while||switch-case||labelled-block) area + static val ALLOW_BREAK_WITHOUT_LABEL = ALLOW_BREAK << 1 // whether we are in (for||while||switch-case) area + static val ALLOW_VAR_WITHOUT_INITIALIZER = ALLOW_BREAK_WITHOUT_LABEL << 1 + static val ALLOW_YIELD_EXPRESSION = ALLOW_VAR_WITHOUT_INITIALIZER << 1 + static val ALLOW_SUPER = ALLOW_YIELD_EXPRESSION << 1 + static val ALLOW_SUPER_CALL = ALLOW_SUPER << 1 + static val IN_FUNCTION_DECLARATION = ALLOW_SUPER_CALL << 1 + + val int bits + + def private static getIf(int value, boolean b) { + if (b) value else 0 + } + + new(boolean builtInTypeDefinition, boolean n4js, boolean external) { + this( + BUILT_IN_TYPE_DEFINITION.getIf(builtInTypeDefinition).bitwiseOr( + N4JS.getIf(n4js).bitwiseOr( + EXTERNAL.getIf(external).bitwiseOr( + ALLOW_VAR_WITHOUT_INITIALIZER.bitwiseOr( + ALLOW_YIELD_EXPRESSION + ) + ) + ) + ) + ) + } + + new(int bits) { + this.bits = bits + } + + def private is(int bit) { + return this.bits.bitwiseAnd(bit) !== 0 + } + + def boolean isBuiltInTypeDefinition() { + return is(BUILT_IN_TYPE_DEFINITION) + } + + def boolean isN4JS() { + return is(N4JS) + } + + def boolean isStrict() { + return is(N4JS) || is(STRICT) + } + + def boolean isExternal() { + return is(EXTERNAL) + } + + def boolean isNestedFunctionAllowed() { + return is(ALLOW_NESTED_FUNCTION_DECLARATION) + } + + def boolean isInFunctionDeclaration() { + return is(IN_FUNCTION_DECLARATION) + } + + def boolean isReturnAllowed() { + return is(ALLOW_RETURN) + } + + def boolean isBreakAllowed() { + return is(ALLOW_BREAK) + } + + def boolean isBreakAllowedWithoutLabel() { + return is(ALLOW_BREAK_WITHOUT_LABEL) + } + + def boolean isContinueAllowed() { + return is(ALLOW_CONTINUE) + } + + def boolean isVarInitializerRequired() { + return !is(ALLOW_VAR_WITHOUT_INITIALIZER) + } + + def boolean isYieldExpressionAllowed() { + return is(ALLOW_YIELD_EXPRESSION) + } + + def boolean isSuperLiteralAllowed() { + return is(ALLOW_SUPER) + } + + def boolean isSuperCallAllowed() { + return is(ALLOW_SUPER_CALL) + } + + def Constraints with(int bit, boolean set) { + val newBits = if (set) { + this.bits.bitwiseOr(bit) + } else { + this.bits.bitwiseAnd(bit.bitwiseNot) + } + if (newBits === this.bits) { + return this + } + return new Constraints(newBits) + } + + def Constraints strict(boolean strict) { + with(STRICT, strict) + } + + def Constraints allowNestedFunctions(boolean allow) { + with(ALLOW_NESTED_FUNCTION_DECLARATION, allow) + } + + def Constraints allowBreak(boolean allow) { + with(ALLOW_BREAK, allow) + } + + def Constraints allowBreakWithoutLabel(boolean allow) { + with(ALLOW_BREAK_WITHOUT_LABEL, allow) + } + + def Constraints allowContinue(boolean allow) { + with(ALLOW_CONTINUE, allow) + } + + def Constraints allowReturn(boolean allow) { + with(ALLOW_RETURN, allow) + } + + def Constraints allowVarWithoutInitializer(boolean allow) { + with(ALLOW_VAR_WITHOUT_INITIALIZER, allow) + } + + def Constraints allowYieldExpression(boolean allow) { + with(ALLOW_YIELD_EXPRESSION, allow) + } + + def Constraints allowSuperLiteral(boolean allow) { + if (!allow) { + allowSuperCall(false).with(ALLOW_SUPER, allow) + } else { + with(ALLOW_SUPER, allow) + } + } + + def Constraints allowSuperCall(boolean allow) { + with(ALLOW_SUPER_CALL, allow) + } + + def Constraints enterFunctionDeclaration() { + with(IN_FUNCTION_DECLARATION, true) + } + + } + + def void validate(EObject model, IDiagnosticConsumer consumer) { + val resource = model?.eResource; + if(resource !== null && !workspaceAccess.isNoValidate(resource, resource.getURI())) { + val producer = new ASTStructureDiagnosticProducer(consumer); + validateASTStructure(model, producer, Sets.newHashSetWithExpectedSize(2), + new Constraints( + N4Scheme.isResourceWithN4Scheme(resource), + jsVariantHelper.isN4JSMode(model), + jsVariantHelper.isExternalMode(model)) + ); + } + } + + def private void recursiveValidateASTStructure( + EObject model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + val content = model.eContents.iterator + var newStrict = constraints.isStrict + var first = true + while (content.hasNext()) { + val next = content.next(); + + // TODO this looks wrong: "strict mode" must be defined as first statement only! + // see IDE-163, also see JavaScriptVariant + // SZ: "use strict" must not be the first entry in the prolog, see test/language/directive-prologue/14.1-5gs.js + newStrict = newStrict || (first && isUseStrictProlog(model, next)) + first = first && isProlog(next) + if (next instanceof StrictModeRelevant) { + next.setStrictMode(newStrict) + } + validateASTStructure( + next, + producer, + validLabels, + constraints.strict(newStrict) + ) + } + } + + def private isProlog(EObject object) { + if (object instanceof ExpressionStatement) { + return object.expression instanceof StringLiteral + } + return false + } + + def private isUseStrictProlog(EObject model, EObject next) { + if (model instanceof Script || model instanceof Block && model.eContainer instanceof FunctionDefinition) { + switch (next) { + ExpressionStatement: { + switch it: next.expression { + StringLiteral: { + return BaseJavaScriptVariantHelper.STRICT_MODE_LITERAL_VALUE == value + } + } + } + } + } + return false + } + + def private dispatch void validateASTStructure( + EObject model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + Script model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints.strict(false).allowNestedFunctions(true).allowReturn(false).allowContinue(false).allowBreak(false).allowBreakWithoutLabel(false) + ); + } + + def private dispatch void validateASTStructure( + CoalesceExpression model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + val container = model.eContainer + if (container instanceof BinaryLogicalExpression) { + val target = NodeModelUtils.findActualNodeFor(model) + producer.node = target + producer.addDiagnostic( + newDiagnosticMessage(IssueCodes.AST_INVALID_COALESCE_PARENT, container.op.literal) + ); + } else if (model.expression instanceof BinaryLogicalExpression) { + val target = NodeModelUtils.findActualNodeFor(model.expression) + producer.node = target + producer.addDiagnostic( + newDiagnosticMessage(IssueCodes.AST_INVALID_COALESCE_CHILD, (model.expression as BinaryLogicalExpression).op.literal) + ); + } else if (model.defaultExpression instanceof BinaryLogicalExpression) { + val target = NodeModelUtils.findActualNodeFor(model.defaultExpression) + producer.node = target + producer.addDiagnostic( + newDiagnosticMessage(IssueCodes.AST_INVALID_COALESCE_CHILD, (model.defaultExpression as BinaryLogicalExpression).op.literal) + ); + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + N4ClassifierDefinition model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (model instanceof N4ClassifierDeclaration) { + if(model.name===null && !model.isExportedAsDefault) { + val target = NodeModelUtils.findActualNodeFor(model) + producer.node = target + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_TYPE_DECL_MISSING_NAME)); + } + } + + recursiveValidateASTStructure( + model, + producer, + validLabels, + // according to ecma6 spec, class bodies are always strict + constraints.strict(true).allowNestedFunctions(true).allowReturn(false).allowContinue(false).allowBreak(false).allowBreakWithoutLabel(false) + ) + } + + def private dispatch void validateASTStructure( + N4EnumDeclaration model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if(model.name===null && !model.isExportedAsDefault) { + val target = NodeModelUtils.findActualNodeFor(model) + producer.node = target + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_TYPE_DECL_MISSING_NAME)); + } + + if (model.literals.isEmpty) { + val target = NodeModelUtils.findActualNodeFor(model) + producer.node = target + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.ENM_WITHOUT_LITERALS)); + } + + recursiveValidateASTStructure( + model, + producer, + validLabels, + // according to ecma6 spec, class bodies are always strict + constraints.strict(true).allowNestedFunctions(true).allowReturn(false).allowContinue(false).allowBreak(false).allowBreakWithoutLabel(false) + ) + } + + def private dispatch void validateASTStructure( + N4EnumLiteral model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (!N4JSLanguageUtils.isEnumLiteralValueExpressionValid(model)) { + val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.eINSTANCE.n4EnumLiteral_ValueExpression); + producer.node = nodes.head; + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.ENM_INVALID_VALUE_EXPRESSION)); + } + + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + LegacyOctalIntLiteral model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (constraints.isStrict) { + val target = NodeModelUtils.findActualNodeFor(model) + producer.node = target + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_STR_NO_OCTALS)); + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + NumericLiteralTypeRef model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (constraints.isStrict) { + val node = NodeModelUtils.findNodesForFeature(model, TypeRefsPackage.Literals.LITERAL_TYPE_REF__AST_VALUE).head; + if (node !== null) { + val text = NodeModelUtils.getTokenText(node); + if (text.length() >= 2 && text.startsWith("0") && Character.isDigit(text.charAt(1))) { + producer.node = node; + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_STR_NO_OCTALS)); + } + } + } + + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + StringLiteral model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (constraints.isStrict) { + addErrorForOctalEscapeSequence(model.rawValue, model, N4JSPackage.Literals.STRING_LITERAL__VALUE, producer); + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + TemplateSegment model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + addErrorForOctalEscapeSequence(model.rawValue, model, N4JSPackage.Literals.TEMPLATE_SEGMENT__VALUE, producer); + + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + StringLiteralTypeRef model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + val node = NodeModelUtils.findNodesForFeature(model, TypeRefsPackage.Literals.LITERAL_TYPE_REF__AST_VALUE).head; + if (node !== null) { + val text = NodeModelUtils.getTokenText(node); + addErrorForOctalEscapeSequence(text, model, TypeRefsPackage.Literals.LITERAL_TYPE_REF__AST_VALUE, producer); + } + + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private addErrorForOctalEscapeSequence(String rawValue, EObject model, EAttribute valueEAttribute, ASTStructureDiagnosticProducer producer) { + val nodes = NodeModelUtils.findNodesForFeature(model, valueEAttribute); + val target = nodes.head; + val syntaxError = target.syntaxErrorMessage; + if ((syntaxError === null || syntaxError.issueCode == WARN_ISSUE_CODE || syntaxError.issueCode == InternalSemicolonInjectingParser.SEMICOLON_INSERTED) && rawValue.hasOctalEscapeSequence) { + producer.node = target; + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_STR_NO_OCTALS)); + } + } + + def private dispatch void validateASTStructure( + PostfixExpression model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + val child = model.expression + if (!child.isValidSimpleAssignmentTarget) { + val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.POSTFIX_EXPRESSION__EXPRESSION) + val target = nodes.head + producer.node = target + val operand = if (model.op == PostfixOperator.DEC) 'decrement' else 'increment' + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_INVALID_OPERAND, operand)); + } + } + + def private dispatch void validateASTStructure( + UnaryExpression model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + if (model.op == UnaryOperator.DEC || model.op == UnaryOperator.INC) { + val child = model.expression + if (child!==null && !child.isValidSimpleAssignmentTarget) { + val nodes = NodeModelUtils.findNodesForFeature(model, + N4JSPackage.Literals.POSTFIX_EXPRESSION__EXPRESSION) + val target = nodes.head + producer.node = target + val operand = if (model.op == UnaryOperator.DEC) 'decrement' else 'increment' + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_INVALID_OPERAND, operand)); + } + } + } + + def private dispatch void validateASTStructure( + YieldExpression model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (!constraints.isYieldExpressionAllowed) { + val target = NodeModelUtils.findActualNodeFor(model) + producer.node = target + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_INVALID_YIELD_EXPRESSION)); + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + AssignmentExpression model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + // first validate the children to make sure strictMode flag was set + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + if (model.lhs !== null && !N4JSLanguageUtils.hasValidLHS(model)) { + val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.ASSIGNMENT_EXPRESSION__LHS) + val target = nodes.head + producer.node = target + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_EXP_INVALID_LHS_ASS)); + } + } + + def private dispatch void validateASTStructure( + ParameterizedCallExpression model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (N4JSLanguageUtils.isDynamicImportCall(model)) { + if (!model.arguments.empty && model.arguments.get(0).isSpread) { + val target = NodeModelUtils.findActualNodeFor(model.arguments.get(0)); + producer.node = target; + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_IMPORT_CALL_SPREAD)); + } + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + IdentifierRef model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + val name = model.idAsText + if (name !== null) { + if (constraints.isStrict && (RESERVED_WORDS_IN_STRICT_MODE.contains(name))) { + if (name == IMPORT_KEYWORD && model.eContainingFeature === N4JSPackage.Literals.EXPRESSION_WITH_TARGET__TARGET) { + // allow use of 'import' here + } else { + issueNameDiagnostic(model, producer, name, N4JSPackage.Literals.IDENTIFIER_REF__ID, Severity.ERROR) + } + } + if (model.eContainingFeature === N4JSPackage.Literals.NAMED_EXPORT_SPECIFIER__EXPORTED_ELEMENT + && name == N4JSLanguageConstants.EXPORT_DEFAULT_NAME) { + val grandParent = model.eContainer?.eContainer; + if (grandParent instanceof ExportDeclaration) { + if (grandParent.exportedElement === null && !grandParent.isReexport) { + val target = NodeModelUtils.findActualNodeFor(model); + producer.node = target; + producer.addDiagnostic( + newDiagnosticMessage(IssueCodes.AST_SEPARATE_DEFAULT_EXPORT_WITHOUT_FROM)); + } + } + } + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + AbstractVariable model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + val name = model.name + if (name !== null) { + if (name == LOCAL_ARGUMENTS_VARIABLE_NAME) { + val isFparInN4jsd = constraints.isExternal // here: isExternal <==> file extension is ".n4jsd" + && (model instanceof FormalParameter); + if (!isFparInN4jsd) { + issueArgumentsError(model, name, constraints.isStrict, producer) + } + } else { + if (name != YIELD_KEYWORD && (languageHelper.getECMAKeywords.contains(name) + || 'enum'.equals(name) || 'await'.equals(name) + || 'true'.equals(name) || 'false'.equals(name) || 'null'.equals(name))) { + + if (constraints.isBuiltInTypeDefinition() && 'import'.equals(name)) { + // ignore + } else { + issueNameDiagnostic(model, producer, name) + } + } else if (constraints.isStrict) { + if (RESERVED_WORDS_IN_STRICT_MODE.contains(name) || name == EVAL_NAME) { + issueNameDiagnostic(model, producer, name) + model.name = null; // do not pollute scope + } + } + } + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + WithStatement model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (constraints.isStrict) { + val node = NodeModelUtils.findActualNodeFor(model).leafNodes.findFirst[ grammarElement == grammarAccess.withStatementAccess.withKeyword_0 ] + producer.node = node + if(node !== null) { + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_STR_NO_WITH_STMT)); + } + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + LabelledStatement model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + val name = model.name + if (name !== null) { + if (constraints.isStrict && (RESERVED_WORDS_IN_STRICT_MODE.contains(name))) { + issueNameDiagnostic(model, producer, name) + model.name = null; // do not pollute scope + } + } + try { + validLabels.add(model) + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints.allowNestedFunctions(!constraints.isStrict).allowBreak(true) + ) + } finally { + validLabels.remove(model) + } + } + + def private dispatch void validateASTStructure( + Block model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + validateBlockStructure( + model.eContainer, + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateBlockStructure( + IfStatement container, + Block model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateBlockStructure( + IterationStatement container, + Block model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints.allowNestedFunctions(!constraints.isStrict && !constraints.isInFunctionDeclaration) + ) + } + + def private dispatch void validateBlockStructure( + FunctionDefinition container, + Block model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints.allowNestedFunctions(true) + ) + } + + def private dispatch void validateBlockStructure( + CatchBlock container, + Block model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints.allowNestedFunctions(true) + ) + } + + def private dispatch void validateBlockStructure( + EObject container, + Block model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints.allowNestedFunctions(!constraints.isStrict) + ) + } + + def private dispatch void validateASTStructure( + IfStatement model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints.allowNestedFunctions(!constraints.isStrict && !constraints.isInFunctionDeclaration) + ) + } + + def private dispatch void validateASTStructure( + AbstractCaseClause model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints.allowBreak(true).allowBreakWithoutLabel(true) + ) + } + + def private dispatch void validateASTStructure( + ForStatement model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (model.isAwait && !model.isForOf) { + val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.FOR_STATEMENT__AWAIT); + val target = nodes.head ?: NodeModelUtils.findActualNodeFor(model); + if (target !== null) { + producer.node = target; + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_INVALID_FOR_AWAIT)); + } + } + if (!model.isForPlain) { + if (! model.varDeclsOrBindings.empty) { + model.varDecl.forEach[ varDecl | + if (varDecl.expression !== null && !(varDecl.eContainer instanceof BindingElement) && (constraints.isStrict || model.varStmtKeyword === VariableStatementKeyword.LET)) { + val nodes = NodeModelUtils.findNodesForFeature(varDecl, N4JSPackage.Literals.VARIABLE_DECLARATION__EXPRESSION) + val target = nodes.head ?: NodeModelUtils.findActualNodeFor(varDecl) + producer.node = target + if(target !== null) { + producer.addDiagnostic( + new DiagnosticMessage(IssueCodes.AST_VAR_DECL_IN_FOR_INVALID_INIT.getMessage(), + if (constraints.isStrict || model.isForIn) IssueCodes.AST_VAR_DECL_IN_FOR_INVALID_INIT.severity else Severity.WARNING, + IssueCodes.AST_VAR_DECL_IN_FOR_INVALID_INIT.name())) + } + } else if (model.varStmtKeyword === VariableStatementKeyword.LET && varDecl.name == 'let') { + val nodes = NodeModelUtils.findNodesForFeature(varDecl, N4JSPackage.Literals.ABSTRACT_VARIABLE__NAME) + val target = nodes.head ?: NodeModelUtils.findActualNodeFor(varDecl) + producer.node = target + if(target !== null) { + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_RESERVED_IDENTIFIER, varDecl.name)); + } + } + ] + } else if (model.initExpr!==null) { + val initExpr = model.initExpr; + if (initExpr instanceof AssignmentExpression) { + val nodes = NodeModelUtils.findNodesForFeature(initExpr, + TypesPackage.Literals.IDENTIFIABLE_ELEMENT__NAME) + val target = nodes.head ?: NodeModelUtils.findActualNodeFor(initExpr) + producer.node = target + if (target !== null) { + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_VAR_DECL_IN_FOR_INVALID_INIT)); + } + } else if(!initExpr.isValidSimpleAssignmentTarget && !model.isTopOfDestructuringForStatement) { + val nodes = NodeModelUtils.findNodesForFeature(model, + N4JSPackage.Literals.FOR_STATEMENT__INIT_EXPR) + val target = nodes.head ?: NodeModelUtils.findActualNodeFor(initExpr) + producer.node = target + if (target !== null) { + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_EXP_INVALID_LHS_ASS)); + } + } + } + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints.allowNestedFunctions(!constraints.isStrict && !constraints.isInFunctionDeclaration).allowBreak(true).allowContinue(true).allowBreakWithoutLabel(true) + ) + } + + def private dispatch void validateASTStructure( + IterationStatement model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints.allowNestedFunctions(!constraints.isStrict && !constraints.isInFunctionDeclaration).allowBreak(true).allowContinue(true).allowBreakWithoutLabel(true) + ) + } + + def private dispatch void validateASTStructure( + FormalParameter model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + val container = model.eContainer + var allowYieldInInit = false + if (container instanceof FunctionDefinition) { + allowYieldInInit = !container.isGenerator + + val issueConsumer = [String msg, String id, EObject eObj | + producer.node = NodeModelUtils.findActualNodeFor(eObj); + producer.addDiagnostic(new DiagnosticMessage(msg, IssueCodes.getSeverityForName(id), id)); + ]; + internalCheckFormalParameter( + container.fpars, + model, + [variadic], + [hasInitializerAssignment], + issueConsumer + ); + } + + _validateASTStructure( + model as AbstractVariable, + producer, + validLabels, + constraints.allowYieldExpression(allowYieldInInit) + ) + } + + def private dispatch void validateASTStructure( + NewTarget model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (EcoreUtil2.getContainerOfType(model, FunctionDefinition) === null) { + val target = NodeModelUtils.findActualNodeFor(model) + if(target !== null) { + producer.node = target + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_INVALID_NEW_TARGET)); + } + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + SuperLiteral model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (model.isInvalidSuperLiteral(constraints)) { + + val target = NodeModelUtils.findActualNodeFor(model) + if(target !== null) { + producer.node = target + if (model.eContainingFeature === N4JSPackage.Literals.EXPRESSION_WITH_TARGET__TARGET && model.eContainer instanceof ParameterizedCallExpression) { + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.KEY_SUP_CTOR_INVALID_LOC)); + } else if (EcoreUtil2.getContainerOfType(model, N4MethodDeclaration) === null) { + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.KEY_SUP_ACCESS_INVALID_LOC)); + } else { + val containingClass = EcoreUtil2.getContainerOfType(model, N4ClassifierDeclaration) + if (containingClass instanceof N4InterfaceDeclaration) { + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.KEY_SUP_ACCESS_INVALID_LOC_INTERFACE)); + } else if (containingClass !== null) { + if (!constraints.isN4JS) { // implicit super type only available in n4js + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.KEY_SUP_ACCESS_NO_EXTENDS)); + } + } else { + throw new IllegalStateException('a') + } + } + } + + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private boolean isInvalidSuperLiteral(SuperLiteral model, Constraints constraints) { + if (!model.isValidContainment) { + return true + } + if (!constraints.isSuperLiteralAllowed) { + return true + } + if (!constraints.isSuperCallAllowed) { + return model.eContainer instanceof ParameterizedCallExpression + } + return false + } + + def private boolean isValidContainment(SuperLiteral literal) { + val container = literal.eContainer + return container instanceof IndexedAccessExpression || container instanceof ParameterizedCallExpression || container instanceof ParameterizedPropertyAccessExpression + } + + def private dispatch void validateASTStructure( + FunctionDeclaration model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + validateFunctionDefinition( + model, + N4JSPackage.Literals.FUNCTION_DECLARATION__NAME, + constraints.enterFunctionDeclaration, + model.name, + producer, + validLabels + ) + } + + def private dispatch void validateASTStructure( + FunctionExpression model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + val name = model.name + if (name !== null) { + if (name == LOCAL_ARGUMENTS_VARIABLE_NAME) { + issueArgumentsError(model, name, constraints.isStrict, producer) + } else if (constraints.isStrict()) { + if (RESERVED_WORDS_IN_STRICT_MODE.contains(name) || name == EVAL_NAME) { + issueNameDiagnostic(model, producer, name) + model.name = null; // do not pollute scope + } + } + } + recursiveValidateASTStructure( + model, + producer, + Sets.newHashSetWithExpectedSize(2), + constraints.allowNestedFunctions(true).allowReturn(true).allowBreak(false).allowContinue(false).allowBreakWithoutLabel(false) + ) + } + + def private void validateFunctionDefinition( + FunctionDefinition model, + EAttribute attribute, + Constraints constraints, + String name, + ASTStructureDiagnosticProducer producer, + Set validLabels + ) { + if (!constraints.isNestedFunctionAllowed) { + val nodes = NodeModelUtils.findNodesForFeature(model, attribute) + val target = nodes.head ?: NodeModelUtils.findActualNodeFor(model) + producer.node = target + + // TODO improve error message + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_STR_FUN_NOT_NESTED)); + } else if (name !== null) { + if (name == LOCAL_ARGUMENTS_VARIABLE_NAME) { + issueArgumentsError(model, name, constraints.isStrict, producer) + } else if (constraints.isStrict()) { + if (RESERVED_WORDS_IN_STRICT_MODE.contains(name) || name == EVAL_NAME) { + issueNameDiagnostic(model, producer, name) + } + } + } + recursiveValidateASTStructure( + model, + producer, + Sets.newHashSetWithExpectedSize(2), + constraints.allowNestedFunctions(true).allowReturn(true).allowContinue(false).allowBreak(false).allowYieldExpression(true).allowBreakWithoutLabel(false) + ) + } + + def private void validateName(PropertyNameOwner model, Constraints constraints, ASTStructureDiagnosticProducer producer) { + val name = model.name + if (name !== null) { + if (!model.isValidName + && !constraints.isBuiltInTypeDefinition) { + issueNameDiagnostic(model, producer, name) + } else { + if (constraints.isN4JS) { + if (RESERVED_WORDS_IN_STRICT_MODE.contains(name)) { + issueNameDiagnostic(model, producer, name) + } + } else if (constraints.isStrict) { + if (RESERVED_WORDS_IN_STRICT_MODE.contains(name)) { + issueNameDiagnostic(model, producer, name, getNameFeature(model), Severity.WARNING) + } + } + } + } + } + + def private void issueArgumentsError(EObject model, String name, boolean strict, ASTStructureDiagnosticProducer producer) { + issueNameDiagnostic(model, producer, name, getNameFeature(model), if (strict) Severity.ERROR else Severity.WARNING); + } + + def private void issueNameDiagnostic(EObject model, ASTStructureDiagnosticProducer producer, String name) { + issueNameDiagnostic(model, producer, name, getNameFeature(model), IssueCodes.AST_RESERVED_IDENTIFIER.severity) + } + + def private void issueNameDiagnostic(EObject model, ASTStructureDiagnosticProducer producer, String name, EStructuralFeature feature, Severity severity) { + val nodes = NodeModelUtils.findNodesForFeature(model, feature) + val target = nodes.head ?: NodeModelUtils.findActualNodeFor(model) + producer.node = target + if(target !== null) { + producer.addDiagnostic( + new DiagnosticMessage(IssueCodes.AST_RESERVED_IDENTIFIER.getMessage(name), + severity, + IssueCodes.AST_RESERVED_IDENTIFIER.name())) + } + } + + def private EStructuralFeature getNameFeature(EObject model) { + return model.eClass.getEStructuralFeature('name') ?: model.eClass.getEStructuralFeature('declaredName'); + } + + def private dispatch void validateASTStructure( + N4FieldAccessor model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + model.validateName(constraints, producer) + recursiveValidateASTStructure( + model, + producer, + Sets.newHashSetWithExpectedSize(2), + constraints.allowReturn(true).allowSuperLiteral(true).allowSuperCall(false) + ) + } + + def private dispatch void validateASTStructure( + MethodDeclaration model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + model.validateName(constraints, producer) + recursiveValidateASTStructure( + model, + producer, + Sets.newHashSetWithExpectedSize(2), + constraints.allowReturn(true).allowSuperLiteral(true).allowSuperCall(model.name == 'constructor' && !model.isStatic && model.canCallSuperConstructor(constraints)) + ) + } + + def private boolean canCallSuperConstructor(MethodDeclaration declaration, Constraints constraints) { + val container = declaration.eContainer + if (container instanceof N4ClassDefinition) { + if (constraints.isN4JS) { + return true + } + return container.superClassRef !== null || container.superClassExpression !== null + } + return false + } + + def private dispatch void validateASTStructure( + FieldAccessor model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + model.validateName(constraints, producer) + recursiveValidateASTStructure( + model, + producer, + Sets.newHashSetWithExpectedSize(2), + constraints.allowReturn(true).allowSuperLiteral(true).allowSuperCall(false) + ) + } + + def private dispatch void validateASTStructure( + PropertyAssignment model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + Sets.newHashSetWithExpectedSize(2), + constraints.allowNestedFunctions(false).allowReturn(true).allowContinue(false).allowBreak(false).allowYieldExpression(true).allowBreakWithoutLabel(false) + ) + } + + def private dispatch void validateASTStructure( + ReturnStatement model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (!constraints.isReturnAllowed) { + val target = NodeModelUtils.findActualNodeFor(model) + producer.node = target + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_INVALID_RETURN)); + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + ContinueStatement model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (!constraints.isContinueAllowed) { + val target = NodeModelUtils.findActualNodeFor(model) + producer.node = target + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_INVALID_CONTINUE)); + } else { + validateLabelRef(model, producer, validLabels) + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + BreakStatement model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (!constraints.isBreakAllowed + || (!validateLabelRef(model, producer, validLabels) && !constraints.isBreakAllowedWithoutLabel) + ) { + val target = NodeModelUtils.findActualNodeFor(model) + producer.node = target + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_INVALID_BREAK)); + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } /* * @returns whether there is a label */ - def private boolean validateLabelRef(LabelRef model, ASTStructureDiagnosticProducer producer, - Set validLabels - ) { - val labelAsText = model.labelAsText; // cannot use model.label, because we aren't allowed to resolve proxies in this phase! - if (labelAsText !== null && !validLabels.exists[it.name==labelAsText]) { - val target = NodeModelUtils.findActualNodeFor(model) - producer.node = target - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_INVALID_LABEL, - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_LABEL), IssueCodes.AST_INVALID_LABEL)) - } - return labelAsText !== null - } - - def private dispatch void validateASTStructure( - Expression model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - ArrayElement model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - - validateExpressionInArrayOrObjectLiteral(model, constraints, producer); - validateSpreadInArrayLiteral(model, producer); - } - - /** @param elem must be an ArrayElement or PropertyNameValuePair. */ - def private void validateExpressionInArrayOrObjectLiteral(EObject elem, Constraints constraints, ASTStructureDiagnosticProducer producer) { - if(!(elem instanceof ArrayElement || elem instanceof PropertyNameValuePair || elem instanceof PropertyMethodDeclaration)) { - throw new IllegalArgumentException(); - } - if(elem instanceof PropertyNameValuePairSingleName) { - val identifier = elem.identifierRef - if (identifier !== null && !identifier.isValidSimpleAssignmentTarget) { - producer.node = NodeModelUtils.findActualNodeFor(identifier) - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_INVALID_EXPR_IN_LHS_DESTRUCTURING_PATTERN, - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_EXPR_IN_LHS_DESTRUCTURING_PATTERN), IssueCodes.AST_INVALID_EXPR_IN_LHS_DESTRUCTURING_PATTERN)) - } - // more validation not required in this case, because expression has a different meaning and problem cannot occur - return; - } - if(elem!==null && DestructureUtils.isArrayOrObjectLiteralUsedAsDestructuringPattern(elem.eContainer)) { - if(elem instanceof PropertyMethodDeclaration) { - // methods are not allowed at all in a destructuring pattern - producer.node = NodeModelUtils.findActualNodeFor(elem) - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_INVALID_PROPERTY_METHOD_IN_LHS_DESTRUCTURING_PATTERN, - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_PROPERTY_METHOD_IN_LHS_DESTRUCTURING_PATTERN), IssueCodes.AST_INVALID_PROPERTY_METHOD_IN_LHS_DESTRUCTURING_PATTERN)) - } else { - val expr = switch(elem) { - ArrayElement: elem.expression - PropertyNameValuePair: elem.expression - }; - if(expr!==null && !expr.isValidBindingElement(constraints)) { - producer.node = NodeModelUtils.findActualNodeFor(expr) - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_INVALID_EXPR_IN_LHS_DESTRUCTURING_PATTERN, - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_EXPR_IN_LHS_DESTRUCTURING_PATTERN), IssueCodes.AST_INVALID_EXPR_IN_LHS_DESTRUCTURING_PATTERN)) - } - } - } - } - - def private isValidBindingElement(Expression expr, Constraints constraints) { - if (constraints.isN4JS) { - return (expr.isValidSimpleAssignmentTarget && expr instanceof IdentifierRef) - || expr instanceof AssignmentExpression - || expr instanceof ArrayLiteral - || expr instanceof ObjectLiteral - } else { - return expr.isValidSimpleAssignmentTarget - || expr instanceof AssignmentExpression - || expr instanceof ArrayLiteral - || expr instanceof ObjectLiteral - } - } - - def private void validateSpreadInArrayLiteral(ArrayElement elem, ASTStructureDiagnosticProducer producer) { - if(elem!==null && elem.spread) { - if(!DestructureUtils.isArrayOrObjectLiteralUsedAsDestructuringPattern(elem.eContainer)) { - // use of spread in an array literal that is *not* used as a destructuring pattern - // --> valid at any position - } - else { - // use of spread in an array literal that *is* used as a destructuring pattern - // --> error if not at end of array literal - val lit = elem.eContainer; - if(lit instanceof ArrayLiteral) { - if(lit.elements.last!==elem || lit.trailingComma) { - val nodes = NodeModelUtils.findNodesForFeature(elem, N4JSPackage.eINSTANCE.arrayElement_Spread); - producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(elem) - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_REST_MUST_APPEAR_AT_END, - IssueCodes.getDefaultSeverity(IssueCodes.AST_REST_MUST_APPEAR_AT_END), IssueCodes.AST_REST_MUST_APPEAR_AT_END)) - } - - if (elem.expression instanceof AssignmentExpression) { - val nodes = NodeModelUtils.findNodesForFeature(elem.expression, N4JSPackage.eINSTANCE.assignmentExpression_Rhs); - producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(elem.expression) - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_REST_WITH_INITIALIZER, - IssueCodes.getDefaultSeverity(IssueCodes.AST_REST_WITH_INITIALIZER), IssueCodes.AST_REST_WITH_INITIALIZER)) - } - } - } - } - } - - def private dispatch void validateASTStructure( - PropertyNameValuePair model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints.allowYieldExpression(true) - ) - - validateExpressionInArrayOrObjectLiteral(model, constraints, producer); - validateSingleNameInObjectLiteral(model, producer); - } - - def private dispatch void validateASTStructure( - PropertyMethodDeclaration model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints.allowReturn(true).allowSuperLiteral(true).allowSuperCall(false).allowYieldExpression(true) - ) - - validateExpressionInArrayOrObjectLiteral(model, constraints, producer); - } - - def private void validateSingleNameInObjectLiteral(PropertyNameValuePair elem, ASTStructureDiagnosticProducer producer) { - if(elem instanceof PropertyNameValuePairSingleName - && !DestructureUtils.isArrayOrObjectLiteralUsedAsDestructuringPattern(elem.eContainer) - && elem.expression instanceof AssignmentExpression) { - - val nodes = NodeModelUtils.findNodesForFeature(elem.expression, N4JSPackage.Literals.ASSIGNMENT_EXPRESSION__RHS) - producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(elem.expression) - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_INVALID_DEFAULT_EXPR_SINGLE_NAME_PROPERTY, - IssueCodes.getDefaultSeverity(IssueCodes.AST_INVALID_DEFAULT_EXPR_SINGLE_NAME_PROPERTY), IssueCodes.AST_INVALID_DEFAULT_EXPR_SINGLE_NAME_PROPERTY)) - } - } - - def private dispatch void validateASTStructure( - VariableStatement model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (model.varStmtKeyword === VariableStatementKeyword.CONST) { - if (!model.isValidConstOrLetPosition) { - val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.VARIABLE_DECLARATION_CONTAINER__VAR_STMT_KEYWORD) - producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(model) - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_CONST_IN_STATEMENT_POSITION, - IssueCodes.getDefaultSeverity(IssueCodes.AST_CONST_IN_STATEMENT_POSITION), - IssueCodes.AST_CONST_IN_STATEMENT_POSITION)) - } - } else if (model.varStmtKeyword === VariableStatementKeyword.LET) { - if (!model.isValidConstOrLetPosition) { - val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.VARIABLE_DECLARATION_CONTAINER__VAR_STMT_KEYWORD) - producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(model) - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_LET_IN_STATEMENT_POSITION, - IssueCodes.getDefaultSeverity(IssueCodes.AST_LET_IN_STATEMENT_POSITION), - IssueCodes.AST_LET_IN_STATEMENT_POSITION)) - } - } - if (model.varDeclsOrBindings.empty) { - val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.VARIABLE_DECLARATION_CONTAINER__VAR_STMT_KEYWORD) - producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(model) - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.messageForAST_VAR_STMT_NO_DECL, - IssueCodes.getDefaultSeverity(IssueCodes.AST_VAR_STMT_NO_DECL), - IssueCodes.AST_VAR_STMT_NO_DECL)) - } - val directParent = model.eContainer; - val parent = if(directParent instanceof ExportDeclaration) directParent.eContainer else directParent; - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints.allowVarWithoutInitializer(model.varStmtKeyword === VariableStatementKeyword.VAR || model.varStmtKeyword === VariableStatementKeyword.LET && - (parent instanceof Block || parent instanceof Script || parent instanceof AbstractCaseClause) - ) - ) - } - - def private boolean isValidConstOrLetPosition(EObject model) { - if (model.eContainer instanceof Block - || model.eContainer instanceof Script - || model.eContainer instanceof AbstractCaseClause - || model.eContainer instanceof N4NamespaceDeclaration - ) { - return true - } - if (model.eContainer instanceof ExportDeclaration) { - return model.eContainer.isValidConstOrLetPosition - } - return false - } - - def private dispatch void validateASTStructure( - VariableDeclaration model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (model.expression === null && constraints.isVarInitializerRequired && !constraints.external) { - val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.ABSTRACT_VARIABLE__NAME); - producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(model) - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_CONST_HAS_NO_INITIALIZER(model.getName()), - IssueCodes.getDefaultSeverity(IssueCodes.AST_CONST_HAS_NO_INITIALIZER), IssueCodes.AST_CONST_HAS_NO_INITIALIZER)) - } - _validateASTStructure(model as AbstractVariable, producer, validLabels, constraints.allowVarWithoutInitializer(true)) - } - - def private dispatch void validateASTStructure( - ThisTypeRef thisTypeRef, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - // note: validity of location of ThisTypeRef was checked here; now moved to N4JSTypeValidator#checkThisTypeRef() - - recursiveValidateASTStructure( - thisTypeRef, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - VariableBinding model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - // no need to assert model.expression!==null (it is enforced by the grammar) - - recursiveValidateASTStructure( - model, - producer, - validLabels, - // initializers of variable declarations below a VariableBinding are always optional, even if we are in the - // context of a const declaration, e.g. the following should not show an error about missing initializer: - // const [c1, c2] = [10, 20]; - // Requiring an initializer of variable declarations below VariableBindings would render the above code - // invalid and require something like: - // const [c1=1, c2=2] = [10, 20]; - constraints.allowVarWithoutInitializer(true) - ) - } - - def private dispatch void validateASTStructure( - BindingElement model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - validateRestInBindingPattern(model, producer); - - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - Annotation model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - // Add an issue for all script annotation (indicated by '@@') that do - // not appear at the very top of the module. - if (model.eContainer instanceof Script) { - val script = model.eContainer as Script; - if (script.scriptElements.size > 0) { - val annotationNode = NodeModelUtils.findActualNodeFor(model); - val annotationOffset = annotationNode.offset - val firstScriptElement = script.scriptElements.get(0); - val scriptElementOffset = NodeModelUtils.findActualNodeFor(firstScriptElement).offset; - - if (annotationOffset > scriptElementOffset) { - producer.node = annotationNode; - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_SCRIPT_ANNO_INVALID_PLACEMENT(model.name), - IssueCodes.getDefaultSeverity(IssueCodes.AST_SCRIPT_ANNO_INVALID_PLACEMENT), IssueCodes.AST_SCRIPT_ANNO_INVALID_PLACEMENT)) - } - } - } - } - - def private void validateRestInBindingPattern(BindingElement elem, ASTStructureDiagnosticProducer producer) { - if(elem!==null && elem.rest) { - val pattern = elem.eContainer; - if(pattern instanceof ArrayBindingPattern) { - // note: the grammar ensures that BindingElement with rest===true will only appear - // within an array binding pattern; we only have to assert that it appears at the end - if(pattern.elements.last!==elem) { - val nodes = NodeModelUtils.findNodesForFeature(elem, N4JSPackage.eINSTANCE.bindingElement_Rest); - producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(elem) - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_REST_MUST_APPEAR_AT_END, - IssueCodes.getDefaultSeverity(IssueCodes.AST_REST_MUST_APPEAR_AT_END), IssueCodes.AST_REST_MUST_APPEAR_AT_END)) - } - } - if (elem.expression !== null) { - val nodes = NodeModelUtils.findNodesForFeature(elem, N4JSPackage.eINSTANCE.bindingElement_Expression); - producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(elem) - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_REST_WITH_INITIALIZER, - IssueCodes.getDefaultSeverity(IssueCodes.AST_REST_WITH_INITIALIZER), IssueCodes.AST_REST_WITH_INITIALIZER)) - } - } - } - - def private dispatch void validateASTStructure( - BinaryLogicalExpression model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - if (model.getLhs() === null) { - producer.node = NodeModelUtils.findActualNodeFor(model); - producer.addDiagnostic( - new DiagnosticMessage( - IssueCodes.getMessageForAST_BINARY_LOGICAL_EXPRESSION_MISSING_PART("left operand"), - IssueCodes.getDefaultSeverity(IssueCodes.AST_BINARY_LOGICAL_EXPRESSION_MISSING_PART), - IssueCodes.AST_BINARY_LOGICAL_EXPRESSION_MISSING_PART)) - - } - if (model.getRhs() === null) { - producer.node = NodeModelUtils.findActualNodeFor(model); - producer.addDiagnostic( - new DiagnosticMessage( - IssueCodes.getMessageForAST_BINARY_LOGICAL_EXPRESSION_MISSING_PART("right operand"), - IssueCodes.getDefaultSeverity(IssueCodes.AST_BINARY_LOGICAL_EXPRESSION_MISSING_PART), - IssueCodes.AST_BINARY_LOGICAL_EXPRESSION_MISSING_PART)) - - } - if (model.getOp() === null) { - producer.node = NodeModelUtils.findActualNodeFor(model); - producer.addDiagnostic( - new DiagnosticMessage(IssueCodes.getMessageForAST_BINARY_LOGICAL_EXPRESSION_MISSING_PART("operator"), - IssueCodes.getDefaultSeverity(IssueCodes.AST_BINARY_LOGICAL_EXPRESSION_MISSING_PART), - IssueCodes.AST_BINARY_LOGICAL_EXPRESSION_MISSING_PART)) - - } - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ); - } - - def private dispatch void validateASTStructure( - N4TypeVariable model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } - - def private dispatch void validateASTStructure( - TypeVariable model, - ASTStructureDiagnosticProducer producer, - Set validLabels, - Constraints constraints - ) { - recursiveValidateASTStructure( - model, - producer, - validLabels, - constraints - ) - } + def private boolean validateLabelRef(LabelRef model, ASTStructureDiagnosticProducer producer, + Set validLabels + ) { + val labelAsText = model.labelAsText; // cannot use model.label, because we aren't allowed to resolve proxies in this phase! + if (labelAsText !== null && !validLabels.exists[it.name==labelAsText]) { + val target = NodeModelUtils.findActualNodeFor(model) + producer.node = target + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_INVALID_LABEL)); + } + return labelAsText !== null + } + + def private dispatch void validateASTStructure( + Expression model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + ArrayElement model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + + validateExpressionInArrayOrObjectLiteral(model, constraints, producer); + validateSpreadInArrayLiteral(model, producer); + } + + /** @param elem must be an ArrayElement or PropertyNameValuePair. */ + def private void validateExpressionInArrayOrObjectLiteral(EObject elem, Constraints constraints, ASTStructureDiagnosticProducer producer) { + if(!(elem instanceof ArrayElement || elem instanceof PropertyNameValuePair || elem instanceof PropertyMethodDeclaration)) { + throw new IllegalArgumentException(); + } + if(elem instanceof PropertyNameValuePairSingleName) { + val identifier = elem.identifierRef + if (identifier !== null && !identifier.isValidSimpleAssignmentTarget) { + producer.node = NodeModelUtils.findActualNodeFor(identifier) + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_INVALID_EXPR_IN_LHS_DESTRUCTURING_PATTERN)); + } + // more validation not required in this case, because expression has a different meaning and problem cannot occur + return; + } + if(elem!==null && DestructureUtils.isArrayOrObjectLiteralUsedAsDestructuringPattern(elem.eContainer)) { + if(elem instanceof PropertyMethodDeclaration) { + // methods are not allowed at all in a destructuring pattern + producer.node = NodeModelUtils.findActualNodeFor(elem) + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_INVALID_PROPERTY_METHOD_IN_LHS_DESTRUCTURING_PATTERN)); + } else { + val expr = switch(elem) { + ArrayElement: elem.expression + PropertyNameValuePair: elem.expression + }; + if(expr!==null && !expr.isValidBindingElement(constraints)) { + producer.node = NodeModelUtils.findActualNodeFor(expr) + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_INVALID_EXPR_IN_LHS_DESTRUCTURING_PATTERN)); + } + } + } + } + + def private isValidBindingElement(Expression expr, Constraints constraints) { + if (constraints.isN4JS) { + return (expr.isValidSimpleAssignmentTarget && expr instanceof IdentifierRef) + || expr instanceof AssignmentExpression + || expr instanceof ArrayLiteral + || expr instanceof ObjectLiteral + } else { + return expr.isValidSimpleAssignmentTarget + || expr instanceof AssignmentExpression + || expr instanceof ArrayLiteral + || expr instanceof ObjectLiteral + } + } + + def private void validateSpreadInArrayLiteral(ArrayElement elem, ASTStructureDiagnosticProducer producer) { + if(elem!==null && elem.spread) { + if(!DestructureUtils.isArrayOrObjectLiteralUsedAsDestructuringPattern(elem.eContainer)) { + // use of spread in an array literal that is *not* used as a destructuring pattern + // --> valid at any position + } + else { + // use of spread in an array literal that *is* used as a destructuring pattern + // --> error if not at end of array literal + val lit = elem.eContainer; + if(lit instanceof ArrayLiteral) { + if(lit.elements.last!==elem || lit.trailingComma) { + val nodes = NodeModelUtils.findNodesForFeature(elem, N4JSPackage.eINSTANCE.arrayElement_Spread); + producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(elem) + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_REST_MUST_APPEAR_AT_END)); + } + + if (elem.expression instanceof AssignmentExpression) { + val nodes = NodeModelUtils.findNodesForFeature(elem.expression, N4JSPackage.eINSTANCE.assignmentExpression_Rhs); + producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(elem.expression) + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_REST_WITH_INITIALIZER)); + } + } + } + } + } + + def private dispatch void validateASTStructure( + PropertyNameValuePair model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints.allowYieldExpression(true) + ) + + validateExpressionInArrayOrObjectLiteral(model, constraints, producer); + validateSingleNameInObjectLiteral(model, producer); + } + + def private dispatch void validateASTStructure( + PropertyMethodDeclaration model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints.allowReturn(true).allowSuperLiteral(true).allowSuperCall(false).allowYieldExpression(true) + ) + + validateExpressionInArrayOrObjectLiteral(model, constraints, producer); + } + + def private void validateSingleNameInObjectLiteral(PropertyNameValuePair elem, ASTStructureDiagnosticProducer producer) { + if(elem instanceof PropertyNameValuePairSingleName + && !DestructureUtils.isArrayOrObjectLiteralUsedAsDestructuringPattern(elem.eContainer) + && elem.expression instanceof AssignmentExpression) { + + val nodes = NodeModelUtils.findNodesForFeature(elem.expression, N4JSPackage.Literals.ASSIGNMENT_EXPRESSION__RHS) + producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(elem.expression) + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_INVALID_DEFAULT_EXPR_SINGLE_NAME_PROPERTY)); + } + } + + def private dispatch void validateASTStructure( + VariableStatement model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (model.varStmtKeyword === VariableStatementKeyword.CONST) { + if (!model.isValidConstOrLetPosition) { + val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.VARIABLE_DECLARATION_CONTAINER__VAR_STMT_KEYWORD) + producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(model) + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_CONST_IN_STATEMENT_POSITION)); + } + } else if (model.varStmtKeyword === VariableStatementKeyword.LET) { + if (!model.isValidConstOrLetPosition) { + val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.VARIABLE_DECLARATION_CONTAINER__VAR_STMT_KEYWORD) + producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(model) + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_LET_IN_STATEMENT_POSITION)); + } + } + if (model.varDeclsOrBindings.empty) { + val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.VARIABLE_DECLARATION_CONTAINER__VAR_STMT_KEYWORD) + producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(model) + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_VAR_STMT_NO_DECL)); + } + val directParent = model.eContainer; + val parent = if(directParent instanceof ExportDeclaration) directParent.eContainer else directParent; + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints.allowVarWithoutInitializer(model.varStmtKeyword === VariableStatementKeyword.VAR || model.varStmtKeyword === VariableStatementKeyword.LET && + (parent instanceof Block || parent instanceof Script || parent instanceof AbstractCaseClause) + ) + ) + } + + def private boolean isValidConstOrLetPosition(EObject model) { + if (model.eContainer instanceof Block + || model.eContainer instanceof Script + || model.eContainer instanceof AbstractCaseClause + || model.eContainer instanceof N4NamespaceDeclaration + ) { + return true + } + if (model.eContainer instanceof ExportDeclaration) { + return model.eContainer.isValidConstOrLetPosition + } + return false + } + + def private dispatch void validateASTStructure( + VariableDeclaration model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (model.expression === null && constraints.isVarInitializerRequired && !constraints.external) { + val nodes = NodeModelUtils.findNodesForFeature(model, N4JSPackage.Literals.ABSTRACT_VARIABLE__NAME); + producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(model) + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_CONST_HAS_NO_INITIALIZER, model.getName())); + } + _validateASTStructure(model as AbstractVariable, producer, validLabels, constraints.allowVarWithoutInitializer(true)) + } + + def private dispatch void validateASTStructure( + ThisTypeRef thisTypeRef, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + // note: validity of location of ThisTypeRef was checked here; now moved to N4JSTypeValidator#checkThisTypeRef() + + recursiveValidateASTStructure( + thisTypeRef, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + VariableBinding model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + // no need to assert model.expression!==null (it is enforced by the grammar) + + recursiveValidateASTStructure( + model, + producer, + validLabels, + // initializers of variable declarations below a VariableBinding are always optional, even if we are in the + // context of a const declaration, e.g. the following should not show an error about missing initializer: + // const [c1, c2] = [10, 20]; + // Requiring an initializer of variable declarations below VariableBindings would render the above code + // invalid and require something like: + // const [c1=1, c2=2] = [10, 20]; + constraints.allowVarWithoutInitializer(true) + ) + } + + def private dispatch void validateASTStructure( + BindingElement model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + validateRestInBindingPattern(model, producer); + + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + Annotation model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + // Add an issue for all script annotation (indicated by '@@') that do + // not appear at the very top of the module. + if (model.eContainer instanceof Script) { + val script = model.eContainer as Script; + if (script.scriptElements.size > 0) { + val annotationNode = NodeModelUtils.findActualNodeFor(model); + val annotationOffset = annotationNode.offset + val firstScriptElement = script.scriptElements.get(0); + val scriptElementOffset = NodeModelUtils.findActualNodeFor(firstScriptElement).offset; + + if (annotationOffset > scriptElementOffset) { + producer.node = annotationNode; + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_SCRIPT_ANNO_INVALID_PLACEMENT, model.name)); + } + } + } + } + + def private void validateRestInBindingPattern(BindingElement elem, ASTStructureDiagnosticProducer producer) { + if(elem!==null && elem.rest) { + val pattern = elem.eContainer; + if(pattern instanceof ArrayBindingPattern) { + // note: the grammar ensures that BindingElement with rest===true will only appear + // within an array binding pattern; we only have to assert that it appears at the end + if(pattern.elements.last!==elem) { + val nodes = NodeModelUtils.findNodesForFeature(elem, N4JSPackage.eINSTANCE.bindingElement_Rest); + producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(elem) + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_REST_MUST_APPEAR_AT_END)); + } + } + if (elem.expression !== null) { + val nodes = NodeModelUtils.findNodesForFeature(elem, N4JSPackage.eINSTANCE.bindingElement_Expression); + producer.node = nodes.head ?: NodeModelUtils.findActualNodeFor(elem) + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_REST_WITH_INITIALIZER)); + } + } + } + + def private dispatch void validateASTStructure( + BinaryLogicalExpression model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + if (model.getLhs() === null) { + producer.node = NodeModelUtils.findActualNodeFor(model); + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_BINARY_LOGICAL_EXPRESSION_MISSING_PART, "left operand")); + + } + if (model.getRhs() === null) { + producer.node = NodeModelUtils.findActualNodeFor(model); + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_BINARY_LOGICAL_EXPRESSION_MISSING_PART, "right operand")); + + } + if (model.getOp() === null) { + producer.node = NodeModelUtils.findActualNodeFor(model); + producer.addDiagnostic(newDiagnosticMessage(IssueCodes.AST_BINARY_LOGICAL_EXPRESSION_MISSING_PART, "operator")); + + } + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ); + } + + def private dispatch void validateASTStructure( + N4TypeVariable model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private dispatch void validateASTStructure( + TypeVariable model, + ASTStructureDiagnosticProducer producer, + Set validLabels, + Constraints constraints + ) { + recursiveValidateASTStructure( + model, + producer, + validLabels, + constraints + ) + } + + def private DiagnosticMessage newDiagnosticMessage(IssueCodes issueCode, Object... msgValues) { + return new DiagnosticMessage(issueCode.getMessage(msgValues), issueCode.severity, issueCode.name()); + } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/AbstractN4JSDeclarativeValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/AbstractN4JSDeclarativeValidator.xtend index 4068c07c1b..24b76093ac 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/AbstractN4JSDeclarativeValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/AbstractN4JSDeclarativeValidator.xtend @@ -219,18 +219,18 @@ public abstract class AbstractN4JSDeclarativeValidator extends AbstractMessageAd "not more than " + typeParameterCount }; if (source instanceof ParameterizedTypeRef && (source as ParameterizedTypeRef).isArrayNTypeExpression) { - val message = IssueCodes. - getMessageForEXP_WRONG_NUMBER_OF_TYPEARGS_FOR_ITERABLE_N_SYNTAX(BuiltInTypeScope.ITERABLE_N__MAX_LEN); - addIssue(message, source, feature, IssueCodes.EXP_WRONG_NUMBER_OF_TYPEARGS_FOR_ITERABLE_N_SYNTAX); + val message = IssueCodes.EXP_WRONG_NUMBER_OF_TYPEARGS_FOR_ITERABLE_N_SYNTAX. + getMessage(BuiltInTypeScope.ITERABLE_N__MAX_LEN); + addIssue(message, source, feature, IssueCodes.EXP_WRONG_NUMBER_OF_TYPEARGS_FOR_ITERABLE_N_SYNTAX.name()); } else if (parameterizedElement !== null && parameterizedElement.name !== null) { - val message = IssueCodes. - getMessageForEXP_WRONG_NUMBER_OF_TYPEARGS_FOR_ELEMENT(parameterizedElement.keyword, + val message = IssueCodes.EXP_WRONG_NUMBER_OF_TYPEARGS_FOR_ELEMENT. + getMessage(parameterizedElement.keyword, parameterizedElement.name, expectationStr, typeArgumentCount); - addIssue(message, source, feature, IssueCodes.EXP_WRONG_NUMBER_OF_TYPEARGS_FOR_ELEMENT); + addIssue(message, source, feature, IssueCodes.EXP_WRONG_NUMBER_OF_TYPEARGS_FOR_ELEMENT.name()); } else { - val message = IssueCodes. - getMessageForEXP_WRONG_NUMBER_OF_TYPEARGS(expectationStr, typeArgumentCount); - addIssue(message, source, feature, IssueCodes.EXP_WRONG_NUMBER_OF_TYPEARGS); + val message = IssueCodes.EXP_WRONG_NUMBER_OF_TYPEARGS. + getMessage(expectationStr, typeArgumentCount); + addIssue(message, source, feature, IssueCodes.EXP_WRONG_NUMBER_OF_TYPEARGS.name()); } return; } @@ -298,15 +298,15 @@ public abstract class AbstractN4JSDeclarativeValidator extends AbstractMessageAd && useSiteVariance !== defSiteVariance) { // we've got an inconsistency! if (typeArgumentInAST.usingInOutNotation) { - val message = IssueCodes.getMessageForEXP_INCONSISTENT_VARIANCE_OF_TYPE_ARG_IN_OUT( + val message = IssueCodes.EXP_INCONSISTENT_VARIANCE_OF_TYPE_ARG_IN_OUT.getMessage( useSiteVariance.getDescriptiveStringNoun(true), defSiteVariance.getDescriptiveStringNoun(true)); - addIssue(message, typeArgumentInAST, IssueCodes.EXP_INCONSISTENT_VARIANCE_OF_TYPE_ARG_IN_OUT); + addIssue(message, typeArgumentInAST, IssueCodes.EXP_INCONSISTENT_VARIANCE_OF_TYPE_ARG_IN_OUT.name()); } else { - val message = IssueCodes.getMessageForEXP_INCONSISTENT_VARIANCE_OF_TYPE_ARG( + val message = IssueCodes.EXP_INCONSISTENT_VARIANCE_OF_TYPE_ARG.getMessage( if (useSiteVariance === Variance.CO) "upper" else "lower", defSiteVariance.getDescriptiveString(true)); - addIssue(message, typeArgumentInAST, IssueCodes.EXP_INCONSISTENT_VARIANCE_OF_TYPE_ARG); + addIssue(message, typeArgumentInAST, IssueCodes.EXP_INCONSISTENT_VARIANCE_OF_TYPE_ARG.name()); } } } @@ -399,8 +399,8 @@ public abstract class AbstractN4JSDeclarativeValidator extends AbstractMessageAd } private def void createUnusedTypeParameterIssue(EObject typeVarInAST) { - val msg = IssueCodes.getMessageForFUN_UNUSED_GENERIC_TYPE_PARAM(N4JSASTUtils.getNameOfTypeVarInAST(typeVarInAST)); - addIssue(msg, typeVarInAST, N4JSASTUtils.getNameFeatureOfTypeVarInAST(typeVarInAST), IssueCodes.FUN_UNUSED_GENERIC_TYPE_PARAM); + val msg = IssueCodes.FUN_UNUSED_GENERIC_TYPE_PARAM.getMessage(N4JSASTUtils.getNameOfTypeVarInAST(typeVarInAST)); + addIssue(msg, typeVarInAST, N4JSASTUtils.getNameFeatureOfTypeVarInAST(typeVarInAST), IssueCodes.FUN_UNUSED_GENERIC_TYPE_PARAM.name()); } /** @@ -637,4 +637,27 @@ public abstract class AbstractN4JSDeclarativeValidator extends AbstractMessageAd return isFieldAccessorPair(m1, m2) } + def public void addIssue(EObject source, IssueCodes issueCode, String... msgValues) { + super.addIssue(issueCode.getMessage(msgValues), source, issueCode.name()); + } + + def public void addIssue(EObject source, EStructuralFeature feature, IssueCodes issueCode, String... msgValues) { + super.addIssue(issueCode.getMessage(msgValues), source, feature, issueCode.name()); + } + + def public void addIssue(EObject source, int offset, int length, IssueItem issueItem) { + super.addIssue(issueItem.message, source, offset, length, issueItem.ID, issueItem.data); + } + + def public void addIssue(EObject source, EStructuralFeature feature, int index, IssueItem issueItem) { + super.addIssue(issueItem.message, source, feature, index, issueItem.ID, issueItem.data); + } + + def public void addIssue(EObject source, EStructuralFeature feature, IssueItem issueItem) { + super.addIssue(issueItem.message, source, feature, issueItem.ID, issueItem.data); + } + + def public void addIssue(EObject source, IssueItem issueItem) { + super.addIssue(issueItem.message, source, null, issueItem.ID, issueItem.data); + } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java new file mode 100644 index 0000000000..ea670ca3f8 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java @@ -0,0 +1,2137 @@ +/** + * Copyright (c) 2023 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; + +import static org.eclipse.xtext.diagnostics.Severity.ERROR; +import static org.eclipse.xtext.diagnostics.Severity.WARNING; + +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.xtext.diagnostics.Severity; + +import com.google.common.base.Preconditions; + +/** + * Enum contains all issues + */ +@SuppressWarnings("javadoc") +public enum IssueCodes { + + /** Only for internal use. */ + INVALID_ISSUE_CODE(WARNING, null), + + /** + * The following message is intended for ES6 features that are implemented in N4JS but are not yet supported in + * current version of V8 or some other relevant runtime environment. 0: description of the feature that is not + * supported + */ + UNSUPPORTED(ERROR, "Unsupported feature: {0}."), + + /** Not necessary. */ + SCR_HASHBANG_WRONG_LOCATION(ERROR, "Hashbang must start at the absolute start of a script or module"), + + /** 0: file names of files that contain errors */ + EXTERNAL_LIBRARY_ERRORS(ERROR, "External library error: {0}"), + + /** 0: file names of files that contain warnings */ + EXTERNAL_LIBRARY_WARNINGS(ERROR, "External library warning: {0}"), + + /** + * 0: kind of throwable ('error', 'exception', or 'throwable'), 1: simple name of throwable, 2: message of throwable + */ + POST_PROCESSING_FAILED(ERROR, "{0} {1} thrown during post-processing (please report this!): {2}"), + + /** Unknown type ref in resource */ + TYS_UNKNOWN_TYPE_REF(ERROR, "Resource contains unknown type ref (please report this!)"), + + /** 0: namespace name, 1: import module name, that both occur multiple times in this combination */ + IMP_STMT_DUPLICATE_NAMESPACE(ERROR, "Duplicate namespace import statement with name {0} and imported module {1}."), + + /** 0: imported element local name, 1: import module name, that both occur multiple times in this combination */ + IMP_STMT_DUPLICATE_NAMED(ERROR, "Duplicate named import statement with local name {0} and imported module {1}."), + + /** 0: type1 imported name1, 1: import module name, 2: name under which type is already imported */ + IMP_DUPLICATE(ERROR, "{0} from {1} is already imported as {2}."), + + /** 0: import module name, 1: namespace name already importing those elements */ + IMP_DUPLICATE_NAMESPACE(ERROR, "Element {0} of {1} is already imported in namespace {2}."), + + /** + * 0: local name (import name, alias name or namespace name), 1: import module name, 2: name under which type is + * already imported + */ + IMP_LOCAL_NAME_CONFLICT(ERROR, "Name {0} is already used as {1}."), + + /** 0: type name, 1: alias name */ + IMP_PLAIN_ACCESS_OF_ALIASED_TYPE(ERROR, "{0} has been imported as {1}."), + + /** 0: type name, 1: full name (namespace + '.' + type name) */ + IMP_PLAIN_ACCESS_OF_NAMESPACED_TYPE(ERROR, "{0} has been imported as {1}."), + + /** 0: imported name */ + IMP_UNUSED_IMPORT(WARNING, "The import of {0} is unused."), + + /** 0: imported name */ + IMP_NOT_EXPORTED(ERROR, "Element {0} is not exported."), + + /** 0: type import name */ + IMP_UNRESOLVED(ERROR, "Import of {0} cannot be resolved."), + + /** Not necessary. */ + IMP_DISCOURAGED_PLACEMENT(WARNING, "The import statement should be placed on top of other statements."), + + /** 0: type or variable, 1: type name, 2: comma separated list of types - the sources of the imports */ + IMP_AMBIGUOUS(ERROR, "The {0} {1} is ambiguously imported from {2}."), + + /** 0: type or variable, 1: type name, 2: comma separated list of types - the sources of the imports */ + IMP_AMBIGUOUS_WILDCARD(ERROR, "The {0} {1} is ambiguously imported from {2}."), + + /** 0: imported type name, 1: qualified name of the module */ + IMP_CONFLICT(ERROR, "Conflicting import of {0} with import from {1}."), + + /** 0: imported type1 name, 1: type1 alias, 2: type2 imported name, 3: type2 import module name */ + IMP_CONFLICT_ALIAS_TYPE(ERROR, + "Conflicting import of {0} as {1}. Cannot import same type with different name ({2}) from {3}."), + + /** 0: type1 imported name, 1: type2 alias, 2: type2 import module name */ + IMP_CONFLICT_ALIASES(ERROR, + "Conflicting import of {0}. Cannot import same type with different name ({1}) from {2}."), + + /** 0: type1 imported name1, that occur multiple times, 1: import module name */ + IMP_DUPLICATEX(ERROR, "Duplicate import of {0} in import from {1}."), + + /** 0: type1 imported name1, 1: type1 imported name2, 2: import module name */ + IMP_DUPLICATE_ALIAS(ERROR, "Duplicate import of {0}, already defined as {1} in import from {2}."), + + /** 0: module in wildcard specifier */ + IMP_EMPTY_WILDCARD_IMPORT(WARNING, + "The wild-card import from {0} doesn't import anything because nothing is exported there."), + + /** 0: alias in namespace import */ + IMP_STATIC_IMPORT_PLAIN_JS(ERROR, "Use dynamic import in order to access elements of {0}."), + + /** 0: alias in namespace import */ + IMP_DYNAMIC_IMPORT_N4JS(ERROR, "N4JS module {0} must not be imported dynamically."), + + /** 0: variant type, 1: alias in namespace import */ + IMP_DYNAMIC_IMPORT_N4JSD(WARNING, "The {0} module {1} should not be imported dynamically."), + + /** no parameters required */ + IMP_DEFAULT_EXPORT_DUPLICATE(ERROR, "Duplicate default export."), + + /** 0: local name of the imported element */ + IMP_IMPORTED_ELEMENT_READ_ONLY(ERROR, "Imported element {0} is read-only."), + + /** 0: local name of the imported element, 1: re-exporting project name to use, 2: imported project name */ + IMP_IMPORTED_ELEMENT_FROM_REEXPORTING_PROJECT(ERROR, + "The imported element {0} is defined in the re-exporting project {1} but project {2} was imported. Import from {1} instead."), + + /** 0: method, field, getter, setter, member, 1: member name */ + VIS_ILLEGAL_MEMBER_ACCESS(ERROR, "The {0} {1} is not visible."), + + /** 0: function name */ + VIS_ILLEGAL_FUN_ACCESS(ERROR, "The function {0} is not visible."), + + /** 0: type name */ + VIS_ILLEGAL_TYPE_ACCESS(ERROR, "The type {0} is not visible."), + + /** 0: variable name */ + VIS_ILLEGAL_VARIABLE_ACCESS(ERROR, "The variable {0} is not visible."), + + /** 0: member name, 1: type defining member */ + VIS_ILLEGAL_STATIC_MEMBER_WRITE_ACCESS(ERROR, + "Write access to the static member {1} defined in {0} must use {0} directly."), + + /** 0: member name, 1: type defining member, 2: member alias */ + VIS_ILLEGAL_STATIC_MEMBER_WRITE_ACCESS_WITH_ALIAS(ERROR, + "Write access to the static member {1} defined in {0} must use the alias {2} directly."), + + /** + * 0: member kind, 1: member name, 2: 'read-only', when a read-only member was used with write access or + * 'write-only' when a write-only member was used with read access. + */ + VIS_WRONG_READ_WRITE_ACCESS(ERROR, "The {0} {1} is {2}."), + + /** 0: static or non-static, 1: member name, 2: static or non-static */ + VIS_WRONG_STATIC_ACCESSOR(ERROR, "The {0} member {1} cannot be accessed from a {2} context."), + + /** 0: type variable name */ + VIS_WRONG_TYPE_VARIABLE_ACCESSOR(ERROR, "The type variable {0} cannot be accessed from a static context."), + + /** 0: type parameter name, 1: kind of type hidden (e.g. class, type variable, etc.) */ + VIS_TYPE_PARAMETER_HIDES_TYPE(WARNING, "The type parameter {0} hides {1} {0}."), + + /** 0: concept which is not allowed, 1: Mode (n4js,strict,...) in which it is not allowed. */ + VIS_RESTRITCTED_USAGE(ERROR, "The usage of {0} is not allowed in {1} mode."), + + /** + * 0: 'constructor' or 'construct signature', 1: classifier name whose constructor / construct signature is not + * visible. + */ + VIS_NEW_CANNOT_INSTANTIATE_INVISIBLE_CONSTRUCTOR(ERROR, "The {0} of {1} is not visible."), + + /** no parameters required */ + TYP_TYPE_PARAM_MANDATORY_AFTER_OPTIONAL(ERROR, + "Mandatory type parameters may not follow optional type parameters."), + + /** no parameters required */ + TYP_TYPE_PARAM_DEFAULT_REFERENCES_LATER_TYPE_PARAM(ERROR, + "Default type arguments may only reference type parameters that are declared before the current type parameter."), + + /** 0: name of type parameter, 1: error message of subtype check */ + TYP_TYPE_PARAM_DEFAULT_NOT_SUBTYPE_OF_BOUND(ERROR, + "Default argument of optional type parameter {0} must comply to its upper bound, but: {1}"), + + /** no parameters required */ + CLF_MUST_BE_NOMINAL(ERROR, "Classes cannot be structural."), + + /** no parameters required */ + CLF_CTOR_RETURN_TYPE(ERROR, "A constructor must not have a return type declaration."), + + /** no parameters required */ + CLF_CTOR_ILLEGAL_MODIFIER(ERROR, + "A constructor must not be declared abstract, static or final and may not be annotated with @Override."), + + /** no parameters required */ + CLF_CALL_CONSTRUCT_SIG_ONLY_IN_N4JSD(ERROR, "Call and construct signatures may only be used in .n4jsd files."), + + /** no parameters required */ + CLF_CALL_CONSTRUCT_SIG_NOT_IN_N4JS(ERROR, + "Call and construct signatures are not allowed in n4js classifiers. Use shapes or @EcmaScript."), + + /** no parameters required */ + CLF_CALL_CONSTRUCT_SIG_BODY(ERROR, "Call and construct signatures must not have a body."), + + /** 0: kind of signature ('call' or 'construct') */ + CLF_CALL_CONSTRUCT_SIG_DUPLICATE(ERROR, "Duplicate {0} signature."), + + /** no parameters required */ + CLF_CALL_CONSTRUCT_SIG_CANNOT_IMPLEMENT(ERROR, + "An interface with a call or construct signature cannot be implemented by a class."), + + /** no parameters required */ + CLF_CONSTRUCT_SIG_ONLY_IN_INTERFACE(ERROR, "Construct signatures may only be used in interfaces."), + + /** no parameters required */ + CLF_CONSTRUCT_SIG_VOID_RETURN_TYPE(ERROR, "Construct signatures must have a non-void return type."), + + /** no parameters required */ + CLF_CTOR_NO_TYPE_PARAMETERS(ERROR, "Constructors must not have any type parameters."), + + /** no parameters required */ + CLF_NAME_DOLLAR(ERROR, "Member names must not start with a dollar character."), + + /** 0: the human readable name of the violating discouraged character */ + CLF_NAME_CONTAINS_DISCOURAGED_CHARACTER(WARNING, "Name should not contain {0} character."), + + /** 0: static or const keywords */ + CLF_NAME_DOES_NOT_MATCH_WITH_PATTERN_FOR_STATIC_OR_CONST(WARNING, + "Name should be all upper case with words separated by underscores for variables with {0} modifier."), + + /** 0: element meta type */ + CLF_NAME_DOES_NOT_START_UPPERCASE(WARNING, "{0} names should start with upper case letter."), + + /** 0: element meta type */ + CLF_NAME_DOES_NOT_START_LOWERCASE(WARNING, "{0} names should start with lower case letter."), + + /** 0: element description, 1: conflicting category */ + CLF_NAME_INDISTINGUISHABLE(ERROR, "{0} may be indistinguishable with {1}."), + + /** 0: element description, 1: conflicting category */ + CLF_NAME_RESERVED(WARNING, "{0} may be confused with {1}."), + + /** no parameters required */ + CLF_NAME_CONFLICTS_WITH_CONSTRUCTOR(WARNING, "Name may be confused with constructor."), + + /** 0: element description, 1: conflicting type name 2: actual type */ + CLF_NAME_DIFFERS_TYPE(WARNING, "{0} is not of type {1} but of type {2}."), + + /** 0: name of final type, 1: name of type parameter */ + CLF_UPPER_BOUND_FINAL(WARNING, + "Final type {0} should not be used as upper bound of type parameter {1}. Final types cannot be extended."), + + /** no parameters required */ + CLF_DEF_SITE_VARIANCE_ONLY_IN_CLASSIFIER(ERROR, + "Declaration of definition-site variance only allowed in generic classes and interfaces, not in generic functions or methods."), + + /** 0: 'covariant' or 'contravariant', 1: 'covariant', 'contravariant', or 'invariant' */ + CLF_TYPE_VARIABLE_AT_INVALID_POSITION(ERROR, "Cannot use {0} type variable at {1} position."), + + /** 0: the actual primitive type */ + CLF_EXTENDS_PRIMITIVE_GENERIC_TYPE(ERROR, "Cannot subclass primitive type {0}."), + + /** 0: class name */ + CLF_EXTEND_FINAL(ERROR, "Cannot extend final class {0}."), + + /** 0: keyword, 1: name of class */ + CLF_EXTEND_NON_ACCESSIBLE_CTOR(ERROR, "Cannot extend {0} {1} because its constructor is not accessible."), + + /** 0: name of class, 1: name of super class */ + CLF_OBSERVABLE_MISSING(ERROR, + "Class {0} extends observable class {1} and must therefore be annotated with @Observable."), + + /** no parameters required */ + CLF_TEST_CLASS_NOT_EXPORTED(WARNING, + "Classes containing test methods must be abstract or marked with modifier export."), + + /** /** 0: module name, 1: path to other module */ + CLF_DUP_MODULE(ERROR, "A duplicate module {0} is also defined in {1}."), + + /** /** 0: module name, 1: js module, 2: path to other module */ + CLF_DUP_DEF_MODULE(ERROR, "A duplicate definition module {0} for {1} is also defined in {2}."), + + /** + * /** 0: first name with line ({@link ValidatorMessageHelper/**nameWithLine(TMember,TMember)}, 1: other name with + * line ({@link ValidatorMessageHelper/**nameWithLine(TMember,TMember)} + */ + CLF_DUP_CTOR(ERROR, "Constructor line {0} duplicates constructor in line {1}."), + + /** + * /** 0: first short description ({@link ValidatorMessageHelper/**descriptionWithLine(TMember,TMember)}, 1: other + * short description ({@link ValidatorMessageHelper/**descriptionWithLine(TMember,TMember)} + */ + CLF_DUP_MEMBER(ERROR, "The {0} duplicates {1}."), + + /** /** 0: first short description ({@link ValidatorMessageHelper/**descriptionWithLine(TMember,TMember)} */ + CLF_DUP_WITH_MEMBER(ERROR, + "The {0} conflicts with the structural this type in the inherit constructor definition."), + + /** + * 0: overriding description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * overridden description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 2: setter or + * getter + */ + CLF_OVERRIDE_FIELD_REQUIRES_ACCESSOR_PAIR(ERROR, "The {0} cannot override {1}, matching {2} missing."), + + /** + * 0: overriding description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * overridden description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)} + */ + CLF_CONSUMED_OVERRIDE_FIELD(ERROR, "The consumed {0} cannot override {1}."), + + /** + * 0: overriding description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * 'overriding' or 'implementing' 2: overridden description + * ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)} + */ + CLF_OVERRIDE_ANNOTATION(ERROR, "The {0} {1} {2} must be annotated with @Override."), + + /** + * 0: overriding description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * overridden description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)} + */ + CLF_REDEFINED_NON_ACCESSIBLE(ERROR, "The {0} cannot override or implement non-accessible {1}."), + + /** + * 0: overriding description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * overridden description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)} + */ + CLF_OVERRIDE_FINAL(ERROR, "The {0} cannot override final {1}."), + + /** + * 0: overridden description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: 'final' + * or 'const' + */ + CLF_OVERRIDE_WITH_FINAL_OR_CONST_FIELD(ERROR, "Cannot override {0} with a {1} field."), + + /** + * 0: overriding description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * overridden description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)} + */ + CLF_OVERRIDE_CONST(ERROR, "The {0} cannot override {1}."), + + /** + * 0: overriding description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * overridden description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)} + */ + CLF_OVERRIDEN_CONCRETE_WITH_ABSTRACT(ERROR, "The abstract {0} cannot override concrete {1}."), + + /** + * 0: overriding description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * overridden description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)} + */ + CLF_OVERRIDE_VISIBILITY(ERROR, "The {0} cannot reduce the visibility of {1}."), + + /** 0: method, getter or setter, 1: member name */ + CLF_OVERRIDE_NON_EXISTENT(ERROR, "The {0} {1} must override or implement a {0} from a super class or interface."), + + /** 0: member description, 1: member description */ + CLF_OVERRIDE_NON_EXISTENT_INTERFACE(WARNING, + "The {0} does not override {1} (no inheritance of static members in interfaces); remove annotation @Override."), + + /** + * 0: description of constructor, 1: description of classifier inheriting the constructor, 2: description of + * classifier owning the constructor + */ + CLF_PSEUDO_REDEFINED_SPEC_CTOR_INCOMPATIBLE(ERROR, + "Inherited {0} in context of {1} not compatible to itself in context of {2}."), + + /** + * 0: overriding description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * overridden/implemented/consumed, 2: overridden description + * ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)} 3: additional members or error + * information (may be empty) + */ + CLF_REDEFINED_TYPE_NOT_SAME_TYPE(ERROR, "Type of {0} must equal type of {1} {2}.{3}"), + + /** + * 0: overriding description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * overridden/implemented/consumed, 2: overridden description + * ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)} + */ + CLF_REDEFINED_BY_CONSUMED_TYPE_NOT_SAME_TYPE(ERROR, "Type of inherited {0} must equal type of {1} {2}."), + + /** + * 0: overriding description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * overridden description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * overridden/implemented/consumed, 3: signature type error message, 4: additional members or error information (may + * be empty) + */ + CLF_REDEFINED_MEMBER_TYPE_INVALID(ERROR, "Type of {0} does not conform to {2} {1}: {3}.{4}"), + + /** + * 0: consumed/inherited, 1: overriding description + * ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 2: overridden/implemented/consumed, + * 3: overridden description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 4: + * signature type error message + */ + CLF_REDEFINED_BY_CONSUMED_MEMBER_TYPE_INVALID(ERROR, "Type of {0} {1} does not conform to {2} {3}: {4}."), + + /** 0: comma separated description of conflicting members */ + CLF_CONSUMED_MEMBER_SOLVABLE_CONFLICT(ERROR, "Redefine ambiguously consumed members: {0}."), + + /** 0: comma separated description of conflicting members */ + CLF_CONSUMED_MEMBER_UNSOLVABLE_CONFLICT(ERROR, "Incompatible consumed members: {0}."), + + /** 0: inherited member leading to conflict, 1: comma separated description of conflicting members */ + CLF_CONSUMED_INHERITED_MEMBER_UNSOLVABLE_CONFLICT(ERROR, "Inherited {0} cannot implement {1}."), + + /** + * 0: overriding description, should usually start with 'Signature of ' + * ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: overridden/implemented/consumed, + * 2: overridden description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 3: + * signature type error message, 4: additional members or error information (may be empty) + */ + CLF_REDEFINED_METHOD_TYPE_CONFLICT(ERROR, "{0} does not conform to {1} {2}: {3}.{4}"), + + /** + * 0: overriding description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * overridden description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)} + */ + CLF_OVERRIDE_MEMBERTYPE_INCOMPATIBLE(ERROR, "Cannot override {1} with {0}."), + + /** + * TODO remove?! 0: overriding description + * ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: overridden description + * ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)} + */ + CLF_CONSUMED_OVERRIDE_MEMBERTYPE_INCOMPATIBLE(ERROR, "Cannot override {1} with consumed {0}."), + + /** + * 0: getter/setter, 0: overridden descriptions (CSV) + * ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)} + */ + CLF_CONSUMED_FIELD_ACCESSOR_PAIR_INCOMPLETE(ERROR, "Missing {0} to completely override consumed {1}."), + + /** no parameters required */ + CLF_FIELD_CONST_FINAL(ERROR, "A field may not be declared both final and const."), + + /** no parameters required */ + CLF_FIELD_CONST_STATIC(ERROR, "All const fields are static. Remove unnecessary modifier 'static'."), + + /** 0: name of const field */ + CLF_FIELD_CONST_MISSING_INIT(ERROR, "Const field {0} must be provided with an initializer."), + + /** no parameters required */ + CLF_FIELD_FINAL_STATIC(ERROR, "A field may not be declared both final and static. Use a const field instead."), + + /** 0: name of final field */ + CLF_FIELD_FINAL_MISSING_INIT(ERROR, + "Final field {0} must be provided with an initializer or must be initialized in the constructor."), + + /** 0: name of final field */ + CLF_FIELD_FINAL_MISSING_INIT_IN_STATIC_POLYFILL(ERROR, + "Final field {0} must be provided with an initializer or must be initialized in the constructor. HINT: You might want to check the polyfilled constructor."), + + /** 0: name of final field (that has an initializer expression) */ + CLF_FIELD_FINAL_REINIT_IN_CTOR(ERROR, + "Final field {0} has an initializer and may therefore not be initialized in the constructor."), + + /** no parameters required */ + CLF_FIELD_OPTIONAL_OLD_SYNTAX(ERROR, + "This syntax for optional fields is no longer allowed. Place the ? right after the field's name."), + + /** no parameters required */ + CLF_IMPLEMENT_EXTEND_WITH_WILDCARD(ERROR, + "Wildcards may not be used as type argument when declaring an extended or implemented type."), + + /** + * 0: 'implement' or 'extend', 0: name of interface, 1: name of type variable, 2: comma-separated list of type + * arguments + */ + CLF_IMPLEMENT_EXTEND_SAME_INTERFACE_INCONSISTENTLY(ERROR, + "Cannot {0} interface {1} multiple times with different type arguments for {2}: {3}."), + + /** + * 0: overridden description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 1: + * overriding description ({@link ValidatorMessageHelper/**descriptionDifferentFrom(TMember,TMember)}, 2: additional + * error information + */ + CLF_IMPLEMENT_MEMBERTYPE_INCOMPATIBLE(ERROR, "Cannot implement {0} with {1}.{2}"), + + /** 0: descriptions of missing members, 1: the consumer */ + CLF_IMPLEMENT_MIXIN_CONFLICTS(ERROR, "The {0} cannot be mixed in {1} due to conflicts."), + + /** 0: name of the current classifier, 1: abstract non overridden descriptions */ + CLF_MISSING_IMPLEMENTATION(ERROR, "Class {0} must either be declared abstract or implement {1}."), + + /** 0: name of the current classifier, 1: abstract non overridden descriptions */ + CLF_MISSING_IMPLEMENTATION_EXT(WARNING, + "External class {0} must either be declared abstract or explicit declare {1}."), + + /** 0: class, method, getter or setter */ + CLF_ABSTRACT_FINAL(ERROR, "An abstract {0} cannot be declared final."), + + /** no parameters required, will be changed to error (IDE-1236) */ + CLF_NO_FINAL_INTERFACE_MEMBER(WARNING, "In interfaces, only methods may be declared final."), + + /** no parameters required */ + CLF_NO_THIS_IN_STATIC_FIELD(ERROR, "The 'this' literal may not be used in initializers of static data fields."), + + /** no parameters required */ + CLF_NO_THIS_IN_FIELD_OF_INTERFACE(ERROR, + "In interfaces, the 'this' literal may not be used in initializers of data fields."), + + /** no parameters required */ + CLF_NO_THIS_IN_STATIC_MEMBER_OF_INTERFACE(ERROR, + "In interfaces, the 'this' literal may not be used in static methods or field accessors and in initializers of static data fields."), + + /** no parameters required */ + CLF_INVALID_ACCESS_OF_STATIC_MEMBER_OF_INTERFACE(ERROR, + "Static members of interfaces may only be accessed directly via the type name of their containing interface."), + + /** 0: method, getter or setter, 1: name of method/getter/setter */ + CLF_STATIC_ABSTRACT(ERROR, "The {0} {1} may not be both static and abstract."), + + /** no parameters required */ + CLF_ABSTRACT_BODY(ERROR, "Abstract methods do not specify a body."), + + /** 0: method, getter or setter, 1: member name, 2: class name */ + CLF_ABSTRACT_MISSING(ERROR, "The abstract {0} {1} in class {2} can only be defined in an abstract class."), + + /** 0: method, getter or setter, 1: member name */ + CLF_MISSING_BODY(ERROR, "The {0} {1} has to have either a body or must be defined abstract."), + + /** no parameters required */ + CLF_MISSING_CTOR_BODY(ERROR, "Constructors must have a body."), + + /** no parameters required */ + CLF_VOID_ACCESSOR(ERROR, "Void is not a valid type for getters and setters."), + + /** 0: accessor description, 1: verb, 2: missing accessor type */ + CLF_UNMATCHED_ACCESSOR_OVERRIDE(ERROR, "{0} cannot be {1} without overriding the corresponding {2}."), + + /** 0: accessor description, 1: verb, 2: missing accessor type */ + CLF_UNMATCHED_ACCESSOR_OVERRIDE_JS(WARNING, "{0} should not be {1} without overriding the corresponding {2}."), + + /** 0: interface name */ + CLF_MULTIPLE_ROLE_CONSUME(ERROR, "Cannot consume {0} multiple times."), + + /** 0: 'Classes' or 'Roles' */ + CLF_EXT_EXTERNAL_N4JSD(ERROR, "{0} declared as external have to be placed in a file with file extension 'n4jsd'."), + + /** none */ + CLF_EXT_PROVIDED_BY_RUNTIME_IN_RUNTIME_TYPE(ERROR, + "Only runtime environments/libraries may specify elements provided by runtime."), + + /** no parameters required */ + CLF_EXT_UNALLOWED_N4JSD(ERROR, + "Only namespaces, classes, interfaces, enums, type aliases and functions declared as external as well as structurally typed interfaces are allowed in n4jsd files."), + + /** no parameters required */ + CLF_EXT_EXPORTED(ERROR, "External elements have to be marked with modifier export."), + + /** no parameters required */ + CLF_EXT_NOT_ANNOTATED_EXTEND_N4OBJECT(ERROR, + "External classes annotated with @EcmaScript are not allowed to inherit from n4js classes."), + + /** 0: classes or interfaces */ + CLF_EXT_CONSUME_NON_EXT(ERROR, "External {0} are not allowed to consume a non external interface."), + + /** 0: classes or interfaces */ + CLF_EXT_IMPLEMENTS_NON_EXT(ERROR, "External {0} are not allowed to implement an interface from a non n4jsd file."), + + /** 0: classes or interfaces */ + CLF_EXT_PUBLIC(ERROR, "External {0} have to be marked as public (and without @Internal)."), + + /** no parameters required */ + CLF_EXT_INTF_PUBLIC(ERROR, + "Structural typed interfaces in n4jsd files have to be marked as public (and without @Internal)."), + + /** 0: classes or interfaces */ + CLF_EXT_EXTERNAL(ERROR, "External {0} have to be marked as external in n4jsd files."), + + /** 0: methods, getters or setters, 1: classes or interfaces */ + CLF_EXT_NO_METHOD_BODY(ERROR, "{0} in external {1} have to have no body."), + + /** 0: classes or interfaces */ + CLF_EXT_NO_FIELD_EXPR(ERROR, "Fields in external {0} have to have no right side."), + + /** no parameters required */ + CLF_EXT_PUBLIC_CONSTRUCTOR(ERROR, "External classes annotated with @EcmaScript have to have a public constructor."), + + /** 0: classes or interfaces */ + CLF_EXT_NO_OBSERV_ANNO(ERROR, "External {0} must not have the Observable annotation."), + + /** 0: methods, getters or setters, 1: classes or interfaces, 2: Observable or Nfon */ + CLF_EXT_METHOD_NO_ANNO(ERROR, "{0} in external {1} must not have the {2} annotation."), + + /** no parameters required */ + CLF_EXT_LITERAL_NO_VALUE(ERROR, "An enumeration literal in a n4jsd file isn't allowed to define a value."), + + /** no parameters required */ + CLF_EXT_FUN_NO_BODY(ERROR, "External function declarations have to have no body."), + + /** 0 var or constant */ + CLF_EXT_VAR_NO_VAL(ERROR, "External {0} declaration cannot be initialized."), + + /** spec: Component/Manifest/General-Constraint, no parameters required */ + CLF_EXT_NO_MATCH(WARNING, + "For the given n4jsd file no corresponding external file resp. no matching implemented by expression can be found."), + + /** + * doc: validate duplicates between src/src-test and external (so there is e.g. file A.n4js that compiles to A.js + * that would be name conflict with A.js in external), spec: Component/Manifest/General-Contraint, 0: file, 1: path + */ + CLF_EXT_DUPLICATE_PATH_SRC_EXTERNAL(ERROR, "Duplicate external file {0}, has been already defined in {1}."), + + /** no parameters required */ + CLF_IN_DEFINITION_PRJ_NON_N4JS(WARNING, + "Class declarations in definition projects should be annotated with @EcmaScript."), + + /** 0: annotation name, 1: type (interface or classifier) */ + CLF_EXT_PROVIDES_IMPL_ONLY_IN_DEFFILES(ERROR, "@{0} must only be used in external {1} in n4jsd files."), + + /** 0: annotation name, 1: type (interface or classifier) */ + CLF_EXT_PROVIDES_IMPL_ONLY_IN_INTERFACE_MEMBERS(ERROR, "@{0} must only be used in {1}."), + + /** 0: annotation name, 1: type (interface or classifier) */ + CLF_EXT_PROVIDES_IMPL_ONLY_IN_N4JS_INTERFACES(ERROR, "@{0} must only be used in n4js interfaces or classes."), + + /** 0: type name, 1: access modifier name */ + CLF_LOW_ACCESSOR_WITH_INTERNAL(ERROR, "A {0} with visibility {1} shouldn't be annotated with @Internal."), + + /** 0: 'extend' or 'implement', 1: type name, 2: description of members causing problems */ + CLF_NON_ACCESSIBLE_ABSTRACT_MEMBERS(ERROR, + "Cannot {0} {1}: cannot implement one or more non-accessible abstract members: {2}."), + + /** no parameters required */ + CLF_MINIMAL_ACCESSIBILITY_IN_INTERFACES(ERROR, "Members of interfaces must not be declared private."), + + /** no parameters required */ + CLF_SPEC_WRONG_TYPE(ERROR, "Annotation @Spec may only be used with formal parameters of type ~i~this."), + + /** 0: name of field, 1: type of member, 2: type system error message */ + CLF_SPEC_WRONG_ADD_MEMBERTYPE(ERROR, + "Type of structural member {0} of spec parameter must be a subtype of {1}: {2}."), + + /** no parameters required */ + CLF_SPEC_MULTIPLE(ERROR, "Only a single formal parameter in each constructor may be annotated with @Spec."), + + /** 0: name of the superfluous property, 1: the type not defining the property */ + CLF_SPEC_SUPERFLUOUS_PROPERTIES(WARNING, + "{0} is not defined in {1}; it will not have any effect in the spec constructor."), + + /** + * 0: name of the superfluous property, 1: the type not defining the property, 2: name of variable the object + * literal is assigned to + */ + CLF_SUPERFLUOUS_PROPERTIES(WARNING, "{0} is not defined in {1}; it will not be accessible from {2}."), + + /** 0: name of the property, {1} built-in/provided by runtime interface */ + CLF_SPEC_BUILT_IN_OR_PROVIDED_BY_RUNTIME_OR_EXTENAL_WITHOUT_N4JS_ANNOTATION(WARNING, + "{0} is a property of a built-in, provided by runtime, or external module with @EcmaScript annotation. Hence the interface {1} can not be initialized in a spec constructor."), + + /** 0:the cycle */ + CLF_INHERITANCE_CYCLE(ERROR, "Inheritance cycle detected: {0}."), + + /** no param */ + CLF_INTERNAL_BAD_WITH_PRIVATE_OR_PROJECT(ERROR, "@Internal is only allowed for public and protected."), + + /** no param */ + CLF_CANNOT_CALL_ABSTRACT_SUPER_METHOD(ERROR, "Cannot call super method since it is abstract."), + + /** no param */ + CLF_CANNOT_REFER_TO_DEFAULT_METHOD_WITH_SUPER(ERROR, + "Cannot refer to default method of an implemented interface with super."), + + /** 0: name of polyfill, 1: 'class' or 'interface' including indefinite article */ + CLF_POLYFILL_EXTEND_MISSING(ERROR, "Polyfill {0} must explicitly extend {1}."), + + /** 0: name of polyfill */ + CLF_POLYFILL_NO_TOPLEVEL(ERROR, "Polyfill {0} can only extend top level class declaration."), + + /** + * 0: 'class' or 'interface', 1: name of correct classifier kind (without article), 2: name of correct classifier + * kind including indefinite article, 3: name of *incorrect* classifier kind including indefinite article + */ + CLF_POLYFILL_DIFFERENT_CLASSIFIER_KIND(ERROR, "Polyfill for {0} {1} must be {2}, not {3}."), + + /** 0: name of polyfill, 1: 'class' or 'interface', 2: name of extended class */ + CLF_POLYFILL_DIFFERENT_NAME(ERROR, "Name of polyfill {0} must equal name of filled {1} {2}."), + + /** 0: name of polyfill, 1: name polyfill's module, 2: name of filled class' module */ + CLF_POLYFILL_DIFFERENT_MODULE_SPECIFIER(ERROR, + "Specifier {1} of module containing polyfill {0} must equal name of filled classes module specifier {2}."), + + /** 0: name of polyfill, 1: global/not global polyfill module, 2: not/empty global polyfill */ + CLF_POLYFILL_DIFFERENT_GLOBALS(ERROR, "Module containing polyfill {0} is {1}, but filled classes module is {2}."), + + /** 0: name of polyfill */ + CLF_POLYFILL_FILLED_NOT_PROVIDEDBYRUNTIME(ERROR, "Polyfill {0} cannot fill class not provided by runtime."), + + /** 0: name of polyfill */ + CLF_POLYFILL_NOT_PROVIDEDBYRUNTIME(ERROR, "Polyfill {0} must be provided by runtime."), + + /** 0: name of polyfill */ + CLF_POLYFILL_NO_IMPLEMENTS(ERROR, "Polyfill {0} must not implement any interfaces."), + + /** 0: name of polyfill */ + CLF_POLYFILL_NO_EXTENDS_ADDITIONAL(ERROR, "Polyfill {0} must not extend any additional interfaces."), + + /** 0: name of polyfill */ + CLF_POLYFILL_NOT_DIRECTLY_EXPORTED(ERROR, "Polyfill {0} must be exported."), + + /** 0: name of polyfill, 1: name of polyfill modifier, 2: name of filled modifier, 3: 'class' or 'interface' */ + CLF_POLYFILL_DIFFERENT_MODIFIER(ERROR, + "Polyfill {0} cannot be declared {1}, must be defined {2} just as the filled {3}."), + + /** 0: name of polyfill, 1: type system error message */ + CLF_POLYFILL_CTOR_NOT_OVERRIDE_COMPATIBLE(ERROR, + "Constructor of polyfill {0} must be override compatible with inherited constructor: {1}"), + + /** 0: name of polyfill, 1: 'class' or 'interface' */ + CLF_POLYFILL_DIFFERENT_TYPEPARS(ERROR, "Polyfill {0} must declare same type parameters as the filled {1}."), + + /** 0: name of polyfill */ + CLF_POLYFILL_INCOMPLETE_TYPEARGS(ERROR, + "Polyfill {0} must pass all type parameters to type arguments (even optional ones)."), + + /** 0: name of polyfill, 1: type par, 2: type arg */ + CLF_POLYFILL_TYPEPARS_DIFFER_TYPEARGS(ERROR, + "Polyfill {0} must pass type parameters to type arguments in same order and without modifications, but {1} differs from {2}."), + + /** 0: list of modules name with polyfills, 0: member name */ + CLF_POLYFILL_MULTIPOLYFILLS_MEMBER_CONFLICT(ERROR, + "Polyfills in {0} provide member {1} - only one provider per member is allowed."), + + /** 0: name of polyfill */ + CLF_POLYFILL_STATIC_FILLED_TYPE_NOT_AWARE(ERROR, + "For static polyfills, the module of the filled type {0} must be annotated with @StaticPolyfillAware."), + + /** 0: name of polyfill, 1: file extension (.n4js or .n4jsd) */ + CLF_POLYFILL_STATIC_DIFFERENT_VARIANT(ERROR, + "Since static polyfill {0} is declared in an {1} file, the filled type must also be declared in an {1} file."), + + /** 0: string that is used as name for more than one literal */ + ENM_DUPLICTAE_LITERALS(ERROR, "Multiple literals with name {0}."), + + /** no parameters required */ + ENM_INVALID_VALUE_EXPRESSION(ERROR, + "Only string literals and number literals are allowed as value of an enum literal."), + + /** 0: string with the name of the meta property */ + ENM_LITERALS_HIDE_META(ERROR, "EnumLiteral cannot have the same name as Enum meta property <{0}>."), + + /** no parameters required */ + ENM_WITHOUT_LITERALS(ERROR, "An enum type must declare at least one literal."), + + /** no parameters required */ + ENM_BOTH_NUMBER_AND_STRING_BASED(ERROR, "An enum may not be annotated with both @NumberBased and @StringBased."), + + /** no parameters required */ + ENM_ILLEGAL_NUMERIC_VALUE(ERROR, "Values of type number may only be used for literals of @NumberBased enums."), + + /** no parameters required */ + ENM_ILLEGAL_STRING_VALUE(ERROR, "Values of literals in @NumberBased enums must be of type number."), + + /** no parameters required */ + ENM_INVALID_USE_OF_NUM_OR_STR_BASED_ENUM(ERROR, + "A @NumberBased or @StringBased enum may only be used in type annotations and in property access expressions to access either one of its literals or the static getter called 'literals'."), + + /** no parameters required */ + /** + * ITF_MEMBER_ACCESSIBILITY(ERROR, "Member of an interface must not have lower accessibility than the containing + * interface."), + */ + /** no parameters required */ + ITF_NO_FINAL(ERROR, "Interfaces must not be declared final."), + + /** 0: name of field, 1: name of interface */ + ITF_NO_FIELD_INITIALIZER(ERROR, + "Cannot initialize field in interface. Only classes or interfaces implementing {1} can initialize {0}."), + + /** 0: property kind name, 1: structural /nominal / */ + ITF_NO_PROPERTY_BODY(ERROR, "{0} in {1}interfaces must not have a body."), + + /** no parameters required */ + ITF_CONSTRUCTOR_COVARIANCE(ERROR, "Constructors in interfaces must be annotated with @CovariantConstructor."), + + /** no parameters required */ + ITF_IN_DEFINITION_PRJ_NON_N4JS(WARNING, + "Nominal interface declarations in definition projects should instead be structural (use '~')."), + + /** no parameters required */ + STRCT_ITF_CANNOT_EXTEND_INTERFACE(ERROR, "Structural interfaces cannot extend nominal interfaces."), + + /** no parameters required */ + STRCT_ITF_CANNOT_CONTAIN_STATIC_MEMBERS(ERROR, "Structural interfaces cannot contain static members."), + + /** no parameters required */ + STRCT_ITF_MEMBER_MUST_BE_PUBLIC(WARNING, "Non-public members of structural interfaces are effectless."), + + /** 0: name of cyclic type aliases */ + ALI_CYCLIC_TYPE_ALIAS(ERROR, "Cyclic type alias declaration: {0}."), + + /** no parameters required */ + ALI_INVALID_MODIFIER(ERROR, "A type alias may be referenced {0} only if its aliased type may be referenced {0}."), + + /** 0: the string '{}' */ + ALI_INVALID_TYPE_ALIAS_IN_TYPE_TYPE_REF(ERROR, + "A type alias may be used inside type{0} or constructor{0} only if its aliased type may be used at this location."), + + /** 0: passed parameter count, 1: expected parameter count */ + FUN_PARAM_COUNT(ERROR, "Passed parameter count {0} doesn't match with expected parameter count {1}."), + + /** no parameters required */ + FUN_BLOCK(WARNING, + "Functions declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function."), + + /** no parameters required */ + FUN_BODY(ERROR, "Functions have to have a body."), + + /** 0: element description, 1: conflicting category */ + FUN_NAME_RESERVED(ERROR, "{0} may be confused with {1}."), + + /** no parameters */ + FUN_NAME_MISSING(ERROR, "Function declarations must have a name."), + + /** 0: formal parameter */ + FUN_PARAM_OPTIONAL_WRONG_SYNTAX(ERROR, "Wrong syntax: Use {0}=undefined instead of ?."), + + /** no parameters */ + FUN_PARAM_INITIALIZER_ILLEGAL_FORWARD_REFERENCE(ERROR, + "Illegal forward reference to formal parameter of same function."), + + /** no parameters */ + FUN_PARAM_INITIALIZER_ONLY_UNDEFINED_ALLOWED(ERROR, + "Only 'undefined' allowed for initializers of default parameters in function types."), + + /** 0: formal parameter */ + /** 1: identifier */ + FUN_PARAM_INITIALIZER_ILLEGAL_REFERENCE_TO_BODY_VARIABLE(ERROR, + "Initializer of parameter '{0}' cannot reference the identifier '{1}' declared in the body."), + + /** 0: formal parameter */ + FUN_PARAM_INITIALIZER_ILLEGAL_AWAIT_CALL(ERROR, + "Illegal await-expression in initializer of formal parameter '{0}'."), + + /** + * 0: name of actually used generator type, 1: expected generator kind (synchronous or asynchronous), 2: name of + * expected generator type + */ + FUN_GENERATOR_RETURN_TYPE_MISMATCH(WARNING, + "Type {0} is intended for {1} generator functions; consider using type {2} instead."), + + /** no parameters required */ + AST_SEPARATE_DEFAULT_EXPORT_WITHOUT_FROM(ERROR, "Missing from-clause in default re-export."), + + /** 0: element, 1: kind of value */ + AST_ELEMENT_MISUSED_AS_VALUE_OR_TYPE(ERROR, "{0} cannot be used as a {1}."), + + /** no parameters required */ + AST_INVALID_NEW_TARGET(ERROR, "Invalid new.target."), + + /** no parameters required */ + AST_INVALID_YIELD_EXPRESSION(ERROR, + "The parameter initializer of a generator may not contain a `yield` expression."), + + /** no parameters required */ + AST_CONST_IN_STATEMENT_POSITION(ERROR, "Const variable statements must be on the top level or nested in a block."), + + /** no parameters required */ + AST_LET_IN_STATEMENT_POSITION(ERROR, "Let declarations may not appear in statement position."), + + /** 0: name of blank const variable */ + AST_CONST_HAS_NO_INITIALIZER(ERROR, "Const variable {0} must be provided with an initializer."), + + /** no parameters required */ + AST_STR_NO_OCTALS(ERROR, "octal literals and octal escape sequences are not allowed in strict mode."), + + /** 0: operand (decrement or increment) */ + AST_INVALID_OPERAND(ERROR, "Invalid {0} operand."), + + /** no parameters required */ + AST_EXP_INVALID_LHS_ASS(ERROR, "Invalid assignment left-hand side."), + + /** 0: identifier */ + AST_RESERVED_IDENTIFIER(ERROR, "{0} is a reserved identifier."), + + /** no parameters required */ + AST_STR_NO_WITH_STMT(ERROR, "With statement not allowed."), + + /** no parameters required, not used yet in AST, was before in N4JSStrictValidator */ + AST_STR_FUN_NOT_NESTED(ERROR, "Functions must only be declared on script level or as part of other expressions"), + + /** no parameters required */ + AST_INVALID_RETURN(ERROR, "return statement without enclosing function"), + + /** no parameters required */ + AST_INVALID_CONTINUE(ERROR, "continue statement without enclosing iteration"), + + /** no parameters required */ + AST_INVALID_BREAK(ERROR, "break statement without enclosing iteration or case block"), + + /** no parameters required */ + AST_INVALID_LABEL(ERROR, "Label must be of an enclosing iteration statement but may not cross function boundaries"), + + /** no parameters required */ + AST_THIS_WRONG_PLACE(ERROR, + "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)"), + + /** 0: variable name */ + AST_VAR_DECL_RECURSIVE(WARNING, + "Reference to variable {0} within the initializer expression of the declaration of {0}."), + + /** no parameters required */ + AST_VAR_DECL_IN_FOR_INVALID_INIT(ERROR, + "The iteration variable of a for..in or for..of loop must not be provided with an initializer."), + + /** no parameters required */ + AST_INVALID_FOR_AWAIT(ERROR, "Only for..of loops may be used for asynchronous iteration with 'for await'."), + + /** no parameters required */ + AST_INVALID_OPTIONAL_TYPE_PARAMS(ERROR, + "Only type parameters of classes, interfaces, and type aliases may be declared optional."), + + /** no parameters required */ + AST_NO_TYPE_ARGS_IN_CLASSIFIERTYPEREF(ERROR, "Only raw types can be used in classifier type references."), + + /** no parameters required */ + AST_NO_FUNCTIONTYPEREFS_IN_CLASSIFIERTYPEREF(ERROR, + "Function types are not allowed in classifier type references."), + + /** no parameters required */ + AST_INVALID_EXPR_IN_LHS_DESTRUCTURING_PATTERN(ERROR, + "Only a variable or nested destructuring pattern is allowed at this location within a destructuring pattern."), + + /** no parameters required */ + AST_INVALID_PROPERTY_METHOD_IN_LHS_DESTRUCTURING_PATTERN(ERROR, + "Property methods are not allowed within an object destructuring pattern."), + + /** no parameters required */ + AST_INVALID_DEFAULT_EXPR_SINGLE_NAME_PROPERTY(ERROR, + "A default value is only allowed within a destructuring pattern."), + + /** no parameters required */ + AST_REST_MUST_APPEAR_AT_END(ERROR, "Rest operator only allowed on last element in an array destructuring pattern."), + + /** no parameters required */ + AST_REST_WITH_INITIALIZER(ERROR, "Rest operator does not support an initializer."), + + /** no parameters required */ + AST_TYPE_DECL_MISSING_NAME(ERROR, "Name missing in type declaration."), + + /** no type annotation for catch variable */ + AST_CATCH_VAR_TYPED(ERROR, "Catch variable must not be typed."), + + /** 0: name of the JavaScript variant of the context */ + AST_TOP_LEVEL_STATEMENTS(ERROR, "Top-level statements are not supported in {0} files."), + + /** No parameters */ + AST_VAR_STMT_NO_DECL(ERROR, "A variable statement must at least contain one variable declaration."), + + /** 0: script annotation name */ + AST_SCRIPT_ANNO_INVALID_PLACEMENT(ERROR, "The script annotation @@{0} must be placed at the top of the module."), + + /** 0: Forbidden Type e.g. null / undefined */ + AST_BINARY_LOGICAL_EXPRESSION_MISSING_PART(ERROR, "The logical expression is missing the {0}."), + + /** no parameters required */ + AST_IMPORT_CALL_SPREAD(ERROR, "The spread operator is not allowed in import calls."), + + /** 0: Invalid parent e.g. && / || */ + AST_INVALID_COALESCE_PARENT(ERROR, "Nullish coalescing expressions cannot be contained within an {0} operation. "), + + /** 0: Invalid child e.g. && / || */ + AST_INVALID_COALESCE_CHILD(ERROR, "Nullish coalescing expressions cannot immediately contain an {0} operation."), + + /** 0: local variable name */ + CFG_LOCAL_VAR_UNUSED(WARNING, "The local variable {0} is never used"), + + /** 0: local variable name */ + CFG_USED_BEFORE_DECLARED(WARNING, "Variable {0} is used before it is declared"), + + /** 0: local variable name */ + /** 1: 'is' or 'may be' */ + /** 2: 'null' or 'undefined' */ + /** 3: reason (optional) */ + DFG_NULL_DEREFERENCE(WARNING, "Variable {0} {1} {2}{3}"), + + /** 0: shadowing object, 1: shadowed object */ + AST_NAME_SHADOW_WARN(WARNING, "{0} shadows {1}."), + + /** 0: shadowing object, 1: shadowed object */ + AST_NAME_SHADOW_ERR(ERROR, "{0} shadows {1}."), + + /** 0: hiding parameter 1: hidden parameter */ + AST_GLOBAL_NAME_SHADOW_ERR(ERROR, "{0} shadows {1} from global scope."), + + /** 0: name */ + AST_GLOBAL_JS_NAME_CONFLICT(ERROR, "Globally defined element named {0} must be defined in runtime environment."), + + /** 0: name */ + AST_GLOBAL_NAME_CONFLICT(ERROR, "Globally defined element must not be named {0}."), + + /** 0: duplicating object, 1: duplicated object */ + AST_NAME_DUPLICATE_ERR(ERROR, "{0} duplicates {1}."), + + /** 0: duplicating object, 1: duplicated object */ + AST_NAME_DUPLICATE_WARN(WARNING, "{0} duplicates {1}."), + + /** 0: grammar rule, 1: value */ + VCO_DOUBLE_NEGATIVE(ERROR, "{0}-value may not be negative (value: {1})."), + + /** no parameters required */ + VCO_DOUBLE_CONVERT_EMPTY_STR(ERROR, "Couldn't convert empty string to a double value."), + + /** 0: the string value */ + VCO_DOUBLE_CONVERT_STR(ERROR, "Couldn't convert {0} to a double value."), + + /** 0: grammar rule, 1: value */ + VCO_HEXINT_NEGATIVE(ERROR, "{0}-value may not be negative (value: {1})."), + + /** no parameters required */ + VCO_HEXINT_CONVERT_EMPTY_STR(ERROR, "Couldn't convert empty string to an hex int value."), + + /** 0: the string value */ + VCO_HEXINT_CONVERT_TOO_SHORT(ERROR, "Couldn't convert {0} to an int value."), + + /** 0: the string value */ + VCO_HEXINT_CONVERT_STR(ERROR, "Couldn't convert {0} to an hex int value."), + + /** 0: grammar rule, 1: value */ + VCO_BINARYINT_NEGATIVE(ERROR, "{0}-value may not be negative (value: {1})."), + + /** no parameters required */ + VCO_BINARYINT_CONVERT_EMPTY_STR(ERROR, "Couldn't convert empty string to a binary int value."), + + /** 0: the string value */ + VCO_BINARYINT_CONVERT_TOO_SHORT(ERROR, "Couldn't convert {0} to an int value."), + + /** 0: the string value */ + VCO_BINARYINT_CONVERT_STR(ERROR, "Couldn't convert {0} to a binary int value."), + + /** 0: grammar rule, 1: value */ + VCO_OCTALINT_NEGATIVE(ERROR, "{0}-value may not be negative (value: {1})."), + + /** no parameters required */ + VCO_OCTALINT_CONVERT_EMPTY_STR(ERROR, "Couldn't convert empty string to an octal int value."), + + /** 0: the string value */ + VCO_OCTALINT_CONVERT_TOO_SHORT(ERROR, "Couldn't convert {0} to an int value."), + + /** 0: the string value */ + VCO_OCTALINT_LEADING_ZEROS(ERROR, "Don't use extra leading zeros {0}."), + + /** 0: the string value */ + VCO_OCTALINT_CONVERT_STR(ERROR, "Couldn't convert {0} to an octal int value."), + + /** 0: grammar rule, 1: value */ + VCO_SCIINT_NEGATIVE(ERROR, "{0}-value may not be negative (value: {1})."), + + /** no parameters required */ + VCO_SCIINT_CONVERT_EMPTY_STR(ERROR, "Couldn't convert empty string to an scientific int value."), + + /** 0: the string value */ + VCO_SCIINT_CONVERT_STR(ERROR, "Couldn't convert {0} to an scientific int value."), + + /** 0: identifier, 1: position */ + VCO_IDENT_ESCAPE_SEQ(ERROR, "Illegal escape sequence in identifier {0} at position {1}."), + + /** 0: result, 1: identifier, 2: position */ + VCO_IDENT_ILLEGAL_CHAR_WITH_RESULT(ERROR, "Illegal character in identifier '{0}' ({1}) at position {2}."), + + /** 0: identifier, 1: position */ + VCO_IDENT_ILLEGAL_CHAR(ERROR, "Illegal character in identifier '{0}' at position {1}."), + + /** no parameters required */ + VCO_JSXIDENT_WHITESPACE_COMMENT(ERROR, + "JSX attribute names may not contain whitespace or comments. Attribute names ending with a '-' and directly followed by another attribute name are merged and must not contain whitespace or comments."), + + /** no parameters required */ + VCO_STRING_DOUBLE_QUOTE(ERROR, "String literal is not properly closed by a double-quote."), + + /** no parameters required */ + VCO_STRING_QUOTE(ERROR, "String literal is not properly closed by a quote."), + + /** no parameters required */ + VCO_TEMPLATE_QUOTE(ERROR, "Template literal is not properly closed by a backtick."), + + /** no parameters required */ + VCO_TEMPLATE_MIDDLE(ERROR, "Template literal is not properly closed by ${."), + + /** no parameters required */ + VCO_TEMPLATE_IN_OPT_CHAIN(ERROR, "Tagged template expressions are not permitted in an optional chain."), + + /** no parameters required */ + VCO_STRING_BAD_ESCAPE_WARN(WARNING, "Bad escapement"), + + /** no parameters required */ + VCO_STRING_BAD_ESCAPE_ERROR(ERROR, "Bad escapement"), + + /** no parameters required */ + VCO_REGEX_INVALID(ERROR, "Invalid regular expression literal"), + + /** 0: literal */ + VCO_REGEX_ILLEGAL_ESCAPE(ERROR, "Illegal escape sequence in regular expression {0}"), + + /** no parameters required */ + VCO_REGEX_NAMED_GROUP(WARNING, "Named capture groups are not supported on all platforms."), + + /** no parameters required */ + VCO_NPE(ERROR, + "A NullPointerException occurred. This indicates a missing value converter or a bug in its implementation."), + + /** 0: feature name */ + VCO_NULL_FEATURE(ERROR, "ValueConverter returned null for primitive feature {0}"), + + /** no parameters required */ + BIT_SYMBOL_INVALID_USE(ERROR, + "Invalid use of 'Symbol': may only be used to create symbols (i.e. Symbol()) or to access built-in symbols (e.g. Symbol.iterator)."), + + /** no parameters required */ + BIT_SYMBOL_NOT_A_CTOR(ERROR, "Symbol is not a constructor, use Symbol() without new."), + + /** no parameters required */ + TYS_MISSING(ERROR, "Types model hasn't been built for this file. Please report this bug to a N4JS developer."), + + /** 0: expression */ + TYS_CANNOT_TYPE(ERROR, "cannot type {0}."), + + /** 0: left expression, 1: right expression */ + TYS_NO_SUBTYPE(ERROR, "{0} is not a subtype of {1}"), + + /** 0: expected type, 1: actual type */ + TYS_NO_SUPERTYPE_WRITE_ACCESS(ERROR, "expecting write-access for type {0} but {1} is not a super type of {0}."), + + /** no parameters required */ + TYS_NULL_OBJECT(ERROR, "passed null object to system at {0}."), + + /** no parameters required */ + TYS_VOID_AT_WRONG_LOCATION(ERROR, + "Type 'void' may only be used to declare the return type of functions and methods."), + + /** 0: member type, 1: member name, 2: type name */ + TYS_MEMBER_NOT_IN_STRUCTURAL_TYPE_DEF_SITE(ERROR, "{0} {1} is not available for structurally defined type {2}."), + + /** 0: member type, 1: member name, 2: type name */ + TYS_MEMBER_NOT_IN_STRUCTURAL_TYPE_USE_SITE(ERROR, "{0} {1} is not available for structurally referenced type {2}."), + + /** 0: member type, 1: member name, 2: type name */ + TYS_MEMBER_NOT_IN_STRUCTURAL_FIELDS_TYPE_USE_SITE(ERROR, + "{0} {1} is not available for fields-only-referenced type {2}."), + + /** no parameters required */ + TYS_INSTANCEOF_NOT_SUPPORTED_FOR_USE_SITE_STRUCTURAL(ERROR, + "'instanceof' cannot be used with use site structural typing."), + + /** 0: type name */ + TYS_INSTANCEOF_NOT_SUPPORTED_FOR_BUILT_IN_INTERFACES(ERROR, + "'instanceof' cannot be used with built-in interface {0}."), + + /** no parameters required */ + TYS_INSTANCEOF_NOT_SUPPORTED_FOR_PRIMITIVE_TYPES(ERROR, "'instanceof' cannot be used with primitive types."), + + /** 0: property name */ + TYS_PROPERTY_HAS_NO_SETTER(ERROR, "Property {0} has no setter."), + + /** 0: type name */ + TYS_PRIMITIVE_TYPE_DYNAMIC(ERROR, "Primitive type {0} must not be referenced dynamically."), + + /** no parameters required */ + TYS_COMPOUND_MISSING_GETTER(ERROR, "Missing getter on left-hand side of compound assignment."), + + /** no parameters required */ + TYS_NON_VOID_ASYNC(ERROR, + "Internal error: Only Promise allowed as inferred return type of an async FunctionDefinition"), + + /** no parameters required */ + TYS_NON_THIS_ASYNC(ERROR, "The return type of an async function is not allowed to refer to the this-type."), + + /** 0: type name */ + TYS_FOR_IN_VAR_STRING(ERROR, "Type of for-in-loop variable must be a super type of string but {0} is not."), + + /** no parameters required */ + TYS_ADDITIONAL_STRUCTURAL_MEMBERS_ON_TYPE_VARS(ERROR, + "No additional structural members allowed on type variables, since they can cause collisions."), + + /** no parameters required */ + TYS_FUNCTION_DISALLOWED_AS_TYPE(ERROR, "The name of a declared function may not be used as a type name."), + + /** no parameters required */ + TYS_STRUCTURAL_PRIMITIVE(WARNING, "Structural type operator ~ does not have any effect on primitive types."), + + /** no parameters required */ + EXP_USE_OF_UNDEF_EXPR(WARNING, + "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'."), + + /** 0: actual type */ + EXP_CALL_NOT_A_FUNCTION(ERROR, "Not a function or method: {0}."), + + /** 0: comma-separated list of conflicting callable type references */ + EXP_CALL_CONFLICT_IN_INTERSECTION(ERROR, "More than one callable type in intersection: {0}."), + + /** no parameters required */ + EXP_CALL_CLASS_CTOR(ERROR, "Cannot directly invoke class constructor functions; use 'new' instead."), + + /** 0: actual type */ + EXP_NEW_NOT_A_CTOR(ERROR, "Not a reference to a constructor: {0}."), + + /** 0: intersection type with conflicting ctors or construct signatures */ + EXP_NEW_CONFLICT_IN_INTERSECTION(ERROR, "More than one constructor or construct signature in intersection: {0}."), + + /** 0: type arg name of constructor, 1: static type */ + EXP_NEW_WILDCARD_NO_COVARIANT_CTOR(ERROR, + "Cannot instantiate {0}, because {1} does not have a @CovariantConstructor."), + + /** 0: type arg name of constructor */ + EXP_NEW_WILDCARD_OR_TYPEVAR(ERROR, "Cannot instantiate {0}."), + + /** 0: abstract class, interface, 1: classifier name */ + EXP_NEW_CANNOT_INSTANTIATE(ERROR, "Cannot instantiate {0} {1}."), + + /** 0: number of expected type args, 1: number of actual type args */ + EXP_WRONG_NUMBER_OF_TYPEARGS(ERROR, "Incorrect number of type arguments: expected {0}, got {1}."), + + /** + * 0: class, interface, method, function 1: name of classifier/method/function, 2: number of expected type args, 3: + * number of actual type args + */ + EXP_WRONG_NUMBER_OF_TYPEARGS_FOR_ELEMENT(ERROR, + "Incorrect number of type arguments for {0} {1}: expected {2}, got {3}."), + + /** 0: maximum number of element types in an ArrayN */ + EXP_WRONG_NUMBER_OF_TYPEARGS_FOR_ITERABLE_N_SYNTAX(ERROR, + "The ArrayN types are available for a maximum of {0} element types only (i.e. type Array{0})."), + + /** 0: upper or lower, 1: covariant or contravariant */ + EXP_INCONSISTENT_VARIANCE_OF_TYPE_ARG(ERROR, + "Cannot use wildcard with {0} bound as argument to a {1} type parameter."), + + /** 0: covariant or contravariant, 1: covariant or contravariant */ + EXP_INCONSISTENT_VARIANCE_OF_TYPE_ARG_IN_OUT(ERROR, "Cannot combine {0} on use site with {1} on definition site."), + + /** 0: expected num of params, 1: actual num of params */ + EXP_NUM_OF_ARGS_TOO_FEW(ERROR, "Incorrect number of arguments: expected {0}, got {1}."), + + /** 0: expected num of params, 1: actual num of params */ + EXP_NUM_OF_ARGS_TOO_MANY(ERROR, "Incorrect number of arguments: expected {0}, got {1}."), + + /** 0: from type ref, 1: target type ref */ + EXP_CAST_FAILED(ERROR, "Cannot cast from {0} to {1}"), + + /** 0: from type ref, 1: target type ref */ + EXP_CAST_UNNECESSARY(WARNING, "Unnecessary cast from {0} to {1}"), + + /** no parameter required */ + EXP_CAST_INVALID_TARGET(ERROR, + "Can only cast to class, interface, enum, function, primitive, union or intersection types"), + + /** 0: recognized type, 2: result, e.g. NaN */ + EXP_MATH_OPERATION_RESULT_IS_CONSTANT(WARNING, "Operand {0} will always result in {1}."), + + /** 0: recognized type, 1: constant value */ + EXP_MATH_OPERAND_IS_CONSTANT(WARNING, "Operand of type {0} will be interpreted as {1}."), + + /** 0: recognized type, 2: result, e.g. NaN */ + EXP_MATH_TYPE_NOT_PERMITTED(ERROR, "Operand of type {0} cannot be converted to number."), + + /** 0: left type 1: rght type 2: result */ + EXP_WARN_CONSTANT_EQUALITY_TEST(WARNING, + "Neither {0} is a subtype of {1} nor {1} is a subtype of {0}. The expression will always evaluate to {2}."), + + /** 0: Forbidden Type e.g. null / undefined */ + EXP_FORBIDDEN_TYPE_IN_BINARY_LOGICAL_EXPRESSION(ERROR, + "{0} is not allowed on the left hand side of a logical expression."), + + /** 0: member description, 1: type of target, 2: declared this type (from @This annotation) */ + EXP_ACCESS_INVALID_TYPE_OF_TARGET(ERROR, + "Target of property access not a subtype of the declared @This type of {0}: {1} is not a subtype of {2}."), + + /** 0: method name */ + EXP_METHOD_REF_UNATTACHED_FROM_RECEIVER(ERROR, + "A reference to method {0} is created detached from a (correct) this-instance."), + + /** 0: await expression, 1 async annotation */ + EXP_MISPLACED_AWAIT(ERROR, "{0} is allowed only inside functions annotated with {1}."), + + /** no parameter required */ + EXP_MISSNG_AWAIT_FOR_ASYNC_TARGET(WARNING, + "Calling async function without await, Promise should be made explicit."), + + /** 0: Suspicious expression, 1: boolean value, 2:left-hand/right-hand */ + EXP_WARN_DISPENSABLE_CONDITIONAL_EXPRESSION(WARNING, + "Dispensable use of conditional expression. The expression '{0}' always evaluates to {1}, so only the {2} side will ever be evaluated."), + + /** no parameter required */ + EXP_AWAIT_NON_ASYNC(WARNING, + "await should only be used on expressions of type Promise since otherwise it has no effect."), + + /** 0: recognized expression */ + EXP_AWAIT_NON_ASYNC_SPECIAL(WARNING, "await should not be used on '{0}' since it has no effect here."), + + /** no parameter required */ + FUN_RETURNTYPE_VOID_FOR_SETTER_VIOLATED(ERROR, "Set accessors must not return anything."), + + /** 0: name of return type */ + FUN_MISSING_RETURN_EXPRESSION(ERROR, "Return statement must have an expression of type {0}"), + + /** no parameter required */ + FUN_MISSING_RETURN_OR_THROW_STATEMENT(ERROR, "Missing return or throw statement."), + + /** no parameter required */ + FUN_MISSING_ELSE_BRANCH_FOR_CONDITIONAL_LAST_CONTROL_FLOW(ERROR, + "Last if statement on control flow path is missing required else branch."), + + /** no parameter required */ + FUN_MISSING_RETURN_OR_THROW_STATEMENT_WHILE_CANNOT_BE_CHECKED(ERROR, + "Missing return or throw statement after while-expression. Correct termination of while-loops cannot be verified. Please append return/throw."), + + /** no parameter required */ + FUN_MISSING_RETURN_OR_THROW_STATEMENT_FOR_CANNOT_BE_CHECKED(ERROR, + "Missing return or throw statement after for-expression. Correct termination of for-loops cannot be verified. Please append return/throw."), + + /** no parameter required */ + FUN_DEAD_CODE(WARNING, "Dead code."), + + /** 0: last executed statement name */ + FUN_DEAD_CODE_WITH_PREDECESSOR(WARNING, "Dead code. No execution possible after {0}."), + + /** no parameters required */ + FUN_SETTER_CANT_BE_VARIADIC(ERROR, "Variadic parameter is not allowed in setter declarations."), + + /** no parameters required */ + FUN_SETTER_CANT_BE_DEFAULT(ERROR, "Default parameter is not allowed in setter declarations."), + + /** no parameters required */ + FUN_PARAM_VARIADIC_ONLY_LAST(ERROR, "Only the last formal parameter can be variadic."), + + /** 0: name of parameter */ + FUN_PARAM_IMPLICIT_DEFAULT_PARAM(WARNING, + "This parameter is changed to the default parameter '{0}=undefined' since it follows a default parameter."), + + /** no parameter required */ + FUN_PARAM_VARIADIC_WITH_INITIALIZER(ERROR, "Variadic parameters must not have a default initializer."), + + /** no parameter required */ + FUN_SINGLE_EXP_LAMBDA_IMPLICIT_RETURN_ALLOWED_UNLESS_VOID(ERROR, + "An arrow-function is used in a context where its body is expected to have some value as opposed to being void."), + + /** 0: type parameter name */ + FUN_UNUSED_GENERIC_TYPE_PARAM(WARNING, "Type variable {0} not used in parameters or return type."), + + /** no parameters required */ + KEY_SUP_INVALID_USAGE(ERROR, + "Keyword super may only be used in member access expressions, call expressions or new expressions."), + + /** no parameters required */ + KEY_SUP_ACCESS_INVALID_LOC(ERROR, + "Super member access may only be used in constructors, methods, getters, or setters."), + + /** no parameters required */ + KEY_SUP_ACCESS_NO_EXTENDS(ERROR, "Super member access requires a declared super type."), + + /** no parameters required */ + KEY_SUP_ACCESS_INVALID_LOC_INTERFACE(ERROR, "Super member access may not be used in interfaces."), + + /** no parameters required */ + KEY_SUP_ACCESS_FIELD(ERROR, "Super member access may not be used to access a field."), + + /** no parameters required */ + KEY_SUP_CTOR_INVALID_LOC(ERROR, "Super calls may only be used in constructors."), + + /** no parameters required */ + KEY_SUP_NEW_NOT_SUPPORTED(ERROR, "Keyword super with in expressions is not supported yet."), + + /** no parameters required */ + KEY_SUP_NESTED(ERROR, "Super call must not be nested in function expressions."), + + /** no parameters required */ + KEY_SUP_CTOR_EXPRSTMT(ERROR, "Super constructor call must no be used in a composed expression."), + + /** 0: container in which super is nested (with line number). */ + KEY_SUP_CTOR_NESTED(ERROR, + "Super constructor call must only be directly contained in constructor body, i.e. not nested in {0}."), + + /** 0: container in which super is nested (with line number). */ + KEY_SUP_CTOR_INVALID_EXPR_BEFORE(ERROR, "Super constructor call must not be preceded by {0}."), + + /** 0: super class name */ + KEY_SUP_REQUIRE_EXPLICIT_SUPERCTOR_CALL(ERROR, "Must explicitly invoke constructor of super class {0}."), + + /** no parameters required */ + KEY_SUP_CALL_NO_INDEXACCESS(ERROR, "Super member access may not be used with index access."), + + /** no parameters required */ + KEY_THIS_REJECTED_IN_TOP_LEVEL_LAMBDA(ERROR, + "In a top-level arrow function, the 'this' keyword refers to nothing."), + + /** no parameters required */ + EXP_OPTIONAL_INVALID_PLACE(ERROR, "The optional modifier isn't allowed here."), + + /** 0: name of const variable */ + EXP_ASSIGN_CONST_VARIABLE(ERROR, "Const variable {0} is read-only."), + + /** 0: names of legal built-in symbol */ + EXP_INDEXED_ACCESS_SYMBOL_INVALID(ERROR, "Indexed access with built-in symbols is only allowed for {0}."), + + /** 0: name of built-in symbol, 1: name of expected receiver type */ + EXP_INDEXED_ACCESS_SYMBOL_WRONG_TYPE(ERROR, + "Access of property Symbol.{0} only allowed for instances of {1}, immediate instances of Object, and dynamic types."), + + /** 0: name of built-in symbol, 1: name of receiver type */ + EXP_INDEXED_ACCESS_SYMBOL_READONLY(ERROR, "Access to property Symbol.{0} of an {1} is read-only."), + + /** no parameters required */ + EXP_INDEXED_ACCESS_ENUM(ERROR, "Indexed access is not allowed for enumerations."), + + /** no parameters required */ + EXP_INDEXED_ACCESS_FORBIDDEN(ERROR, + "Indexed access is only allowed for strings, arrays and iterables and for immediate(!) instances of Object."), + + /** 0: index-key in indexed-access */ + EXP_INDEXED_ACCESS_COMPUTED_NOTFOUND(ERROR, "Member {0} not found."), + + /** no parameters required */ + EXP_INDEXED_ACCESS_IMPL_RESTRICTION(ERROR, + "Implementation restriction: member name clashes with compiler-internal, synthetic, mangled name."), + + /** no parameters required */ + EXP_PROMISIFY_INVALID_USE(ERROR, + "@Promisify may only be applied to a call expression with a @Promisifiable function or method as target."), + + /** no parameters required */ + EXP_COMPUTED_PROP_NAME_DISCOURAGED(WARNING, + "Computed property name using an expression other than a compile-time expression; this property won't be type-checked at compile time."), + + /** 0: detailed message */ + EXP_COMPILE_TIME_MANDATORY(ERROR, "Not a compile-time expression: {0}."), + + /** + * 0: usage type ('invoke' or 'instantiate'), 1: name of interface with call/construct signature, 2: signature kind + * ('call' or 'construct') + */ + EXP_CALL_CONSTRUCT_SIG_OF_INTERFACE_DIRECTLY_USED(ERROR, + "Cannot directly {0} interface {1}; its {2} signature applies to values of type {1}, not to {1} itself."), + + /** 0: type names, submessage -- full message is a concatenation of these messages */ + COMP_SUBMESSAGES(ERROR, "{1} in {0}."), + + /** 0: member name */ + UNI_UNCOMMON(ERROR, "Member {0} not present in all types of union or incompatible."), + + /** 0: member name, 1: list of types in union that do not contain a member of that name */ + UNI_MISSING(ERROR, "Member {0} not present in all types of union; missing from: {1}."), + + /** 0: either 'getters' or 'setters', 1: member name, 2: either 'read-only' or 'write-only' */ + UNI_INVALID_COMBINATION(ERROR, "Union combines fields and {0} with name {1} and therefore property {1} is {2}."), + + /** 0: member name */ + UNI_INVALID_COMBINATION_SETTER_VS_READ_ONLY_FIELD(ERROR, + "Union combines fields and setters with name {0} but still write-access is not allowed because one or more fields are read-only (const or @Final)."), + + /** 0: member name, 1: list of kinds */ + UNI_MULTIPLE_KINDS(ERROR, "Member {0} not of same kind in all types of union: {1}."), + + /** 0: member name, 1: list of types */ + UNI_DIFFERENT_TYPES(ERROR, "Member {0} not of same type in all types of union: {1}."), + + /** no parameters required */ + UNI_ANY_USED(WARNING, "The use of the any type in a union type is discouraged."), + + /** no parameters required */ + UNI_REDUNDANT_SUBTYPE(WARNING, "The use of redundant subtypes is discouraged."), + + /** no parameters required */ + INTER_ANY_USED(WARNING, "The use of the any type in an intersection type is discouraged."), + + /** no parameters required */ + INTER_ONLY_ONE_CLASS_ALLOWED(WARNING, + "An intersection type should not contain more than one class. Otherwise there cannot exist a value of such a type."), + + /** no parameters required */ + INTER_TYEPARGS_ONLY_ONE_CLASS_ALLOWED(WARNING, + "Type arguments for the same covariant type parameter in an intersection type should not contain more than one class. Otherwise there cannot exist a value of such a type."), + + /** no parameters required */ + INTER_WITH_ONE_GENERIC(WARNING, + "An intersection type should not contain different type arguments for the same invariant type parameter. Otherwise is can be instantiated only with undefined."), + + /** no parameters required */ + INTER_REDUNDANT_SUPERTYPE(WARNING, "The use of redundant supertypes is discouraged."), + + /** 0: method member name, 1: list of kinds */ + INTER_MEMBER_TYPE_CONFLICT(ERROR, + "Member method {0} is in conflict with non-method members in types of intersection: {1}."), + + /** 0: member name */ + INTER_UNCOMMON(ERROR, "Member {0} is incompatible in types of intersection."), + + /** no parameters required */ + ANN__N4JS_NO_EFFECT(WARNING, "This annotation is deprecated and has no effect."), + + /** no parameters required */ + ANN__ONLY_IN_N4JS(ERROR, "Annotations are a N4JS feature and cannot be used in JS mode."), + + /** 0: annotation name */ + ANN_NOT_DEFINED(ERROR, "The annotation @{0} is not defined."), + + /** 0: annotation name, 1: expected number of arguments, 2: actual number of arguments */ + ANN_WRONG_NUMBER_OF_ARGUMENTS(ERROR, "Wrong number of annotation arguments: @{0} expects {1} but got {2}."), + + /** 0: annotation name, 1: expected type */ + ANN_WRONG_ARGUMENT_TYPE(ERROR, "The annotation @{0} expects a {1} here."), + + /** 0: annotation name */ + ANN_DISALLOWED_AT_LOCATION(ERROR, "The annotation @{0} is disallowed for this location."), + + /** 0: annotation name, 1: list of language variants */ + ANN_ONLY_ALLOWED_LOCATION_CONSTRUCTORS(ERROR, + "The annotation @{0} may only be applied at a parameter of a constructor."), + + /** 0: name of annotation (without @) */ + ANN_NON_REPEATABLE(ERROR, "Duplicate annotation of non-repeatable type @{0}."), + + /** 0: name of annotation */ + ANN_UNNECESSARY(WARNING, "Unnecessary @{0}."), + + /** no parameters required */ + ANN_THIS_DISALLOWED_ON_STATIC_MEMBER_OF_INTERFACE(ERROR, + "@This annotation not allowed on static members of interfaces."), + + /** 0: member description, 1: description of containing type, 2: required type */ + ANN_THIS_NOT_SUBTYPE_OF_CONTAINING_TYPE(ERROR, "Declared @This type of {0} in {1} must be a subtype of {2}."), + + /** no parameters required */ + ANN_POLY_STATIC_POLY_ONLY_IN_POLYFILL_MODULE(ERROR, + "The annotation StaticPolyfill is only allowed in modules annotated as StaticPolyfillModule."), + + /** no parameters required */ + ANN_POLY_AWARE_AND_MODULE_MUTUAL_EXCLUSIVE(ERROR, + "A module cannot be annotated as filler and filling at the same time."), + + /** no parameters required */ + ANN_PROMISIFIABLE_MISSING_CALLBACK(ERROR, + "The annotation @Promisifiable is only allowed on functions/methods that take a function as a last argument (i.e. the callback)."), + + /** no parameters required */ + ANN_PROMISIFIABLE_BAD_CALLBACK_MORE_THAN_ONE_ERROR(ERROR, + "The callback of a @Promisifiable function/method must not have more than one parameter of type Error."), + + /** no parameters required */ + ANN_PROMISIFIABLE_BAD_CALLBACK_ERROR_NOT_FIRST_ARG(ERROR, + "If the callback of a @Promisifiable function/method has a parameter of type Error, this parameter must be the first parameter."), + + /** 0: annotation name */ + ANN_DISALLOWED_IN_NONDEFINTION_FILE(ERROR, "The annotation @{0} can only be applied in definition files."), + + /** 0: annotation name */ + ANN_DISALLOWED_IN_NON_RUNTIME_COMPONENT(ERROR, "The annotation @{0} can only be applied in a runtime component."), + + /** 0: bug id */ + ANN_UNUSED_IDEBUG(ERROR, + "No matching error found, apparently bug IDEBUG-{0} has been fixed or does not occur here."), + + /** 0: name of the violating annotation. */ + ANN_REQUIRES_TEST(ERROR, "Only methods annotated with @Test could be annotated with {0}."), + + /** 0: annotation name, 1: list of language variants */ + ANN_ONL_ALLOWED_IN_VARIANTS(ERROR, "The annotation @{0} may only be applied in {1} files."), + + /** 0: annotation name, 1: list of language variants */ + ANN_ONL_ALLOWED_AT_CLASSES_IN_N4JSD(ERROR, "The annotation @{0} may only be applied at classes in n4jsd files."), + + /** 0: annotation name, 1: list of language variants */ + ANN_DISALLOWED_ON_SHAPES(ERROR, "Only nominal interfaces can be annotated with @{0}."), + + /** 0: annotation name */ + ANN__TEST_ONLY_IN_TEST_SOURCES(WARNING, + "Test annotation @{0} may only be used in test source folders (defined in package.json)."), + + /** 0: library name, 1: String of concatenated polyfilled things. */ + POLY_ERROR_IN_RUNTIMEDEPENDENCY(ERROR, "Erroneous library {0} provides contradicting polyfills for {1}."), + + /** 0: String of concatenated library names, 1: String of concatenated polyfilled things. */ + POLY_CLASH_IN_RUNTIMEDEPENDENCY(ERROR, + "The libraries {0} provide polyfills for the same element {1} and cannot be used together."), + + /** 0: String of concatenated library names, 1: String of concatenated polyfilled things. */ + POLY_CLASH_IN_RUNTIMEDEPENDENCY_MULTI(ERROR, + "The libraries {0} provide polyfills for the same elements {1} and cannot be used together."), + + /** 0: String of conflicting static-polyfilling modules. */ + POLY_CLASH_IN_STATIC_POLYFILL_MODULE(ERROR, + "Only one module annotated with @@StaticPolyfillModule is allowed per project. Conflicting with {0}."), + + /** no param */ + POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES(ERROR, + "Only top-level classes annotated as StaticPolyfill are allowed in a module annotated with StaticPolyfillModule."), + + /** no param */ + POLY_IMPLEMENTING_INTERFACE_NOT_ALLOWED(ERROR, + "The filling class cannot introduce additional interfaces; all interfaces must be declared on the filled class."), + + /** doc: detected dependency cycle 0:String describing the cycle. */ + PROJECT_DEPENDENCY_CYCLE(ERROR, "Dependency cycle of the projects: {0}."), + + /** 0: ID of the non-existing project. */ + NON_EXISTING_PROJECT(ERROR, "Project does not exist with project ID: {0}."), + + /** 0: ID of the non-existing project. */ + MISSING_YARN_WORKSPACE(ERROR, + "Project depends on workspace project {0} which is missing in the node_modules folder. Either install project {0} or introduce a yarn workspace of both of the projects."), + + /** 0: human readable name of the obsolete feature block. */ + OBSOLETE_BLOCK(WARNING, "Obsolete {0} block."), + + /** 0: project project ID, 1: human readable name of the project type, 2: human readable name of the feature. */ + INVALID_PROJECT_TYPE_REF(WARNING, "Project {0} of type {1} cannot be declared among the {2}."), + + /** 0: library project ID */ + INVALID_API_PROJECT_DEPENDENCY(WARNING, + "Library project {0} with an implementation ID cannot be declared among the dependencies of an API project."), + + /** 0: violating feature/block name, 1: actual project type name */ + INVALID_FEATURE_FOR_PROJECT_TYPE(WARNING, "{0} cannot be specified for {1} projects."), + + /** 0: name used in duplicate */ + DUPLICATE_PROJECT_REF(ERROR, "Duplicate project reference {0}."), + + /** 0: name of the containing folder, 1: name of the nested folder */ + OUTPUT_AND_SOURCES_FOLDER_NESTING(ERROR, "{0} must not be located inside {1}."), + + /** no parameters required */ + PROJECT_REFERENCES_ITSELF(ERROR, "Project cannot reference itself."), + + /** 0: the type of the deprecated project 1: alternatives */ + DEPRECATED_PROJECT_TYPE(WARNING, "Project type '{0}' is deprecated and will be removed soon. {1}"), + + /** no parameters are required. */ + MISMATCHING_TESTED_PROJECT_TYPES(WARNING, "Tested projects should have the same project type."), + + /** + * 0: current project implementation ID, 1: the violating project's ID, 2: the implementation ID of the violating + * project + */ + MISMATCHING_IMPLEMENTATION_ID(WARNING, + "Implementation ID mismatch. Current project belongs to '{0}' implementation while {1} project belongs to '{2}' implementation."), + + /** 0: test library name */ + SRCTEST_NO_TESTLIB_DEP(ERROR, "Project with source folder of type test should depend on {0}."), + + /** + * 0: ID of the violating transitive external project dependency, 1: ID of the workspace project that is required by + * an external one. + */ + EXTERNAL_PROJECT_REFERENCES_WORKSPACE_PROJECT(WARNING, + "Transitive external project dependency of project '{0}' requires a workspace project '{1}'. Current project setup could result in runtime oddities. It is highly recommended to import project '{0}' into workspace as well."), + + /** 0: project type of containing project */ + INVALID_FILE_TYPE_FOR_PROJECT_TYPE(ERROR, "An n4js file may not be contained in a project of type '{0}'."), + + /** 0: resource name */ + NO_PROJECT_FOUND(WARNING, "No project found for resource {0}."), + + /** 0: part of the specifier that contains a dot, 1: the module specifier */ + MOD_NAME_MUST_NOT_CONTAIN_DOTS(ERROR, "{0} of this module contain(s) the disallowed character '.' : '{1}'."), + + /** 0: dependency name, 1: required version, 2: present version */ + NO_MATCHING_VERSION(WARNING, "Project {0} is required in version {1}, but only version {2} is present."), + + /** + * doc: checks if the module specifier wildcard can be resolved to an existing resource (not applied for + * implementation provided by runtime), spec: Component/Manifest/ModuleSpecifier-Constraint, 0: the module specifier + */ + NON_EXISTING_MODULE_SPECIFIER(WARNING, "Module specifier {0} doesn't exist."), + + /** + * doc: checks for invalid wildcards, spec: Component/Manifest/ModuleSpecifierWildcardConstraints, 0: the invalid + * part of the wild card + */ + INVALID_WILDCARD(ERROR, "'{0}' isn't a valid character sequence in a wild card."), + + /** + * doc: disallow relative navigation, spec: Component/Manifest/ModuleSpecifierWildcardConstraints, no parameters + * required + */ + NO_RELATIVE_NAVIGATION(ERROR, "Relative navigation isn't allowed in a module specifier."), + + /** + * doc: disallow switching off semantic validation for n4js files, spec: + * Component/Manifest/ModuleSpecifier-Constraint, 0: module filter type (e.g. noValidate) + */ + DISALLOWED_NO_VALIDATE_FOR_N4JS(ERROR, "{0} paths shouldn't match n4js files."), + + /** 0: sub description, 1: extend/implement, 2: super description, 3: implements/extends */ + SYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP(ERROR, "The {0} cannot {1} {2}, use '{3}'."), + + /** no parameters required */ + SYN_KW_EXTENDS_IMPLEMENTS_WRONG_ORDER(ERROR, "Extended class must be declared before implemented interfaces."), + + /** 0: class description, 1: keyword, 2: super description */ + CLF_WRONG_META_TYPE(ERROR, "The {0} cannot {1} {2}."), + + /** 0: modifier name, 1: type of element that may not have this modifier (e.g. 'class', 'interface', etc.) */ + SYN_MODIFIER_INVALID(ERROR, "Modifier {0} is not allowed on a {1}."), + + /** 0: modifier name */ + SYN_MODIFIER_DUPLICATE(ERROR, "Duplicate modifier {0}."), + + /** no parameters required */ + SYN_MODIFIER_ACCESS_SEVERAL(ERROR, "Only a single access modifier may be provided."), + + /** 0: modifiers in correct order */ + SYN_MODIFIER_BAD_ORDER(ERROR, "Modifiers should appear in this order: {0}."), + + /** 0: element {modifier|keyword}, 1: name of modifier or keyword element (e.g. public) */ + SYN_UNNECESSARY_ELEMENT(WARNING, "Unnecessary {0} {1}."), + + /** no parameters required */ + EXP_ONLY_TOP_LEVEL_ELEMENTS(ERROR, "Only top level elements can be exported."), + + /** 0: element kind, 1: element name */ + EXP_PRIVATE_ELEMENT(ERROR, "Private {0} {1} cannot be exported."), + + /** no parameters required */ + DESTRUCT_EMPTY_PATTERN(ERROR, + "Empty destructuring pattern (disallowed for time being, since ES6 implementations have different semantics)."), + + /** 0: name of missing property, 1: type of value to be destructured */ + DESTRUCT_PROP_MISSING(ERROR, + "Value to be destructured does not contain a property, field or getter named '{0}': {1}."), + + /** 0: name of property that returned AbstractDescriptionWithError, 1: error message */ + DESTRUCT_PROP_WITH_ERROR(ERROR, "Property named '{0}' is not readable: {1}."), + + /** + * 0: name of variable, 1: 'at index N' or 'of property NAME', 2: error message from type system (must not end in a + * dot!) + */ + DESTRUCT_TYPE_ERROR_VAR(ERROR, "Variable {0} cannot hold destructured value {1}: {2}."), + + /** + * 0: kind of destructuring pattern ('Array' or 'Object' or 'Nested array' or 'Nested object'), 1: 'destructured + * value at index N' or 'destructured value of property NAME', 2: error message from type system (must not end in a + * dot!) + */ + DESTRUCT_TYPE_ERROR_PATTERN(ERROR, "{0} destructuring pattern cannot be applied to {1}: {2}."), + + ////// Dependency Injection + /** + * 0: type name, 1: additional description identifying the place of the violating context (name of the + * member/parameter) + */ + DI_NOT_INJECTABLE(ERROR, + "Type {0} is not injectable{1}: only user-defined, non-generic, nominally typed interfaces and classes are allowed."), + + /** no parameters are required */ + DI_VARARGS_NOT_INJECTABLE(ERROR, "Injection of parameters that are variadic or optional is not supported."), + + /** 0: type name */ + DI_MUST_BE_INJECTED(WARNING, + "Type {0} must be injected, because it contains or inherits one or more members annotated with @Inject."), + + /** 0: annotation name, 1: name of required annotation on containing class */ + DI_ANN_ONLY_ON_CLASS_ANNOTATED_WITH(ERROR, "The annotation @{0} is only allowed on classes annotated with @{1}."), + + /** 0: annotation name, 1: name of required annotation on containing class */ + DI_ANN_ONLY_ON_METHOD_IN_CLASS_ANNOTATED_WITH(ERROR, + "The annotation @{0} is only allowed on methods contained in a class annotated with @{1}."), + + /** 0: annotation name, 1: name of required annotation on argument class */ + DI_ANN_ARG_MUST_BE_ANNOTATED_WITH(ERROR, "Argument to annotation @{0} must be a class annotated with @{1}."), + + /** 0: the name of the violating annotation. */ + DI_ANN_BIND_SECOND_MUST_BE_SUBTYPE_FIRST(ERROR, "Second argument to @{0} must be a subtype of the first."), + + /** no parameters required */ + DI_ANN_PROVIDES_METHOD_MUST_RETURN_VALUE(ERROR, "A provider method must return a value."), + + /** no parameters required */ + DI_ANN_INTERFACE_INJECTION_NOT_SUPPORTED(ERROR, "Injection inside interfaces is not supported."), + + /** no parameters required */ + DI_ANN_INJECTOR_EXTENDS(ERROR, "Classes annotated with @GenerateInjector cannot extend other class."), + + /** 0: the binded type name */ + DI_ANN_BIND_SINGLETON_TARGET_SHOULD_BE_DEFINED_AS_SINGLETON(ERROR, + "{0} can be defined as a singleton if it is annotated with @Singleton on the definition site."), + + /** no parameters required */ + DI_ANN_INJECTOR_CANNOT_BE_INJECTED_INTO_INJECTOR(ERROR, + "Types annotated with @GenerateInjector cannot be injected. Use @WithParentInjector instead for creating nested injectors."), + + /** 0: the cyclic graph as a string */ + DI_ANN_USE_INJECTOR_CYCLE(ERROR, "A cycle was detected among the parent injectors: {0}."), + + /** 0: the name of the unavailable field */ + DI_FIELD_IS_NOT_INJECTED_YET(ERROR, "{0} is not yet injected at this point."), + + /** 0: super class type name, 1: violating type name */ + DI_CTOR_BREAKS_INJECTION_CHAIN(WARNING, + "Constructor at super class {0} is annotated with @Inject. Omitting the @Inject annotation from constructor at class {1} could break injection chain."), + + /** no parameters required */ + DI_ANN_BINDER_NOT_APPLICABLE(ERROR, + "Annotation @Binder is applicable only for (exported) non-abstract class definitions."), + + /** no parameters required */ + DI_ANN_BINDER_AND_INJECTOR_DONT_GO_TOGETHER(ERROR, + "Annotations @Binder and @GenerateInjector may not be applied both on the same class definition."), + + /** no parameters required */ + DI_ANN_DUPLICATE_BINDING(ERROR, + "Duplicate @Binding-s (two different bindings share the same key, for the same @Binder)."), + + /** no parameters required */ + DI_ANN_BIND_ABSTRACT_TARGET(ERROR, "The target of a @Binding must be a non-abstract class."), + + /** no parameters required */ + DI_ANN_INJECT_METHOD_NOT_SUPPORTED_YET(ERROR, "Method injection not supported yet."), + + /** no parameters required */ + DI_ANN_BINDER_EXTENDS(ERROR, "Classes annotated with @Binder may not extend another class."), + + /** no parameters required */ + DI_ANN_INJECTOR_CTOR_MUST_BE_INJECT(ERROR, + "The constructor of an injector must itself be injected unless it declares no parameters."), + + /** no parameters required */ + DI_ANN_INJECTOR_REQUIRED(ERROR, "Only types annotated with @GenerateInjector can be used here."), + + /** 0: list of missing binders (as a list of type names) */ + DI_ANN_MISSING_PROVIDED_BINDERS(ERROR, + "No binders are provided (third param for this callsite). The following binders are used by the injector and themselves require injection: {0}."), + + /** no parameters required */ + DI_ANN_INJECTOR_MISSING(ERROR, "An instance of N4Injector is required here."), + + /** 0: list of missing binders (as a list of type names) */ + DI_ANN_MISSING_NEEDED_BINDERS(ERROR, + "Instances are missing for the following binders (they are used by the injector and themselves require injection): {0}."), + + /** no parameters required */ + DI_API_INJECTED(ERROR, + "The class being instantiated (or one of its super-types) has been marked @Injected in an API project."), + + /** no parameters required */ + DI_ANN_INJECTED_NOT_APPLICABLE(ERROR, "@Injected annotates a class (abstract or not) defined in an API project."), + + ////// JSX + /** 0: name of opening JSX element, 1: name of closing JSX element */ + JSX_JSXELEMENT_OPENING_CLOSING_ELEMENT_NOT_MATCH(ERROR, + "Opening element {0} does not match with closing element {1}."), + + /** 0: name of the type JSX element is binding to */ + JSX_REACT_ELEMENT_NOT_FUNCTION_OR_CLASS_ERROR(ERROR, + "JSX element is expected to bind to either a function or class, but bind to type {0} instead."), + + /** No parameter */ + JSX_REACT_ELEMENT_CLASS_MUST_NOT_BE_ABSTRACT(ERROR, "JSX element class must not be abstract."), + + /** 0: name of the return type of the function that JSX element is binding to */ + JSX_REACT_ELEMENT_FUNCTION_NOT_REACT_ELEMENT_ERROR(ERROR, + "Expecting a function returning a value of type {0} but the return type is {1}."), + + /** no argument */ + JSX_REACT_ELEMENT_CLASS_NOT_REACT_ELEMENT_ERROR(ERROR, "The referred class is not a subtype of React.Component"), + + /** 0: name of the function that JSX element is binding to */ + JSX_REACT_FUNCTIONAL_COMPONENT_CANNOT_START_WITH_LOWER_CASE(ERROR, + "React functional component {0} cannot start with lower case."), + + /** 0: name of the class that JSX element is binding to */ + JSX_REACT_CLASS_COMPONENT_CANNOT_START_WITH_LOWER_CASE(ERROR, + "React class component {0} cannot start with lower case."), + + /** 0: name of JSX element is binding to */ + JSX_JSXELEMENT_NOT_BIND_TO_REACT_COMPONENT(ERROR, "JSX element {0} does not bind to any valid React component."), + + /** 0: name of JSX element is binding to */ + JSX_TAG_UNKNOWN(WARNING, "Tag {0} is neither a known HTML tag nor an SVG tag."), + + /** 0: name of JSX property */ + JSX_JSXPROPERTY_ATTRIBUTE_NON_OPTIONAL_PROPERTY_NOT_SPECIFIED(ERROR, + "Non-optional property {0} should be specified."), + + /** + * 0: The name of attribute in spread operator, 1: type of the attribute, 2: the declared type of the corresponding + * property in 'props' + */ + JSX_JSXSPREADATTRIBUTE_WRONG_SUBTYPE(ERROR, "Attribute {0} has wrong type because {1} not subtype of {2}."), + + /** 0: The name of attribute in spread operator, 1: name of JSX element */ + JSX_JSXSPREADATTRIBUTE_NOT_DECLARED_IN_PROPS(WARNING, + "Attribute {0} is not a declared property in the props of {1}."), + + /** 0: The name of attribute in JSX property, 1: name of JSX element */ + JSX_JSXSPROPERTYATTRIBUTE_NOT_DECLARED_IN_PROPS(WARNING, + "Attribute {0} is not a declared property in the props of {1}."), + + /** 0: JSX element in non-JSX file */ + JSX_JSXELEMENT_IN_NON_JSX_RESOURCE(ERROR, "JSX element is expected to be placed in JSX like resource, was {0}."), + + /** No parameter */ + JSX_REACT_NAMESPACE_NOT_ALLOWED(ERROR, "Namespace to react must be React."), + + /** No parameter */ + JSX_REACT_NOT_RESOLVED(ERROR, "Cannot resolve JSX implementation."), + + /** No parameter */ + JSX_NAME_CANNOT_BE_REACT(ERROR, "Element cannot be named React in N4JSX file."), + + ////// THIRD PARTY + /** no parameters required */ + THIRD_PARTY_BABEL_LET_CONST_IN_FUN_EXPR(WARNING, + "This code is prone to Babel bug #6302. If you use Babel in your build pipeline, you should rename this let/const or the containing function expression."), + + ////// N4JS package.json + /** no parameters */ + PKGJ_MISSING_DEPENDENCY_N4JS_RUNTIME(ERROR, + "Missing dependency to 'n4js-runtime' (mandatory for all N4JS projects of type library, application, test)."), + + /** no parameters */ + PKGJ_WRONG_DEPENDENCY_N4JS_RUNTIME(ERROR, + "Dependency to 'n4js-runtime' should be defined below key 'dependencies', not 'devDependencies'."), + + /** 0: The package name without scope, as declared in the package.json, 1: project folder name */ + PKGJ_PACKAGE_NAME_MISMATCH(WARNING, + "As a convention the package name '{0}' should match the name of the project folder '{1}' on the file system."), + + /** 0: The scope name, as declared in the package.json, 1: parent folder name */ + PKGJ_SCOPE_NAME_MISMATCH(WARNING, + "As a convention the scope name '{0}' should match the name of the project folder's parent folder '{1}' on the file system."), + + /** 0: The project name without scope */ + PKGJ_INVALID_PROJECT_NAME(ERROR, "The name '{0}' is not a valid package name."), + + /** 0: The scope name */ + PKGJ_INVALID_SCOPE_NAME(ERROR, "The name '{0}' is not a valid scope name."), + + /** 0: Invalid source container type name */ + PKGJ_INVALID_SOURCE_CONTAINER_TYPE(ERROR, "Invalid source container type '{0}'."), + + /** 0: the non-existing path */ + PKGJ_NON_EXISTING_PATH(ERROR, "Path {0} does not exist."), + + /** no parameters */ + PKGJ_EMPTY_SOURCE_PATH(ERROR, "Source container paths must not be empty."), + + /** 0: the non-existing source container path */ + PKGJ_NON_EXISTING_SOURCE_PATH(WARNING, "Source container path {0} does not exist."), + + /** 0: the path 1: 'in'-clause with leading space (e.g. ' in external, test') */ + PKGJ_DUPLICATE_SOURCE_CONTAINER(WARNING, "Duplicate path '{0}' has already been declared as source container{1}."), + + /** 0: the container source path */ + PKGJ_NESTED_SOURCE_CONTAINER(ERROR, + "A source container must not be nested within other source containers (nested in {0})"), + + /** no parameters */ + PKGJ_NO_OUTPUT_FOLDER(ERROR, "There is no output folder defined, so compilation isn't possible."), + + /** 0: the invalid path */ + PKGJ_INVALID_PATH(ERROR, "'{0}' is not a valid path."), + + /** 0: the absolute path */ + PKGJ_INVALID_ABSOLUTE_PATH(ERROR, "Path '{0}' must not be absolute."), + + /** 0: the non-directory path */ + PKGJ_EXPECTED_DIRECTORY_PATH(ERROR, "Path '{0}' does not point to a directory."), + + /** 0: the non-existing main module specifier */ + PKGJ_NON_EXISTING_MAIN_MODULE(ERROR, "Main module specifier {0} does not exist."), + + /** 0: invalid module filter type, 1: all valid module filter types */ + PKGJ_INVALID_MODULE_FILTER_TYPE(ERROR, "Invalid module filter type '{0}'. Valid filter types are {1}."), + + /** 0: invalid module specifier */ + PKGJ_INVALID_MODULE_FILTER_SPECIFIER(ERROR, + "Invalid module specifier. Use simple strings or object syntax instead."), + + /** no parameters */ + PKGJ_INVALID_MODULE_FILTER_SPECIFIER_EMPTY(ERROR, + "The filter specifier and declared source container must not be empty."), + + /** no parameters */ + PKGJ_DUPLICATE_MODULE_FILTER_SPECIFIER(ERROR, "Duplicate module filter specifier."), + + /** no parameters */ + PKGJ_SRC_IN_FILTER_IS_NO_DECLARED_SOURCE(ERROR, + "The given source container '{0}' has not been declared as source container."), + + /** 0: the invalid part of a wildcard */ + PKGJ_INVALID_WILDCARD(ERROR, "'{0}' is not a valid character sequence in a wildcard."), + + /** no parameters */ + PKGJ_NO_RELATIVE_NAVIGATION(ERROR, "Relative navigation is not allowed in a module filter specifier."), + + /** 0: the module filter specifier */ + PKGJ_MODULE_FILTER_DOES_NOT_MATCH(WARNING, "Module filter '{0}' does not match any modules."), + + /** 0: module filter type (e.g. noValidate) */ + PKGJ_FILTER_NO_N4JS_MATCH(ERROR, "Module filters of type {0} must not match N4JS modules/files."), + + /** no parameters */ + PKGJ_APIIMPL_MISSING_IMPL_PROJECTS(ERROR, + "When defining an implementation ID, you also have to define one or more API projects that are implemented by this project using property 'n4js.implementedProjects'."), + + /** no parameters */ + PKGJ_APIIMPL_REFLEXIVE(ERROR, "An implementation project may not implement itself."), + + /** no parameters required */ + PKGJ_APIIMPL_MISSING_IMPL_ID(ERROR, + "When defining one or more implemented projects, you also have to define an implementation ID, using property 'implementationId'."), + + /** 0: invalid project type */ + PKGJ_INVALID_PROJECT_TYPE(ERROR, "Invalid project type '{0}'."), + + /** 0: project id 1: section label (e.g. required runtime libraries) */ + PKGJ_PROJECT_REFERENCE_MUST_BE_DEPENDENCY(ERROR, + "The project reference {0} in {1} must also be declared as explicit project dependency in 'dependencies' or 'devDependencies'."), + + /** 0: message */ + PKGJ_SEMVER_ERROR(ERROR, "{0}"), + + /** 0: message */ + PKGJ_SEMVER_WARNING(WARNING, "{0}"), + + /** 0: version number string representation, 1: reason */ + PKGJ_INVALID_VERSION_NUMBER(ERROR, "Invalid version number '{0}': {1}."), + + /** 0: version constraint string representation, 1: reason */ + PKGJ_INVALID_VERSION_REQUIREMENT(WARNING, "Invalid version requirement '{0}': {1}. Will assume empty string."), + + /** 0: project type */ + PKGJ_PROJECT_TYPE_MANDATORY_OUTPUT_AND_SOURCES(ERROR, + "Projects of type {0} must always declare an output folder and at least one source container."), + + /** no parameters */ + PKGJ_EMPTY_PROJECT_REFERENCE(ERROR, "A project reference must not be empty."), + + /** no parameters */ + PKGJ_EMPTY_INIT_MODULE(ERROR, "An init module specifier must not be empty."), + + /** 0: project type, 1: empty or 'not ', 2: property name */ + PKGJ_DEFINES_PROPERTY(ERROR, "A project of type '{0}' must {1}define the property '{2}'."), + + /** 0: property name */ + PKGJ_PROPERTY_UNKNOWN(WARNING, "Property '{0}' is unknown."), + + /** 0: implementation project name, 1: type definition project name */ + PKGJ_IMPL_PROJECT_IS_MISSING_FOR_TYPE_DEF(WARNING, + "The implementation project {0} of type definition project {1} is missing from the dependencies section."), + + /** 0: 'Source' or 'Output code' */ + PKGJ_REWRITE_MODULE_SPECIFIERS__EMPTY_SPECIFIER(ERROR, "{0} module specifier must not be empty."), + + /** no parameters */ + PKGJ_REWRITE_MODULE_SPECIFIERS__INVALID_VALUE(ERROR, + "String expected (i.e. the module specifier to use in the output code)."), + + /** 0: dependency cycle */ + LTD_ILLEGAL_LOADTIME_REFERENCE(ERROR, + "Load-time references to the same or other modules are not allowed within a runtime dependency cycle (except in extends/implements clauses).{0}"), + + /** + * 0: name of load-time dependency target module, 1: comma-separated list of other load-time dependency source + * modules (including the prefix 'modules ' or 'module '), 2: dependency cycle + */ + LTD_LOADTIME_DEPENDENCY_CONFLICT(ERROR, + "A load-time dependency target module {0} must only be imported once within the same runtime dependency cycle, but {0} is also imported by {1}.{2}"), + + /** 0: dependency cycle */ + LTD_LOADTIME_DEPENDENCY_CYCLE(ERROR, + "Load-time dependency cycles are disallowed, because successful resolution by Javascript engine cannot be guaranteed.{0}"), + + /** + * 0: name of load-time dependency target module, 1: modules that could heal this reference (including the prefix + * 'one of the modules ' or 'module '), 2: dependency cycle + */ + LTD_REFERENCE_TO_LOADTIME_DEPENDENCY_TARGET(ERROR, + "When importing modules from a runtime cycle, those that are the target of a load-time dependency (marked with * below) may only be imported after first importing one of the others. Thus, import of module {0} must be preceded by an import of {1}.{2}") + + ; + + public final Severity severity; + private final String msgTemplate; + private final int argCount; + + private final Pattern ARG = Pattern.compile("\\{\\d\\}"); + + IssueCodes(Severity severity, String msgTemplate) { + this.severity = severity; + this.msgTemplate = msgTemplate; + if (msgTemplate == null) { + this.argCount = 0; + } else { + Matcher matcher = ARG.matcher(msgTemplate); + int maxArgCount = 0; + while (matcher.find()) { + String digitStr = matcher.group().substring(1, 2); + int argPlace = Integer.parseInt(digitStr); + maxArgCount = Math.max(maxArgCount, argPlace + 1); + } + this.argCount = maxArgCount; + } + } + + public String getMessage(Object... values) { + Preconditions.checkArgument(argCount == 0 || (values != null && values.length == argCount), "Check arguments"); + if (values == null) { + return msgTemplate; + } + String message = msgTemplate; + for (int i = 0; i < values.length; i++) { + message = message.replace("{" + i + "}", values[i].toString()); + } + return message; + } + + public IssueItem toIssueItem(Object... values) { + return new IssueItem(this, severity, getMessage(values)); + } + + public IssueItem toIssueItemWithData(List data, Object... values) { + return new IssueItem(this, severity, getMessage(values), data.toArray(new String[0])); + } + + static public Severity getSeverityForName(String issueName) { + try { + return valueOf(issueName).severity; + } catch (Exception e) { + return null; + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.xtend deleted file mode 100644 index e34f50e771..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.xtend +++ /dev/null @@ -1,21 +0,0 @@ -/** - * 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 - -import org.eclipse.n4js.utils.NLS - -/** - * Provides messages and helper methods for creating NLS messages. - * This class uses an active annotation {@code @NLS} to derive constants and methods out of the entries of the - * {@code messages.properties}. See {@link org.eclipse.n4js.utils.NLSProcessor} for details about the message format. - */ -@NLS(propertyFileName="messages") -class IssueCodes {} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueItem.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueItem.java new file mode 100644 index 0000000000..5d715c5565 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueItem.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2023 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; + +import org.eclipse.xtext.diagnostics.Severity; + +/** + * Data container for concrete issues. + */ +public class IssueItem { + /** Reference to the general {@link IssueCodes} */ + public final IssueCodes code; + /** Severity */ + public final Severity severity; + /** Complete message */ + public final String message; + /** Auxiliary data */ + public final String[] data; + + /** Constructor */ + public IssueItem(IssueCodes code, Severity severity, String message) { + this(code, severity, message, new String[0]); + } + + /** Constructor */ + public IssueItem(IssueCodes code, Severity severity, String message, String[] data) { + this.code = code; + this.severity = severity; + this.message = message; + this.data = data; + } + + /** Returns the issue code name */ + public String getID() { + return code.name(); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/N4JSIssueSeverities.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/N4JSIssueSeverities.java index 27ded0668b..7f0bc495a2 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/N4JSIssueSeverities.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/N4JSIssueSeverities.java @@ -39,7 +39,7 @@ public N4JSIssueSeverities(IPreferenceValues preferenceValues, Map issues) { if (cache != null && cache.hasUnknownTypeRef()) { boolean hasErrors = issues.stream().anyMatch(issue -> issue.getSeverity() == Severity.ERROR); if (!hasErrors) { - final String msg = IssueCodes.getMessageForTYS_UNKNOWN_TYPE_REF(); + final String msg = IssueCodes.TYS_UNKNOWN_TYPE_REF.getMessage(); for (TypableElement elem : cache.getAstNodesOfUnknownTypes()) { - Issue issue = createFileIssue(resource, elem, msg, IssueCodes.TYS_UNKNOWN_TYPE_REF); + Issue issue = createFileIssue(resource, elem, msg, IssueCodes.TYS_UNKNOWN_TYPE_REF.name()); issues.add(issue); } @@ -223,8 +223,8 @@ private boolean isValidFileTypeForProjectType(Resource resource, N4JSProjectConf private static Issue createInvalidFileTypeError(Resource res, N4JSProjectConfigSnapshot project) { final String projectTypeStr = PackageJsonUtils.getProjectTypeStringRepresentation(project.getType()); - final String msg = IssueCodes.getMessageForINVALID_FILE_TYPE_FOR_PROJECT_TYPE(projectTypeStr); - return createFileIssue(res, msg, IssueCodes.INVALID_FILE_TYPE_FOR_PROJECT_TYPE); + final String msg = IssueCodes.INVALID_FILE_TYPE_FOR_PROJECT_TYPE.getMessage(projectTypeStr); + return createFileIssue(res, msg, IssueCodes.INVALID_FILE_TYPE_FOR_PROJECT_TYPE.name()); } private static Issue createPostProcessingFailedError(Resource res, Throwable th) { @@ -233,8 +233,8 @@ private static Issue createPostProcessingFailedError(Resource res, Throwable th) final String trace = "\n" + Stream.of(th.getStackTrace()) .map(ste -> ste.toString()) .collect(Collectors.joining("\n")); // cannot add indentation, because Xtext would reformat the message - final String msg = IssueCodes.getMessageForPOST_PROCESSING_FAILED(thKind, thName, th.getMessage() + trace); - return createFileIssue(res, msg, IssueCodes.POST_PROCESSING_FAILED); + final String msg = IssueCodes.POST_PROCESSING_FAILED.getMessage(thKind, thName, th.getMessage() + trace); + return createFileIssue(res, msg, IssueCodes.POST_PROCESSING_FAILED.name()); } private static Issue createFileIssue(Resource res, String message, String issueCode) { @@ -245,7 +245,7 @@ private static Issue createFileIssue(Resource res, TypableElement elem, String m URI uri = res.getURI(); final IssueImpl issue = new IssueImpl(); issue.setCode(issueCode); - issue.setSeverity(IssueCodes.getDefaultSeverity(issueCode)); + issue.setSeverity(IssueCodes.getSeverityForName(issueCode)); issue.setMessage(message); issue.setUriToProblem(URIUtils.getBaseOfVirtualResourceURI(uri)); issue.setType(CheckType.FAST); // using CheckType.FAST is important to get proper marker update behavior in ... diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/helper/FunctionValidationHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/helper/FunctionValidationHelper.java index f6dea87eed..bd15408eb2 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/helper/FunctionValidationHelper.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/helper/FunctionValidationHelper.java @@ -15,11 +15,6 @@ import static org.eclipse.n4js.validation.IssueCodes.FUN_PARAM_INITIALIZER_ILLEGAL_FORWARD_REFERENCE; import static org.eclipse.n4js.validation.IssueCodes.FUN_PARAM_VARIADIC_ONLY_LAST; import static org.eclipse.n4js.validation.IssueCodes.FUN_PARAM_VARIADIC_WITH_INITIALIZER; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForFUN_PARAM_IMPLICIT_DEFAULT_PARAM; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForFUN_PARAM_INITIALIZER_ILLEGAL_AWAIT_CALL; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForFUN_PARAM_INITIALIZER_ILLEGAL_FORWARD_REFERENCE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForFUN_PARAM_VARIADIC_ONLY_LAST; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForFUN_PARAM_VARIADIC_WITH_INITIALIZER; import java.util.Arrays; import java.util.Iterator; @@ -95,8 +90,8 @@ static public void internalCheckFormalParameters( TypesPackage.Literals.SYNTAX_RELATED_TELEMENT__AST_ELEMENT, false); } if (fparsL.indexOf(id) >= fpPos) { - String msg = getMessageForFUN_PARAM_INITIALIZER_ILLEGAL_FORWARD_REFERENCE(); - issueConsumer.accept(msg, FUN_PARAM_INITIALIZER_ILLEGAL_FORWARD_REFERENCE, ir); + String msg = FUN_PARAM_INITIALIZER_ILLEGAL_FORWARD_REFERENCE.getMessage(); + issueConsumer.accept(msg, FUN_PARAM_INITIALIZER_ILLEGAL_FORWARD_REFERENCE.name(), ir); } } @@ -110,8 +105,8 @@ static public void internalCheckFormalParameters( paramName = ((FormalParameter) fPar).getName(); } for (AwaitExpression await : awaits) { - String msg = getMessageForFUN_PARAM_INITIALIZER_ILLEGAL_AWAIT_CALL(paramName); - issueConsumer.accept(msg, FUN_PARAM_INITIALIZER_ILLEGAL_AWAIT_CALL, await); + String msg = FUN_PARAM_INITIALIZER_ILLEGAL_AWAIT_CALL.getMessage(paramName); + issueConsumer.accept(msg, FUN_PARAM_INITIALIZER_ILLEGAL_AWAIT_CALL.name(), await); } } } @@ -126,8 +121,8 @@ static public void internalCheckFormalParameters( while (initAssgnVisited && iter.hasNext()) { T fpar = iter.next(); if (!hasInitAssgn.test(fpar) && !variadic.test(fpar)) { - String msg = getMessageForFUN_PARAM_IMPLICIT_DEFAULT_PARAM(name.apply(fpar)); - issueConsumer.accept(msg, FUN_PARAM_IMPLICIT_DEFAULT_PARAM, fpar); + String msg = FUN_PARAM_IMPLICIT_DEFAULT_PARAM.getMessage(name.apply(fpar)); + issueConsumer.accept(msg, FUN_PARAM_IMPLICIT_DEFAULT_PARAM.name(), fpar); } } } @@ -149,14 +144,14 @@ static public void internalCheckFormalParameter( // 1. Variadic is last if (fpPos != fPars.size() - 1) { // is not last? - String msg = getMessageForFUN_PARAM_VARIADIC_ONLY_LAST(); - issueConsumer.accept(msg, FUN_PARAM_VARIADIC_ONLY_LAST, fPar); + String msg = FUN_PARAM_VARIADIC_ONLY_LAST.getMessage(); + issueConsumer.accept(msg, FUN_PARAM_VARIADIC_ONLY_LAST.name(), fPar); } // 2. Both variadic and initializerAssignment if (hasInitAssgn.test(fPar)) { - String msg = getMessageForFUN_PARAM_VARIADIC_WITH_INITIALIZER(); - issueConsumer.accept(msg, FUN_PARAM_VARIADIC_WITH_INITIALIZER, fPar); + String msg = FUN_PARAM_VARIADIC_WITH_INITIALIZER.getMessage(); + issueConsumer.accept(msg, FUN_PARAM_VARIADIC_WITH_INITIALIZER.name(), fPar); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/messages.properties b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/messages.properties deleted file mode 100644 index 3fa0603598..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/messages.properties +++ /dev/null @@ -1,1221 +0,0 @@ -# see NLSProcessor for description of value format -# If you change anything here, manually trigger re-compilation of IssueCodes - - -# The following message is intended for ES6 features that are implemented in N4JS but -# are not yet supported in current version of V8 or some other relevant runtime environment. -# 0: description of the feature that is not supported -UNSUPPORTED=error;;;Unsupported feature: {0}. - -# Not necessary. -SCR_HASHBANG_WRONG_LOCATION=error;;;Hashbang must start at the absolute start of a script or module - -# 0: file names of files that contain errors -EXTERNAL_LIBRARY_ERRORS=error;;;External library error: {0} -# 0: file names of files that contain warnings -EXTERNAL_LIBRARY_WARNINGS=error;;;External library warning: {0} - -# 0: kind of throwable ("error", "exception", or "throwable"), 1: simple name of throwable, 2: message of throwable -POST_PROCESSING_FAILED=error;;;{0} {1} thrown during post-processing (please report this!): {2} -# Unknown type ref in resource -TYS_UNKNOWN_TYPE_REF=error;;;Resource contains unknown type ref (please report this!) - -# 0: namespace name, 1: import module name, that both occur multiple times in this combination -IMP_STMT_DUPLICATE_NAMESPACE=error;;;Duplicate namespace import statement with name {0} and imported module {1}. -# 0: imported element local name, 1: import module name, that both occur multiple times in this combination -IMP_STMT_DUPLICATE_NAMED=error;;;Duplicate named import statement with local name {0} and imported module {1}. -# 0: type1 imported name1, 1: import module name, 2: name under which type is already imported -IMP_DUPLICATE=error;;;{0} from {1} is already imported as {2}. -# 0: import module name, 1: namespace name already importing those elements -IMP_DUPLICATE_NAMESPACE=error;;;Element {0} of {1} is already imported in namespace {2}. -# 0: local name (import name, alias name or namespace name), 1: import module name, 2: name under which type is already imported -IMP_LOCAL_NAME_CONFLICT=error;;;Name {0} is already used as {1}. -# 0: type name, 1: alias name -IMP_PLAIN_ACCESS_OF_ALIASED_TYPE=error;;;{0} has been imported as {1}. -# 0: type name, 1: full name (namespace + '.' + type name) -IMP_PLAIN_ACCESS_OF_NAMESPACED_TYPE=error;;;{0} has been imported as {1}. -# 0: imported name -IMP_UNUSED_IMPORT=warning;;;The import of {0} is unused. -# 0: imported name -IMP_NOT_EXPORTED=error;;;Element {0} is not exported. -# 0: type import name -IMP_UNRESOLVED=error;;;Import of {0} cannot be resolved. -# Not necessary. -IMP_DISCOURAGED_PLACEMENT=warning;;;The import statement should be placed on top of other statements. - - -# 0: type or variable, 1: type name, 2: comma separated list of types - the sources of the imports -IMP_AMBIGUOUS=error;;;The {0} {1} is ambiguously imported from {2}. -# 0: type or variable, 1: type name, 2: comma separated list of types - the sources of the imports -IMP_AMBIGUOUS_WILDCARD=error;;;The {0} {1} is ambiguously imported from {2}. -# 0: imported type name, 1: qualified name of the module -IMP_CONFLICT=error;;;Conflicting import of {0} with import from {1}. -# 0: imported type1 name, 1: type1 alias, 2: type2 imported name, 3: type2 import module name -IMP_CONFLICT_ALIAS_TYPE=error;;;Conflicting import of {0} as {1}. Cannot import same type with different name ({2}) from {3}. -# 0: type1 imported name, 1: type2 alias, 2: type2 import module name -IMP_CONFLICT_ALIASES=error;;;Conflicting import of {0}. Cannot import same type with different name ({1}) from {2}. -# 0: type1 imported name1, that occur multiple times, 1: import module name -IMP_DUPLICATEX=error;;;Duplicate import of {0} in import from {1}. -# 0: type1 imported name1, 1: type1 imported name2, 2: import module name -IMP_DUPLICATE_ALIAS=error;;;Duplicate import of {0}, already defined as {1} in import from {2}. -# 0: module in wildcard specifier -IMP_EMPTY_WILDCARD_IMPORT=warning;;;The wild-card import from {0} doesn't import anything because nothing is exported there. -# 0: alias in namespace import -IMP_STATIC_IMPORT_PLAIN_JS=error;;;Use dynamic import in order to access elements of {0}. -# 0: alias in namespace import -IMP_DYNAMIC_IMPORT_N4JS=error;;;N4JS module {0} must not be imported dynamically. -# 0: variant type, 1: alias in namespace import -IMP_DYNAMIC_IMPORT_N4JSD=warning;;;The {0} module {1} should not be imported dynamically. -# no parameters required -IMP_DEFAULT_EXPORT_DUPLICATE=error;;;Duplicate default export. -# 0: local name of the imported element -IMP_IMPORTED_ELEMENT_READ_ONLY=error;;;Imported element {0} is read-only. -# 0: local name of the imported element, 1: re-exporting project name to use, 2: imported project name -IMP_IMPORTED_ELEMENT_FROM_REEXPORTING_PROJECT=error;;;The imported element {0} is defined in the re-exporting project {1} but project {2} was imported. Import from {1} instead. - -# 0: method, field, getter, setter, member, 1: member name -VIS_ILLEGAL_MEMBER_ACCESS=error;;;The {0} {1} is not visible. -# 0: function name -VIS_ILLEGAL_FUN_ACCESS=error;;;The function {0} is not visible. -# 0: type name -VIS_ILLEGAL_TYPE_ACCESS=error;;;The type {0} is not visible. -# 0: variable name -VIS_ILLEGAL_VARIABLE_ACCESS=error;;;The variable {0} is not visible. -# 0: member name, 1: type defining member -VIS_ILLEGAL_STATIC_MEMBER_WRITE_ACCESS=error;;;Write access to the static member {1} defined in {0} must use {0} directly. -# 0: member name, 1: type defining member, 2: member alias -VIS_ILLEGAL_STATIC_MEMBER_WRITE_ACCESS_WITH_ALIAS=error;;;Write access to the static member {1} defined in {0} must use the alias {2} directly. -# 0: member kind, 1: member name, 2: 'read-only', when a read-only member was used with write access or 'write-only' when a write-only member was used with read access. -VIS_WRONG_READ_WRITE_ACCESS=error;;;The {0} {1} is {2}. -# 0: static or non-static, 1: member name, 2: static or non-static -VIS_WRONG_STATIC_ACCESSOR=error;;;The {0} member {1} cannot be accessed from a {2} context. -# 0: type variable name -VIS_WRONG_TYPE_VARIABLE_ACCESSOR=error;;;The type variable {0} cannot be accessed from a static context. -# 0: type parameter name, 1: kind of type hidden (e.g. class, type variable, etc.) -VIS_TYPE_PARAMETER_HIDES_TYPE=warning;;;The type parameter {0} hides {1} {0}. -# 0: concept which is not allowed, 1: Mode (n4js,strict,...) in which it is not allowed. -VIS_RESTRITCTED_USAGE=error;;;The usage of {0} is not allowed in {1} mode. -# 0: 'constructor' or 'construct signature', 1: classifier name whose constructor / construct signature is not visible. -VIS_NEW_CANNOT_INSTANTIATE_INVISIBLE_CONSTRUCTOR=error;;;The {0} of {1} is not visible. - -# no parameters required -TYP_TYPE_PARAM_MANDATORY_AFTER_OPTIONAL=error;;;Mandatory type parameters may not follow optional type parameters. -# no parameters required -TYP_TYPE_PARAM_DEFAULT_REFERENCES_LATER_TYPE_PARAM=error;;;Default type arguments may only reference type parameters that are declared before the current type parameter. -# 0: name of type parameter, 1: error message of subtype check -TYP_TYPE_PARAM_DEFAULT_NOT_SUBTYPE_OF_BOUND=error;;;Default argument of optional type parameter {0} must comply to its upper bound, but: {1} - -# no parameters required -CLF_MUST_BE_NOMINAL=error;;;Classes cannot be structural. -# no parameters required -CLF_CTOR_RETURN_TYPE=error;;;A constructor must not have a return type declaration. -# no parameters required -CLF_CTOR_ILLEGAL_MODIFIER=error;;;A constructor must not be declared abstract, static or final and may not be annotated with @Override. -# no parameters required -CLF_CALL_CONSTRUCT_SIG_ONLY_IN_N4JSD=error;;;Call and construct signatures may only be used in .n4jsd files. -# no parameters required -CLF_CALL_CONSTRUCT_SIG_NOT_IN_N4JS=error;;;Call and construct signatures are not allowed in n4js classifiers. Use shapes or @EcmaScript. -# no parameters required -CLF_CALL_CONSTRUCT_SIG_BODY=error;;;Call and construct signatures must not have a body. -# 0: kind of signature ('call' or 'construct') -CLF_CALL_CONSTRUCT_SIG_DUPLICATE=error;;;Duplicate {0} signature. -# no parameters required -CLF_CALL_CONSTRUCT_SIG_CANNOT_IMPLEMENT=error;;;An interface with a call or construct signature cannot be implemented by a class. -# no parameters required -CLF_CONSTRUCT_SIG_ONLY_IN_INTERFACE=error;;;Construct signatures may only be used in interfaces. -# no parameters required -CLF_CONSTRUCT_SIG_VOID_RETURN_TYPE=error;;;Construct signatures must have a non-void return type. -# no parameters required -CLF_CTOR_NO_TYPE_PARAMETERS=error;;;Constructors must not have any type parameters. -# no parameters required -CLF_NAME_DOLLAR=error;;;Member names must not start with a dollar character. -# 0: the human readable name of the violating discouraged character -CLF_NAME_CONTAINS_DISCOURAGED_CHARACTER=warning;;;Name should not contain {0} character. -# 0: static or const keywords -CLF_NAME_DOES_NOT_MATCH_WITH_PATTERN_FOR_STATIC_OR_CONST=warning;;;Name should be all upper case with words separated by underscores for variables with {0} modifier. -# 0: element meta type -CLF_NAME_DOES_NOT_START_UPPERCASE=warning;;;{0} names should start with upper case letter. -# 0: element meta type -CLF_NAME_DOES_NOT_START_LOWERCASE=warning;;;{0} names should start with lower case letter. -# 0: element description, 1: conflicting category -CLF_NAME_INDISTINGUISHABLE=error;;;{0} may be indistinguishable with {1}. -# 0: element description, 1: conflicting category -CLF_NAME_RESERVED=warning;;;{0} may be confused with {1}. -# no parameters required -CLF_NAME_CONFLICTS_WITH_CONSTRUCTOR=warning;;;Name may be confused with constructor. -# 0: element description, 1: conflicting type name 2: actual type -CLF_NAME_DIFFERS_TYPE=warning;;;{0} is not of type {1} but of type {2}. -# 0: name of final type, 1: name of type parameter -CLF_UPPER_BOUND_FINAL=warning;;;Final type {0} should not be used as upper bound of type parameter {1}. Final types cannot be extended. -# no parameters required -CLF_DEF_SITE_VARIANCE_ONLY_IN_CLASSIFIER=error;;;Declaration of definition-site variance only allowed in generic classes and interfaces, not in generic functions or methods. -# 0: "covariant" or "contravariant", 1: "covariant", "contravariant", or "invariant" -CLF_TYPE_VARIABLE_AT_INVALID_POSITION=error;;;Cannot use {0} type variable at {1} position. -# 0: the actual primitive type -CLF_EXTENDS_PRIMITIVE_GENERIC_TYPE=error;;;Cannot subclass primitive type {0}. -# 0: keyword (extends, implements, with), 1: expected meta type in plural form (classes, interfaces, roles), 2: type name, 3: actual meta type (class, interface) -CLF_WRONG_META_TYPE=error;;;Keyword {0} must be used with {1} but {2} is a {3}. -# 0: class name -CLF_EXTEND_FINAL=error;;;Cannot extend final class {0}. -# 0: keyword, 1: name of class -CLF_EXTEND_NON_ACCESSIBLE_CTOR=error;;;Cannot extend {0} {1} because its constructor is not accessible. -# 0: name of class, 1: name of super class -CLF_OBSERVABLE_MISSING=error;;;Class {0} extends observable class {1} and must therefore be annotated with @Observable. -# no parameters required -CLF_TEST_CLASS_NOT_EXPORTED=warning;;;Classes containing test methods must be abstract or marked with modifier export. - -# # 0: module name, 1: path to other module -CLF_DUP_MODULE=error;;;A duplicate module {0} is also defined in {1}. -# # 0: module name, 1: js module, 2: path to other module -CLF_DUP_DEF_MODULE=error;;;A duplicate definition module {0} for {1} is also defined in {2}. -# # 0: first name with line ({@link ValidatorMessageHelper#nameWithLine(TMember,TMember)}, 1: other name with line ({@link ValidatorMessageHelper#nameWithLine(TMember,TMember)} -CLF_DUP_CTOR=error;;;Constructor line {0} duplicates constructor in line {1}. -# # 0: first short description ({@link ValidatorMessageHelper#descriptionWithLine(TMember,TMember)}, 1: other short description ({@link ValidatorMessageHelper#descriptionWithLine(TMember,TMember)} -CLF_DUP_MEMBER=error;;;The {0} duplicates {1}. -# # 0: first short description ({@link ValidatorMessageHelper#descriptionWithLine(TMember,TMember)} -CLF_DUP_WITH_MEMBER=error;;;The {0} conflicts with the structural this type in the inherit constructor definition. -# 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 2: setter or getter -CLF_OVERRIDE_FIELD_REQUIRES_ACCESSOR_PAIR=error;;;The {0} cannot override {1}, matching {2} missing. -# 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)} -CLF_CONSUMED_OVERRIDE_FIELD=error;;;The consumed {0} cannot override {1}. -# 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: "overriding" or "implementing" 2: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)} -CLF_OVERRIDE_ANNOTATION=error;;;The {0} {1} {2} must be annotated with @Override. -# 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)} -CLF_REDEFINED_NON_ACCESSIBLE=error;;;The {0} cannot override or implement non-accessible {1}. -# 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)} -CLF_OVERRIDE_FINAL=error;;;The {0} cannot override final {1}. -# 0: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: "final" or "const" -CLF_OVERRIDE_WITH_FINAL_OR_CONST_FIELD=error;;;Cannot override {0} with a {1} field. -# 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)} -CLF_OVERRIDE_CONST=error;;;The {0} cannot override {1}. -# 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)} -CLF_OVERRIDEN_CONCRETE_WITH_ABSTRACT=error;;;The abstract {0} cannot override concrete {1}. -# 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)} -CLF_OVERRIDE_VISIBILITY=error;;;The {0} cannot reduce the visibility of {1}. -# 0: method, getter or setter, 1: member name -CLF_OVERRIDE_NON_EXISTENT=error;;;The {0} {1} must override or implement a {0} from a super class or interface. -# 0: member description, 1: member description -CLF_OVERRIDE_NON_EXISTENT_INTERFACE=warning;;;The {0} does not override {1} (no inheritance of static members in interfaces); remove annotation @Override. -# 0: description of constructor, 1: description of classifier inheriting the constructor, 2: description of classifier owning the constructor -CLF_PSEUDO_REDEFINED_SPEC_CTOR_INCOMPATIBLE=error;;;Inherited {0} in context of {1} not compatible to itself in context of {2}. -# 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden/implemented/consumed, 2: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)} 3: additional members or error information (may be empty) -CLF_REDEFINED_TYPE_NOT_SAME_TYPE=error;;;Type of {0} must equal type of {1} {2}.{3} -# 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden/implemented/consumed, 2: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)} -CLF_REDEFINED_BY_CONSUMED_TYPE_NOT_SAME_TYPE=error;;;Type of inherited {0} must equal type of {1} {2}. -# 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden/implemented/consumed, 3: signature type error message, 4: additional members or error information (may be empty) -CLF_REDEFINED_MEMBER_TYPE_INVALID=error;;;Type of {0} does not conform to {2} {1}: {3}.{4} -# 0: consumed/inherited, 1: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 2: overridden/implemented/consumed, 3: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 4: signature type error message -CLF_REDEFINED_BY_CONSUMED_MEMBER_TYPE_INVALID=error;;;Type of {0} {1} does not conform to {2} {3}: {4}. -# 0: comma separated description of conflicting members -CLF_CONSUMED_MEMBER_SOLVABLE_CONFLICT=error;;;Redefine ambiguously consumed members: {0}. -# 0: comma separated description of conflicting members -CLF_CONSUMED_MEMBER_UNSOLVABLE_CONFLICT=error;;;Incompatible consumed members: {0}. -# 0: inherited member leading to conflict, 1: comma separated description of conflicting members -CLF_CONSUMED_INHERITED_MEMBER_UNSOLVABLE_CONFLICT=error;;;Inherited {0} cannot implement {1}. -# 0: overriding description, should usually start with "Signature of " ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden/implemented/consumed, 2: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 3: signature type error message, 4: additional members or error information (may be empty) -CLF_REDEFINED_METHOD_TYPE_CONFLICT=error;;;{0} does not conform to {1} {2}: {3}.{4} -# 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)} -CLF_OVERRIDE_MEMBERTYPE_INCOMPATIBLE=error;;;Cannot override {1} with {0}. -# TODO remove?! 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)} -CLF_CONSUMED_OVERRIDE_MEMBERTYPE_INCOMPATIBLE=error;;;Cannot override {1} with consumed {0}. -# 0: getter/setter, 0: overridden descriptions (CSV) ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)} -CLF_CONSUMED_FIELD_ACCESSOR_PAIR_INCOMPLETE=error;;;Missing {0} to completely override consumed {1}. -# no parameters required -CLF_FIELD_CONST_FINAL=error;;;A field may not be declared both final and const. -# no parameters required -CLF_FIELD_CONST_STATIC=error;;;All const fields are static. Remove unnecessary modifier 'static'. -# 0: name of const field -CLF_FIELD_CONST_MISSING_INIT=error;;;Const field {0} must be provided with an initializer. -# no parameters required -CLF_FIELD_FINAL_STATIC=error;;;A field may not be declared both final and static. Use a const field instead. -# 0: name of final field -CLF_FIELD_FINAL_MISSING_INIT=error;;;Final field {0} must be provided with an initializer or must be initialized in the constructor. -# 0: name of final field -CLF_FIELD_FINAL_MISSING_INIT_IN_STATIC_POLYFILL=error;;;Final field {0} must be provided with an initializer or must be initialized in the constructor. HINT: You might want to check the polyfilled constructor. -# 0: name of final field (that has an initializer expression) -CLF_FIELD_FINAL_REINIT_IN_CTOR=error;;;Final field {0} has an initializer and may therefore not be initialized in the constructor. -# no parameters required -CLF_FIELD_OPTIONAL_OLD_SYNTAX=error;;;This syntax for optional fields is no longer allowed. Place the ? right after the field's name. - -# no parameters required -CLF_IMPLEMENT_EXTEND_WITH_WILDCARD=error;;;Wildcards may not be used as type argument when declaring an extended or implemented type. -# 0: "implement" or "extend", 0: name of interface, 1: name of type variable, 2: comma-separated list of type arguments -CLF_IMPLEMENT_EXTEND_SAME_INTERFACE_INCONSISTENTLY=error;;;Cannot {0} interface {1} multiple times with different type arguments for {2}: {3}. -# 0: overriding description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)}, 1: overridden description ({@link ValidatorMessageHelper#descriptionDifferentFrom(TMember,TMember)} 2: additional error information -CLF_IMPLEMENT_MEMBERTYPE_INCOMPATIBLE=error;;;Cannot implement {1} with {0}.{2} -# 0: descriptions of missing members, 1: the consumer -CLF_IMPLEMENT_MIXIN_CONFLICTS=error;;;The {0} cannot be mixed in {1} due to conflicts. - -# 0: name of the current classifier, 1: abstract non overridden descriptions -CLF_MISSING_IMPLEMENTATION=error;;;Class {0} must either be declared abstract or implement {1}. -# 0: name of the current classifier, 1: abstract non overridden descriptions -CLF_MISSING_IMPLEMENTATION_EXT=warning;;;External class {0} must either be declared abstract or explicit declare {1}. -# 0: class, method, getter or setter -CLF_ABSTRACT_FINAL=error;;;An abstract {0} cannot be declared final. -# no parameters required, will be changed to error (IDE-1236) -CLF_NO_FINAL_INTERFACE_MEMBER=warning;;;In interfaces, only methods may be declared final. -# no parameters required -CLF_NO_THIS_IN_STATIC_FIELD=error;;;The 'this' literal may not be used in initializers of static data fields. -# no parameters required -CLF_NO_THIS_IN_FIELD_OF_INTERFACE=error;;;In interfaces, the 'this' literal may not be used in initializers of data fields. -# no parameters required -CLF_NO_THIS_IN_STATIC_MEMBER_OF_INTERFACE=error;;;In interfaces, the 'this' literal may not be used in static methods or field accessors and in initializers of static data fields. -# no parameters required -CLF_INVALID_ACCESS_OF_STATIC_MEMBER_OF_INTERFACE=error;;;Static members of interfaces may only be accessed directly via the type name of their containing interface. -# 0: method, getter or setter, 1: name of method/getter/setter -CLF_STATIC_ABSTRACT=error;;;The {0} {1} may not be both static and abstract. -# no parameters required -CLF_ABSTRACT_BODY=error;;;Abstract methods do not specify a body. -# 0: method, getter or setter, 1: member name, 2: class name -CLF_ABSTRACT_MISSING=error;;;The abstract {0} {1} in class {2} can only be defined in an abstract class. -# 0: method, getter or setter, 1: member name -CLF_MISSING_BODY=error;;;The {0} {1} has to have either a body or must be defined abstract. -# no parameters required -CLF_MISSING_CTOR_BODY=error;;;Constructors must have a body. -# no parameters required -CLF_VOID_ACCESSOR=error;;;Void is not a valid type for getters and setters. -# 0: accessor description, 1: verb, 2: missing accessor type -CLF_UNMATCHED_ACCESSOR_OVERRIDE=error;;;{0} cannot be {1} without overriding the corresponding {2}. -# 0: accessor description, 1: verb, 2: missing accessor type -CLF_UNMATCHED_ACCESSOR_OVERRIDE_JS=warning;;;{0} should not be {1} without overriding the corresponding {2}. -# 0: interface name -CLF_MULTIPLE_ROLE_CONSUME=error;;;Cannot consume {0} multiple times. -# 0: 'Classes' or 'Roles' -CLF_EXT_EXTERNAL_N4JSD=error;;;{0} declared as external have to be placed in a file with file extension 'n4jsd'. -# none -CLF_EXT_PROVIDED_BY_RUNTIME_IN_RUNTIME_TYPE=error;;;Only runtime environments/libraries may specify elements provided by runtime. -# no parameters required -CLF_EXT_UNALLOWED_N4JSD=error;;;Only namespaces, classes, interfaces, enums, type aliases and functions declared as external as well as structurally typed interfaces are allowed in n4jsd files. -# no parameters required -CLF_EXT_EXPORTED=error;;;External elements have to be marked with modifier export. -# no parameters required -CLF_EXT_NOT_ANNOTATED_EXTEND_N4OBJECT=error;;;External classes annotated with @EcmaScript are not allowed to inherit from n4js classes. -# 0: classes or interfaces -CLF_EXT_CONSUME_NON_EXT=error;;;External {0} are not allowed to consume a non external interface. -# 0: classes or interfaces -CLF_EXT_IMPLEMENTS_NON_EXT=error;;;External {0} are not allowed to implement an interface from a non n4jsd file. -# 0: classes or interfaces -CLF_EXT_PUBLIC=error;;;External {0} have to be marked as public (and without @Internal). -# no parameters required -CLF_EXT_INTF_PUBLIC=error;;;Structural typed interfaces in n4jsd files have to be marked as public (and without @Internal). -# 0: classes or interfaces -CLF_EXT_EXTERNAL=error;;;External {0} have to be marked as external in n4jsd files. -# 0: methods, getters or setters, 1: classes or interfaces -CLF_EXT_NO_METHOD_BODY=error;;;{0} in external {1} have to have no body. -# 0: classes or interfaces -CLF_EXT_NO_FIELD_EXPR=error;;;Fields in external {0} have to have no right side. -# no parameters required -CLF_EXT_PUBLIC_CONSTRUCTOR=error;;;External classes annotated with @EcmaScript have to have a public constructor. -# 0: classes or interfaces -CLF_EXT_NO_OBSERV_ANNO=error;;;External {0} must not have the Observable annotation. -# 0: methods, getters or setters, 1: classes or interfaces, 2: Observable or Nfon -CLF_EXT_METHOD_NO_ANNO=error;;;{0} in external {1} must not have the {2} annotation. -# no parameters required -CLF_EXT_LITERAL_NO_VALUE=error;;;An enumeration literal in a n4jsd file isn't allowed to define a value. -# no parameters required -CLF_EXT_FUN_NO_BODY=error;;;External function declarations have to have no body. -# 0 var or constant -CLF_EXT_VAR_NO_VAL=error;;;External {0} declaration cannot be initialized. -# spec: Component/Manifest/General-Constraint, no parameters required -CLF_EXT_NO_MATCH=warning;;;For the given n4jsd file no corresponding external file resp. no matching implemented by expression can be found. -# doc: validate duplicates between src/src-test and external (so there is e.g. file A.n4js that compiles to A.js that would be name conflict with A.js in external), spec: Component/Manifest/General-Contraint, 0: file, 1: path -CLF_EXT_DUPLICATE_PATH_SRC_EXTERNAL=error;;;Duplicate external file {0}, has been already defined in {1}. -# no parameters required -CLF_IN_DEFINITION_PRJ_NON_N4JS=warning;;;Class declarations in definition projects should be annotated with @EcmaScript. - -# 0: annotation name, 1: type (interface or classifier) -CLF_EXT_PROVIDES_IMPL_ONLY_IN_DEFFILES=error;;;@{0} must only be used in external {1} in n4jsd files. -# 0: annotation name, 1: type (interface or classifier) -CLF_EXT_PROVIDES_IMPL_ONLY_IN_INTERFACE_MEMBERS=error;;;@{0} must only be used in {1}. -# 0: annotation name, 1: type (interface or classifier) -CLF_EXT_PROVIDES_IMPL_ONLY_IN_N4JS_INTERFACES=error;;;@{0} must only be used in n4js interfaces or classes. - - -# 0: type name, 1: access modifier name -CLF_LOW_ACCESSOR_WITH_INTERNAL=error;;;A {0} with visibility {1} shouldn't be annotated with @Internal. -# 0: 'extend' or 'implement', 1: type name, 2: description of members causing problems -CLF_NON_ACCESSIBLE_ABSTRACT_MEMBERS=error;;;Cannot {0} {1}: cannot implement one or more non-accessible abstract members: {2}. -# no parameters required -CLF_MINIMAL_ACCESSIBILITY_IN_INTERFACES=error;;;Members of interfaces must not be declared private. -# no parameters required -CLF_SPEC_WRONG_TYPE=error;;;Annotation @Spec may only be used with formal parameters of type ~i~this. -# 0: name of field, 1: type of member, 2: type system error message -CLF_SPEC_WRONG_ADD_MEMBERTYPE=error;;;Type of structural member {0} of spec parameter must be a subtype of {1}: {2}. -# no parameters required -CLF_SPEC_MULTIPLE=error;;;Only a single formal parameter in each constructor may be annotated with @Spec. -# 0: name of the superfluous property, 1: the type not defining the property -CLF_SPEC_SUPERFLUOUS_PROPERTIES=warning;;;{0} is not defined in {1}; it will not have any effect in the spec constructor. -# 0: name of the superfluous property, 1: the type not defining the property, 2: name of variable the object literal is assigned to -CLF_SUPERFLUOUS_PROPERTIES=warning;;;{0} is not defined in {1}; it will not be accessible from {2}. -# 0: name of the property, {1} built-in/provided by runtime interface -CLF_SPEC_BUILT_IN_OR_PROVIDED_BY_RUNTIME_OR_EXTENAL_WITHOUT_N4JS_ANNOTATION=warning;;;{0} is a property of a built-in, provided by runtime, or external module with @EcmaScript annotation. Hence the interface {1} can not be initialized in a spec constructor. -# 0:the cycle -CLF_INHERITANCE_CYCLE=error;;;Inheritance cycle detected: {0}. -# no param -CLF_INTERNAL_BAD_WITH_PRIVATE_OR_PROJECT=error;;;@Internal is only allowed for public and protected. -# no param -CLF_CANNOT_CALL_ABSTRACT_SUPER_METHOD=error;;;Cannot call super method since it is abstract. -# no param -CLF_CANNOT_REFER_TO_DEFAULT_METHOD_WITH_SUPER=error;;;Cannot refer to default method of an implemented interface with super. - -# 0: name of polyfill, 1: 'class' or 'interface' including indefinite article -CLF_POLYFILL_EXTEND_MISSING=error;;;Polyfill {0} must explicitly extend {1}. -# 0: name of polyfill -CLF_POLYFILL_NO_TOPLEVEL=error;;;Polyfill {0} can only extend top level class declaration. -# 0: 'class' or 'interface', 1: name of correct classifier kind (without article), 2: name of correct classifier kind including indefinite article, 3: name of *incorrect* classifier kind including indefinite article -CLF_POLYFILL_DIFFERENT_CLASSIFIER_KIND=error;;;Polyfill for {0} {1} must be {2}, not {3}. -# 0: name of polyfill, 1: 'class' or 'interface', 2: name of extended class -CLF_POLYFILL_DIFFERENT_NAME=error;;;Name of polyfill {0} must equal name of filled {1} {2}. -# 0: name of polyfill, 1: name polyfill's module, 2: name of filled class' module -CLF_POLYFILL_DIFFERENT_MODULE_SPECIFIER=error;;;Specifier {1} of module containing polyfill {0} must equal name of filled classes module specifier {2}. -# 0: name of polyfill, 1: global/not global polyfill module, 2: not/empty global polyfill -CLF_POLYFILL_DIFFERENT_GLOBALS=error;;;Module containing polyfill {0} is {1}, but filled classes module is {2}. -# 0: name of polyfill -CLF_POLYFILL_FILLED_NOT_PROVIDEDBYRUNTIME=error;;;Polyfill {0} cannot fill class not provided by runtime. -# 0: name of polyfill -CLF_POLYFILL_NOT_PROVIDEDBYRUNTIME=error;;;Polyfill {0} must be provided by runtime. -# 0: name of polyfill -CLF_POLYFILL_NO_IMPLEMENTS=error;;;Polyfill {0} must not implement any interfaces. -# 0: name of polyfill -CLF_POLYFILL_NO_EXTENDS_ADDITIONAL=error;;;Polyfill {0} must not extend any additional interfaces. -# 0: name of polyfill -CLF_POLYFILL_NOT_DIRECTLY_EXPORTED=error;;;Polyfill {0} must be exported. -# 0: name of polyfill, 1: name of polyfill modifier, 2: name of filled modifier, 3: 'class' or 'interface' -CLF_POLYFILL_DIFFERENT_MODIFIER=error;;;Polyfill {0} cannot be declared {1}, must be defined {2} just as the filled {3}. -# 0: name of polyfill, 1: type system error message -CLF_POLYFILL_CTOR_NOT_OVERRIDE_COMPATIBLE=error;;;Constructor of polyfill {0} must be override compatible with inherited constructor: {1} -# 0: name of polyfill, 1: 'class' or 'interface' -CLF_POLYFILL_DIFFERENT_TYPEPARS=error;;;Polyfill {0} must declare same type parameters as the filled {1}. -# 0: name of polyfill -CLF_POLYFILL_INCOMPLETE_TYPEARGS=error;;;Polyfill {0} must pass all type parameters to type arguments (even optional ones). -# 0: name of polyfill, 1: type par, 2: type arg -CLF_POLYFILL_TYPEPARS_DIFFER_TYPEARGS=error;;;Polyfill {0} must pass type parameters to type arguments in same order and without modifications, but {1} differs from {2}. -# 0: list of modules name with polyfills, 0: member name -CLF_POLYFILL_MULTIPOLYFILLS_MEMBER_CONFLICT=error;;;Polyfills in {0} provide member {1} - only one provider per member is allowed. -# 0: name of polyfill -CLF_POLYFILL_STATIC_FILLED_TYPE_NOT_AWARE=error;;;For static polyfills, the module of the filled type {0} must be annotated with @StaticPolyfillAware. -# 0: name of polyfill, 1: file extension (.n4js or .n4jsd) -CLF_POLYFILL_STATIC_DIFFERENT_VARIANT=error;;;Since static polyfill {0} is declared in an {1} file, the filled type must also be declared in an {1} file. - -# 0: string that is used as name for more than one literal -ENM_DUPLICTAE_LITERALS=error;;;Multiple literals with name {0}. -# no parameters required -ENM_INVALID_VALUE_EXPRESSION=error;;;Only string literals and number literals are allowed as value of an enum literal. -# 0: string with the name of the meta property -ENM_LITERALS_HIDE_META=error;;;EnumLiteral cannot have the same name as Enum meta property <{0}>. -# no parameters required -ENM_WITHOUT_LITERALS=error;;;An enum type must declare at least one literal. -# no parameters required -ENM_BOTH_NUMBER_AND_STRING_BASED=error;;;An enum may not be annotated with both @NumberBased and @StringBased. -# no parameters required -ENM_ILLEGAL_NUMERIC_VALUE=error;;;Values of type number may only be used for literals of @NumberBased enums. -# no parameters required -ENM_ILLEGAL_STRING_VALUE=error;;;Values of literals in @NumberBased enums must be of type number. -# no parameters required -ENM_INVALID_USE_OF_NUM_OR_STR_BASED_ENUM=error;;;A @NumberBased or @StringBased enum may only be used in type annotations and in property access expressions to access either one of its literals or the static getter called 'literals'. - -# no parameters required -# ITF_MEMBER_ACCESSIBILITY=error;;;Member of an interface must not have lower accessibility than the containing interface. -# no parameters required -ITF_NO_FINAL=error;;;Interfaces must not be declared final. -# 0: name of field, 1: name of interface -ITF_NO_FIELD_INITIALIZER=error;;;Cannot initialize field in interface. Only classes or interfaces implementing {1} can initialize {0}. -# 0: property kind name, 1: structural /nominal / -ITF_NO_PROPERTY_BODY=error;;;{0} in {1}interfaces must not have a body. -# no parameters required -ITF_CONSTRUCTOR_COVARIANCE=error;;;Constructors in interfaces must be annotated with @CovariantConstructor. -# no parameters required -ITF_IN_DEFINITION_PRJ_NON_N4JS=warning;;;Nominal interface declarations in definition projects should instead be structural (use '~'). - -# no parameters required -STRCT_ITF_CANNOT_EXTEND_INTERFACE=error;;;Structural interfaces cannot extend nominal interfaces. -# no parameters required -STRCT_ITF_CANNOT_CONTAIN_STATIC_MEMBERS=error;;;Structural interfaces cannot contain static members. -# no parameters required -STRCT_ITF_MEMBER_MUST_BE_PUBLIC=warning;;;Non-public members of structural interfaces are effectless. - -# 0: name of cyclic type aliases -ALI_CYCLIC_TYPE_ALIAS=error;;;Cyclic type alias declaration: {0}. -# no parameters required -ALI_INVALID_MODIFIER=error;;;A type alias may be referenced {0} only if its aliased type may be referenced {0}. -# 0: the string "{}" -ALI_INVALID_TYPE_ALIAS_IN_TYPE_TYPE_REF=error;;;A type alias may be used inside type{0} or constructor{0} only if its aliased type may be used at this location. - -# 0: passed parameter count, 1: expected parameter count -FUN_PARAM_COUNT=error;;;Passed parameter count {0} doesn't match with expected parameter count {1}. -# no parameters required -FUN_BLOCK=warning;;;Functions declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function. -# no parameters required -FUN_BODY=error;;;Functions have to have a body. -# 0: element description, 1: conflicting category -FUN_NAME_RESERVED=error;;;{0} may be confused with {1}. -# no parameters -FUN_NAME_MISSING=error;;;Function declarations must have a name. -# 0: formal parameter -FUN_PARAM_OPTIONAL_WRONG_SYNTAX=error;;;Wrong syntax: Use {0}=undefined instead of ?. -# no parameters -FUN_PARAM_INITIALIZER_ILLEGAL_FORWARD_REFERENCE=error;;;Illegal forward reference to formal parameter of same function. -# no parameters -FUN_PARAM_INITIALIZER_ONLY_UNDEFINED_ALLOWED=error;;;Only ''undefined'' allowed for initializers of default parameters in function types. -# 0: formal parameter -# 1: identifier -FUN_PARAM_INITIALIZER_ILLEGAL_REFERENCE_TO_BODY_VARIABLE=error;;;Initializer of parameter ''{0}'' cannot reference the identifier ''{1}'' declared in the body. -# 0: formal parameter -FUN_PARAM_INITIALIZER_ILLEGAL_AWAIT_CALL=error;;;Illegal await-expression in initializer of formal parameter ''{0}''. -# 0: name of actually used generator type, 1: expected generator kind (synchronous or asynchronous), 2: name of expected generator type -FUN_GENERATOR_RETURN_TYPE_MISMATCH=warning;;;Type {0} is intended for {1} generator functions; consider using type {2} instead. - -# no parameters required -AST_SEPARATE_DEFAULT_EXPORT_WITHOUT_FROM=error;;;Missing from-clause in default re-export. -# 0: element, 1: kind of value -AST_ELEMENT_MISUSED_AS_VALUE_OR_TYPE=error;;;{0} cannot be used as a {1}. -# no parameters required -AST_INVALID_NEW_TARGET=error;;;Invalid new.target. -# no parameters required -AST_INVALID_YIELD_EXPRESSION=error;;;The parameter initializer of a generator may not contain a `yield` expression. -# no parameters required -AST_CONST_IN_STATEMENT_POSITION=error;;;Const variable statements must be on the top level or nested in a block. -# no parameters required -AST_LET_IN_STATEMENT_POSITION=error;;;Let declarations may not appear in statement position. -# 0: name of blank const variable -AST_CONST_HAS_NO_INITIALIZER=error;;;Const variable {0} must be provided with an initializer. -# no parameters required -AST_STR_NO_OCTALS=error;;;octal literals and octal escape sequences are not allowed in strict mode. -# 0: operand (decrement or increment) -AST_INVALID_OPERAND=error;;;Invalid {0} operand. -# no parameters required -AST_EXP_INVALID_LHS_ASS=error;;;Invalid assignment left-hand side. -# 0: identifier -AST_RESERVED_IDENTIFIER=error;;;{0} is a reserved identifier. -# no parameters required -AST_STR_NO_WITH_STMT=error;;;With statement not allowed. -# no parameters required, not used yet in AST, was before in N4JSStrictValidator -AST_STR_FUN_NOT_NESTED=error;;;Functions must only be declared on script level or as part of other expressions -# no parameters required -AST_INVALID_RETURN=error;;;return statement without enclosing function -# no parameters required -AST_INVALID_CONTINUE=error;;;continue statement without enclosing iteration -# no parameters required -AST_INVALID_BREAK=error;;;break statement without enclosing iteration or case block -# no parameters required -AST_INVALID_LABEL=error;;;Label must be of an enclosing iteration statement but may not cross function boundaries -# no parameters required -AST_THIS_WRONG_PLACE=error;;;The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.) -# 0: variable name -AST_VAR_DECL_RECURSIVE=warning;;;Reference to variable {0} within the initializer expression of the declaration of {0}. -# no parameters required -AST_VAR_DECL_IN_FOR_INVALID_INIT=error;;;The iteration variable of a for..in or for..of loop must not be provided with an initializer. -# no parameters required -AST_INVALID_FOR_AWAIT=error;;;Only for..of loops may be used for asynchronous iteration with "for await". -# no parameters required -AST_INVALID_OPTIONAL_TYPE_PARAMS=error;;;Only type parameters of classes, interfaces, and type aliases may be declared optional. -# no parameters required -AST_NO_TYPE_ARGS_IN_CLASSIFIERTYPEREF=error;;;Only raw types can be used in classifier type references. -# no parameters required -AST_NO_FUNCTIONTYPEREFS_IN_CLASSIFIERTYPEREF=error;;;Function types are not allowed in classifier type references. -# no parameters required -AST_INVALID_EXPR_IN_LHS_DESTRUCTURING_PATTERN=error;;;Only a variable or nested destructuring pattern is allowed at this location within a destructuring pattern. -# no parameters required -AST_INVALID_PROPERTY_METHOD_IN_LHS_DESTRUCTURING_PATTERN=error;;;Property methods are not allowed within an object destructuring pattern. -# no parameters required -AST_INVALID_DEFAULT_EXPR_SINGLE_NAME_PROPERTY=error;;;A default value is only allowed within a destructuring pattern. -# no parameters required -AST_REST_MUST_APPEAR_AT_END=error;;;Rest operator only allowed on last element in an array destructuring pattern. -# no parameters required -AST_REST_WITH_INITIALIZER=error;;;Rest operator does not support an initializer. -# no parameters required -AST_TYPE_DECL_MISSING_NAME=error;;;Name missing in type declaration. -# no type annotation for catch variable -AST_CATCH_VAR_TYPED=error;;;Catch variable must not be typed. -# 0: name of the JavaScript variant of the context -AST_TOP_LEVEL_STATEMENTS=error;;;Top-level statements are not supported in {0} files. -# No parameters -AST_VAR_STMT_NO_DECL=error;;;A variable statement must at least contain one variable declaration. -# 0: script annotation name -AST_SCRIPT_ANNO_INVALID_PLACEMENT=error;;;The script annotation @@{0} must be placed at the top of the module. -# 0: Forbidden Type e.g. null / undefined -AST_BINARY_LOGICAL_EXPRESSION_MISSING_PART=error;;;The logical expression is missing the {0}. -# no parameters required -AST_IMPORT_CALL_SPREAD=error;;;The spread operator is not allowed in import calls. -# 0: Invalid parent e.g. && / || -AST_INVALID_COALESCE_PARENT=error;;;Nullish coalescing expressions cannot be contained within an {0} operation. -# 0: Invalid child e.g. && / || -AST_INVALID_COALESCE_CHILD=error;;;Nullish coalescing expressions cannot immediately contain an {0} operation. - -# 0: local variable name -CFG_LOCAL_VAR_UNUSED=warning;;;The local variable {0} is never used -# 0: local variable name -CFG_USED_BEFORE_DECLARED=warning;;;Variable {0} is used before it is declared - -# 0: local variable name -# 1: 'is' or 'may be' -# 2: 'null' or 'undefined' -# 3: reason (optional) -DFG_NULL_DEREFERENCE=warning;;;Variable {0} {1} {2}{3} - -# 0: shadowing object, 1: shadowed object -AST_NAME_SHADOW_WARN=warning;;;{0} shadows {1}. -# 0: shadowing object, 1: shadowed object -AST_NAME_SHADOW_ERR=error;;;{0} shadows {1}. -# 0: hiding parameter 1: hidden parameter -AST_GLOBAL_NAME_SHADOW_ERR=error;;;{0} shadows {1} from global scope. -# 0: name -AST_GLOBAL_JS_NAME_CONFLICT=error;;;Globally defined element named {0} must be defined in runtime environment. -# 0: name -AST_GLOBAL_NAME_CONFLICT=error;;;Globally defined element must not be named {0}. -# 0: duplicating object, 1: duplicated object -AST_NAME_DUPLICATE_ERR=error;;;{0} duplicates {1}. -# 0: duplicating object, 1: duplicated object -AST_NAME_DUPLICATE_WARN=warning;;;{0} duplicates {1}. - - -# 0: grammar rule, 1: value -VCO_DOUBLE_NEGATIVE=error;;;{0}-value may not be negative (value: {1}). -# no parameters required -VCO_DOUBLE_CONVERT_EMPTY_STR=error;;;Couldn't convert empty string to a double value. -# 0: the string value -VCO_DOUBLE_CONVERT_STR=error;;;Couldn't convert {0} to a double value. -# 0: grammar rule, 1: value -VCO_HEXINT_NEGATIVE=error;;;{0}-value may not be negative (value: {1}). -# no parameters required -VCO_HEXINT_CONVERT_EMPTY_STR=error;;;Couldn't convert empty string to an hex int value. -# 0: the string value -VCO_HEXINT_CONVERT_TOO_SHORT=error;;;Couldn't convert {0} to an int value. -# 0: the string value -VCO_HEXINT_CONVERT_STR=error;;;Couldn't convert {0} to an hex int value. -# 0: grammar rule, 1: value -VCO_BINARYINT_NEGATIVE=error;;;{0}-value may not be negative (value: {1}). -# no parameters required -VCO_BINARYINT_CONVERT_EMPTY_STR=error;;;Couldn't convert empty string to a binary int value. -# 0: the string value -VCO_BINARYINT_CONVERT_TOO_SHORT=error;;;Couldn't convert {0} to an int value. -# 0: the string value -VCO_BINARYINT_CONVERT_STR=error;;;Couldn't convert {0} to a binary int value. -# 0: grammar rule, 1: value -VCO_OCTALINT_NEGATIVE=error;;;{0}-value may not be negative (value: {1}). -# no parameters required -VCO_OCTALINT_CONVERT_EMPTY_STR=error;;;Couldn't convert empty string to an octal int value. -# 0: the string value -VCO_OCTALINT_CONVERT_TOO_SHORT=error;;;Couldn't convert {0} to an int value. -# 0: the string value -VCO_OCTALINT_LEADING_ZEROS=error;;;Don't use extra leading zeros {0}." -# 0: the string value -VCO_OCTALINT_CONVERT_STR=error;;;Couldn't convert {0} to an octal int value. -# 0: grammar rule, 1: value -VCO_SCIINT_NEGATIVE=error;;;{0}-value may not be negative (value: {1}). -# no parameters required -VCO_SCIINT_CONVERT_EMPTY_STR=error;;;Couldn't convert empty string to an scientific int value. -# 0: the string value -VCO_SCIINT_CONVERT_STR=error;;;Couldn't convert {0} to an scientific int value. -# 0: identifier, 1: position -VCO_IDENT_ESCAPE_SEQ=error;;;Illegal escape sequence in identifier {0} at position {1}. -# 0: result, 1: identifier, 2: position -VCO_IDENT_ILLEGAL_CHAR_WITH_RESULT=error;;;Illegal character in identifier ''{0}'' ({1}) at position {2}. -# 0: identifier, 1: position -VCO_IDENT_ILLEGAL_CHAR=error;;;Illegal character in identifier ''{0}'' at position {1}. -# no parameters required -VCO_JSXIDENT_WHITESPACE_COMMENT=error;;;JSX attribute names may not contain whitespace or comments. Attribute names ending with a '-' and directly followed by another attribute name are merged and must not contain whitespace or comments. -# no parameters required -VCO_STRING_DOUBLE_QUOTE=error;;;String literal is not properly closed by a double-quote. -# no parameters required -VCO_STRING_QUOTE=error;;;String literal is not properly closed by a quote. -# no parameters required -VCO_TEMPLATE_QUOTE=error;;;Template literal is not properly closed by a backtick. -# no parameters required -VCO_TEMPLATE_MIDDLE=error;;;Template literal is not properly closed by ${. -# no parameters required -VCO_TEMPLATE_IN_OPT_CHAIN=error;;;Tagged template expressions are not permitted in an optional chain. -# no parameters required -VCO_STRING_BAD_ESCAPE_WARN=warning;;;Bad escapement -# no parameters required -VCO_STRING_BAD_ESCAPE_ERROR=error;;;Bad escapement -# no parameters required -VCO_REGEX_INVALID=error;;;Invalid regular expression literal -# 0: literal -VCO_REGEX_ILLEGAL_ESCAPE=error;;;Illegal escape sequence in regular expression {0} -# no parameters required -VCO_REGEX_NAMED_GROUP=warning;;;Named capture groups are not supported on all platforms. -# no parameters required -VCO_NPE=error;;;A NullPointerException occurred. This indicates a missing value converter or a bug in its implementation. -# 0: feature name -VCO_NULL_FEATURE=error;;;ValueConverter returned null for primitive feature {0} - - -# no parameters required -BIT_SYMBOL_INVALID_USE=error;;;Invalid use of 'Symbol': may only be used to create symbols (i.e. Symbol()) or to access built-in symbols (e.g. Symbol.iterator). -# no parameters required -BIT_SYMBOL_NOT_A_CTOR=error;;;Symbol is not a constructor, use Symbol() without new. - - -# no parameters required -TYS_MISSING=error;;;Types model hasn't been built for this file. Please report this bug to a N4JS developer. -# 0: expression -TYS_CANNOT_TYPE=error;;;cannot type {0}. -# 0: left expression, 1: right expression -TYS_NO_SUBTYPE=error;;;{0} is not a subtype of {1}. -# 0: expected type, 1: actual type -TYS_NO_SUPERTYPE_WRITE_ACCESS=error;;;expecting write-access for type {0} but {1} is not a super type of {0}. -# no parameters required -TYS_NULL_OBJECT=error;;;passed null object to system at {0}. -# no parameters required -TYS_VOID_AT_WRONG_LOCATION=error;;;Type 'void' may only be used to declare the return type of functions and methods. -# 0: member type, 1: member name, 2: type name -TYS_MEMBER_NOT_IN_STRUCTURAL_TYPE_DEF_SITE=error;;;{0} {1} is not available for structurally defined type {2}. -# 0: member type, 1: member name, 2: type name -TYS_MEMBER_NOT_IN_STRUCTURAL_TYPE_USE_SITE=error;;;{0} {1} is not available for structurally referenced type {2}. -# 0: member type, 1: member name, 2: type name -TYS_MEMBER_NOT_IN_STRUCTURAL_FIELDS_TYPE_USE_SITE=error;;;{0} {1} is not available for fields-only-referenced type {2}. -# no parameters required -TYS_INSTANCEOF_NOT_SUPPORTED_FOR_USE_SITE_STRUCTURAL=error;;;'instanceof' cannot be used with use site structural typing. -# 0: type name -TYS_INSTANCEOF_NOT_SUPPORTED_FOR_BUILT_IN_INTERFACES=error;;;'instanceof' cannot be used with built-in interface {0}. -# no parameters required -TYS_INSTANCEOF_NOT_SUPPORTED_FOR_PRIMITIVE_TYPES=error;;;'instanceof' cannot be used with primitive types. -# 0: property name -TYS_PROPERTY_HAS_NO_SETTER=error;;;Property {0} has no setter. -# 0: type name -TYS_PRIMITIVE_TYPE_DYNAMIC=error;;;Primitive type {0} must not be referenced dynamically. -# no parameters required -TYS_COMPOUND_MISSING_GETTER=error;;;Missing getter on left-hand side of compound assignment. -# no parameters required -TYS_NON_VOID_ASYNC=error;;;Internal error: Only Promise allowed as inferred return type of an async FunctionDefinition -# no parameters required -TYS_NON_THIS_ASYNC=error;;;The return type of an async function is not allowed to refer to the this-type. -# 0: type name -TYS_FOR_IN_VAR_STRING=error;;;Type of for-in-loop variable must be a super type of string but {0} is not. -# no parameters required -TYS_ADDITIONAL_STRUCTURAL_MEMBERS_ON_TYPE_VARS=error;;;No additional structural members allowed on type variables, since they can cause collisions. -# no parameters required -TYS_FUNCTION_DISALLOWED_AS_TYPE=error;;;The name of a declared function may not be used as a type name. -# no parameters required -TYS_STRUCTURAL_PRIMITIVE=warning;;;Structural type operator ~ does not have any effect on primitive types. - -# no parameters required -EXP_USE_OF_UNDEF_EXPR=warning;;;The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'. -# 0: actual type -EXP_CALL_NOT_A_FUNCTION=error;;;Not a function or method: {0}. -# 0: comma-separated list of conflicting callable type references -EXP_CALL_CONFLICT_IN_INTERSECTION=error;;;More than one callable type in intersection: {0}. -# no parameters required -EXP_CALL_CLASS_CTOR=error;;;Cannot directly invoke class constructor functions; use 'new' instead. -# 0: actual type -EXP_NEW_NOT_A_CTOR=error;;;Not a reference to a constructor: {0}. -# 0: intersection type with conflicting ctors or construct signatures -EXP_NEW_CONFLICT_IN_INTERSECTION=error;;;More than one constructor or construct signature in intersection: {0}. -# 0: type arg name of constructor, 1: static type -EXP_NEW_WILDCARD_NO_COVARIANT_CTOR=error;;;Cannot instantiate {0}, because {1} does not have a @CovariantConstructor. -# 0: type arg name of constructor -EXP_NEW_WILDCARD_OR_TYPEVAR=error;;;Cannot instantiate {0}. -# 0: abstract class, interface, 1: classifier name -EXP_NEW_CANNOT_INSTANTIATE=error;;;Cannot instantiate {0} {1}. -# 0: number of expected type args, 1: number of actual type args -EXP_WRONG_NUMBER_OF_TYPEARGS=error;;;Incorrect number of type arguments: expected {0}, got {1}. -# 0: class, interface, method, function 1: name of classifier/method/function, 2: number of expected type args, 3: number of actual type args -EXP_WRONG_NUMBER_OF_TYPEARGS_FOR_ELEMENT=error;;;Incorrect number of type arguments for {0} {1}: expected {2}, got {3}. -# 0: maximum number of element types in an ArrayN -EXP_WRONG_NUMBER_OF_TYPEARGS_FOR_ITERABLE_N_SYNTAX=error;;;The ArrayN types are available for a maximum of {0} element types only (i.e. type Array{0}). -# 0: upper or lower, 1: covariant or contravariant -EXP_INCONSISTENT_VARIANCE_OF_TYPE_ARG=error;;;Cannot use wildcard with {0} bound as argument to a {1} type parameter. -# 0: covariant or contravariant, 1: covariant or contravariant -EXP_INCONSISTENT_VARIANCE_OF_TYPE_ARG_IN_OUT=error;;;Cannot combine {0} on use site with {1} on definition site. -# 0: expected num of params, 1: actual num of params -EXP_NUM_OF_ARGS_TOO_FEW=error;;;Incorrect number of arguments: expected {0}, got {1}. -# 0: expected num of params, 1: actual num of params -EXP_NUM_OF_ARGS_TOO_MANY=error;;;Incorrect number of arguments: expected {0}, got {1}. -# 0: from type ref, 1: target type ref -EXP_CAST_FAILED=error;;;Cannot cast from {0} to {1} -# 0: from type ref, 1: target type ref -EXP_CAST_UNNECESSARY=warning;;;Unnecessary cast from {0} to {1} -# no parameter required -EXP_CAST_INVALID_TARGET=error;;;Can only cast to class, interface, enum, function, primitive, union or intersection types -# 0: recognized type, 2: result, e.g. NaN -EXP_MATH_OPERATION_RESULT_IS_CONSTANT=warning;;;Operand {0} will always result in {1}. -# 0: recognized type, 1: constant value -EXP_MATH_OPERAND_IS_CONSTANT=warning;;;Operand of type {0} will be interpreted as {1}. -# 0: recognized type, 2: result, e.g. NaN -EXP_MATH_TYPE_NOT_PERMITTED=error;;;Operand of type {0} cannot be converted to number. -# 0: left type 1: rght type 2: result -EXP_WARN_CONSTANT_EQUALITY_TEST=warning;;;Neither {0} is a subtype of {1} nor {1} is a subtype of {0}. The expression will always evaluate to {2}. -# 0: Forbidden Type e.g. null / undefined -EXP_FORBIDDEN_TYPE_IN_BINARY_LOGICAL_EXPRESSION=error;;;{0} is not allowed on the left hand side of a logical expression. -# 0: member description, 1: type of target, 2: declared this type (from @This annotation) -EXP_ACCESS_INVALID_TYPE_OF_TARGET=error;;;Target of property access not a subtype of the declared @This type of {0}: {1} is not a subtype of {2}. -# 0: method name -EXP_METHOD_REF_UNATTACHED_FROM_RECEIVER=error;;;A reference to method {0} is created detached from a (correct) this-instance. -# 0: await expression, 1 async annotation -EXP_MISPLACED_AWAIT=error;;;{0} is allowed only inside functions annotated with {1}. -# no parameter required -EXP_MISSNG_AWAIT_FOR_ASYNC_TARGET=warning;;;Calling async function without await, Promise should be made explicit. -# 0: Suspicious expression, 1: boolean value, 2:left-hand/right-hand -EXP_WARN_DISPENSABLE_CONDITIONAL_EXPRESSION=warning;;;Dispensable use of conditional expression. The expression ''{0}'' always evaluates to {1}, so only the {2} side will ever be evaluated. -# no parameter required -EXP_AWAIT_NON_ASYNC=warning;;;await should only be used on expressions of type Promise since otherwise it has no effect. -# 0: recognized expression -EXP_AWAIT_NON_ASYNC_SPECIAL=warning;;;await should not be used on ''{0}'' since it has no effect here. - -# no parameter required -FUN_RETURNTYPE_VOID_FOR_SETTER_VIOLATED=error;;;Set accessors must not return anything. -# 0: name of return type -FUN_MISSING_RETURN_EXPRESSION=error;;;Return statement must have an expression of type {0} -# no parameter required -FUN_MISSING_RETURN_OR_THROW_STATEMENT=error;;;Missing return or throw statement. -# no parameter required -FUN_MISSING_ELSE_BRANCH_FOR_CONDITIONAL_LAST_CONTROL_FLOW=error;;;Last if statement on control flow path is missing required else branch. -# no parameter required -FUN_MISSING_RETURN_OR_THROW_STATEMENT_WHILE_CANNOT_BE_CHECKED=error;;;Missing return or throw statement after while-expression. Correct termination of while-loops cannot be verified. Please append return/throw. -# no parameter required -FUN_MISSING_RETURN_OR_THROW_STATEMENT_FOR_CANNOT_BE_CHECKED=error;;;Missing return or throw statement after for-expression. Correct termination of for-loops cannot be verified. Please append return/throw. -# no parameter required -FUN_DEAD_CODE=warning;;;Dead code. -# 0: last executed statement name -FUN_DEAD_CODE_WITH_PREDECESSOR=warning;;;Dead code. No execution possible after {0}. -# no parameters required -FUN_SETTER_CANT_BE_VARIADIC=error;;;Variadic parameter is not allowed in setter declarations. -# no parameters required -FUN_SETTER_CANT_BE_DEFAULT=error;;;Default parameter is not allowed in setter declarations. -# no parameters required -FUN_PARAM_VARIADIC_ONLY_LAST=error;;;Only the last formal parameter can be variadic. -# 0: name of parameter -FUN_PARAM_IMPLICIT_DEFAULT_PARAM=warning;;;This parameter is changed to the default parameter ''{0}=undefined'' since it follows a default parameter. -# no parameter required -FUN_PARAM_VARIADIC_WITH_INITIALIZER=error;;;Variadic parameters must not have a default initializer. -# no parameter required -FUN_SINGLE_EXP_LAMBDA_IMPLICIT_RETURN_ALLOWED_UNLESS_VOID=error;;;An arrow-function is used in a context where its body is expected to have some value as opposed to being void. -# 0: type parameter name -FUN_UNUSED_GENERIC_TYPE_PARAM=warning;;;Type variable {0} not used in parameters or return type. - -# no parameters required -KEY_SUP_INVALID_USAGE=error;;;Keyword super may only be used in member access expressions, call expressions or new expressions. -# no parameters required -KEY_SUP_ACCESS_INVALID_LOC=error;;;Super member access may only be used in constructors, methods, getters, or setters. -# no parameters required -KEY_SUP_ACCESS_NO_EXTENDS=error;;;Super member access requires a declared super type. -# no parameters required -KEY_SUP_ACCESS_INVALID_LOC_INTERFACE=error;;;Super member access may not be used in interfaces. -# no parameters required -KEY_SUP_ACCESS_FIELD=error;;;Super member access may not be used to access a field. -# no parameters required -KEY_SUP_CTOR_INVALID_LOC=error;;;Super calls may only be used in constructors. -# no parameters required -KEY_SUP_NEW_NOT_SUPPORTED=error;;;Keyword super with in expressions is not supported yet. -# no parameters required -KEY_SUP_NESTED=error;;;Super call must not be nested in function expressions. -# no parameters required -KEY_SUP_CTOR_EXPRSTMT=error;;;Super constructor call must no be used in a composed expression. -# 0: container in which super is nested (with line number). -KEY_SUP_CTOR_NESTED=error;;;Super constructor call must only be directly contained in constructor body, i.e. not nested in {0}. -# 0: container in which super is nested (with line number). -KEY_SUP_CTOR_INVALID_EXPR_BEFORE=error;;;Super constructor call must not be preceded by {0}. -# 0: super class name -KEY_SUP_REQUIRE_EXPLICIT_SUPERCTOR_CALL=error;;;Must explicitly invoke constructor of super class {0}. -# no parameters required -KEY_SUP_CALL_NO_INDEXACCESS=error;;;Super member access may not be used with index access. - -# no parameters required -KEY_THIS_REJECTED_IN_TOP_LEVEL_LAMBDA=error;;;In a top-level arrow function, the 'this' keyword refers to nothing. - -# no parameters required -EXP_OPTIONAL_INVALID_PLACE=error;;;The optional modifier isn't allowed here. -# 0: name of const variable -EXP_ASSIGN_CONST_VARIABLE=error;;;Const variable {0} is read-only. -# 0: names of legal built-in symbol -EXP_INDEXED_ACCESS_SYMBOL_INVALID=error;;;Indexed access with built-in symbols is only allowed for {0}. -# 0: name of built-in symbol, 1: name of expected receiver type -EXP_INDEXED_ACCESS_SYMBOL_WRONG_TYPE=error;;;Access of property Symbol.{0} only allowed for instances of {1}, immediate instances of Object, and dynamic types. -# 0: name of built-in symbol, 1: name of receiver type -EXP_INDEXED_ACCESS_SYMBOL_READONLY=error;;;Access to property Symbol.{0} of an {1} is read-only. -# no parameters required -EXP_INDEXED_ACCESS_ENUM=error;;;Indexed access is not allowed for enumerations. -# no parameters required -EXP_INDEXED_ACCESS_FORBIDDEN=error;;;Indexed access is only allowed for strings, arrays and iterables and for immediate(!) instances of Object. -# 0: index-key in indexed-access -EXP_INDEXED_ACCESS_COMPUTED_NOTFOUND=error;;;Member {0} not found. -# no parameters required -EXP_INDEXED_ACCESS_IMPL_RESTRICTION=error;;;Implementation restriction: member name clashes with compiler-internal, synthetic, mangled name. -# no parameters required -EXP_PROMISIFY_INVALID_USE=error;;;@Promisify may only be applied to a call expression with a @Promisifiable function or method as target. -# no parameters required -EXP_COMPUTED_PROP_NAME_DISCOURAGED=warning;;;Computed property name using an expression other than a compile-time expression; this property won't be type-checked at compile time. -# 0: detailed message -EXP_COMPILE_TIME_MANDATORY=error;;;Not a compile-time expression: {0}. - -# 0: usage type ('invoke' or 'instantiate'), 1: name of interface with call/construct signature, 2: signature kind ('call' or 'construct') -EXP_CALL_CONSTRUCT_SIG_OF_INTERFACE_DIRECTLY_USED=error;;;Cannot directly {0} interface {1}; its {2} signature applies to values of type {1}, not to {1} itself. - - -# 0: type names, submessage -- full message is a concatenation of these messages -COMP_SUBMESSAGES=error;;;{1} in {0}. - -# 0: member name -UNI_UNCOMMON=error;;;Member {0} not present in all types of union or incompatible. -# 0: member name, 1: list of types in union that do not contain a member of that name -UNI_MISSING=error;;;Member {0} not present in all types of union; missing from: {1}. -# 0: either "getters" or "setters", 1: member name, 2: either "read-only" or "write-only" -UNI_INVALID_COMBINATION=error;;;Union combines fields and {0} with name {1} and therefore property {1} is {2}. -# 0: member name -UNI_INVALID_COMBINATION_SETTER_VS_READ_ONLY_FIELD=error;;;Union combines fields and setters with name {0} but still write-access is not allowed because one or more fields are read-only (const or @Final). -# 0: member name, 1: list of kinds -UNI_MULTIPLE_KINDS=error;;;Member {0} not of same kind in all types of union: {1}. -# 0: member name, 1: list of types -UNI_DIFFERENT_TYPES=error;;;Member {0} not of same type in all types of union: {1}. -# no parameters required -UNI_ANY_USED=warning;;;The use of the any type in a union type is discouraged. -# no parameters required -UNI_REDUNDANT_SUBTYPE=warning;;;The use of redundant subtypes is discouraged. - - -# no parameters required -INTER_ANY_USED=warning;;;The use of the any type in an intersection type is discouraged. -# no parameters required -INTER_ONLY_ONE_CLASS_ALLOWED=warning;;;An intersection type should not contain more than one class. Otherwise there cannot exist a value of such a type. -# no parameters required -INTER_TYEPARGS_ONLY_ONE_CLASS_ALLOWED=warning;;;Type arguments for the same covariant type parameter in an intersection type should not contain more than one class. Otherwise there cannot exist a value of such a type. -# no parameters required -INTER_WITH_ONE_GENERIC=warning;;;An intersection type should not contain different type arguments for the same invariant type parameter. Otherwise is can be instantiated only with undefined. -# no parameters required -INTER_REDUNDANT_SUPERTYPE=warning;;;The use of redundant supertypes is discouraged. -# 0: method member name, 1: list of kinds -INTER_MEMBER_TYPE_CONFLICT=error;;;Member method {0} is in conflict with non-method members in types of intersection: {1}. -# 0: member name -INTER_UNCOMMON=error;;;Member {0} is incompatible in types of intersection. - -# no parameters required -ANN__N4JS_NO_EFFECT=warning;;;This annotation is deprecated and has no effect. -# no parameters required -ANN__ONLY_IN_N4JS=error;;;Annotations are a N4JS feature and cannot be used in JS mode. -# 0: annotation name -ANN_NOT_DEFINED=error;;;The annotation @{0} is not defined. -# 0: annotation name, 1: expected number of arguments, 2: actual number of arguments -ANN_WRONG_NUMBER_OF_ARGUMENTS=error;;;Wrong number of annotation arguments: @{0} expects {1} but got {2}. -# 0: annotation name, 1: expected type -ANN_WRONG_ARGUMENT_TYPE=error;;;The annotation @{0} expects a {1} here. -# 0: annotation name -ANN_DISALLOWED_AT_LOCATION=error;;;The annotation @{0} is disallowed for this location. -# 0: annotation name, 1: list of language variants -ANN_ONLY_ALLOWED_LOCATION_CONSTRUCTORS=error;;;The annotation @{0} may only be applied at a parameter of a constructor. -# 0: name of annotation (without @) -ANN_NON_REPEATABLE=error;;;Duplicate annotation of non-repeatable type @{0}. -# 0: name of annotation -ANN_UNNECESSARY=warning;;;Unnecessary @{0}. -# no parameters required -ANN_THIS_DISALLOWED_ON_STATIC_MEMBER_OF_INTERFACE=error;;;@This annotation not allowed on static members of interfaces. -# 0: member description, 1: description of containing type, 2: required type -ANN_THIS_NOT_SUBTYPE_OF_CONTAINING_TYPE=error;;;Declared @This type of {0} in {1} must be a subtype of {2}. -# no parameters required -ANN_POLY_STATIC_POLY_ONLY_IN_POLYFILL_MODULE=error;;;The annotation StaticPolyfill is only allowed in modules annotated as StaticPolyfillModule. -# no parameters required -ANN_POLY_AWARE_AND_MODULE_MUTUAL_EXCLUSIVE=error;;;A module cannot be annotated as filler and filling at the same time. -# no parameters required -ANN_PROMISIFIABLE_MISSING_CALLBACK=error;;;The annotation @Promisifiable is only allowed on functions/methods that take a function as a last argument (i.e. the callback). -# no parameters required -ANN_PROMISIFIABLE_BAD_CALLBACK_MORE_THAN_ONE_ERROR=error;;;The callback of a @Promisifiable function/method must not have more than one parameter of type Error. -# no parameters required -ANN_PROMISIFIABLE_BAD_CALLBACK_ERROR_NOT_FIRST_ARG=error;;;If the callback of a @Promisifiable function/method has a parameter of type Error, this parameter must be the first parameter. - -# 0: annotation name -ANN_DISALLOWED_IN_NONDEFINTION_FILE=error;;;The annotation @{0} can only be applied in definition files. -# 0: annotation name -ANN_DISALLOWED_IN_NON_RUNTIME_COMPONENT=error;;;The annotation @{0} can only be applied in a runtime component. -# 0: bug id -ANN_UNUSED_IDEBUG=error;;;No matching error found, apparently bug IDEBUG-{0} has been fixed or does not occur here. -# 0: name of the violating annotation. -ANN_REQUIRES_TEST=error;;;Only methods annotated with @Test could be annotated with {0}. -# 0: annotation name, 1: list of language variants -ANN_ONL_ALLOWED_IN_VARIANTS=error;;;The annotation @{0} may only be applied in {1} files. -# 0: annotation name, 1: list of language variants -ANN_ONL_ALLOWED_AT_CLASSES_IN_N4JSD=error;;;The annotation @{0} may only be applied at classes in n4jsd files. -# 0: annotation name, 1: list of language variants -ANN_DISALLOWED_ON_SHAPES=error;;;Only nominal interfaces can be annotated with @{0}. - -# 0: annotation name -ANN__TEST_ONLY_IN_TEST_SOURCES=warning;;;Test annotation @{0} may only be used in test source folders (defined in package.json). - -# 0: library name, 1: String of concatenated polyfilled things. -POLY_ERROR_IN_RUNTIMEDEPENDENCY=error;;;Erroneous library {0} provides contradicting polyfills for {1}. -# 0: String of concatenated library names, 1: String of concatenated polyfilled things. -POLY_CLASH_IN_RUNTIMEDEPENDENCY=error;;;The libraries {0} provide polyfills for the same element {1} and cannot be used together. -# 0: String of concatenated library names, 1: String of concatenated polyfilled things. -POLY_CLASH_IN_RUNTIMEDEPENDENCY_MULTI=error;;;The libraries {0} provide polyfills for the same elements {1} and cannot be used together. -# 0: String of conflicting static-polyfilling modules. -POLY_CLASH_IN_STATIC_POLYFILL_MODULE=error;;;Only one module annotated with @@StaticPolyfillModule is allowed per project. Conflicting with {0}. -# no param -POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES=error;;;Only top-level classes annotated as StaticPolyfill are allowed in a module annotated with StaticPolyfillModule. -# no param -POLY_IMPLEMENTING_INTERFACE_NOT_ALLOWED=error;;;The filling class cannot introduce additional interfaces; all interfaces must be declared on the filled class. - -# doc: detected dependency cycle 0:String describing the cycle. -PROJECT_DEPENDENCY_CYCLE=error;;;Dependency cycle of the projects: {0}. -# 0: ID of the non-existing project. -NON_EXISTING_PROJECT=error;;;Project does not exist with project ID: {0}. -# 0: ID of the non-existing project. -MISSING_YARN_WORKSPACE=error;;;Project depends on workspace project {0} which is missing in the node_modules folder. Either install project {0} or introduce a yarn workspace of both of the projects. -# 0: human readable name of the obsolete feature block. -OBSOLETE_BLOCK=warning;;;Obsolete {0} block. -# 0: project project ID, 1: human readable name of the project type, 2: human readable name of the feature. -INVALID_PROJECT_TYPE_REF=warning;;;Project {0} of type {1} cannot be declared among the {2}. -# 0: library project ID -INVALID_API_PROJECT_DEPENDENCY=warning;;;Library project {0} with an implementation ID cannot be declared among the dependencies of an API project. -# 0: violating feature/block name, 1: actual project type name -INVALID_FEATURE_FOR_PROJECT_TYPE=warning;;;{0} cannot be specified for {1} projects. -# 0: name used in duplicate -DUPLICATE_PROJECT_REF=error;;;Duplicate project reference {0}. -# 0: name of the containing folder, 1: name of the nested folder -OUTPUT_AND_SOURCES_FOLDER_NESTING=error;;;{0} must not be located inside {1}. -# no parameters required -PROJECT_REFERENCES_ITSELF=error;;;Project cannot reference itself. -# 0: the type of the deprecated project 1: alternatives -DEPRECATED_PROJECT_TYPE=warning;;;Project type ''{0}'' is deprecated and will be removed soon. {1} -# no parameters are required. -MISMATCHING_TESTED_PROJECT_TYPES=warning;;;Tested projects should have the same project type. -# 0: current project implementation ID, 1: the violating project's ID, 2: the implementation ID of the violating project -MISMATCHING_IMPLEMENTATION_ID=warning;;;Implementation ID mismatch. Current project belongs to ''{0}'' implementation while {1} project belongs to ''{2}'' implementation. -# 0: test library name -SRCTEST_NO_TESTLIB_DEP=error;;;Project with source folder of type test should depend on {0}. -# 0: ID of the violating transitive external project dependency, 1: ID of the workspace project that is required by an external one. -EXTERNAL_PROJECT_REFERENCES_WORKSPACE_PROJECT=warning;;;Transitive external project dependency of project ''{0}'' requires a workspace project ''{1}''. Current project setup could result in runtime oddities. It is highly recommended to import project ''{0}'' into workspace as well. -# 0: project type of containing project -INVALID_FILE_TYPE_FOR_PROJECT_TYPE=error;;;An n4js file may not be contained in a project of type ''{0}''. -# 0: resource name -NO_PROJECT_FOUND=warning;;;No project found for resource {0}. -# 0: part of the specifier that contains a dot, 1: the module specifier -MOD_NAME_MUST_NOT_CONTAIN_DOTS=error;;;{0} of this module contain(s) the disallowed character ''.'' : ''{1}''. -# 0: dependency name, 1: required version, 2: present version -NO_MATCHING_VERSION=warning;;;Project {0} is required in version {1}, but only version {2} is present. -# doc: checks if the module specifier wildcard can be resolved to an existing resource (not applied for implementation provided by runtime), spec: Component/Manifest/ModuleSpecifier-Constraint, 0: the module specifier -NON_EXISTING_MODULE_SPECIFIER=warning;;;Module specifier {0} doesn't exist. -# doc: checks for invalid wildcards, spec: Component/Manifest/ModuleSpecifierWildcardConstraints, 0: the invalid part of the wild card -INVALID_WILDCARD=error;;;"{0}" isn't a valid character sequence in a wild card. -# doc: disallow relative navigation, spec: Component/Manifest/ModuleSpecifierWildcardConstraints, no parameters required -NO_RELATIVE_NAVIGATION=error;;;Relative navigation isn't allowed in a module specifier. -# doc: disallow switching off semantic validation for n4js files, spec: Component/Manifest/ModuleSpecifier-Constraint, 0: module filter type (e.g. noValidate) -DISALLOWED_NO_VALIDATE_FOR_N4JS=error;;;{0} paths shouldn't match n4js files. - -# 0: sub description, 1: extend/implement, 2: super description, 3: implements/extends -SYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP=error;;;The {0} cannot {1} {2}, use "{3}". -# no parameters required -SYN_KW_EXTENDS_IMPLEMENTS_WRONG_ORDER=error;;;Extended class must be declared before implemented interfaces. -# 0: class description, 1: keyword, 2: super description -CLF_WRONG_META_TYPE=error;;;The {0} cannot {1} {2}. -# 0: modifier name, 1: type of element that may not have this modifier (e.g. 'class', 'interface', etc.) -SYN_MODIFIER_INVALID=error;;;Modifier {0} is not allowed on a {1}. -# 0: modifier name -SYN_MODIFIER_DUPLICATE=error;;;Duplicate modifier {0}. -# no parameters required -SYN_MODIFIER_ACCESS_SEVERAL=error;;;Only a single access modifier may be provided. -# 0: modifiers in correct order -SYN_MODIFIER_BAD_ORDER=error;;;Modifiers should appear in this order: {0}. -# 0: element {modifier|keyword}, 1: name of modifier or keyword element (e.g. public) -SYN_UNNECESSARY_ELEMENT=warning;;;Unnecessary {0} {1}. -# no parameters required -EXP_ONLY_TOP_LEVEL_ELEMENTS=error;;;Only top level elements can be exported. -# 0: element kind, 1: element name -EXP_PRIVATE_ELEMENT=error;;;Private {0} {1} cannot be exported. - -# no parameters required -DESTRUCT_EMPTY_PATTERN=error;;;Empty destructuring pattern (disallowed for time being, since ES6 implementations have different semantics). -# 0: name of missing property, 1: type of value to be destructured -DESTRUCT_PROP_MISSING=error;;;Value to be destructured does not contain a property, field or getter named "{0}": {1}. -# 0: name of property that returned AbstractDescriptionWithError, 1: error message -DESTRUCT_PROP_WITH_ERROR=error;;;Property named "{0}" is not readable: {1}. -# 0: name of variable, 1: "at index N" or "of property NAME", 2: error message from type system (must not end in a dot!) -DESTRUCT_TYPE_ERROR_VAR=error;;;Variable {0} cannot hold destructured value {1}: {2}. -# 0: kind of destructuring pattern ("Array" or "Object" or "Nested array" or "Nested object"), 1: "destructured value at index N" or "destructured value of property NAME", 2: error message from type system (must not end in a dot!) -DESTRUCT_TYPE_ERROR_PATTERN=error;;;{0} destructuring pattern cannot be applied to {1}: {2}. - -### Dependency Injection -# 0: type name, 1: additional description identifying the place of the violating context (name of the member/parameter) -DI_NOT_INJECTABLE=error;;;Type {0} is not injectable{1}: only user-defined, non-generic, nominally typed interfaces and classes are allowed. -# no parameters are required -DI_VARARGS_NOT_INJECTABLE=error;;;Injection of parameters that are variadic or optional is not supported. -# 0: type name -DI_MUST_BE_INJECTED=warning;;;Type {0} must be injected, because it contains or inherits one or more members annotated with @Inject. -# 0: annotation name, 1: name of required annotation on containing class -DI_ANN_ONLY_ON_CLASS_ANNOTATED_WITH=error;;;The annotation @{0} is only allowed on classes annotated with @{1}. -# 0: annotation name, 1: name of required annotation on containing class -DI_ANN_ONLY_ON_METHOD_IN_CLASS_ANNOTATED_WITH=error;;;The annotation @{0} is only allowed on methods contained in a class annotated with @{1}. -# 0: annotation name, 1: name of required annotation on argument class -DI_ANN_ARG_MUST_BE_ANNOTATED_WITH=error;;;Argument to annotation @{0} must be a class annotated with @{1}. -# 0: the name of the violating annotation. -DI_ANN_BIND_SECOND_MUST_BE_SUBTYPE_FIRST=error;;;Second argument to @{0} must be a subtype of the first. -# no parameters required -DI_ANN_PROVIDES_METHOD_MUST_RETURN_VALUE=error;;;A provider method must return a value. -# no parameters required -DI_ANN_INTERFACE_INJECTION_NOT_SUPPORTED=error;;;Injection inside interfaces is not supported. -# no parameters required -DI_ANN_INJECTOR_EXTENDS=error;;;Classes annotated with @GenerateInjector cannot extend other class. -# 0: the binded type name -DI_ANN_BIND_SINGLETON_TARGET_SHOULD_BE_DEFINED_AS_SINGLETON=error;;;{0} can be defined as a singleton if it is annotated with @Singleton on the definition site. -# no parameters required -DI_ANN_INJECTOR_CANNOT_BE_INJECTED_INTO_INJECTOR=error;;;Types annotated with @GenerateInjector cannot be injected. Use @WithParentInjector instead for creating nested injectors. -# 0: the cyclic graph as a string -DI_ANN_USE_INJECTOR_CYCLE=error;;;A cycle was detected among the parent injectors: {0}. -# 0: the name of the unavailable field -DI_FIELD_IS_NOT_INJECTED_YET=error;;;{0} is not yet injected at this point. -# 0: super class type name, 1: violating type name -DI_CTOR_BREAKS_INJECTION_CHAIN=warning;;;Constructor at super class {0} is annotated with @Inject. Omitting the @Inject annotation from constructor at class {1} could break injection chain. -# no parameters required -DI_ANN_BINDER_NOT_APPLICABLE=error;;;Annotation @Binder is applicable only for (exported) non-abstract class definitions. -# no parameters required -DI_ANN_BINDER_AND_INJECTOR_DONT_GO_TOGETHER=error;;;Annotations @Binder and @GenerateInjector may not be applied both on the same class definition. -# no parameters required -DI_ANN_DUPLICATE_BINDING=error;;;Duplicate @Binding-s (two different bindings share the same key, for the same @Binder). -# no parameters required -DI_ANN_BIND_ABSTRACT_TARGET=error;;;The target of a @Binding must be a non-abstract class. -# no parameters required -DI_ANN_INJECT_METHOD_NOT_SUPPORTED_YET=error;;;Method injection not supported yet. -# no parameters required -DI_ANN_BINDER_EXTENDS=error;;;Classes annotated with @Binder may not extend another class. -# no parameters required -DI_ANN_INJECTOR_CTOR_MUST_BE_INJECT=error;;;The constructor of an injector must itself be injected unless it declares no parameters. -# no parameters required -DI_ANN_INJECTOR_REQUIRED=error;;;Only types annotated with @GenerateInjector can be used here. -# 0: list of missing binders (as a list of type names) -DI_ANN_MISSING_PROVIDED_BINDERS=error;;;No binders are provided (third param for this callsite). The following binders are used by the injector and themselves require injection: {0}. -# no parameters required -DI_ANN_INJECTOR_MISSING=error;;;An instance of N4Injector is required here. -# 0: list of missing binders (as a list of type names) -DI_ANN_MISSING_NEEDED_BINDERS=error;;;Instances are missing for the following binders (they are used by the injector and themselves require injection): {0}. -# no parameters required -DI_API_INJECTED=error;;;The class being instantiated (or one of its super-types) has been marked @Injected in an API project. -# no parameters required -DI_ANN_INJECTED_NOT_APPLICABLE=error;;;@Injected annotates a class (abstract or not) defined in an API project. - - -### JSX -# 0: name of opening JSX element, 1: name of closing JSX element -JSX_JSXELEMENT_OPENING_CLOSING_ELEMENT_NOT_MATCH=error;;;Opening element {0} does not match with closing element {1}. -# 0: name of the type JSX element is binding to -JSX_REACT_ELEMENT_NOT_FUNCTION_OR_CLASS_ERROR=error;;;JSX element is expected to bind to either a function or class, but bind to type {0} instead. -# No parameter -JSX_REACT_ELEMENT_CLASS_MUST_NOT_BE_ABSTRACT=error;;;JSX element class must not be abstract. -# 0: name of the return type of the function that JSX element is binding to -JSX_REACT_ELEMENT_FUNCTION_NOT_REACT_ELEMENT_ERROR=error;;;Expecting a function returning a value of type {0} but the return type is {1}. -# no argument -JSX_REACT_ELEMENT_CLASS_NOT_REACT_ELEMENT_ERROR=error;;;The referred class is not a subtype of React.Component -# 0: name of the function that JSX element is binding to -JSX_REACT_FUNCTIONAL_COMPONENT_CANNOT_START_WITH_LOWER_CASE=error;;;React functional component {0} cannot start with lower case. -# 0: name of the class that JSX element is binding to -JSX_REACT_CLASS_COMPONENT_CANNOT_START_WITH_LOWER_CASE=error;;;React class component {0} cannot start with lower case. -# 0: name of JSX element is binding to -JSX_JSXELEMENT_NOT_BIND_TO_REACT_COMPONENT=error;;;JSX element {0} does not bind to any valid React component. -# 0: name of JSX element is binding to -JSX_TAG_UNKNOWN=warning;;;Tag {0} is neither a known HTML tag nor an SVG tag. -# 0: name of JSX property -JSX_JSXPROPERTY_ATTRIBUTE_NON_OPTIONAL_PROPERTY_NOT_SPECIFIED=error;;;Non-optional property {0} should be specified. -# 0: The name of attribute in spread operator, 1: type of the attribute, 2: the declared type of the corresponding property in "props" -JSX_JSXSPREADATTRIBUTE_WRONG_SUBTYPE=error;;;Attribute {0} has wrong type because {1} not subtype of {2}. -# 0: The name of attribute in spread operator, 1: name of JSX element -JSX_JSXSPREADATTRIBUTE_NOT_DECLARED_IN_PROPS=warning;;;Attribute {0} is not a declared property in the props of {1}. -# 0: The name of attribute in JSX property, 1: name of JSX element -JSX_JSXSPROPERTYATTRIBUTE_NOT_DECLARED_IN_PROPS=warning;;;Attribute {0} is not a declared property in the props of {1}. -# 0: JSX element in non-JSX file -JSX_JSXELEMENT_IN_NON_JSX_RESOURCE=error;;;JSX element is expected to be placed in JSX like resource, was {0}. -# No parameter -JSX_REACT_NAMESPACE_NOT_ALLOWED=error;;;Namespace to react must be React. -# No parameter -JSX_REACT_NOT_RESOLVED=error;;;Cannot resolve JSX implementation. -# No parameter -JSX_NAME_CANNOT_BE_REACT=error;;;Element cannot be named React in N4JSX file. - - -### THIRD PARTY -# no parameters required -THIRD_PARTY_BABEL_LET_CONST_IN_FUN_EXPR=warning;;;This code is prone to Babel bug #6302. If you use Babel in your build pipeline, you should rename this let/const or the containing function expression. - - -### N4JS package.json -# no parameters -PKGJ_MISSING_DEPENDENCY_N4JS_RUNTIME=error;;;Missing dependency to 'n4js-runtime' (mandatory for all N4JS projects of type library, application, test). -# no parameters -PKGJ_WRONG_DEPENDENCY_N4JS_RUNTIME=error;;;Dependency to 'n4js-runtime' should be defined below key "dependencies", not "devDependencies". -# 0: The package name without scope, as declared in the package.json, 1: project folder name -PKGJ_PACKAGE_NAME_MISMATCH=warning;;;As a convention the package name "{0}" should match the name of the project folder "{1}" on the file system. -# 0: The scope name, as declared in the package.json, 1: parent folder name -PKGJ_SCOPE_NAME_MISMATCH=warning;;;As a convention the scope name "{0}" should match the name of the project folder's parent folder "{1}" on the file system. -# 0: The project name without scope -PKGJ_INVALID_PROJECT_NAME=error;;;The name "{0}" is not a valid package name. -# 0: The scope name -PKGJ_INVALID_SCOPE_NAME=error;;;The name "{0}" is not a valid scope name. -# 0: Invalid source container type name -PKGJ_INVALID_SOURCE_CONTAINER_TYPE=error;;;Invalid source container type "{0}". -# 0: the non-existing path -PKGJ_NON_EXISTING_PATH=error;;;Path {0} does not exist. -# no parameters -PKGJ_EMPTY_SOURCE_PATH=error;;;Source container paths must not be empty. -# 0: the non-existing source container path -PKGJ_NON_EXISTING_SOURCE_PATH=warning;;;Source container path {0} does not exist. -# 0: the path 1: 'in'-clause with leading space (e.g. " in external, test") -PKGJ_DUPLICATE_SOURCE_CONTAINER=warning;;;Duplicate path "{0}" has already been declared as source container{1}. -# 0: the container source path -PKGJ_NESTED_SOURCE_CONTAINER=error;;;A source container must not be nested within other source containers (nested in {0}) -# no parameters -PKGJ_NO_OUTPUT_FOLDER=error;;;There is no output folder defined, so compilation isn't possible. -# 0: the invalid path -PKGJ_INVALID_PATH=error;;;"{0}" is not a valid path. -# 0: the absolute path -PKGJ_INVALID_ABSOLUTE_PATH=error;;;Path "{0}" must not be absolute. -# 0: the non-directory path -PKGJ_EXPECTED_DIRECTORY_PATH=error;;;Path "{0}" does not point to a directory. -# 0: the non-existing main module specifier -PKGJ_NON_EXISTING_MAIN_MODULE=error;;;Main module specifier {0} does not exist. -# 0: invalid module filter type, 1: all valid module filter types -PKGJ_INVALID_MODULE_FILTER_TYPE=error;;;Invalid module filter type "{0}". Valid filter types are {1}. -# 0: invalid module specifier -PKGJ_INVALID_MODULE_FILTER_SPECIFIER=error;;;Invalid module specifier. Use simple strings or object syntax instead. -# no parameters -PKGJ_INVALID_MODULE_FILTER_SPECIFIER_EMPTY=error;;;The filter specifier and declared source container must not be empty. -# no parameters -PKGJ_DUPLICATE_MODULE_FILTER_SPECIFIER=error;;;Duplicate module filter specifier. -# no parameters -PKGJ_SRC_IN_FILTER_IS_NO_DECLARED_SOURCE=error;;;The given source container "{0}" has not been declared as source container. -# 0: the invalid part of a wildcard -PKGJ_INVALID_WILDCARD=error;;;"{0}" is not a valid character sequence in a wildcard. -# no parameters -PKGJ_NO_RELATIVE_NAVIGATION=error;;;Relative navigation is not allowed in a module filter specifier. -# 0: the module filter specifier -PKGJ_MODULE_FILTER_DOES_NOT_MATCH=warning;;;Module filter "{0}" does not match any modules. -# 0: module filter type (e.g. noValidate) -PKGJ_FILTER_NO_N4JS_MATCH=error;;;Module filters of type {0} must not match N4JS modules/files. -# no parameters -PKGJ_APIIMPL_MISSING_IMPL_PROJECTS=error;;;When defining an implementation ID, you also have to define one or more API projects that are implemented by this project using property 'n4js.implementedProjects'. -# no parameters -PKGJ_APIIMPL_REFLEXIVE=error;;;An implementation project may not implement itself. -# no parameters required -PKGJ_APIIMPL_MISSING_IMPL_ID=error;;;When defining one or more implemented projects, you also have to define an implementation ID, using property "implementationId". -# 0: invalid project type -PKGJ_INVALID_PROJECT_TYPE=error;;;Invalid project type "{0}". -# 0: project id 1: section label (e.g. required runtime libraries) -PKGJ_PROJECT_REFERENCE_MUST_BE_DEPENDENCY=error;;;The project reference {0} in {1} must also be declared as explicit project dependency in 'dependencies' or 'devDependencies'. -# 0: message -PKGJ_SEMVER_ERROR=error;;;{0} -# 0: message -PKGJ_SEMVER_WARNING=warning;;;{0} -# 0: version number string representation, 1: reason -PKGJ_INVALID_VERSION_NUMBER=error;;;Invalid version number "{0}": {1}. -# 0: version constraint string representation, 1: reason -PKGJ_INVALID_VERSION_REQUIREMENT=warning;;;Invalid version requirement "{0}": {1}. Will assume empty string. -# 0: project type -PKGJ_PROJECT_TYPE_MANDATORY_OUTPUT_AND_SOURCES=error;;;Projects of type {0} must always declare an output folder and at least one source container. -# no parameters -PKGJ_EMPTY_PROJECT_REFERENCE=error;;;A project reference must not be empty. -# no parameters -PKGJ_EMPTY_INIT_MODULE=error;;;An init module specifier must not be empty. -# 0: project type, 1: empty or 'not ', 2: property name -PKGJ_DEFINES_PROPERTY=error;;;A project of type "{0}" must {1}define the property "{2}". -# 0: property name -PKGJ_PROPERTY_UNKNOWN=warning;;;Property "{0}" is unknown. -# 0: implementation project name, 1: type definition project name -PKGJ_IMPL_PROJECT_IS_MISSING_FOR_TYPE_DEF=warning;;;The implementation project {0} of type definition project {1} is missing from the dependencies section. -# 0: "Source" or "Output code" -PKGJ_REWRITE_MODULE_SPECIFIERS__EMPTY_SPECIFIER=error;;;{0} module specifier must not be empty. -# no parameters -PKGJ_REWRITE_MODULE_SPECIFIERS__INVALID_VALUE=error;;;String expected (i.e. the module specifier to use in the output code). - -# no parameters -LTD_ILLEGAL_LOADTIME_REFERENCE=error;;;Load-time references to the same or other modules are not allowed within a runtime dependency cycle (except in extends/implements clauses). -# 0: name of load-time dependency target module, 1: comma-separated list of other load-time dependency source modules (including the prefix "modules " or "module ") -LTD_LOADTIME_DEPENDENCY_CONFLICT=error;;;A load-time dependency target module {0} must only be imported once within the same runtime dependency cycle, but {0} is also imported by {1}. -# no parameters -LTD_LOADTIME_DEPENDENCY_CYCLE=error;;;Load-time dependency cycles are disallowed, because successful resolution by Javascript engine cannot be guaranteed. -# 0: name of load-time dependency target module, 1: modules that could heal this reference (including the prefix "one of the modules " or "module ") -LTD_REFERENCE_TO_LOADTIME_DEPENDENCY_TARGET=error;;;When importing modules from a runtime cycle, those that are the target of a load-time dependency (marked with * below) may only be imported after first importing one of the others. Thus, import of module {0} must be preceded by an import of {1}. diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/IDEBUGValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/IDEBUGValidator.xtend index 772173a02c..58f6c72ce0 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/IDEBUGValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/IDEBUGValidator.xtend @@ -10,14 +10,15 @@ */ package org.eclipse.n4js.validation.validators +import java.util.Collection +import java.util.HashSet +import java.util.Map import org.eclipse.n4js.AnnotationDefinition import org.eclipse.n4js.n4JS.Annotation +import org.eclipse.n4js.utils.validation.PostValidation import org.eclipse.n4js.validation.AbstractMessageAdjustingN4JSValidator import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator -import org.eclipse.n4js.utils.validation.PostValidation -import java.util.Collection -import java.util.HashSet -import java.util.Map +import org.eclipse.n4js.validation.IssueItem import org.eclipse.xtext.validation.Check import org.eclipse.xtext.validation.EValidatorRegistrar @@ -78,7 +79,8 @@ class IDEBUGValidator extends AbstractMessageAdjustingN4JSValidator { for (Annotation a: definedAnnotations.filter[!usedAnnotations.contains(it)]) { if (!a.args.isEmpty) { val bugID = a.args.get(0).valueAsString; - addIssue(getMessageForANN_UNUSED_IDEBUG(bugID), a, ANN_UNUSED_IDEBUG); + val IssueItem issueItem = ANN_UNUSED_IDEBUG.toIssueItem(bugID); + addIssue(issueItem.message, a, issueItem.getID()); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSAccessModifierValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSAccessModifierValidator.xtend index 25c5b8d994..07ae6af2c9 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSAccessModifierValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSAccessModifierValidator.xtend @@ -24,8 +24,11 @@ import org.eclipse.n4js.n4JS.ModifierUtils import org.eclipse.n4js.n4JS.N4ClassifierDefinition import org.eclipse.n4js.n4JS.N4FieldDeclaration import org.eclipse.n4js.n4JS.N4GetterDeclaration +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration import org.eclipse.n4js.n4JS.N4JSPackage +import org.eclipse.n4js.n4JS.N4MemberDeclaration import org.eclipse.n4js.n4JS.N4MethodDeclaration +import org.eclipse.n4js.n4JS.N4Modifier import org.eclipse.n4js.n4JS.NamespaceExportSpecifier import org.eclipse.n4js.n4JS.NamespaceImportSpecifier import org.eclipse.n4js.n4JS.ObjectLiteral @@ -53,6 +56,7 @@ import org.eclipse.n4js.utils.ContainerTypesHelper import org.eclipse.n4js.utils.StaticPolyfillHelper import org.eclipse.n4js.utils.StructuralTypesHelper import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator +import org.eclipse.n4js.validation.IssueItem import org.eclipse.n4js.validation.JavaScriptVariantHelper import org.eclipse.xtext.nodemodel.ILeafNode import org.eclipse.xtext.nodemodel.util.NodeModelUtils @@ -62,9 +66,6 @@ import org.eclipse.xtext.validation.EValidatorRegistrar import static org.eclipse.n4js.validation.IssueCodes.* import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* -import org.eclipse.n4js.n4JS.N4MemberDeclaration -import org.eclipse.n4js.n4JS.N4InterfaceDeclaration -import org.eclipse.n4js.n4JS.N4Modifier /** */ @@ -131,13 +132,13 @@ class N4JSAccessModifierValidator extends AbstractN4JSDeclarativeValidator { // NOTE: we are using issue code UNSUPPORTED here, because the only reason for disallowing a visibility higher than // private on non-exported types is that it is required/useful only with separate export declarations and such export // declarations are UNSUPPORTED in N4JS(D) at the moment. - val message = getMessageForUNSUPPORTED("non-exported " + tElem.keyword + " with a visibility higher than private"); + val issueItem = UNSUPPORTED.toIssueItem("non-exported " + tElem.keyword + " with a visibility higher than private"); val node = findModifierNode(astNode, tElem.typeAccessModifier); if (node !== null) { - addIssue(message, astNode, node.getOffset(), node.getLength(), UNSUPPORTED); + addIssue(astNode, node.getOffset(), node.getLength(), issueItem); } else { val eObjectToNameFeature = findNameFeature(astNode); - addIssue(message, eObjectToNameFeature.key, eObjectToNameFeature.value, UNSUPPORTED) + addIssue(eObjectToNameFeature.key, eObjectToNameFeature.value, issueItem) } } } @@ -168,8 +169,8 @@ class N4JSAccessModifierValidator extends AbstractN4JSDeclarativeValidator { if (exportedElement instanceof AccessibleTypeElement) { val tam = exportedElement.typeAccessModifier; if (!(tam.ordinal > TypeAccessModifier.PRIVATE.ordinal)) { - val msg = getMessageForEXP_PRIVATE_ELEMENT(exportedElement.keyword, exportedElement.name); - addIssue(msg, idRef, EXP_PRIVATE_ELEMENT); + val IssueItem issueItem = EXP_PRIVATE_ELEMENT.toIssueItem(exportedElement.keyword, exportedElement.name); + addIssue(idRef, issueItem); } } } @@ -199,10 +200,10 @@ class N4JSAccessModifierValidator extends AbstractN4JSDeclarativeValidator { null } if (typeAccessModifier !== null && typeAccessModifier.ordinal <= TypeAccessModifier.PROJECT.ordinal) { - val message = getMessageForCLF_LOW_ACCESSOR_WITH_INTERNAL(exportableElement.keyword, + val IssueItem issueItem = CLF_LOW_ACCESSOR_WITH_INTERNAL.toIssueItem(exportableElement.keyword, typeAccessModifier.keyword) val eObjectToNameFeature = exportableElement.findNameFeature - addIssue(message, eObjectToNameFeature.key, eObjectToNameFeature.value, CLF_LOW_ACCESSOR_WITH_INTERNAL) + addIssue(eObjectToNameFeature.key, eObjectToNameFeature.value, issueItem) } } } @@ -222,16 +223,14 @@ class N4JSAccessModifierValidator extends AbstractN4JSDeclarativeValidator { if(parent instanceof TFormalParameter) { return; // avoid duplicate error messages } else if(parent instanceof N4FieldDeclaration || parent instanceof TField) { - val message = messageForCLF_FIELD_OPTIONAL_OLD_SYNTAX; val node = NodeModelUtils.findActualNodeFor(typeRefInAST) if (node !== null) { - addIssue(message, typeRefInAST, node.offset, node.length, CLF_FIELD_OPTIONAL_OLD_SYNTAX) + addIssue(typeRefInAST, node.offset, node.length, CLF_FIELD_OPTIONAL_OLD_SYNTAX.toIssueItem()) } } else { - val message = messageForEXP_OPTIONAL_INVALID_PLACE; val node = NodeModelUtils.findActualNodeFor(typeRefInAST) if (node !== null) { - addIssue(message, typeRefInAST, node.offset, node.length, EXP_OPTIONAL_INVALID_PLACE) + addIssue(typeRefInAST, node.offset, node.length, EXP_OPTIONAL_INVALID_PLACE.toIssueItem()) } } } @@ -254,22 +253,18 @@ class N4JSAccessModifierValidator extends AbstractN4JSDeclarativeValidator { && !n4member.declaredModifiers.contains(N4Modifier.PRIVATE) // see: CLF_MINIMAL_ACCESSIBILITY_IN_INTERFACES && !(n4member.eContainer as N4InterfaceDeclaration).declaredModifiers.contains(N4Modifier.PUBLIC) ) { - val msg = getMessageForSTRCT_ITF_MEMBER_MUST_BE_PUBLIC; - addIssue(msg, n4member, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, STRCT_ITF_MEMBER_MUST_BE_PUBLIC); + addIssue(n4member, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, STRCT_ITF_MEMBER_MUST_BE_PUBLIC.toIssueItem()); } } @Check def checkFieldConstFinalValidCombinations(N4FieldDeclaration n4field) { if (n4field.const && n4field.declaredStatic) { - val msg = getMessageForCLF_FIELD_CONST_STATIC; - addIssue(msg, n4field, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, CLF_FIELD_CONST_STATIC); + addIssue(n4field, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, CLF_FIELD_CONST_STATIC.toIssueItem()); } else if (n4field.const && n4field.final) { - val msg = getMessageForCLF_FIELD_CONST_FINAL; - addIssue(msg, n4field, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, CLF_FIELD_CONST_FINAL); + addIssue(n4field, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, CLF_FIELD_CONST_FINAL.toIssueItem()); } else if (n4field.final && n4field.declaredStatic) { - val msg = getMessageForCLF_FIELD_FINAL_STATIC; - addIssue(msg, n4field, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, CLF_FIELD_FINAL_STATIC); + addIssue(n4field, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, CLF_FIELD_FINAL_STATIC.toIssueItem()); } } @@ -280,8 +275,7 @@ class N4JSAccessModifierValidator extends AbstractN4JSDeclarativeValidator { } if (n4field.const && n4field.expression === null) { - val msg = getMessageForCLF_FIELD_CONST_MISSING_INIT(n4field.name); - addIssue(msg, n4field, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, CLF_FIELD_CONST_MISSING_INIT); + addIssue(n4field, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, CLF_FIELD_CONST_MISSING_INIT.toIssueItem(n4field.name)); } } @@ -315,14 +309,12 @@ class N4JSAccessModifierValidator extends AbstractN4JSDeclarativeValidator { val boolean replacedByPolyfill = n4classifier.ownedCtor !== n4classifier.polyfilledOrOwnCtor; if (replacedByPolyfill) { finalFieldsWithoutInit.forEach [ - val msg = getMessageForCLF_FIELD_FINAL_MISSING_INIT_IN_STATIC_POLYFILL(it.name); - addIssue(msg, it, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, - CLF_FIELD_FINAL_MISSING_INIT_IN_STATIC_POLYFILL) + addIssue(it, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, + CLF_FIELD_FINAL_MISSING_INIT_IN_STATIC_POLYFILL.toIssueItem(it.name)) ] } else { finalFieldsWithoutInit.forEach [ - val msg = getMessageForCLF_FIELD_FINAL_MISSING_INIT(it.name); - addIssue(msg, it, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, CLF_FIELD_FINAL_MISSING_INIT) + addIssue(it, N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName, CLF_FIELD_FINAL_MISSING_INIT.toIssueItem(it.name)) ] } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSAnnotationValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSAnnotationValidator.xtend index 13340744d7..cebe5fe6a4 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSAnnotationValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSAnnotationValidator.xtend @@ -28,6 +28,7 @@ import org.eclipse.n4js.n4JS.FormalParameter import org.eclipse.n4js.n4JS.FunctionDeclaration import org.eclipse.n4js.n4JS.FunctionDefinition import org.eclipse.n4js.n4JS.N4ClassDeclaration +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration import org.eclipse.n4js.n4JS.N4MemberDeclaration import org.eclipse.n4js.n4JS.N4MethodDeclaration import org.eclipse.n4js.n4JS.Script @@ -45,7 +46,7 @@ import org.eclipse.n4js.types.utils.TypeUtils import org.eclipse.n4js.typesystem.N4JSTypeSystem import org.eclipse.n4js.utils.PromisifyHelper import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator -import org.eclipse.n4js.validation.IssueCodes +import org.eclipse.n4js.validation.IssueItem import org.eclipse.n4js.validation.JavaScriptVariantHelper import org.eclipse.n4js.workspace.WorkspaceAccess import org.eclipse.xtext.EcoreUtil2 @@ -60,7 +61,6 @@ import static org.eclipse.n4js.validation.IssueCodes.* import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* import static extension org.eclipse.n4js.utils.N4JSLanguageUtils.* -import org.eclipse.n4js.n4JS.N4InterfaceDeclaration /** * Annotation validation rules for N4JS. @@ -102,7 +102,7 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { if (!jsVariantHelper.allowAnnotation(annotableElement)) { // Annotation not allowed in other then N4JS modes: if (annotableElement.annotations.size > 0) { - addIssue(messageForANN__ONLY_IN_N4JS, annotableElement, annotableElement.annoFeature, ANN__ONLY_IN_N4JS) + addIssue(annotableElement, annotableElement.annoFeature, ANN__ONLY_IN_N4JS.toIssueItem()) } return } @@ -115,7 +115,7 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { if (a.name !== null) { val def = AnnotationDefinition.find(a.name); if (def === null) { - addIssue(getMessageForANN_NOT_DEFINED(a.name), a, ANNOTATION__NAME, ANN_NOT_DEFINED); + addIssue(a, ANNOTATION__NAME, ANN_NOT_DEFINED.toIssueItem(a.name)); } else { if (def.repeatable) { if (foundNames.add(a.name)) { @@ -125,7 +125,7 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { } } else { if (! foundNames.add(a.name)) { - addIssue(getMessageForANN_NON_REPEATABLE(a.name), a, ANNOTATION__NAME, ANN_NON_REPEATABLE); + addIssue(a, ANNOTATION__NAME, ANN_NON_REPEATABLE.toIssueItem(a.name)); } else { internalCheckAnnotation(def, a); } @@ -205,7 +205,7 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { if (definition.transitive && !definition.repeatable) { if (definition.hasAnnotation( EcoreUtil2.getContainerOfType(annotation.annotatedElement.eContainer, AnnotableElement))) { - addIssue(getMessageForANN_UNNECESSARY(annotation.name), annotation, ANNOTATION__NAME, ANN_UNNECESSARY); + addIssue(annotation, ANNOTATION__NAME, ANN_UNNECESSARY.toIssueItem(annotation.name)); } } } @@ -220,8 +220,8 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { // less actual arguments than specified in the definition if (expectedSize - actualSize >= 2) { - addIssue(getMessageForANN_WRONG_NUMBER_OF_ARGUMENTS(definition.name, expectedSize - 1, actualSize), - annotation, ANNOTATION__NAME, ANN_WRONG_NUMBER_OF_ARGUMENTS); + val IssueItem issueItem = ANN_WRONG_NUMBER_OF_ARGUMENTS.toIssueItem(definition.name, expectedSize - 1, actualSize); + addIssue(annotation, ANNOTATION__NAME, issueItem); return false; } @@ -236,8 +236,8 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { val argType = if (i + 1 > definition.argtypes.length) definition.argtypes.last else definition.argtypes. get(i); if (!argType.isInstance(arg)) { - addIssue(getMessageForANN_WRONG_ARGUMENT_TYPE(definition.name, argType.name), annotation, - ANNOTATION__ARGS, i, ANN_WRONG_ARGUMENT_TYPE); + val IssueItem issueItem = ANN_WRONG_ARGUMENT_TYPE.toIssueItem(definition.name, argType.name); + addIssue(annotation, ANNOTATION__ARGS, i, issueItem); valid = false; } } @@ -245,8 +245,8 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { } else { if (actualSize > expectedSize || (!definition.argsOptional && actualSize !== expectedSize)) { - addIssue(getMessageForANN_WRONG_NUMBER_OF_ARGUMENTS(definition.name, expectedSize, actualSize), - annotation, ANNOTATION__NAME, ANN_WRONG_NUMBER_OF_ARGUMENTS); + val IssueItem issueItem = ANN_WRONG_NUMBER_OF_ARGUMENTS.toIssueItem(definition.name, expectedSize, actualSize); + addIssue(annotation, ANNOTATION__NAME, issueItem); return false; } } @@ -263,12 +263,10 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { val arg = annotation.args.get(i).value(); val argType = definition.argtypes.get(i); if (!argType.isInstance(arg)) { - - addIssue(getMessageForANN_WRONG_ARGUMENT_TYPE(definition.name, argType.name), annotation, - ANNOTATION__ARGS, i, ANN_WRONG_ARGUMENT_TYPE); + val IssueItem issueItem = ANN_WRONG_ARGUMENT_TYPE.toIssueItem(definition.name, argType.name); + addIssue(annotation, ANNOTATION__ARGS, i, issueItem); valid = false; } - } return valid; @@ -283,9 +281,9 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { val element = annotation.annotatedElement; if (!definition.javaScriptVariants.contains(jsVariantHelper.variantMode(element))) { - val message = IssueCodes.getMessageForANN_ONL_ALLOWED_IN_VARIANTS(definition.name, + val IssueItem issueItem = ANN_ONL_ALLOWED_IN_VARIANTS.toIssueItem(definition.name, orList(definition.javaScriptVariants.map[v | jsVariantHelper.getVariantName(v)])); - addIssue(message, annotation, IssueCodes.ANN_ONL_ALLOWED_IN_VARIANTS); + addIssue(annotation, issueItem); return false; } return true; @@ -324,8 +322,8 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { } private def addWrongLocationIssue(Annotation annotation) { - addIssue(getMessageForANN_DISALLOWED_AT_LOCATION(annotation.name), annotation, ANNOTATION__NAME, - ANN_DISALLOWED_AT_LOCATION); + val IssueItem issueItem = ANN_DISALLOWED_AT_LOCATION.toIssueItem(annotation.name); + addIssue(annotation, ANNOTATION__NAME, issueItem); } /** @@ -360,8 +358,7 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { } // constraint #1: @This not allowed on static members of interfaces if (tMember.static && containingType instanceof TInterface) { - val msg = getMessageForANN_THIS_DISALLOWED_ON_STATIC_MEMBER_OF_INTERFACE(); - addIssue(msg, annotation, ANNOTATION__NAME, ANN_THIS_DISALLOWED_ON_STATIC_MEMBER_OF_INTERFACE); + addIssue(annotation, ANNOTATION__NAME, ANN_THIS_DISALLOWED_ON_STATIC_MEMBER_OF_INTERFACE.toIssueItem()); return; } // constraint #2: declared this type must be subtype of the containing type @@ -376,9 +373,9 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { }; val G = element.newRuleEnvironment; if (!ts.subtypeSucceeded(G, declThisTypeRef, containingTypeRef)) { - val msg = getMessageForANN_THIS_NOT_SUBTYPE_OF_CONTAINING_TYPE(tMember.description, + val IssueItem issueItem = ANN_THIS_NOT_SUBTYPE_OF_CONTAINING_TYPE.toIssueItem(tMember.description, containingType.description, containingTypeRef.typeRefAsString); - addIssue(msg, annotation, ANNOTATION__ARGS, ANN_THIS_NOT_SUBTYPE_OF_CONTAINING_TYPE); + addIssue(annotation, ANNOTATION__ARGS, issueItem); } } } @@ -392,16 +389,16 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { return; } if (!jsVariantHelper.isExternalMode(element)) { - addIssue(getMessageForANN_DISALLOWED_IN_NONDEFINTION_FILE(annotation.name), annotation, ANNOTATION__NAME, - ANN_DISALLOWED_IN_NONDEFINTION_FILE); + val IssueItem issueItem = ANN_DISALLOWED_IN_NONDEFINTION_FILE.toIssueItem(annotation.name); + addIssue(annotation, ANNOTATION__NAME, issueItem); return; } if (element instanceof ExportDeclaration && (element as ExportDeclaration).exportedElement instanceof N4InterfaceDeclaration && ((element as ExportDeclaration).exportedElement as N4InterfaceDeclaration).typingStrategy === TypingStrategy.STRUCTURAL ) { - addIssue(getMessageForANN_DISALLOWED_ON_SHAPES(annotation.name), annotation, ANNOTATION__NAME, - ANN_DISALLOWED_ON_SHAPES); + val IssueItem issueItem = ANN_DISALLOWED_ON_SHAPES.toIssueItem(annotation.name); + addIssue(annotation, ANNOTATION__NAME, issueItem); } } @@ -414,16 +411,16 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { return; } if (!jsVariantHelper.isExternalMode(element)) { - addIssue(getMessageForANN_ONL_ALLOWED_AT_CLASSES_IN_N4JSD(annotation.name), annotation, ANNOTATION__NAME, - ANN_ONL_ALLOWED_AT_CLASSES_IN_N4JSD); + val IssueItem issueItem = ANN_ONL_ALLOWED_AT_CLASSES_IN_N4JSD.toIssueItem(annotation.name); + addIssue(annotation, ANNOTATION__NAME, issueItem); return; } if (element instanceof ExportDeclaration && !((element as ExportDeclaration).exportedElement instanceof N4ClassDeclaration) ) { - addIssue(getMessageForANN_ONL_ALLOWED_AT_CLASSES_IN_N4JSD(annotation.name), annotation, ANNOTATION__NAME, - ANN_ONL_ALLOWED_AT_CLASSES_IN_N4JSD); + val IssueItem issueItem = ANN_ONL_ALLOWED_AT_CLASSES_IN_N4JSD.toIssueItem(annotation.name); + addIssue(annotation, ANNOTATION__NAME, issueItem); return; } } @@ -442,8 +439,8 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { return; } if (!srcContainer.isTest) { - val msg = getMessageForANN__TEST_ONLY_IN_TEST_SOURCES(annotation.name); - addIssue(msg, annotation, ANNOTATION__NAME, ANN__TEST_ONLY_IN_TEST_SOURCES); + val IssueItem issueItem = ANN__TEST_ONLY_IN_TEST_SOURCES.toIssueItem(annotation.name); + addIssue(annotation, ANNOTATION__NAME, issueItem); return; } } @@ -461,8 +458,8 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { } } } - val msg = getMessageForANN_ONLY_ALLOWED_LOCATION_CONSTRUCTORS(annotation.name); - addIssue(msg, annotation, ANNOTATION__NAME, ANN_ONLY_ALLOWED_LOCATION_CONSTRUCTORS); + val IssueItem issueItem = ANN_ONLY_ALLOWED_LOCATION_CONSTRUCTORS.toIssueItem(annotation.name); + addIssue(annotation, ANNOTATION__NAME, issueItem); return false; } @@ -475,8 +472,8 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { return } if (!jsVariantHelper.isExternalMode(element)) { - addIssue(getMessageForANN_DISALLOWED_IN_NONDEFINTION_FILE(annotation.name), annotation, ANNOTATION__NAME, - ANN_DISALLOWED_IN_NONDEFINTION_FILE); + val IssueItem issueItem = ANN_DISALLOWED_IN_NONDEFINTION_FILE.toIssueItem(annotation.name); + addIssue(annotation, ANNOTATION__NAME, issueItem); return } val resource = element.eResource; @@ -484,15 +481,15 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { val project = workspaceAccess.findProjectByNestedLocation(annotation, projURI); if (project === null) { if (!N4Scheme.isResourceWithN4Scheme(resource)) { // built-in type definition files are not contained in a project - val msg = getMessageForNO_PROJECT_FOUND(projURI); + val IssueItem issueItem = NO_PROJECT_FOUND.toIssueItem(projURI); val script = EcoreUtil2.getContainerOfType(element, Script); - addIssue(msg, script, NO_PROJECT_FOUND); + addIssue(script, issueItem); } } else { val projectType = project.type; if (projectType !== ProjectType.RUNTIME_ENVIRONMENT && projectType !== ProjectType.RUNTIME_LIBRARY) { - addIssue(getMessageForANN_DISALLOWED_IN_NON_RUNTIME_COMPONENT(annotation.name), annotation, - ANNOTATION__NAME, ANN_DISALLOWED_IN_NON_RUNTIME_COMPONENT); + val IssueItem issueItem = ANN_DISALLOWED_IN_NON_RUNTIME_COMPONENT.toIssueItem(annotation.name); + addIssue(annotation, ANNOTATION__NAME, issueItem); return } } @@ -507,8 +504,8 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { return } if (!jsVariantHelper.isExternalMode(element)) { - addIssue(getMessageForANN_DISALLOWED_IN_NONDEFINTION_FILE(annotation.name), annotation, ANNOTATION__NAME, - ANN_DISALLOWED_IN_NONDEFINTION_FILE); + val IssueItem issueItem = ANN_DISALLOWED_IN_NONDEFINTION_FILE.toIssueItem(annotation.name); + addIssue(annotation, ANNOTATION__NAME, issueItem); return } } @@ -529,8 +526,7 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { // mutual exclusive with poly-fill aware. if (script.isContainedInStaticPolyfillAware) { - addIssue(messageForANN_POLY_AWARE_AND_MODULE_MUTUAL_EXCLUSIVE, annotation, ANNOTATION__NAME, - ANN_POLY_AWARE_AND_MODULE_MUTUAL_EXCLUSIVE) + addIssue(annotation, ANNOTATION__NAME, ANN_POLY_AWARE_AND_MODULE_MUTUAL_EXCLUSIVE.toIssueItem()) return } @@ -574,8 +570,8 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { it.URI.toString } ]) - addIssue(getMessageForPOLY_CLASH_IN_STATIC_POLYFILL_MODULE(msg_prefix + clashes), annotation, - ANNOTATION__NAME, POLY_CLASH_IN_STATIC_POLYFILL_MODULE) + val IssueItem issueItem = POLY_CLASH_IN_STATIC_POLYFILL_MODULE.toIssueItem(msg_prefix + clashes); + addIssue(annotation, ANNOTATION__NAME, issueItem) } } @@ -592,8 +588,7 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { // inside a static-polyfill module (IDE-1735) if (! element.isContainedInStaticPolyfillModule) { // transitively inherited // not in a polyfill-module - addIssue(messageForANN_POLY_STATIC_POLY_ONLY_IN_POLYFILL_MODULE, annotation, ANNOTATION__NAME, - ANN_POLY_STATIC_POLY_ONLY_IN_POLYFILL_MODULE) + addIssue(annotation, ANNOTATION__NAME, ANN_POLY_STATIC_POLY_ONLY_IN_POLYFILL_MODULE.toIssueItem); return } @@ -630,18 +625,15 @@ class N4JSAnnotationValidator extends AbstractN4JSDeclarativeValidator { def private boolean holdsPromisifiablePreconditions(FunctionDefinition funDef) { return switch (promisifyHelper.checkPromisifiablePreconditions(funDef)) { case MISSING_CALLBACK: { - addIssue(getMessageForANN_PROMISIFIABLE_MISSING_CALLBACK, PROMISIFIABLE.getAnnotation(funDef), - ANN_PROMISIFIABLE_MISSING_CALLBACK); + addIssue(PROMISIFIABLE.getAnnotation(funDef), ANN_PROMISIFIABLE_MISSING_CALLBACK.toIssueItem()); false } case BAD_CALLBACK__MORE_THAN_ONE_ERROR: { - addIssue(getMessageForANN_PROMISIFIABLE_BAD_CALLBACK_MORE_THAN_ONE_ERROR, - PROMISIFIABLE.getAnnotation(funDef), ANN_PROMISIFIABLE_BAD_CALLBACK_MORE_THAN_ONE_ERROR); + addIssue(PROMISIFIABLE.getAnnotation(funDef), ANN_PROMISIFIABLE_BAD_CALLBACK_MORE_THAN_ONE_ERROR.toIssueItem()); false } case BAD_CALLBACK__ERROR_NOT_FIRST_ARG: { - addIssue(getMessageForANN_PROMISIFIABLE_BAD_CALLBACK_ERROR_NOT_FIRST_ARG, - PROMISIFIABLE.getAnnotation(funDef), ANN_PROMISIFIABLE_BAD_CALLBACK_ERROR_NOT_FIRST_ARG); + addIssue(PROMISIFIABLE.getAnnotation(funDef), ANN_PROMISIFIABLE_BAD_CALLBACK_ERROR_NOT_FIRST_ARG.toIssueItem()); false } case OK: { diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSClassValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSClassValidator.xtend index 32246c48c9..d643ae7ce7 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSClassValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSClassValidator.xtend @@ -11,6 +11,7 @@ package org.eclipse.n4js.validation.validators import com.google.inject.Inject +import java.util.List import java.util.Map import org.eclipse.emf.ecore.EObject import org.eclipse.emf.ecore.EStructuralFeature @@ -49,7 +50,7 @@ import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions import org.eclipse.n4js.utils.ContainerTypesHelper import org.eclipse.n4js.utils.N4JSLanguageUtils import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator -import org.eclipse.n4js.validation.IssueCodes +import org.eclipse.n4js.validation.IssueItem import org.eclipse.n4js.validation.IssueUserDataKeys import org.eclipse.n4js.validation.N4JSElementKeywordProvider import org.eclipse.xtext.validation.Check @@ -95,13 +96,11 @@ class N4JSClassValidator extends AbstractN4JSDeclarativeValidator implements Pol if (classDecl?.definedType instanceof TClass) { var clazz = classDecl.definedType as TClass; if (!clazz.abstract && !clazz.directlyExported && clazz.hasTestMethods) { - addIssue(getMessageForCLF_TEST_CLASS_NOT_EXPORTED, classDecl, - N4_TYPE_DECLARATION__NAME, CLF_TEST_CLASS_NOT_EXPORTED - ); + addIssue(classDecl, N4_TYPE_DECLARATION__NAME, CLF_TEST_CLASS_NOT_EXPORTED.toIssueItem()); } } if (classDecl.typingStrategy === TypingStrategy.STRUCTURAL) { - addIssue(getMessageForCLF_MUST_BE_NOMINAL, classDecl, N4JSPackage.eINSTANCE.n4ClassifierDeclaration_TypingStrategy, CLF_MUST_BE_NOMINAL); + addIssue(classDecl, N4JSPackage.eINSTANCE.n4ClassifierDeclaration_TypingStrategy, CLF_MUST_BE_NOMINAL.toIssueItem()); } } @@ -206,10 +205,10 @@ class N4JSClassValidator extends AbstractN4JSDeclarativeValidator implements Pol val containingClassifier = field.containingType; if (containingClassifier instanceof TInterface) { if (N4JSLanguageUtils.builtInOrProvidedByRuntime(containingClassifier)) { - val message = getMessageForCLF_SPEC_BUILT_IN_OR_PROVIDED_BY_RUNTIME_OR_EXTENAL_WITHOUT_N4JS_ANNOTATION(field.name, containingClassifier.name); + val IssueItem issueItem = CLF_SPEC_BUILT_IN_OR_PROVIDED_BY_RUNTIME_OR_EXTENAL_WITHOUT_N4JS_ANNOTATION.toIssueItem(field.name, containingClassifier.name); val feature = if ((property.astElement as PropertyNameValuePair).property === null) PROPERTY_NAME_OWNER__DECLARED_NAME else N4JSPackage.eINSTANCE.propertyNameValuePair_Property; - addIssue(message, property.astElement, feature, CLF_SPEC_BUILT_IN_OR_PROVIDED_BY_RUNTIME_OR_EXTENAL_WITHOUT_N4JS_ANNOTATION); + addIssue(property.astElement, feature, issueItem); } } } @@ -248,8 +247,7 @@ class N4JSClassValidator extends AbstractN4JSDeclarativeValidator implements Pol def private internalCheckAbstractFinal(TClass tClass) { if (tClass.abstract && tClass.final) { - val message = getMessageForCLF_ABSTRACT_FINAL("class"); - addIssue(message, tClass.astElement, N4_TYPE_DECLARATION__NAME, CLF_ABSTRACT_FINAL); + addIssue(tClass.astElement, N4_TYPE_DECLARATION__NAME, CLF_ABSTRACT_FINAL.toIssueItem("class")); } } @@ -260,17 +258,17 @@ class N4JSClassValidator extends AbstractN4JSDeclarativeValidator implements Pol if (superType instanceof PrimitiveType) { if (!N4Scheme.isFromResourceWithN4Scheme(n4Class)) { // primitive types may be extended in built-in types - val message = getMessageForCLF_EXTENDS_PRIMITIVE_GENERIC_TYPE(superType.name); - addIssue(message, n4Class.superClassRef, null, CLF_EXTENDS_PRIMITIVE_GENERIC_TYPE); + val IssueItem issueItem = CLF_EXTENDS_PRIMITIVE_GENERIC_TYPE.toIssueItem(superType.name); + addIssue(n4Class.superClassRef, null, issueItem); } } else if (!(superType instanceof TClass)) { if (superType instanceof TInterface) { - val message = getMessageForSYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP(n4Class.description, "extend", + val IssueItem issueItem = SYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP.toIssueItem(n4Class.description, "extend", superType.description, "implements"); - addIssue(message, n4Class.superClassRef, null, SYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP); + addIssue(n4Class.superClassRef, null, issueItem); } else { - val message = getMessageForCLF_WRONG_META_TYPE(n4Class.description, "extend", superType.description); - addIssue(message, n4Class.superClassRef, null, CLF_WRONG_META_TYPE); + val IssueItem issueItem = CLF_WRONG_META_TYPE.toIssueItem(n4Class.description, "extend", superType.description); + addIssue(n4Class.superClassRef, null, issueItem); return false; } } else if(superType instanceof TClass) { @@ -278,18 +276,22 @@ class N4JSClassValidator extends AbstractN4JSDeclarativeValidator implements Pol // super class must not be final (except in case of polyfills) if (superType.final && !(N4JSLanguageUtils.isNonStaticPolyfill(n4Class) || N4JSLanguageUtils.isStaticPolyfill(n4Class))) { - val message = getMessageForCLF_EXTEND_FINAL(superType.name); val superTypeAstElement = superType.eGet(TypesPackage.eINSTANCE.syntaxRelatedTElement_AstElement, false) as EObject; val superClassUri = if (superTypeAstElement!==null) EcoreUtil.getURI(superTypeAstElement).toString; if (superClassUri !== null) { - addIssue(message, n4Class.superClassRef, null, CLF_EXTEND_FINAL, - IssueUserDataKeys.CLF_EXTEND_FINAL.SUPER_TYPE_DECLARATION_URI, superClassUri); + val IssueItem issueItem = CLF_EXTEND_FINAL.toIssueItemWithData( + List.of(IssueUserDataKeys.CLF_EXTEND_FINAL.SUPER_TYPE_DECLARATION_URI, superClassUri), + superType.name + ); + addIssue(n4Class.superClassRef, null, issueItem); } else { - addIssue(message, n4Class.superClassRef, null, CLF_EXTEND_FINAL, - IssueUserDataKeys.CLF_EXTEND_FINAL.SUPER_TYPE_DECLARATION_URI); + val IssueItem issueItem = CLF_EXTEND_FINAL.toIssueItemWithData( + List.of(IssueUserDataKeys.CLF_EXTEND_FINAL.SUPER_TYPE_DECLARATION_URI), + superType.name); + addIssue(n4Class.superClassRef, null, issueItem); } return false; } @@ -301,15 +303,15 @@ class N4JSClassValidator extends AbstractN4JSDeclarativeValidator implements Pol // if super class is observable, then this class must be observable as well if (superType.observable && !(n4Class.definedType as TClass).observable) { - val message = getMessageForCLF_OBSERVABLE_MISSING(n4Class.name, superType.name); - addIssue(message, n4Class, N4_TYPE_DECLARATION__NAME, CLF_OBSERVABLE_MISSING); + val IssueItem issueItem = CLF_OBSERVABLE_MISSING.toIssueItem(n4Class.name, superType.name); + addIssue(n4Class, N4_TYPE_DECLARATION__NAME, issueItem); return false; } } } else if (superTypeRef !== null && superTypeRef.isAliasResolved) { // not all aliases are illegal after "extends", but if we get to this point we have an illegal case: - val message = getMessageForCLF_WRONG_META_TYPE(n4Class.description, "extend", superTypeRef.typeRefAsStringWithAliasResolution); - addIssue(message, n4Class.superClassRef, null, CLF_WRONG_META_TYPE); + val IssueItem issueItem = CLF_WRONG_META_TYPE.toIssueItem(n4Class.description, "extend", superTypeRef.typeRefAsStringWithAliasResolution); + addIssue(n4Class.superClassRef, null, issueItem); return false; } return true; @@ -319,10 +321,10 @@ class N4JSClassValidator extends AbstractN4JSDeclarativeValidator implements Pol val receiverTypeRef = TypeUtils.createTypeRef(n4Class.definedType); val superCtor = containerTypesHelper.fromContext(n4Class).findConstructor(superType); if(superCtor!==null && !memberVisibilityChecker.isVisible(n4Class, receiverTypeRef, superCtor).visibility) { - val message = getMessageForCLF_EXTEND_NON_ACCESSIBLE_CTOR( + val IssueItem issueItem = CLF_EXTEND_NON_ACCESSIBLE_CTOR.toIssueItem( n4jsElementKeywordProvider.keyword(superType), superType.name); - addIssue(message, n4Class, N4_CLASS_DEFINITION__SUPER_CLASS_REF, CLF_EXTEND_NON_ACCESSIBLE_CTOR); + addIssue(n4Class, N4_CLASS_DEFINITION__SUPER_CLASS_REF, issueItem); return false; } return true; @@ -337,27 +339,26 @@ class N4JSClassValidator extends AbstractN4JSDeclarativeValidator implements Pol // consumed type must be an interface if (!(consumedType instanceof TInterface)) { if (consumedType instanceof TClass && n4Class.superClassRef === null) { - val message = getMessageForSYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP(n4Class.description, "implement", + val IssueItem issueItem = SYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP.toIssueItem(n4Class.description, "implement", consumedType.description, "extends"); - addIssue(message, it, null, SYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP); + addIssue(it, null, issueItem); } else { - val message = getMessageForCLF_WRONG_META_TYPE(n4Class.description, "implement", + val IssueItem issueItem = CLF_WRONG_META_TYPE.toIssueItem(n4Class.description, "implement", consumedType.description); - addIssue(message, it, null, CLF_WRONG_META_TYPE); + addIssue(it, null, issueItem); } } else { val tIfc = consumedType as TInterface; val cth = containerTypesHelper.fromContext(n4Class); val hasCallConstructSig = cth.findCallSignature(tIfc) !== null || cth.findConstructSignature(tIfc) !== null; if (hasCallConstructSig) { - val message = getMessageForCLF_CALL_CONSTRUCT_SIG_CANNOT_IMPLEMENT(); - addIssue(message, it, null, CLF_CALL_CONSTRUCT_SIG_CANNOT_IMPLEMENT); + addIssue(it, null, CLF_CALL_CONSTRUCT_SIG_CANNOT_IMPLEMENT.toIssueItem()); } } } else if (consumedTypeRef !== null && consumedTypeRef.isAliasResolved) { // not all aliases are illegal after "implements", but if we get to this point we have an illegal case: - val message = getMessageForCLF_WRONG_META_TYPE(n4Class.description, "implement", consumedTypeRef.typeRefAsStringWithAliasResolution); - addIssue(message, it, null, CLF_WRONG_META_TYPE); + val IssueItem issueItem = CLF_WRONG_META_TYPE.toIssueItem(n4Class.description, "implement", consumedTypeRef.typeRefAsStringWithAliasResolution); + addIssue(it, null, issueItem); } ] } @@ -374,8 +375,7 @@ class N4JSClassValidator extends AbstractN4JSDeclarativeValidator implements Pol val correctType = currFPar.declaredTypeRef instanceof ThisTypeRef && STRUCTURAL_FIELD_INITIALIZER === currFPar.declaredTypeRef.typingStrategy; if (!correctType) { - val message = messageForCLF_SPEC_WRONG_TYPE; - addIssue(message, annSpec, null, CLF_SPEC_WRONG_TYPE); + addIssue(annSpec, null, CLF_SPEC_WRONG_TYPE.toIssueItem()); } else { // prevent consequential errors holdsAdditionalSpecFieldMatchesOwnedFields( n4ClassDeclaration, @@ -388,8 +388,7 @@ class N4JSClassValidator extends AbstractN4JSDeclarativeValidator implements Pol } if (specAnnotations.size >= 2) { for (currAnnSpec : specAnnotations) { - val message = messageForCLF_SPEC_MULTIPLE; - addIssue(message, currAnnSpec, null, CLF_SPEC_MULTIPLE); + addIssue(currAnnSpec, null, CLF_SPEC_MULTIPLE.toIssueItem()); } } } @@ -415,16 +414,12 @@ class N4JSClassValidator extends AbstractN4JSDeclarativeValidator implements Pol val smemberType = ts.tau(smember, TypeUtils.createTypeRef(tclass)); val subtypeRes = ts.subtype(G, smemberType, fieldType); if (subtypeRes.failure) { - val message = getMessageForCLF_SPEC_WRONG_ADD_MEMBERTYPE(smember.name, description(tfield), + val IssueItem issueItem = CLF_SPEC_WRONG_ADD_MEMBERTYPE.toIssueItem(smember.name, description(tfield), trimTypesystemMessage(subtypeRes)); val errMember = (ctor.fpars.get(parIndex).declaredTypeRefInAST as StructuralTypeRef).structuralMembers. get(memberIndex); val sourceObject = (if (errMember.astElement !== null) errMember.astElement else errMember); - addIssue( - message, - sourceObject, - CLF_SPEC_WRONG_ADD_MEMBERTYPE - ); + addIssue(sourceObject, issueItem); } } @@ -437,10 +432,9 @@ class N4JSClassValidator extends AbstractN4JSDeclarativeValidator implements Pol def private boolean holdsNoCyclicInheritance(N4ClassDeclaration n4ClassDeclaration) { val cls = n4ClassDeclaration.definedType as TClassifier; val cycle = findCyclicInheritance(cls); - if(cycle!==null) { - val message = IssueCodes.getMessageForCLF_INHERITANCE_CYCLE(cycle.map[name].join(", ")); - addIssue(message, n4ClassDeclaration, N4JSPackage.Literals.N4_CLASS_DEFINITION__SUPER_CLASS_REF, - IssueCodes.CLF_INHERITANCE_CYCLE); + if (cycle!==null) { + val IssueItem issueItem = CLF_INHERITANCE_CYCLE.toIssueItem(cycle.map[name].join(", ")); + addIssue(n4ClassDeclaration, N4JSPackage.Literals.N4_CLASS_DEFINITION__SUPER_CLASS_REF, issueItem); return false; } return true; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSClassifierValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSClassifierValidator.xtend index c0b378a1dc..d3d673ae82 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSClassifierValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSClassifierValidator.xtend @@ -36,6 +36,7 @@ import org.eclipse.n4js.ts.types.TypeVariable import org.eclipse.n4js.ts.types.util.Variance import org.eclipse.n4js.utils.N4JSLanguageUtils import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator +import org.eclipse.n4js.validation.IssueItem import org.eclipse.xtext.naming.IQualifiedNameProvider import org.eclipse.xtext.naming.QualifiedName import org.eclipse.xtext.nodemodel.util.NodeModelUtils @@ -76,7 +77,7 @@ class N4JSClassifierValidator extends AbstractN4JSDeclarativeValidator { for(typeRefInAST : superTypeRefs) { for(typeArgInAST : typeRefInAST.declaredTypeArgs) { if(typeArgInAST instanceof Wildcard) { - addIssue(getMessageForCLF_IMPLEMENT_EXTEND_WITH_WILDCARD, typeArgInAST, CLF_IMPLEMENT_EXTEND_WITH_WILDCARD); + addIssue(typeArgInAST, CLF_IMPLEMENT_EXTEND_WITH_WILDCARD.toIssueItem()); } } } @@ -127,8 +128,7 @@ class N4JSClassifierValidator extends AbstractN4JSDeclarativeValidator { val duplicates = names.computeStringOccurance.filter[value > 1] for (dupe : duplicates) { - val message = getMessageForCLF_MULTIPLE_ROLE_CONSUME(QualifiedNameUtils.toHumanReadableString(dupe.key)) - addIssue(message, source.astElement, eref, CLF_MULTIPLE_ROLE_CONSUME) + addIssue(source.astElement, eref, CLF_MULTIPLE_ROLE_CONSUME.toIssueItem(QualifiedNameUtils.toHumanReadableString(dupe.key))) } } @@ -193,31 +193,27 @@ class N4JSClassifierValidator extends AbstractN4JSDeclarativeValidator { if (! isFieldAccessorPair(firstDup, otherDup)) { if (firstDup.constructor) { if (createErrorForFirst) { - val message = getMessageForCLF_DUP_CTOR( + val IssueItem issueItem = CLF_DUP_CTOR.toIssueItem( NodeModelUtils::getNode(firstDup.astElement).startLine, NodeModelUtils::getNode(otherDup.astElement).startLine ); - addIssue(message, firstDup.astElement, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, - CLF_DUP_CTOR) + addIssue(firstDup.astElement, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem) createErrorForFirst = false; } - val message = getMessageForCLF_DUP_CTOR( + val IssueItem issueItem = CLF_DUP_CTOR.toIssueItem( NodeModelUtils::getNode(otherDup.astElement).startLine, NodeModelUtils::getNode(firstDup.astElement).startLine); - addIssue(message, otherDup.astElement, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, - CLF_DUP_CTOR) + addIssue(otherDup.astElement, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem); } else { if (createErrorForFirst) { - val message = getMessageForCLF_DUP_MEMBER(firstDup.descriptionWithLine(), + val IssueItem issueItem = CLF_DUP_MEMBER.toIssueItem(firstDup.descriptionWithLine(), otherDup.descriptionWithLine()); - addIssue(message, firstDup.astElement, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, - CLF_DUP_MEMBER) + addIssue(firstDup.astElement, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem); createErrorForFirst = false; } - val message = getMessageForCLF_DUP_MEMBER(otherDup.descriptionWithLine(), + val IssueItem issueItem = CLF_DUP_MEMBER.toIssueItem(otherDup.descriptionWithLine(), firstDup.descriptionWithLine()); - addIssue(message, otherDup.astElement, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, - CLF_DUP_MEMBER) + addIssue(otherDup.astElement, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem); } } } @@ -228,13 +224,12 @@ class N4JSClassifierValidator extends AbstractN4JSDeclarativeValidator { if((n4TypeVar.declaredCovariant || n4TypeVar.declaredContravariant) && !(n4TypeVar.eContainer instanceof N4ClassifierDeclaration && n4TypeVar.eContainmentFeature===N4JSPackage.eINSTANCE.genericDeclaration_TypeVars)) { - val message = messageForCLF_DEF_SITE_VARIANCE_ONLY_IN_CLASSIFIER; val feature = if(n4TypeVar.declaredCovariant) { N4JSPackage.eINSTANCE.n4TypeVariable_DeclaredCovariant } else { N4JSPackage.eINSTANCE.n4TypeVariable_DeclaredContravariant }; - addIssue(message, n4TypeVar, feature, CLF_DEF_SITE_VARIANCE_ONLY_IN_CLASSIFIER); + addIssue(n4TypeVar, feature, CLF_DEF_SITE_VARIANCE_ONLY_IN_CLASSIFIER.toIssueItem()); } } @@ -251,9 +246,10 @@ class N4JSClassifierValidator extends AbstractN4JSDeclarativeValidator { if(variance!==Variance.INV) { val varianceOfPos = N4JSLanguageUtils.getVarianceOfPosition(typeRefInAST); if(varianceOfPos!==null && variance!==varianceOfPos) { - val msg = getMessageForCLF_TYPE_VARIABLE_AT_INVALID_POSITION(variance.getDescriptiveString(true), + val IssueItem issueItem = CLF_TYPE_VARIABLE_AT_INVALID_POSITION.toIssueItem( + variance.getDescriptiveString(true), varianceOfPos.getDescriptiveString(false)); - addIssue(msg, typeRefInAST, CLF_TYPE_VARIABLE_AT_INVALID_POSITION); + addIssue(typeRefInAST, issueItem); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSDeclaredNameValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSDeclaredNameValidator.xtend index 7c6cc857bb..d7e77c983a 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSDeclaredNameValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSDeclaredNameValidator.xtend @@ -81,6 +81,7 @@ import org.eclipse.xtext.validation.EValidatorRegistrar import static org.eclipse.n4js.validation.IssueCodes.* import org.eclipse.n4js.n4JS.PropertyNameValuePair +import org.eclipse.n4js.validation.IssueItem /** */ @@ -139,11 +140,10 @@ class N4JSDeclaredNameValidator extends AbstractN4JSDeclarativeValidator { return; } - addIssue( - StringExtensions.toFirstUpper( - getMessageForAST_NAME_DUPLICATE_ERR(messageHelper.description(dupeEO, name), - messageHelper.descriptionWithLine(baseEO, name))), dupeEO, findNameEAttribute(dupeEO), - AST_NAME_DUPLICATE_ERR); + val IssueItem issueItem = AST_NAME_DUPLICATE_ERR.toIssueItem( + StringExtensions.toFirstUpper(messageHelper.description(dupeEO, name)), + messageHelper.descriptionWithLine(baseEO, name)); + addIssue(dupeEO, findNameEAttribute(dupeEO), issueItem); } ]); ] @@ -167,12 +167,10 @@ class N4JSDeclaredNameValidator extends AbstractN4JSDeclarativeValidator { if (BASE_JS_TYPES.contains(name)) { val project = workspaceAccess.findProjectContaining(exportableElement); if (project === null || project.type !== ProjectType.RUNTIME_ENVIRONMENT) { - addIssue(getMessageForAST_GLOBAL_JS_NAME_CONFLICT(name), exportableElement, - AST_GLOBAL_JS_NAME_CONFLICT); + addIssue(exportableElement, AST_GLOBAL_JS_NAME_CONFLICT.toIssueItem(name)); } } else if (BASE_GLOBAL_NAMES.contains(name)) { - addIssue(getMessageForAST_GLOBAL_NAME_CONFLICT(name), exportableElement, - AST_GLOBAL_NAME_CONFLICT); + addIssue(exportableElement, AST_GLOBAL_NAME_CONFLICT.toIssueItem(name)); } } } @@ -247,12 +245,10 @@ class N4JSDeclaredNameValidator extends AbstractN4JSDeclarativeValidator { val globalObjectMember = globalEntry.value.head; val localObjects = localNames.get(name); for (innerScopeObject : localObjects) { - addIssue( - StringExtensions.toFirstUpper( - getMessageForAST_GLOBAL_NAME_SHADOW_ERR( - messageHelper.description(innerScopeObject, name), - messageHelper.description(globalObjectMember, name))), innerScopeObject, - findNameEAttribute(innerScopeObject), AST_GLOBAL_NAME_SHADOW_ERR); + val IssueItem issueItem = AST_GLOBAL_NAME_SHADOW_ERR.toIssueItem( + StringExtensions.toFirstUpper(messageHelper.description(innerScopeObject, name)), + messageHelper.description(globalObjectMember, name)); + addIssue(innerScopeObject, findNameEAttribute(innerScopeObject), issueItem); } } } @@ -305,31 +301,26 @@ class N4JSDeclaredNameValidator extends AbstractN4JSDeclarativeValidator { if (baseEO.equals(vee)) { if (dupeEO instanceof FormalParameter) { - addIssue( - StringExtensions.toFirstUpper( - getMessageForAST_NAME_SHADOW_ERR( - messageHelper.description(dupeEO, name), - messageHelper.description(baseEO, name))), dupeEO, - findNameEAttribute(dupeEO), AST_NAME_SHADOW_ERR); + val IssueItem issueItem = AST_NAME_SHADOW_ERR.toIssueItem( + StringExtensions.toFirstUpper(messageHelper.description(dupeEO, name)), + messageHelper.description(baseEO, name)); + addIssue(dupeEO, findNameEAttribute(dupeEO), issueItem); } else { - addIssue( - StringExtensions.toFirstUpper( - getMessageForAST_NAME_SHADOW_ERR( - messageHelper.description(dupeEO, name), - messageHelper.descriptionWithLine(baseEO, name))), dupeEO, - findNameEAttribute(dupeEO), AST_NAME_SHADOW_ERR); + val IssueItem issueItem = AST_NAME_SHADOW_ERR.toIssueItem( + StringExtensions.toFirstUpper(messageHelper.description(dupeEO, name)), + messageHelper.descriptionWithLine(baseEO, name)); + addIssue(dupeEO, findNameEAttribute(dupeEO), issueItem); } return; } // otherwise mark duplicates if (dupeEO instanceof FormalParameter) { - addIssue( - StringExtensions.toFirstUpper( - getMessageForAST_NAME_DUPLICATE_ERR( - messageHelper.description(dupeEO, name), - messageHelper.description(baseEO, name))), dupeEO, - findNameEAttribute(dupeEO), AST_NAME_DUPLICATE_ERR); + val IssueItem issueItem = AST_NAME_DUPLICATE_ERR.toIssueItem( + StringExtensions.toFirstUpper(messageHelper.description(dupeEO, name)), + messageHelper.description(baseEO, name) + ); + addIssue(dupeEO, findNameEAttribute(dupeEO), issueItem); } else if ((dupeEO instanceof NamedImportSpecifier && baseEO instanceof NamedImportSpecifier) || (dupeEO instanceof NamespaceImportSpecifier && @@ -353,12 +344,10 @@ class N4JSDeclaredNameValidator extends AbstractN4JSDeclarativeValidator { N4JSLanguageUtils.isNonStaticPolyfill(dupeEO as N4ClassifierDeclaration) // TODO IDE-1735 does this check need to be activated for static polyfills? )) { - addIssue( - StringExtensions.toFirstUpper( - getMessageForAST_NAME_DUPLICATE_ERR( - messageHelper.description(dupeEO, name), - messageHelper.descriptionWithLine(baseEO, name))), dupeEO, - findNameEAttribute(dupeEO), AST_NAME_DUPLICATE_ERR); + val IssueItem issueItem = AST_NAME_DUPLICATE_ERR.toIssueItem( + StringExtensions.toFirstUpper(messageHelper.description(dupeEO, name)), + messageHelper.descriptionWithLine(baseEO, name)); + addIssue(dupeEO, findNameEAttribute(dupeEO), issueItem); } } } @@ -421,12 +410,10 @@ class N4JSDeclaredNameValidator extends AbstractN4JSDeclarativeValidator { declaredLetConst.filter[fparNames.contains(declaredName)].forEach[dupeEO| val name = dupeEO.declaredName; val baseEO = fpars.filter[it.name==name].head; - addIssue( - StringExtensions.toFirstUpper( - getMessageForAST_NAME_DUPLICATE_ERR( - messageHelper.description(dupeEO, name), - messageHelper.description(baseEO, name))), dupeEO, - findNameEAttribute(dupeEO), AST_NAME_SHADOW_ERR); + val IssueItem issueItem = AST_NAME_DUPLICATE_ERR.toIssueItem( + StringExtensions.toFirstUpper(messageHelper.description(dupeEO, name)), + messageHelper.description(baseEO, name)); + addIssue(dupeEO, findNameEAttribute(dupeEO), issueItem); ]; } @@ -487,12 +474,10 @@ class N4JSDeclaredNameValidator extends AbstractN4JSDeclarativeValidator { && innerScopeObject.eContainer === outerScopeObject) { // formal parameters hides containing function name - addIssue( - StringExtensions.toFirstUpper( - getMessageForAST_NAME_SHADOW_ERR( - messageHelper.description(innerScopeObject, name), - messageHelper.description(outerScopeObject, name))), innerScopeObject, - findNameEAttribute(innerScopeObject), AST_NAME_SHADOW_ERR); + val IssueItem issueItem = AST_NAME_SHADOW_ERR.toIssueItem( + StringExtensions.toFirstUpper(messageHelper.description(innerScopeObject, name)), + messageHelper.description(outerScopeObject, name)); + addIssue(innerScopeObject, findNameEAttribute(innerScopeObject), issueItem); return; } @@ -503,12 +488,10 @@ class N4JSDeclaredNameValidator extends AbstractN4JSDeclarativeValidator { } // but not containing function - addIssue( - StringExtensions.toFirstUpper( - getMessageForAST_NAME_SHADOW_ERR( - messageHelper.description(innerScopeObject, name), - messageHelper.descriptionWithLine(outerScopeObject, name))), - innerScopeObject, findNameEAttribute(innerScopeObject), AST_NAME_SHADOW_ERR); + val IssueItem issueItem = AST_NAME_SHADOW_ERR.toIssueItem( + StringExtensions.toFirstUpper(messageHelper.description(innerScopeObject, name)), + messageHelper.descriptionWithLine(outerScopeObject, name)); + addIssue(innerScopeObject, findNameEAttribute(innerScopeObject), issueItem); return; } @@ -520,23 +503,19 @@ class N4JSDeclaredNameValidator extends AbstractN4JSDeclarativeValidator { //adding a warning, consider removing if it gets annoying //in our platform code if(jsVariantHelper.isN4JSMode(innerScopeObject)){ - addIssue( - StringExtensions.toFirstUpper( - getMessageForAST_NAME_SHADOW_WARN( - messageHelper.description(innerScopeObject, name), - messageHelper.descriptionWithLine(outerScopeObject, name))), - innerScopeObject, findNameEAttribute(innerScopeObject), AST_NAME_SHADOW_WARN); + val IssueItem issueItem = AST_NAME_SHADOW_WARN.toIssueItem( + StringExtensions.toFirstUpper(messageHelper.description(innerScopeObject, name)), + messageHelper.descriptionWithLine(outerScopeObject, name)); + addIssue(innerScopeObject, findNameEAttribute(innerScopeObject), issueItem); return; } //if js mode return; } - addIssue( - StringExtensions.toFirstUpper( - getMessageForAST_NAME_SHADOW_ERR( - messageHelper.description(innerScopeObject, name), - messageHelper.descriptionWithLine(outerScopeObject, name))), - innerScopeObject, findNameEAttribute(innerScopeObject), AST_NAME_SHADOW_ERR); + val IssueItem issueItem = AST_NAME_SHADOW_ERR.toIssueItem( + StringExtensions.toFirstUpper(messageHelper.description(innerScopeObject, name)), + messageHelper.descriptionWithLine(outerScopeObject, name)); + addIssue(innerScopeObject, findNameEAttribute(innerScopeObject), issueItem); return; } return; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSDependencyInjectionValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSDependencyInjectionValidator.xtend index 396dbc4182..5a7fe76468 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSDependencyInjectionValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSDependencyInjectionValidator.xtend @@ -59,6 +59,7 @@ import org.eclipse.n4js.typesystem.utils.TypeSystemHelper import org.eclipse.n4js.utils.ContainerTypesHelper import org.eclipse.n4js.utils.DeclMergingHelper import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator +import org.eclipse.n4js.validation.IssueItem import org.eclipse.n4js.xtext.scoping.IEObjectDescriptionWithError import org.eclipse.xtext.scoping.IScopeProvider import org.eclipse.xtext.validation.Check @@ -142,12 +143,10 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator val tClazz = staticType as TClass; if (requiresInjection(tClazz, declMergingHelper)) { - addIssue(getMessageForDI_MUST_BE_INJECTED(tClazz.typeAsString), - newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, DI_MUST_BE_INJECTED); + addIssue(newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, DI_MUST_BE_INJECTED.toIssueItem(tClazz.typeAsString)); } if (isMarkedInjected(tClazz, declMergingHelper)) { - addIssue(getMessageForDI_API_INJECTED(), - newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, DI_API_INJECTED); + addIssue(newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, DI_API_INJECTED.toIssueItem()); } } @@ -208,9 +207,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator if (!injectedParentInjectors.empty) { val currentName = currentType.name; val superName = injectedParentInjectors.get(0)?.containingType?.name; - addIssue(getMessageForDI_CTOR_BREAKS_INJECTION_CHAIN(superName, currentName), - ctor, PROPERTY_NAME_OWNER__DECLARED_NAME, DI_CTOR_BREAKS_INJECTION_CHAIN - ) + addIssue(ctor, PROPERTY_NAME_OWNER__DECLARED_NAME, DI_CTOR_BREAKS_INJECTION_CHAIN.toIssueItem(superName, currentName)); return false; } } @@ -260,7 +257,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator val isInjectedCtor = INJECT.hasAnnotation(ctor) if (!isInjectedCtor) { // read-access "this.f" where f is injected is valid only in a constructor that is itself marked (at)Inject - addIssue(getMessageForDI_FIELD_IS_NOT_INJECTED_YET(accessedField.name), propAccess, DI_FIELD_IS_NOT_INJECTED_YET); + addIssue(propAccess, DI_FIELD_IS_NOT_INJECTED_YET.toIssueItem(accessedField.name)); isValid = false; } else { // some param must exist whose type conforms to that of the injected field being read. @@ -270,7 +267,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator || ts.subtypeSucceeded(G, it, accessedField?.typeRef) ]; if (!someParamSubtypesFieldType) { - addIssue(getMessageForDI_FIELD_IS_NOT_INJECTED_YET(accessedField.name), propAccess, DI_FIELD_IS_NOT_INJECTED_YET); + addIssue(propAccess, DI_FIELD_IS_NOT_INJECTED_YET.toIssueItem(accessedField.name)); isValid = false; } } @@ -336,7 +333,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator return // invalid AST } if(injtorClassDecl.superClassRef !== null){ - addIssue(getMessageForDI_ANN_INJECTOR_EXTENDS(), ann, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_INJECTOR_EXTENDS); + addIssue(ann, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_INJECTOR_EXTENDS.toIssueItem()); } // collect binding across all binders used by the injector of interest val usedBindersAnns = USE_BINDER.getAllAnnotations(injtorClassDecl) @@ -356,7 +353,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator val injtorCtor = injtorClassDecl.ownedCtor if ((null !== injtorCtor) && !(injtorCtor.fpars.isEmpty)) { if (!INJECT.hasAnnotation(injtorCtor)) { - addIssue(getMessageForDI_ANN_INJECTOR_CTOR_MUST_BE_INJECT(), injtorCtor, DI_ANN_INJECTOR_CTOR_MUST_BE_INJECT); + addIssue(injtorCtor, DI_ANN_INJECTOR_CTOR_MUST_BE_INJECT.toIssueItem()); } } } @@ -409,8 +406,8 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator // comparing structurally leads to flagging as duplicates, say, two different classes lacking members val dupBinding = getDuplicate(extra, seen, G) if (null !== dupBinding) { - addIssue(getMessageForDI_ANN_DUPLICATE_BINDING(), useBinderAnn, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_DUPLICATE_BINDING); - addIssue(getMessageForDI_ANN_DUPLICATE_BINDING(), dupBinding, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_DUPLICATE_BINDING); + addIssue(useBinderAnn, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_DUPLICATE_BINDING.toIssueItem()); + addIssue(dupBinding, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_DUPLICATE_BINDING.toIssueItem()); } else { seen.put(extra, useBinderAnn) } @@ -435,15 +432,15 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator // TODO this assumes an ExportDeclaration may be annotated @Binder. Fix javadoc if so. Fix error message if not. val binderClassDecl = getAnnotatedClass(binderAnn); if(null === binderClassDecl || binderClassDecl.isAbstract){ - addIssue(getMessageForDI_ANN_BINDER_NOT_APPLICABLE(), binderAnn, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_BINDER_NOT_APPLICABLE); + addIssue(binderAnn, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_BINDER_NOT_APPLICABLE.toIssueItem()); return } if(binderClassDecl.superClassRef !== null){ - addIssue(getMessageForDI_ANN_BINDER_EXTENDS(), binderAnn, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_BINDER_EXTENDS); + addIssue(binderAnn, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_BINDER_EXTENDS.toIssueItem()); } val binderTClazz = binderClassDecl.definedTypeAsClass; if (GENERATE_INJECTOR.hasAnnotation(binderTClazz)) { - addIssue(getMessageForDI_ANN_BINDER_AND_INJECTOR_DONT_GO_TOGETHER(), binderAnn, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_BINDER_AND_INJECTOR_DONT_GO_TOGETHER); + addIssue(binderAnn, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_BINDER_AND_INJECTOR_DONT_GO_TOGETHER.toIssueItem()); } internalCheckNoDupBindings(BIND.getAllAnnotations(binderClassDecl), newRuleEnvironment(binderClassDecl)) } @@ -461,8 +458,8 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator // comparing structurally leads to flagging as duplicates, say, two different classes lacking members val dupBinding = getDuplicate(extra, seen, G) if (null !== dupBinding) { - addIssue(getMessageForDI_ANN_DUPLICATE_BINDING(), binding, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_DUPLICATE_BINDING); - addIssue(getMessageForDI_ANN_DUPLICATE_BINDING(), dupBinding, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_DUPLICATE_BINDING); + addIssue(binding, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_DUPLICATE_BINDING.toIssueItem()); + addIssue(dupBinding, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_DUPLICATE_BINDING.toIssueItem()); } else { seen.put(extra, binding) } @@ -535,11 +532,11 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator } else { val indexOf = visitedTypes.indexOf(type.name); if (indexOf > -1) { + val IssueItem issueItem = DI_ANN_USE_INJECTOR_CYCLE.toIssueItem('''«visitedTypes.join(' > ')» > «type.name»'''); addIssue( - getMessageForDI_ANN_USE_INJECTOR_CYCLE('''«visitedTypes.join(' > ')» > «type.name»'''), it, N4JSPackage.eINSTANCE.annotation_Name, - DI_ANN_USE_INJECTOR_CYCLE + issueItem ); return false } @@ -618,7 +615,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator //check the container (classifier decl) of the annotated element (ie, field or constructor) val annElemCont = annElem.eContainer; if(annElemCont instanceof N4InterfaceDeclaration){ - addIssue(getMessageForDI_ANN_INTERFACE_INJECTION_NOT_SUPPORTED(), ann, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_INTERFACE_INJECTION_NOT_SUPPORTED); + addIssue(ann, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_INTERFACE_INJECTION_NOT_SUPPORTED.toIssueItem()); //no return, do other checks } @@ -636,10 +633,9 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator valid = !AnnotationDefinition.GENERATE_INJECTOR.hasAnnotation(clazz) if (!valid) { addIssue( - getMessageForDI_ANN_INJECTOR_CANNOT_BE_INJECTED_INTO_INJECTOR(), ann, N4JSPackage.eINSTANCE.annotation_Name, - DI_ANN_INJECTOR_CANNOT_BE_INJECTED_INTO_INJECTOR + DI_ANN_INJECTOR_CANNOT_BE_INJECTED_INTO_INJECTOR.toIssueItem() ); } val type = clazz?.superClassRef?.declaredType; @@ -662,9 +658,8 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator defMember.fpars.forEach[ann.holdsIsInjectableType(it)] } else { // method injection not supported yet - addIssue(getMessageForDI_ANN_INJECT_METHOD_NOT_SUPPORTED_YET(), - ann, N4JSPackage.eINSTANCE.annotation_Name, - DI_ANN_INJECT_METHOD_NOT_SUPPORTED_YET) + addIssue(ann, N4JSPackage.eINSTANCE.annotation_Name, + DI_ANN_INJECT_METHOD_NOT_SUPPORTED_YET.toIssueItem()) } } }; @@ -680,8 +675,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator val classDecl = getAnnotatedClass(ann); val tClass = classDecl?.definedType; if(tClass!==null && !requiredDef.hasAnnotation(tClass)) { - addIssue(getMessageForDI_ANN_ONLY_ON_CLASS_ANNOTATED_WITH(ann.name,requiredDef.name), - ann, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_ONLY_ON_CLASS_ANNOTATED_WITH); + addIssue(ann, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_ONLY_ON_CLASS_ANNOTATED_WITH.toIssueItem(ann.name,requiredDef.name)); return false; } return true; @@ -697,8 +691,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator val methodDecl = getAnnotatedMethod(ann); val tClass = methodDecl?.definedType?.eContainer; if(tClass instanceof TClass && !requiredDef.hasAnnotation(tClass as TClass)) { - addIssue(getMessageForDI_ANN_ONLY_ON_METHOD_IN_CLASS_ANNOTATED_WITH(ann.name,requiredDef.name), - ann, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_ONLY_ON_METHOD_IN_CLASS_ANNOTATED_WITH); + addIssue(ann, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_ONLY_ON_METHOD_IN_CLASS_ANNOTATED_WITH.toIssueItem(ann.name,requiredDef.name)); return false; } return true; @@ -720,10 +713,9 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator val nonInjectableParams = tMethod.fpars.filter[fpar| !(fpar.typeRef.isInjectableType)] nonInjectableParams.forEach[fpar| addIssue( - getMessageForDI_NOT_INJECTABLE(fpar.typeRef.typeRefAsString, ''' at «fpar.name»'''), fpar.astElement, N4JSPackage.eINSTANCE.abstractVariable_Name, - DI_NOT_INJECTABLE + DI_NOT_INJECTABLE.toIssueItem(fpar.typeRef.typeRefAsString, ''' at «fpar.name»''') ); ]; @@ -734,8 +726,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator val retTR = tMethod.returnTypeRef val isVoidOrOptional = TypeUtils.isVoid(retTR) || tMethod.isReturnValueOptional; if(isVoidOrOptional) { - addIssue(messageForDI_ANN_PROVIDES_METHOD_MUST_RETURN_VALUE, - methodDecl, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, DI_ANN_PROVIDES_METHOD_MUST_RETURN_VALUE); + addIssue(methodDecl, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, DI_ANN_PROVIDES_METHOD_MUST_RETURN_VALUE.toIssueItem()); return false; } return ann.holdsIsInjectableType(tMethod.returnTypeRef) @@ -754,8 +745,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator } val argTypeRef = if(arg instanceof TypeRefAnnotationArgument) arg.typeRef else null; if(!isTypeRefToTClassAnnotatedWith(argTypeRef, requiredDef)) { - addIssue(getMessageForDI_ANN_ARG_MUST_BE_ANNOTATED_WITH(ann.name,requiredDef.name), - arg, DI_ANN_ARG_MUST_BE_ANNOTATED_WITH); + addIssue(arg, DI_ANN_ARG_MUST_BE_ANNOTATED_WITH.toIssueItem(ann.name,requiredDef.name)); return false; } return true; @@ -780,7 +770,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator val arg0TypeRef = ann.getArgAsTypeRef(0); val arg1TypeRef = ann.getArgAsTypeRef(1); if(arg0TypeRef!==null && arg1TypeRef!==null && !ts.subtypeSucceeded(G, arg1TypeRef,arg0TypeRef)) { - addIssue(getMessageForDI_ANN_BIND_SECOND_MUST_BE_SUBTYPE_FIRST(ann.name), ann.args.get(1), DI_ANN_BIND_SECOND_MUST_BE_SUBTYPE_FIRST) + addIssue(ann.args.get(1), DI_ANN_BIND_SECOND_MUST_BE_SUBTYPE_FIRST.toIssueItem(ann.name)) return false; } return true; @@ -795,9 +785,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator return true; } if (isVariadicOrOptional) { - addIssue(getMessageForDI_VARARGS_NOT_INJECTABLE(), astElement, - N4JSPackage.eINSTANCE.abstractVariable_Name, DI_VARARGS_NOT_INJECTABLE - ); + addIssue(astElement, N4JSPackage.eINSTANCE.abstractVariable_Name, DI_VARARGS_NOT_INJECTABLE.toIssueItem()); return false; } return ann.holdsIsInjectableType(typeRef, name); @@ -821,7 +809,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator return false } if (!isConcrete(targetTypeRef)) { - addIssue(getMessageForDI_ANN_BIND_ABSTRACT_TARGET(), bindAnn, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_BIND_ABSTRACT_TARGET); + addIssue(bindAnn, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_BIND_ABSTRACT_TARGET.toIssueItem()); return false } return true @@ -861,7 +849,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator } if (!typeRef.isInjectableType) { val description = if (null === name) '''''' else ''' at «name»'''; - addIssue(getMessageForDI_NOT_INJECTABLE(typeRef.typeRefAsString, description), ann, DI_NOT_INJECTABLE); + addIssue(ann, DI_NOT_INJECTABLE.toIssueItem(typeRef.typeRefAsString, description)); return false; } return true; @@ -1019,7 +1007,7 @@ class N4JSDependencyInjectionValidator extends AbstractN4JSDeclarativeValidator private def internalCheckAnnotationInjected(Annotation ann) { val classDecl = getAnnotatedClass(ann); if(!isInjectedApplicable(classDecl)){ - addIssue(getMessageForDI_ANN_INJECTED_NOT_APPLICABLE(), ann, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_INJECTED_NOT_APPLICABLE); + addIssue(ann, N4JSPackage.eINSTANCE.annotation_Name, DI_ANN_INJECTED_NOT_APPLICABLE.toIssueItem()); return } // val tClass = classDecl?.definedTypeAsClass; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSDestructureValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSDestructureValidator.xtend index 6dfe3a58a4..398e869746 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSDestructureValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSDestructureValidator.xtend @@ -40,6 +40,7 @@ import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions import org.eclipse.n4js.utils.DestructureHelper import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator import org.eclipse.n4js.validation.IssueCodes +import org.eclipse.n4js.validation.IssueItem import org.eclipse.xtext.scoping.IScope import org.eclipse.xtext.validation.Check import org.eclipse.xtext.validation.EValidatorRegistrar @@ -80,8 +81,7 @@ class N4JSDestructureValidator extends AbstractN4JSDeclarativeValidator { ObjectBindingPattern: pattern.properties.empty }; if(isEmpty) { - val message = IssueCodes.messageForDESTRUCT_EMPTY_PATTERN; - addIssue(message, pattern, IssueCodes.DESTRUCT_EMPTY_PATTERN); + addIssue(pattern, IssueCodes.DESTRUCT_EMPTY_PATTERN.toIssueItem()); } } @@ -94,8 +94,7 @@ class N4JSDestructureValidator extends AbstractN4JSDeclarativeValidator { ObjectLiteral: lhs.propertyAssignments.filter(PropertyNameValuePair).empty } if(empty) { - val message = IssueCodes.messageForDESTRUCT_EMPTY_PATTERN; - addIssue(message, lhs, IssueCodes.DESTRUCT_EMPTY_PATTERN); + addIssue(lhs, IssueCodes.DESTRUCT_EMPTY_PATTERN.toIssueItem()); } } } @@ -163,7 +162,7 @@ class N4JSDestructureValidator extends AbstractN4JSDeclarativeValidator { if(errMsg.length>0) { val astElement = node.astElement; val issueCode = mDescRef.get().issueCode; - if (Set.of(VIS_ILLEGAL_MEMBER_ACCESS, VIS_WRONG_READ_WRITE_ACCESS).contains(issueCode)) { + if (Set.of(VIS_ILLEGAL_MEMBER_ACCESS.name(), VIS_WRONG_READ_WRITE_ACCESS.name()).contains(issueCode)) { if (astElement instanceof BindingProperty && !(astElement as BindingProperty).isSingleNameBinding) { // handled elsewhere: var {fieldPublic: a, fieldPrivate: b} = cls; return true; @@ -174,15 +173,13 @@ class N4JSDestructureValidator extends AbstractN4JSDeclarativeValidator { } } - val msg = getMessageForDESTRUCT_PROP_WITH_ERROR(node.propName, errMsg.toString.trim.trimSuffix('.')); val astNodeOfPropName = node.getEObjectAndFeatureForPropName(); - addIssue(msg, astNodeOfPropName.key, astNodeOfPropName.value, DESTRUCT_PROP_WITH_ERROR); + addIssue(astNodeOfPropName.key, astNodeOfPropName.value, DESTRUCT_PROP_WITH_ERROR.toIssueItem(node.propName, errMsg.toString.trim.trimSuffix('.'))); return false; } else if(propTypeRef===null) { - val msg = getMessageForDESTRUCT_PROP_MISSING(node.propName, valueTypePerNode.get(parentNode)?.typeRefAsString); val astNodeOfPropName = node.getEObjectAndFeatureForPropName(); - addIssue(msg, astNodeOfPropName.key, astNodeOfPropName.value, DESTRUCT_PROP_MISSING); + addIssue(astNodeOfPropName.key, astNodeOfPropName.value, DESTRUCT_PROP_MISSING.toIssueItem(node.propName, valueTypePerNode.get(parentNode)?.typeRefAsString)); return false; } } @@ -236,11 +233,11 @@ class N4JSDestructureValidator extends AbstractN4JSDeclarativeValidator { "of property '"+node.propName+"'" }; var tsMsg = result.failureMessage.trimPrefix('failed: ').trimSuffix('.'); - val msg = getMessageForDESTRUCT_TYPE_ERROR_VAR(varName, elemDesc, tsMsg); + val IssueItem issueItem = DESTRUCT_TYPE_ERROR_VAR.toIssueItem(varName, elemDesc, tsMsg); if(node.varDecl!==null) { - addIssue(msg, node.varDecl, N4JSPackage.eINSTANCE.abstractVariable_Name, DESTRUCT_TYPE_ERROR_VAR) + addIssue(node.varDecl, N4JSPackage.eINSTANCE.abstractVariable_Name, issueItem) } else { - addIssue(msg, node.varRef, DESTRUCT_TYPE_ERROR_VAR); + addIssue(node.varRef, issueItem); } return false; } @@ -274,25 +271,25 @@ class N4JSDestructureValidator extends AbstractN4JSDeclarativeValidator { "a value of type '"+valueTypeRef.typeRefAsString+"'" }; var tsMsg = result.failureMessage.trimPrefix('failed: ').trimSuffix('.'); - val msg = getMessageForDESTRUCT_TYPE_ERROR_PATTERN(patternKind, elemDesc, tsMsg); + val IssueItem issueItem = DESTRUCT_TYPE_ERROR_PATTERN.toIssueItem(patternKind, elemDesc, tsMsg); val astElem = node.astElement; switch(astElem) { PropertyNameValuePair: - addIssue(msg, astElem, N4JSPackage.eINSTANCE.propertyNameValuePair_Expression, DESTRUCT_TYPE_ERROR_PATTERN) + addIssue(astElem, N4JSPackage.eINSTANCE.propertyNameValuePair_Expression, issueItem) BindingProperty: - addIssue(msg, astElem, N4JSPackage.eINSTANCE.bindingProperty_Value, DESTRUCT_TYPE_ERROR_PATTERN) + addIssue(astElem, N4JSPackage.eINSTANCE.bindingProperty_Value, issueItem) VariableBinding: - addIssue(msg, astElem, N4JSPackage.eINSTANCE.variableBinding_Pattern, DESTRUCT_TYPE_ERROR_PATTERN) + addIssue(astElem, N4JSPackage.eINSTANCE.variableBinding_Pattern, issueItem) AssignmentExpression: - addIssue(msg, astElem, N4JSPackage.eINSTANCE.assignmentExpression_Lhs, DESTRUCT_TYPE_ERROR_PATTERN) + addIssue(astElem, N4JSPackage.eINSTANCE.assignmentExpression_Lhs, issueItem) ForStatement case !astElem.varDeclsOrBindings.empty: - addIssue(msg, astElem, N4JSPackage.eINSTANCE.variableDeclarationContainer_VarDeclsOrBindings, DESTRUCT_TYPE_ERROR_PATTERN) + addIssue(astElem, N4JSPackage.eINSTANCE.variableDeclarationContainer_VarDeclsOrBindings, issueItem) ForStatement case astElem.initExpr !== null: - addIssue(msg, astElem, N4JSPackage.eINSTANCE.forStatement_InitExpr, DESTRUCT_TYPE_ERROR_PATTERN) + addIssue(astElem, N4JSPackage.eINSTANCE.forStatement_InitExpr, issueItem) ForStatement case astElem.expression !== null: - addIssue(msg, astElem, N4JSPackage.eINSTANCE.iterationStatement_Expression, DESTRUCT_TYPE_ERROR_PATTERN) + addIssue(astElem, N4JSPackage.eINSTANCE.iterationStatement_Expression, issueItem) default: - addIssue(msg, astElem, DESTRUCT_TYPE_ERROR_PATTERN) + addIssue(astElem, issueItem) } return false; } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSEnumValidator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSEnumValidator.java index 91b5fedf02..5cceabf23c 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSEnumValidator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSEnumValidator.java @@ -12,8 +12,6 @@ import static org.eclipse.n4js.validation.IssueCodes.ENM_DUPLICTAE_LITERALS; import static org.eclipse.n4js.validation.IssueCodes.ENM_LITERALS_HIDE_META; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForENM_DUPLICTAE_LITERALS; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForENM_LITERALS_HIDE_META; import static org.eclipse.n4js.validation.validators.StaticPolyfillValidatorExtension.internalCheckNotInStaticPolyfillModule; import java.math.BigDecimal; @@ -21,7 +19,6 @@ import java.util.stream.Collectors; import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.n4js.AnnotationDefinition; import org.eclipse.n4js.n4JS.IdentifierRef; import org.eclipse.n4js.n4JS.N4EnumDeclaration; @@ -68,8 +65,8 @@ public void register(EValidatorRegistrar registrar) { public void checkEnumAnnotations(N4EnumDeclaration n4EnumDecl) { if (AnnotationDefinition.NUMBER_BASED.hasAnnotation(n4EnumDecl) && AnnotationDefinition.STRING_BASED.hasAnnotation(n4EnumDecl)) { - addIssue(IssueCodes.getMessageForENM_BOTH_NUMBER_AND_STRING_BASED(), n4EnumDecl, - N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, IssueCodes.ENM_BOTH_NUMBER_AND_STRING_BASED); + addIssue(n4EnumDecl, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, + IssueCodes.ENM_BOTH_NUMBER_AND_STRING_BASED); } } @@ -96,18 +93,16 @@ public void checkNamesOfEnumLiterals(N4EnumDeclaration n4EnumDeclaration) { // 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); + addIssue(literals.get(0), N4JSPackage.Literals.N4_ENUM_LITERAL__NAME, + ENM_DUPLICTAE_LITERALS, name); 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); + addIssue(literals.get(0), N4JSPackage.Literals.N4_ENUM_LITERAL__NAME, + ENM_LITERALS_HIDE_META, name); } }); } @@ -149,14 +144,12 @@ public void checkValuesOfEnumLiterals(N4EnumDeclaration n4EnumDecl) { boolean isNumeric = actualValue instanceof BigDecimal; if (enumKind == EnumKind.NumberBased) { if (!isNumeric) { - addIssue(IssueCodes.getMessageForENM_ILLEGAL_STRING_VALUE(), literal, - N4JSPackage.Literals.N4_ENUM_LITERAL__VALUE_EXPRESSION, + addIssue(literal, N4JSPackage.Literals.N4_ENUM_LITERAL__VALUE_EXPRESSION, IssueCodes.ENM_ILLEGAL_STRING_VALUE); } } else { if (isNumeric) { - addIssue(IssueCodes.getMessageForENM_ILLEGAL_NUMERIC_VALUE(), literal, - N4JSPackage.Literals.N4_ENUM_LITERAL__VALUE_EXPRESSION, + addIssue(literal, N4JSPackage.Literals.N4_ENUM_LITERAL__VALUE_EXPRESSION, IssueCodes.ENM_ILLEGAL_NUMERIC_VALUE); } } @@ -210,14 +203,7 @@ public void checkUsageOfNumberOrStringBasedEnum(IdentifierRef identRef) { } } // invalid usage! - addIssue(IssueCodes.getMessageForENM_INVALID_USE_OF_NUM_OR_STR_BASED_ENUM(), identRef, - IssueCodes.ENM_INVALID_USE_OF_NUM_OR_STR_BASED_ENUM); + addIssue(identRef, IssueCodes.ENM_INVALID_USE_OF_NUM_OR_STR_BASED_ENUM); } - // publish - @Override - public void addIssue(String message, EObject source, EStructuralFeature feature, String issueCode, - String... issueData) { - super.addIssue(message, source, feature, issueCode, issueData); - } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSExpressionValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSExpressionValidator.xtend index 55c4154ed6..75b37b8066 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSExpressionValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSExpressionValidator.xtend @@ -37,6 +37,7 @@ import org.eclipse.n4js.n4JS.EqualityExpression import org.eclipse.n4js.n4JS.EqualityOperator import org.eclipse.n4js.n4JS.Expression import org.eclipse.n4js.n4JS.ExpressionStatement +import org.eclipse.n4js.n4JS.ExpressionWithTarget import org.eclipse.n4js.n4JS.IdentifierRef import org.eclipse.n4js.n4JS.IndexedAccessExpression import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName @@ -126,6 +127,7 @@ import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind import org.eclipse.n4js.utils.PromisifyHelper import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator import org.eclipse.n4js.validation.IssueCodes +import org.eclipse.n4js.validation.IssueItem import org.eclipse.n4js.validation.JavaScriptVariantHelper import org.eclipse.n4js.validation.N4JSElementKeywordProvider import org.eclipse.n4js.validation.ValidatorMessageHelper @@ -139,7 +141,6 @@ import org.eclipse.xtext.validation.EValidatorRegistrar import static org.eclipse.n4js.validation.IssueCodes.* import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* -import org.eclipse.n4js.n4JS.ExpressionWithTarget /** */ @@ -178,8 +179,8 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { @Check def checkAwaitExpression(AwaitExpression awaitExpression) { if (!N4JSLanguageUtils.isValidLocationForAwait(awaitExpression)) { - val message = IssueCodes.getMessageForEXP_MISPLACED_AWAIT("await", "async"); - addIssue(message, awaitExpression, IssueCodes.EXP_MISPLACED_AWAIT); + val IssueItem issueItem = EXP_MISPLACED_AWAIT.toIssueItem("await", "async"); + addIssue(awaitExpression, issueItem); } if( awaitExpression.getExpression() === null ){ @@ -215,12 +216,10 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val boolean isUndef = typeRef.declaredType == G.undefinedType; val boolean isNull = typeRef.declaredType == G.nullType; if (!stUnions) { - val message = IssueCodes.getMessageForEXP_AWAIT_NON_ASYNC(); - addIssue(message, awaitExpression, IssueCodes.EXP_AWAIT_NON_ASYNC); + addIssue(awaitExpression, EXP_AWAIT_NON_ASYNC.toIssueItem()); } if (isUndef || isNull) { - val message = IssueCodes.getMessageForEXP_AWAIT_NON_ASYNC_SPECIAL(typeRef.declaredType.name); - addIssue(message, awaitExpression, IssueCodes.EXP_AWAIT_NON_ASYNC_SPECIAL); + addIssue(awaitExpression, EXP_AWAIT_NON_ASYNC_SPECIAL.toIssueItem(typeRef.declaredType.name)); } } @@ -259,10 +258,9 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val G = propAccessExpr.newRuleEnvironment; val targetTypeRef = ts.type(G, propAccessExpr.target); if(!ts.subtypeSucceeded(G, targetTypeRef, declThisTypeRef)) { - val msg = IssueCodes.getMessageForEXP_ACCESS_INVALID_TYPE_OF_TARGET(prop.description, + val IssueItem issueItem = EXP_ACCESS_INVALID_TYPE_OF_TARGET.toIssueItem(prop.description, targetTypeRef.typeRefAsString, declThisTypeRef.typeRefAsString); - addIssue(msg, propAccessExpr, N4JSPackage.eINSTANCE.parameterizedPropertyAccessExpression_Property, - IssueCodes.TYS_NO_SUBTYPE); + addIssue(propAccessExpr, N4JSPackage.eINSTANCE.parameterizedPropertyAccessExpression_Property, issueItem); } } } @@ -332,10 +330,10 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { return } // no more whitelist checks - val message = IssueCodes.getMessageForEXP_METHOD_REF_UNATTACHED_FROM_RECEIVER(method.name); + val message = EXP_METHOD_REF_UNATTACHED_FROM_RECEIVER.getMessage(method.name); val source = propAccessExpression val feature = N4JSPackage.eINSTANCE.parameterizedPropertyAccessExpression_Property - warning(message, source, feature, IssueCodes.EXP_METHOD_REF_UNATTACHED_FROM_RECEIVER); + warning(message, source, feature, EXP_METHOD_REF_UNATTACHED_FROM_RECEIVER.name()); } private def boolean isMethodEffectivelyFinal(TMethod method) { @@ -364,10 +362,8 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val targetIdRef = if (target instanceof IdentifierRef) target else null; val isExceptionCase = target instanceof ThisLiteral; // avoid duplicate error messages if (targetIdRef?.id !== prop.eContainer && !isExceptionCase) { - val message = IssueCodes.getMessageForCLF_INVALID_ACCESS_OF_STATIC_MEMBER_OF_INTERFACE; - addIssue(message, propAccessExpr, - N4JSPackage.Literals.EXPRESSION_WITH_TARGET__TARGET, - IssueCodes.CLF_INVALID_ACCESS_OF_STATIC_MEMBER_OF_INTERFACE); + addIssue(propAccessExpr, N4JSPackage.Literals.EXPRESSION_WITH_TARGET__TARGET, + CLF_INVALID_ACCESS_OF_STATIC_MEMBER_OF_INTERFACE.toIssueItem()); } } } @@ -395,19 +391,18 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { if (!isCallable && !(callExpression.target instanceof SuperLiteral)) { if (callablesCount > 1) { val callableTypeRefsAsStr = callables.map[callableTypeRef.typeRefAsString].join(", "); - val message = IssueCodes.getMessageForEXP_CALL_CONFLICT_IN_INTERSECTION(callableTypeRefsAsStr); - addIssue(message, callExpression.target, null, IssueCodes.EXP_CALL_CONFLICT_IN_INTERSECTION); + val IssueItem issueItem = EXP_CALL_CONFLICT_IN_INTERSECTION.toIssueItem(callableTypeRefsAsStr); + addIssue(callExpression.target, issueItem); } else if (tsh.isClassConstructorFunction(G, typeRef) || isClassifierTypeRefToAbstractClass(G, typeRef)) { - val message = IssueCodes.getMessageForEXP_CALL_CLASS_CTOR; - addIssue(message, callExpression.target, null, IssueCodes.EXP_CALL_CLASS_CTOR); + addIssue(callExpression.target, EXP_CALL_CLASS_CTOR.toIssueItem()); } else { val staticType = if (typeRef instanceof TypeTypeRef) tsh.getStaticType(G, typeRef); if (staticType instanceof TInterface && tsh.getCallSignature(callExpression.eResource, TypeUtils.createTypeRef(staticType)) !== null) { - val message = IssueCodes.getMessageForEXP_CALL_CONSTRUCT_SIG_OF_INTERFACE_DIRECTLY_USED("invoke", staticType.name, "call"); - addIssue(message, callExpression.target, null, IssueCodes.EXP_CALL_CONSTRUCT_SIG_OF_INTERFACE_DIRECTLY_USED); + val IssueItem issueItem = EXP_CALL_CONSTRUCT_SIG_OF_INTERFACE_DIRECTLY_USED.toIssueItem("invoke", staticType.name, "call"); + addIssue(callExpression.target, issueItem); } else { - val message = IssueCodes.getMessageForEXP_CALL_NOT_A_FUNCTION(typeRef.typeRefAsString); - addIssue(message, callExpression.target, null, IssueCodes.EXP_CALL_NOT_A_FUNCTION); + val IssueItem issueItem = EXP_CALL_NOT_A_FUNCTION.toIssueItem(typeRef.typeRefAsString); + addIssue(callExpression.target, issueItem); } } return; @@ -473,8 +468,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { } val shouldWarn = !isPromiseExplict; if (shouldWarn) { - val message = IssueCodes.getMessageForEXP_MISSNG_AWAIT_FOR_ASYNC_TARGET(); - addIssue(message, callExpression.target, IssueCodes.EXP_MISSNG_AWAIT_FOR_ASYNC_TARGET); + addIssue(callExpression.target, IssueCodes.EXP_MISSNG_AWAIT_FOR_ASYNC_TARGET.toIssueItem()); } } @@ -565,9 +559,8 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val newables = tsh.getNewableTypeRefs(G, typeRef, newExpression, false); if (newables.size > 1) { val newableTypeRefsAsStr = newables.map[newableTypeRef.typeRefAsString].join(", "); - val message = IssueCodes.getMessageForEXP_NEW_CONFLICT_IN_INTERSECTION(newableTypeRefsAsStr); - addIssue(message, newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, - IssueCodes.EXP_NEW_CONFLICT_IN_INTERSECTION); + addIssue(newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, + EXP_NEW_CONFLICT_IN_INTERSECTION.toIssueItem(newableTypeRefsAsStr)); return; } else if (newables.size === 1) { // special success case; but perform some further checks @@ -603,54 +596,45 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { || (staticType instanceof TClassifier && N4JSLanguageUtils.hasCovariantConstructor(staticType as TClassifier, declMergingHelper)); if (staticType === G.symbolObjectType) { // error case #1: new Symbol() - val message = IssueCodes.messageForBIT_SYMBOL_NOT_A_CTOR; - addIssue(message, newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, - IssueCodes.BIT_SYMBOL_NOT_A_CTOR); + addIssue(newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, BIT_SYMBOL_NOT_A_CTOR.toIssueItem()); return; } else if (!isCtor && staticType instanceof TInterface && isDirectRef) { // error case #2: trying to instantiate an interface val tInterface = staticType as TInterface; if (tInterface.constructSignature !== null) { // special case: trying to directly instantiate an interface with a construct signature - val message = IssueCodes.getMessageForEXP_CALL_CONSTRUCT_SIG_OF_INTERFACE_DIRECTLY_USED("instantiate", staticType.name, "construct"); - addIssue(message, newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, - IssueCodes.EXP_CALL_CONSTRUCT_SIG_OF_INTERFACE_DIRECTLY_USED); + val IssueItem issueItem = EXP_CALL_CONSTRUCT_SIG_OF_INTERFACE_DIRECTLY_USED.toIssueItem("instantiate", staticType.name, "construct"); + addIssue(newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, issueItem); return; } - val message = IssueCodes.getMessageForEXP_NEW_CANNOT_INSTANTIATE(staticType.keyword, staticType.name); - addIssue(message, newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, - IssueCodes.EXP_NEW_CANNOT_INSTANTIATE); + val IssueItem issueItem = EXP_NEW_CANNOT_INSTANTIATE.toIssueItem(staticType.keyword, staticType.name); + addIssue(newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, issueItem); return; } else if (!isCtor && staticType instanceof TClass && (staticType as TClass).abstract && isDirectRef) { // error case #3: trying to instantiate an abstract class - val message = IssueCodes.getMessageForEXP_NEW_CANNOT_INSTANTIATE("abstract class", staticType.name); - addIssue(message, newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, - IssueCodes.EXP_NEW_CANNOT_INSTANTIATE); + val IssueItem issueItem = EXP_NEW_CANNOT_INSTANTIATE.toIssueItem("abstract class", staticType.name); + addIssue(newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, issueItem); return; } else if (isCtor && !isConcreteOrCovariant && staticType instanceof TClassifier) { // error case #4: trying to instantiate "constructor{? extends C}", with C not having @CovariantConstructor - val message = IssueCodes.getMessageForEXP_NEW_WILDCARD_NO_COVARIANT_CTOR(typeArg.typeRefAsString, staticType.typeAsString); - addIssue(message, newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, - IssueCodes.EXP_NEW_WILDCARD_NO_COVARIANT_CTOR); + val IssueItem issueItem = EXP_NEW_WILDCARD_NO_COVARIANT_CTOR.toIssueItem(typeArg.typeRefAsString, staticType.typeAsString); + addIssue(newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, issueItem); return; } else if (staticType instanceof TEnum) { // error case #5: trying to instantiate an enum - val message = IssueCodes.getMessageForEXP_NEW_CANNOT_INSTANTIATE("enum", staticType.name); - addIssue(message, newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, - IssueCodes.EXP_NEW_CANNOT_INSTANTIATE); + val IssueItem issueItem = EXP_NEW_CANNOT_INSTANTIATE.toIssueItem("enum", staticType.name); + addIssue(newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, issueItem); return; } else if (staticType instanceof TypeVariable ) { // error case #6: trying to instantiate a type variable - val message = IssueCodes.getMessageForEXP_NEW_CANNOT_INSTANTIATE("type variable", staticType.name); - addIssue(message, newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, - IssueCodes.EXP_NEW_CANNOT_INSTANTIATE); + val IssueItem issueItem = EXP_NEW_CANNOT_INSTANTIATE.toIssueItem("type variable", staticType.name); + addIssue(newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, issueItem); return; } else if (staticType === null || !isCtor || !isConcreteOrCovariant) { // remaining cases val name = typeRef.typeRefAsString; - val message = IssueCodes.getMessageForEXP_NEW_WILDCARD_OR_TYPEVAR(name); - addIssue(message, newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, - IssueCodes.EXP_NEW_WILDCARD_OR_TYPEVAR); + val IssueItem issueItem = EXP_NEW_WILDCARD_OR_TYPEVAR.toIssueItem(name); + addIssue(newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, issueItem); return; } @@ -677,8 +661,8 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val container = constructSig?.eContainer; if (container instanceof TInterface) { // avoid checking accessibility of construct signatures in StructuralTypeRefs/TStructuralTypes (they're always public) if (!memberVisibilityChecker.isVisible(newExpression, calleeTypeRef, constructSig).visibility) { - val message = IssueCodes.getMessageForVIS_NEW_CANNOT_INSTANTIATE_INVISIBLE_CONSTRUCTOR("construct signature", container.name); - addIssue(message, newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, IssueCodes.VIS_NEW_CANNOT_INSTANTIATE_INVISIBLE_CONSTRUCTOR); + val IssueItem issueItem = VIS_NEW_CANNOT_INSTANTIATE_INVISIBLE_CONSTRUCTOR.toIssueItem("construct signature", container.name); + addIssue(newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, issueItem); return false; } } @@ -703,8 +687,8 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { /** Helper to issue the error case of having a new-expression on a non-constructor element */ private def issueNotACtor(TypeRef typeRef, NewExpression newExpression) { - val message = IssueCodes.getMessageForEXP_NEW_NOT_A_CTOR(typeRef.typeRefAsString); - addIssue(message, newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, IssueCodes.EXP_NEW_NOT_A_CTOR) + val IssueItem issueItem = EXP_NEW_NOT_A_CTOR.toIssueItem(typeRef.typeRefAsString); + addIssue(newExpression, N4JSPackage.eINSTANCE.newExpression_Callee, issueItem); } /** @@ -720,10 +704,8 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val staticType = tsh.getStaticType(G, typeRef); if (staticType instanceof TN4Classifier) { if (staticType instanceof TInterface && N4Scheme.isFromResourceWithN4Scheme(staticType)) { - val message = IssueCodes. - getMessageForTYS_INSTANCEOF_NOT_SUPPORTED_FOR_BUILT_IN_INTERFACES(staticType.name); - addIssue(message, relationalExpression, N4JSPackage.eINSTANCE.relationalExpression_Rhs, - IssueCodes.TYS_INSTANCEOF_NOT_SUPPORTED_FOR_BUILT_IN_INTERFACES); + val IssueItem issueItem = TYS_INSTANCEOF_NOT_SUPPORTED_FOR_BUILT_IN_INTERFACES.toIssueItem(staticType.name); + addIssue(relationalExpression, N4JSPackage.eINSTANCE.relationalExpression_Rhs, issueItem); } } } @@ -735,9 +717,8 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val rhsTypeRef = ts.tau((innerExpression instanceof UnaryExpression) ? innerExpression.expression : innerExpression); if (!RuleEnvironmentExtensions.isNumeric(G, rhsTypeRef)) { - val message = IssueCodes.getMessageForTYS_INSTANCEOF_NOT_SUPPORTED_FOR_USE_SITE_STRUCTURAL(); - addIssue(message, relationalExpression, N4JSPackage.eINSTANCE.relationalExpression_Rhs, - IssueCodes.TYS_INSTANCEOF_NOT_SUPPORTED_FOR_USE_SITE_STRUCTURAL); + addIssue(relationalExpression, N4JSPackage.eINSTANCE.relationalExpression_Rhs, + TYS_INSTANCEOF_NOT_SUPPORTED_FOR_USE_SITE_STRUCTURAL.toIssueItem()); } } } @@ -780,11 +761,9 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val setterExists = containerTypesHelper.fromContext(expression).members(declaredType).filter( TSetter).exists[name.equals(property.name)] if (!setterExists) { - val msg = IssueCodes.getMessageForTYS_PROPERTY_HAS_NO_SETTER(property.name) - addIssue(msg, expression, - N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION__PROPERTY, - IssueCodes.TYS_PROPERTY_HAS_NO_SETTER); - return false; + addIssue(expression, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION__PROPERTY, + IssueCodes.TYS_PROPERTY_HAS_NO_SETTER.toIssueItem(property.name)); + return false; } } } @@ -804,8 +783,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val module = EcoreUtil2.getContainerOfType(expression, Script).module; if (id.containingModule != module) { // imported variable, class, etc. - addIssue(IssueCodes.getMessageForIMP_IMPORTED_ELEMENT_READ_ONLY(expression.idAsText), - expression, IssueCodes.IMP_IMPORTED_ELEMENT_READ_ONLY); + addIssue(expression, IMP_IMPORTED_ELEMENT_READ_ONLY.toIssueItem(expression.idAsText)); return false; } } @@ -831,8 +809,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val importedElmentText = NodeModelUtils.getTokenText( NodeModelUtils.findActualNodeFor(expression)); - addIssue(IssueCodes.getMessageForIMP_IMPORTED_ELEMENT_READ_ONLY(importedElmentText), - expression, IssueCodes.IMP_IMPORTED_ELEMENT_READ_ONLY); + addIssue(expression, IMP_IMPORTED_ELEMENT_READ_ONLY.toIssueItem(importedElmentText)); return false; } } @@ -890,11 +867,9 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { Expression expr) { val cmp = compareNumberOfArgsWithNumberOfFPars(fpars, args); if (cmp < 0) { // too few - addIssue(IssueCodes.getMessageForEXP_NUM_OF_ARGS_TOO_FEW(fpars.size, args.size), expr, - IssueCodes.EXP_NUM_OF_ARGS_TOO_FEW); + addIssue(expr, EXP_NUM_OF_ARGS_TOO_FEW.toIssueItem(fpars.size, args.size)); } else if (cmp > 0) { // too many - addIssue(IssueCodes.getMessageForEXP_NUM_OF_ARGS_TOO_MANY(fpars.size, args.size), expr, - IssueCodes.EXP_NUM_OF_ARGS_TOO_MANY); + addIssue(expr, EXP_NUM_OF_ARGS_TOO_MANY.toIssueItem(fpars.size, args.size)); } } @@ -1000,21 +975,15 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { def issueMathResultIsConstant(String operand, String constResult, Expression location) { - addIssue(IssueCodes.getMessageForEXP_MATH_OPERATION_RESULT_IS_CONSTANT(operand, constResult), - location, - IssueCodes.EXP_MATH_OPERATION_RESULT_IS_CONSTANT); + addIssue(location, EXP_MATH_OPERATION_RESULT_IS_CONSTANT.toIssueItem(operand, constResult)); } def issueMathOperandIsConstant(String operandType, String constValue, Expression location) { - addIssue(IssueCodes.getMessageForEXP_MATH_OPERAND_IS_CONSTANT(operandType, constValue), - location, - IssueCodes.EXP_MATH_OPERAND_IS_CONSTANT); + addIssue(location, EXP_MATH_OPERAND_IS_CONSTANT.toIssueItem(operandType, constValue)); } def issueMathOperandTypeNotPermitted(String operandType, Expression location) { - addIssue(IssueCodes.getMessageForEXP_MATH_TYPE_NOT_PERMITTED(operandType), - location, - IssueCodes.EXP_MATH_TYPE_NOT_PERMITTED); + addIssue(location, EXP_MATH_TYPE_NOT_PERMITTED.toIssueItem(operandType)); } @@ -1079,10 +1048,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { if (! (leftSubOfRight || rightSubOfLeft)) { // no subtype-relationship found, issue warning: - addIssue( - IssueCodes. - getMessageForEXP_WARN_CONSTANT_EQUALITY_TEST(tlhs.warningNameOf, trhs.warningNameOf, - ee.op === EqualityOperator::NSAME), ee, IssueCodes.EXP_WARN_CONSTANT_EQUALITY_TEST); + addIssue(ee, EXP_WARN_CONSTANT_EQUALITY_TEST.toIssueItem(tlhs.warningNameOf, trhs.warningNameOf, ee.op === EqualityOperator::NSAME)); } } @@ -1196,11 +1162,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { if (forbidden !== null) { val theType = ts.tau(e)?.declaredType if (theType === forbidden) { - addIssue( - IssueCodes.getMessageForEXP_FORBIDDEN_TYPE_IN_BINARY_LOGICAL_EXPRESSION(typeName), - e, - IssueCodes.EXP_FORBIDDEN_TYPE_IN_BINARY_LOGICAL_EXPRESSION - ); + addIssue(e, EXP_FORBIDDEN_TYPE_IN_BINARY_LOGICAL_EXPRESSION.toIssueItem(typeName)); } } } @@ -1249,11 +1211,11 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { msg1 = "false"; msg2 = "right-hand"; } - addIssue(IssueCodes.getMessageForEXP_WARN_DISPENSABLE_CONDITIONAL_EXPRESSION( + val IssueItem issueItem = EXP_WARN_DISPENSABLE_CONDITIONAL_EXPRESSION.toIssueItem( NodeModelUtils.findActualNodeFor(expressionToCheck).text.trim, msg1, - msg2 - ), expressionToCheck, IssueCodes.EXP_WARN_DISPENSABLE_CONDITIONAL_EXPRESSION); + msg2); + addIssue(expressionToCheck, issueItem); } @@ -1312,8 +1274,8 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { if (BooleanExtensions::xor(S.isDynamic, T.isDynamic)) return; if (ts.subtypeSucceeded(G, S, T)) { // Constraint 81.2 (Cast Validation At Compile-Time): 1 - addIssue(IssueCodes.getMessageForEXP_CAST_UNNECESSARY(S.typeRefAsString, T.typeRefAsString), - castExpression, IssueCodes.EXP_CAST_UNNECESSARY); + val IssueItem issueItem = EXP_CAST_UNNECESSARY.toIssueItem(S.typeRefAsString, T.typeRefAsString); + addIssue(castExpression, issueItem); } else { val specialChecks = (T.declaredType instanceof ContainerType) || (T.declaredType instanceof PrimitiveType) @@ -1329,7 +1291,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { internalCheckCastExpression(G, S, T, castExpression, true, false); } else { // Constraint 78 (Cast Validation At Compile-Time): 2 - addIssue(IssueCodes.getMessageForEXP_CAST_INVALID_TARGET(), castExpression, IssueCodes.EXP_CAST_INVALID_TARGET); + addIssue(castExpression, EXP_CAST_INVALID_TARGET.toIssueItem()); } } } @@ -1365,8 +1327,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { internalCheckCastExpression(G, S, it, castExpression, false, actualSourceTypeIsCPOE) ]) { if (addIssues) { - addIssue(IssueCodes.getMessageForEXP_CAST_FAILED(S.typeRefAsString, T.typeRefAsString), - castExpression, IssueCodes.EXP_CAST_FAILED); + addIssue(castExpression, EXP_CAST_FAILED.toIssueItem(S.typeRefAsString, T.typeRefAsString)); } return false; } @@ -1375,8 +1336,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { internalCheckCastExpression(G, S, it, castExpression, false, actualSourceTypeIsCPOE) ]) { if (addIssues) { - addIssue(IssueCodes.getMessageForEXP_CAST_FAILED(S.typeRefAsString, T.typeRefAsString), - castExpression, IssueCodes.EXP_CAST_FAILED); + addIssue(castExpression, EXP_CAST_FAILED.toIssueItem(S.typeRefAsString, T.typeRefAsString)); } return false; } @@ -1389,8 +1349,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { ] && ! S.typeRefs.exists[ts.subtypeSucceeded(G, it, T)] // one type in composed is a subtype of target ) { if (addIssues) { - addIssue(IssueCodes.getMessageForEXP_CAST_FAILED(S.typeRefAsString, T.typeRefAsString), - castExpression, IssueCodes.EXP_CAST_FAILED); + addIssue(castExpression, EXP_CAST_FAILED.toIssueItem(S.typeRefAsString, T.typeRefAsString)); } return false; } @@ -1440,8 +1399,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { } if (!castOK) { if (addIssues) { - addIssue(IssueCodes.getMessageForEXP_CAST_FAILED(S.typeRefAsString, T.typeRefAsString), - castExpression, IssueCodes.EXP_CAST_FAILED); + addIssue(castExpression, EXP_CAST_FAILED.toIssueItem(S.typeRefAsString, T.typeRefAsString)); } return false; } @@ -1452,8 +1410,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { actualSourceTypeIsCPOE )) { if (addIssues) { - addIssue(IssueCodes.getMessageForEXP_CAST_FAILED(S.typeRefAsString, T.typeRefAsString), - castExpression, IssueCodes.EXP_CAST_FAILED); + addIssue(castExpression, EXP_CAST_FAILED.toIssueItem(S.typeRefAsString, T.typeRefAsString)); } return false; } @@ -1563,7 +1520,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { // allowed: index into exact-type Object instance (not subtype thereof) } else if (accessedStaticType instanceof TEnum) { // Constraints 69.2 // disallowed: index access into an enum - addIssue(messageForEXP_INDEXED_ACCESS_ENUM, indexedAccess, EXP_INDEXED_ACCESS_ENUM); + addIssue(indexedAccess, EXP_INDEXED_ACCESS_ENUM.toIssueItem()); } else if (indexIsNumeric && (targetTypeRef.isArrayLike || targetIsLiteralOfStringBasedEnum)) { // Constraints 69.3 // allowed: index into array-like with a numeric index } else if (accessedBuiltInSymbol !== null) { @@ -1595,8 +1552,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val memberName = N4JSLanguageUtils.derivePropertyNameFromCompileTimeValue(indexValue); if (N4JSLanguageUtils.SYMBOL_ITERATOR_MANGLED == memberName) { // Implementation restriction: member name clashes with compiler-internal, synthetic, mangled name. - addIssue(getMessageForEXP_INDEXED_ACCESS_IMPL_RESTRICTION(), indexedAccess, - EXP_INDEXED_ACCESS_IMPL_RESTRICTION); + addIssue(indexedAccess, EXP_INDEXED_ACCESS_IMPL_RESTRICTION.toIssueItem()); return } if (receiverTypeRef.dynamic) { @@ -1614,10 +1570,9 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val isNonExistentMember = member===null || member.eIsProxy; if (isNonExistentMember) { if (indexIsNumeric) { - addIssue(messageForEXP_INDEXED_ACCESS_FORBIDDEN, indexedAccess, EXP_INDEXED_ACCESS_FORBIDDEN); + addIssue(indexedAccess, EXP_INDEXED_ACCESS_FORBIDDEN.toIssueItem()); } else { - addIssue(getMessageForEXP_INDEXED_ACCESS_COMPUTED_NOTFOUND(memberName), indexedAccess, - EXP_INDEXED_ACCESS_COMPUTED_NOTFOUND); + addIssue(indexedAccess, EXP_INDEXED_ACCESS_COMPUTED_NOTFOUND.toIssueItem(memberName)); } return; } @@ -1633,8 +1588,8 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val symbolIterator = G.symbolObjectType.findOwnedMember("iterator", false, true); val symbolAsyncIterator = G.symbolObjectType.findOwnedMember("asyncIterator", false, true); if (accessedBuiltInSymbol !== symbolIterator && accessedBuiltInSymbol !== symbolAsyncIterator) { - val msg = getMessageForEXP_INDEXED_ACCESS_SYMBOL_INVALID("Symbol.iterator and Symbol.asyncIterator"); - addIssue(msg, indexedAccess, N4JSPackage.Literals.INDEXED_ACCESS_EXPRESSION__INDEX, EXP_INDEXED_ACCESS_SYMBOL_INVALID); + val IssueItem issueItem = EXP_INDEXED_ACCESS_SYMBOL_INVALID.toIssueItem("Symbol.iterator and Symbol.asyncIterator"); + addIssue(indexedAccess, N4JSPackage.Literals.INDEXED_ACCESS_EXPRESSION__INDEX, issueItem); return false; } // check valid receiver type (currently only for instance of [Async]Iterable and immediate(!) instances of Object and dynamic types) @@ -1648,16 +1603,16 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { receiverTypeRef.typingStrategy === TypingStrategy.NOMINAL; val isDynamic = receiverTypeRef.dynamic; if (!(isIterable || isObjectImmediate || isDynamic)) { - val msg = getMessageForEXP_INDEXED_ACCESS_SYMBOL_WRONG_TYPE(accessedBuiltInSymbol.name, correspondingIterableTypeRef.declaredType.name); - addIssue(msg, indexedAccess, N4JSPackage.Literals.INDEXED_ACCESS_EXPRESSION__INDEX, EXP_INDEXED_ACCESS_SYMBOL_WRONG_TYPE); + val IssueItem issueItem = EXP_INDEXED_ACCESS_SYMBOL_WRONG_TYPE.toIssueItem(accessedBuiltInSymbol.name, correspondingIterableTypeRef.declaredType.name); + addIssue(indexedAccess, N4JSPackage.Literals.INDEXED_ACCESS_EXPRESSION__INDEX, issueItem); return false; } // check valid access (currently read-only, except for immediate(!) instances of Object and dynamic types) if (!(isObjectImmediate || isDynamic)) { val boolean writeAccess = ExpressionExtensions.isLeftHandSide(indexedAccess); if (writeAccess) { - val msg = getMessageForEXP_INDEXED_ACCESS_SYMBOL_READONLY(accessedBuiltInSymbol.name, correspondingIterableTypeRef.declaredType.name); - addIssue(msg, indexedAccess, N4JSPackage.Literals.INDEXED_ACCESS_EXPRESSION__INDEX, EXP_INDEXED_ACCESS_SYMBOL_READONLY); + val IssueItem issueItem = EXP_INDEXED_ACCESS_SYMBOL_READONLY.toIssueItem(accessedBuiltInSymbol.name, correspondingIterableTypeRef.declaredType.name); + addIssue(indexedAccess, N4JSPackage.Literals.INDEXED_ACCESS_EXPRESSION__INDEX, issueItem); return false; } } @@ -1687,22 +1642,18 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val id = lhs.id; switch (id) { VariableDeclaration case id.const: { - addIssue(getMessageForEXP_ASSIGN_CONST_VARIABLE(id.name), lhs, - EXP_ASSIGN_CONST_VARIABLE); + addIssue(lhs, EXP_ASSIGN_CONST_VARIABLE.toIssueItem(id.name)); return false; } TVariable case id.const: { - addIssue(getMessageForEXP_ASSIGN_CONST_VARIABLE(id.name), lhs, - EXP_ASSIGN_CONST_VARIABLE); + addIssue(lhs, EXP_ASSIGN_CONST_VARIABLE.toIssueItem(id.name)); return false; } TField case !id.writeable: { // note: this case can happen only when referring to globals in GlobalObject (see file global.n4jsd); // in all other cases of referencing a field, 'lhs' will be a PropertyAccessExpression (those cases // will be handled in class AbstractMemberScope as part of scoping) - addIssue( - getMessageForVIS_WRONG_READ_WRITE_ACCESS("built-in constant", id.name, "read-only"), - lhs, VIS_WRONG_READ_WRITE_ACCESS); + addIssue(lhs, VIS_WRONG_READ_WRITE_ACCESS.toIssueItem("built-in constant", id.name, "read-only")); return false; } } @@ -1712,7 +1663,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { @Check def checkPromisify(PromisifyExpression promiExpr) { if (!promisifyHelper.isPromisifiableExpression(promiExpr.expression)) { - addIssue(getMessageForEXP_PROMISIFY_INVALID_USE, promiExpr, EXP_PROMISIFY_INVALID_USE); + addIssue(promiExpr, EXP_PROMISIFY_INVALID_USE.toIssueItem()); } } @@ -1732,8 +1683,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { if(context instanceof N4MemberDeclaration) { val tMember = context.definedTypeElement; if(tMember?.containingType instanceof TInterface && tMember.static) { - val msg = getMessageForCLF_NO_THIS_IN_STATIC_MEMBER_OF_INTERFACE - addIssue(msg, thisLiteral, CLF_NO_THIS_IN_STATIC_MEMBER_OF_INTERFACE); + addIssue(thisLiteral, CLF_NO_THIS_IN_STATIC_MEMBER_OF_INTERFACE.toIssueItem()); return; } } @@ -1741,15 +1691,13 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val tField = context.definedTypeElement; // 2) not in initializers of data fields in interfaces if(tField?.containingType instanceof TInterface) { - val msg = getMessageForCLF_NO_THIS_IN_FIELD_OF_INTERFACE - addIssue(msg, thisLiteral, CLF_NO_THIS_IN_FIELD_OF_INTERFACE); + addIssue(thisLiteral, CLF_NO_THIS_IN_FIELD_OF_INTERFACE.toIssueItem()); return; } // 3) not in initializers of static(!) data fields in classes if(tField?.containingType instanceof TClass) { if(tField.static) { - val msg = getMessageForCLF_NO_THIS_IN_STATIC_FIELD - addIssue(msg, thisLiteral, CLF_NO_THIS_IN_STATIC_FIELD); + addIssue(thisLiteral, CLF_NO_THIS_IN_STATIC_FIELD.toIssueItem()); return; } } @@ -1759,7 +1707,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { @Check def void checkTaggedTemplateString(TaggedTemplateString ttString) { if (isInOptionalChaining(ttString)) { - addIssue(getMessageForVCO_TEMPLATE_IN_OPT_CHAIN, ttString.template, VCO_TEMPLATE_IN_OPT_CHAIN); + addIssue(ttString.template, VCO_TEMPLATE_IN_OPT_CHAIN.toIssueItem()); } } @@ -1787,8 +1735,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { if(isExpressionOfComputedPropertyNameInObjectLiteral(expr)) { // special case: in object literals, anything goes // (but show a warning) - addIssue(IssueCodes.getMessageForEXP_COMPUTED_PROP_NAME_DISCOURAGED, expr, - IssueCodes.EXP_COMPUTED_PROP_NAME_DISCOURAGED); + addIssue(expr, IssueCodes.EXP_COMPUTED_PROP_NAME_DISCOURAGED.toIssueItem()); return; } createIssuesForEvalErrors(evalResult.errors); @@ -1833,8 +1780,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { val astNode = error.astNode; val feature = error.feature; if(message!==null && astNode!==null) { // feature may be null, that is ok! - val msgFull = getMessageForEXP_COMPILE_TIME_MANDATORY(message); - addIssue(msgFull, astNode, feature, IssueCodes.EXP_COMPILE_TIME_MANDATORY); + addIssue(astNode, feature, EXP_COMPILE_TIME_MANDATORY.toIssueItem(message)); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSExternalValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSExternalValidator.xtend index d42a89dabc..2473ae7e47 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSExternalValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSExternalValidator.xtend @@ -47,6 +47,7 @@ import org.eclipse.n4js.types.utils.TypeUtils import org.eclipse.n4js.utils.N4JSLanguageUtils import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator +import org.eclipse.n4js.validation.IssueItem import org.eclipse.n4js.validation.JavaScriptVariantHelper import org.eclipse.n4js.workspace.WorkspaceAccess import org.eclipse.xtext.util.Tuples @@ -89,8 +90,7 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { @Check def checkAnnotationsInN4JSDFile(Annotation annotation) { if (AnnotationDefinition.N4JS.isAnnotation(annotation)) { - val message = getMessageForANN__N4JS_NO_EFFECT(); - addIssue(message, annotation, ANN__N4JS_NO_EFFECT); + addIssue(annotation, ANN__N4JS_NO_EFFECT.toIssueItem()); } } @@ -105,8 +105,7 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { if (clazz.external && jsVariantHelper.isExternalMode(clazz)) { val projectType = workspaceAccess.findProjectContaining(clazz)?.type; if (projectType === ProjectType.DEFINITION && !AnnotationDefinition.ECMASCRIPT.hasAnnotation(clazz)) { - val message = getMessageForCLF_IN_DEFINITION_PRJ_NON_N4JS() - addIssue(message, clazz, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, CLF_IN_DEFINITION_PRJ_NON_N4JS) + addIssue(clazz, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, CLF_IN_DEFINITION_PRJ_NON_N4JS.toIssueItem()) return; } } @@ -124,8 +123,7 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { val isStructural = TypeUtils.isStructural(interfaceDecl.typingStrategy); val projectType = workspaceAccess.findProjectContaining(interfaceDecl)?.type; if (!isStructural && projectType === ProjectType.DEFINITION) { - val message = getMessageForITF_IN_DEFINITION_PRJ_NON_N4JS() - addIssue(message, interfaceDecl, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, ITF_IN_DEFINITION_PRJ_NON_N4JS) + addIssue(interfaceDecl, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, ITF_IN_DEFINITION_PRJ_NON_N4JS.toIssueItem()) return; } } @@ -143,8 +141,7 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { private def boolean holdsExternalOnlyInDefinitionFile(N4TypeDeclaration typeDecl, String typesName) { if (typeDecl.external && !jsVariantHelper.isExternalMode(typeDecl)) { - val message = getMessageForCLF_EXT_EXTERNAL_N4JSD(typesName) - addIssue(message, typeDecl, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, CLF_EXT_EXTERNAL_N4JSD) + addIssue(typeDecl, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, CLF_EXT_EXTERNAL_N4JSD.toIssueItem(typesName)) return false; } return true; @@ -173,25 +170,22 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { if (annodef.hasAnnotation(memberDecl)) { if (!jsVariantHelper.isExternalMode(memberDecl)) { - val msg = getMessageForCLF_EXT_PROVIDES_IMPL_ONLY_IN_DEFFILES(annodef.name, typeName); - addIssue(msg, memberDecl, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, - CLF_EXT_PROVIDES_IMPL_ONLY_IN_DEFFILES); + val IssueItem issueItem = CLF_EXT_PROVIDES_IMPL_ONLY_IN_DEFFILES.toIssueItem(annodef.name, typeName); + addIssue(memberDecl, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem); return; } val N4ClassifierDefinition owner = memberDecl.owner; if (!(metaType.isInstance(owner))) { - val msg = getMessageForCLF_EXT_PROVIDES_IMPL_ONLY_IN_INTERFACE_MEMBERS(annodef.name, typeName); - addIssue(msg, memberDecl, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, - CLF_EXT_PROVIDES_IMPL_ONLY_IN_INTERFACE_MEMBERS); + val IssueItem issueItem = CLF_EXT_PROVIDES_IMPL_ONLY_IN_INTERFACE_MEMBERS.toIssueItem(annodef.name, typeName); + addIssue(memberDecl, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem); return; } if (N4JSLanguageUtils.isShapeOrEcmaScript(owner)) { - val msg = getMessageForCLF_EXT_PROVIDES_IMPL_ONLY_IN_N4JS_INTERFACES(annodef.name); - addIssue(msg, memberDecl, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, - CLF_EXT_PROVIDES_IMPL_ONLY_IN_N4JS_INTERFACES); + val IssueItem issueItem = CLF_EXT_PROVIDES_IMPL_ONLY_IN_N4JS_INTERFACES.toIssueItem(annodef.name); + addIssue(memberDecl, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem); return; } @@ -205,8 +199,7 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { @Check def checkExternalFunctionsDefinedInN4JSDFile(FunctionDeclaration funDecl) { if (funDecl.external && !jsVariantHelper.isExternalMode(funDecl)) { - val message = getMessageForCLF_EXT_EXTERNAL_N4JSD("Functions") - addIssue(message, funDecl, N4JSPackage.Literals.FUNCTION_DECLARATION__NAME, CLF_EXT_EXTERNAL_N4JSD) + addIssue(funDecl, N4JSPackage.Literals.FUNCTION_DECLARATION__NAME, CLF_EXT_EXTERNAL_N4JSD.toIssueItem("Functions")); } } @@ -221,8 +214,7 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { if (variableStatement.external && !jsVariantHelper.isExternalMode(variableStatement)) { - val message = getMessageForCLF_EXT_EXTERNAL_N4JSD("Variables") - addIssue(message, variableStatement, CLF_EXT_EXTERNAL_N4JSD) + addIssue(variableStatement, CLF_EXT_EXTERNAL_N4JSD.toIssueItem("Variables")); } variableStatement.varDecl.forEach [ evd | @@ -232,8 +224,7 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { } else { "variable" } - val message = getMessageForCLF_EXT_VAR_NO_VAL(mod) - addIssue(message, evd, CLF_EXT_VAR_NO_VAL) + addIssue(evd, CLF_EXT_VAR_NO_VAL.toIssueItem(mod)) } ] } @@ -298,8 +289,7 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { val enumKind = N4JSLanguageUtils.getEnumKind(exported); if (enumKind === EnumKind.Normal) { // note: literal in a number-/string-based enum may have value even in .n4jsd files! for (literal : exported.literals.filter[it.valueExpression !== null]) { - val message = getMessageForCLF_EXT_LITERAL_NO_VALUE - addIssue(message, literal, N4JSPackage.Literals.N4_ENUM_LITERAL__VALUE_EXPRESSION, CLF_EXT_LITERAL_NO_VALUE) + addIssue(literal, N4JSPackage.Literals.N4_ENUM_LITERAL__VALUE_EXPRESSION, CLF_EXT_LITERAL_NO_VALUE.toIssueItem()) } } } @@ -307,9 +297,8 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { def private handleFunctionDeclaration(ExportDeclaration eo, FunctionDeclaration exported) { // relaxed by IDEBUG-561: exported.validateFunctionIsPublicApi(eo) if (exported.body !== null) { - val message = getMessageForCLF_EXT_FUN_NO_BODY val eObjectToNameFeature = exported.findNameFeature - addIssue(message, eObjectToNameFeature.key, eObjectToNameFeature.value, CLF_EXT_FUN_NO_BODY) + addIssue(eObjectToNameFeature.key, eObjectToNameFeature.value, CLF_EXT_FUN_NO_BODY.toIssueItem()) } } @@ -340,19 +329,16 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { return true; } - val message = messageForCLF_EXT_PROVIDED_BY_RUNTIME_IN_RUNTIME_TYPE val eObjectToNameFeature = element.findNameFeature - addIssue(message, eObjectToNameFeature.key, eObjectToNameFeature.value, - CLF_EXT_PROVIDED_BY_RUNTIME_IN_RUNTIME_TYPE) + addIssue(eObjectToNameFeature.key, eObjectToNameFeature.value, CLF_EXT_PROVIDED_BY_RUNTIME_IN_RUNTIME_TYPE.toIssueItem()) return false; } def private validateNoObservableAtClassifier(ExportDeclaration ed, N4ClassifierDeclaration declaration, String classesOrRolesOrInterface) { if (AnnotationDefinition.OBSERVABLE.hasAnnotation(ed)) { - val message = getMessageForCLF_EXT_NO_OBSERV_ANNO(classesOrRolesOrInterface) val eObjectToNameFeature = declaration.findNameFeature - addIssue(message, eObjectToNameFeature.key, eObjectToNameFeature.value, CLF_EXT_NO_OBSERV_ANNO) + addIssue(eObjectToNameFeature.key, eObjectToNameFeature.value, CLF_EXT_NO_OBSERV_ANNO.toIssueItem(classesOrRolesOrInterface)) } } @@ -365,24 +351,24 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { private def validateNoObservableAtMember(N4ClassifierDeclaration declaration, String classesOrRolesOrInterface) { for (member : declaration.ownedMembers.filter[AnnotationDefinition.OBSERVABLE.hasAnnotation(it)]) { - val message = getMessageForCLF_EXT_METHOD_NO_ANNO(member.keyword.toFirstUpper + "s", + val IssueItem issueItem = CLF_EXT_METHOD_NO_ANNO.toIssueItem(member.keyword.toFirstUpper + "s", classesOrRolesOrInterface, "Observable") - addIssue(message, member, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_EXT_METHOD_NO_ANNO) + addIssue(member, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem) } } private def validateNoNfonAtMember(N4ClassifierDeclaration declaration, String classesOrRolesOrInterface) { for (member : declaration.ownedMembers.filter[AnnotationDefinition.NFON.hasAnnotation(it)]) { - val message = getMessageForCLF_EXT_METHOD_NO_ANNO(member.keyword.toFirstUpper + "s", + val IssueItem issueItem = CLF_EXT_METHOD_NO_ANNO.toIssueItem(member.keyword.toFirstUpper + "s", classesOrRolesOrInterface, "Nfon") - addIssue(message, member, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_EXT_METHOD_NO_ANNO) + addIssue(member, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem) } } private def validateNoFieldExpression(N4ClassifierDeclaration declaration, String classesOrRolesOrInterface) { for (member : declaration.ownedFields.filter[expression !== null]) { - val message = getMessageForCLF_EXT_NO_FIELD_EXPR(classesOrRolesOrInterface) - addIssue(message, member, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_EXT_NO_FIELD_EXPR) + val IssueItem issueItem = CLF_EXT_NO_FIELD_EXPR.toIssueItem(classesOrRolesOrInterface) + addIssue(member, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem) } } @@ -390,26 +376,23 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { for (member : declaration.ownedMembers.filter[!(it instanceof N4FieldDeclaration)].filter [ body !== null ]) { - val message = getMessageForCLF_EXT_NO_METHOD_BODY(member.keyword.toFirstUpper + "s", + val IssueItem issueItem = CLF_EXT_NO_METHOD_BODY.toIssueItem(member.keyword.toFirstUpper + "s", classesOrRolesOrInterface) - addIssue(message, member, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_EXT_NO_METHOD_BODY) + addIssue(member, N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem) } } def private validateEcmaScriptClassDoesntExtendN4Object(N4ClassDeclaration exported, TClass superType) { if (superType !== null && (!superType.isExternal || !AnnotationDefinition.ECMASCRIPT.hasAnnotation(superType))) { - val message = messageForCLF_EXT_NOT_ANNOTATED_EXTEND_N4OBJECT val eObjectToNameFeature = exported.findNameFeature - addIssue(message, eObjectToNameFeature.key, eObjectToNameFeature.value, - CLF_EXT_NOT_ANNOTATED_EXTEND_N4OBJECT) + addIssue(eObjectToNameFeature.key, eObjectToNameFeature.value, CLF_EXT_NOT_ANNOTATED_EXTEND_N4OBJECT.toIssueItem()) } } def private validateClassifierIsExternal(N4ClassifierDefinition exported, String classifiers) { if (!exported.external) { - val message = getMessageForCLF_EXT_EXTERNAL(classifiers) val eObjectToNameFeature = exported.findNameFeature - addIssue(message, eObjectToNameFeature.key, eObjectToNameFeature.value, CLF_EXT_EXTERNAL) + addIssue(eObjectToNameFeature.key, eObjectToNameFeature.value, CLF_EXT_EXTERNAL.toIssueItem(classifiers)) } } @@ -423,20 +406,18 @@ class N4JSExternalValidator extends AbstractN4JSDeclarativeValidator { private def validateConsumptionOfNonExternalInterface(N4ClassDeclaration exported, TInterface tinterface, String classifiers) { if (!tinterface.external && tinterface.typingStrategy !== TypingStrategy.STRUCTURAL) { - val message = getMessageForCLF_EXT_CONSUME_NON_EXT(classifiers) val eObjectToNameFeature = exported.findNameFeature - addIssue(message, eObjectToNameFeature.key, eObjectToNameFeature.value, CLF_EXT_CONSUME_NON_EXT) + addIssue(eObjectToNameFeature.key, eObjectToNameFeature.value, CLF_EXT_CONSUME_NON_EXT.toIssueItem(classifiers)) } } def private handleUnallowedElement(EObject eo) { - val message = messageForCLF_EXT_UNALLOWED_N4JSD val eObjectToNameFeature = eo.findNameFeature if (eObjectToNameFeature === null) { val offsetAndLength = eo.findOffsetAndLength - addIssue(message, eo, offsetAndLength.key, offsetAndLength.value, CLF_EXT_UNALLOWED_N4JSD) + addIssue(eo, offsetAndLength.key, offsetAndLength.value, CLF_EXT_UNALLOWED_N4JSD.toIssueItem()) } else { - addIssue(message, eObjectToNameFeature.key, eObjectToNameFeature.value, CLF_EXT_UNALLOWED_N4JSD) + addIssue(eObjectToNameFeature.key, eObjectToNameFeature.value, CLF_EXT_UNALLOWED_N4JSD.toIssueItem()) } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSFunctionValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSFunctionValidator.xtend index f4d2f813b0..d6adcb7380 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSFunctionValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSFunctionValidator.xtend @@ -47,6 +47,7 @@ import org.eclipse.n4js.utils.N4JSLanguageHelper import org.eclipse.n4js.utils.nodemodel.HiddenLeafAccess import org.eclipse.n4js.utils.nodemodel.HiddenLeafAccess.HiddenLeafs import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator +import org.eclipse.n4js.validation.IssueItem import org.eclipse.n4js.validation.JavaScriptVariantHelper import org.eclipse.xtext.EcoreUtil2 import org.eclipse.xtext.nodemodel.util.NodeModelUtils @@ -104,11 +105,10 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { def checkFunctionExpressionInExpressionStatement(FunctionDeclaration functionDeclaration) { val container = functionDeclaration.eContainer if (container instanceof Block && jsVariantHelper.requireCheckFunctionExpressionInExpressionStatement(functionDeclaration)) { - val msg = getMessageForFUN_BLOCK if (functionDeclaration.name !== null) { - addIssue(msg, functionDeclaration, N4JSPackage.Literals.FUNCTION_DECLARATION__NAME, FUN_BLOCK) + addIssue(functionDeclaration, N4JSPackage.Literals.FUNCTION_DECLARATION__NAME, FUN_BLOCK.toIssueItem()); } else { - addIssue(msg, container, functionDeclaration.eContainmentFeature, FUN_BLOCK) + addIssue(container, functionDeclaration.eContainmentFeature, FUN_BLOCK.toIssueItem()) } } } @@ -164,8 +164,7 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { if (isSetter) { // Something else than void is returned -> Error - val String msg = messageForFUN_RETURNTYPE_VOID_FOR_SETTER_VIOLATED - addIssue(msg, rst, FUN_RETURNTYPE_VOID_FOR_SETTER_VIOLATED) + addIssue(rst, FUN_RETURNTYPE_VOID_FOR_SETTER_VIOLATED.toIssueItem()) return false; } else { // other cases are handled by type system (except setters). @@ -197,7 +196,7 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { def checkFunctionName(FunctionDefinition definition) { val name = definition.name.nullToEmpty; val desc = validatorMessageHelper.description(definition); - var errorMessage = ""; + var IssueItem issueItem; // Disable function name validation against keywords if not N4JS file. if (jsVariantHelper.requireCheckFunctionName(definition)) { @@ -205,26 +204,27 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { //IDEBUG-304 : allow keywords as member names if(definition instanceof N4MethodDeclaration === false){ if (FUTURE_RESERVED_WORDS.contains(name)) { - errorMessage = getMessageForFUN_NAME_RESERVED(desc, "future reserved word") + issueItem = FUN_NAME_RESERVED.toIssueItem(toFirstUpper(desc), "future reserved word") } if (N4JSLanguageConstants.YIELD_KEYWORD != name && languageHelper.getECMAKeywords.contains(name)) { - errorMessage = getMessageForFUN_NAME_RESERVED(desc, "keyword") + issueItem = FUN_NAME_RESERVED.toIssueItem(toFirstUpper(desc), "keyword") } } } - if (!errorMessage.nullOrEmpty) { + if (issueItem !== null) { var feature = switch (definition) { FunctionDeclaration: FUNCTION_DECLARATION__NAME N4MethodDeclaration: PROPERTY_NAME_OWNER__DECLARED_NAME FunctionExpression: FUNCTION_EXPRESSION__NAME default: null } - addIssue(toFirstUpper(errorMessage), definition, feature, FUN_NAME_RESERVED); + addIssue(definition, feature, issueItem); + return false; } - return errorMessage.nullOrEmpty + return true; } /** @@ -289,8 +289,7 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { // check missing return-expression if (returnTypeRef !== null && retStmt.expression === null) { - val String msg = getMessageForFUN_MISSING_RETURN_EXPRESSION(returnTypeRef.typeRefAsString); - addIssue(msg, retStmt, FUN_MISSING_RETURN_EXPRESSION); + addIssue(retStmt, FUN_MISSING_RETURN_EXPRESSION.toIssueItem(returnTypeRef.typeRefAsString)); return true; } @@ -322,10 +321,10 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { val off = firstNode.offset; val len = hLeafs.offset - firstNode.offset; - addIssue(messageForFUN_NAME_MISSING,functionDeclaration,off,len,FUN_NAME_MISSING); + addIssue(functionDeclaration,off,len,FUN_NAME_MISSING.toIssueItem()); } else { // mark complete function. - addIssue(messageForFUN_NAME_MISSING,functionDeclaration,FUN_NAME_MISSING); + addIssue(functionDeclaration,FUN_NAME_MISSING.toIssueItem()); } } @@ -335,8 +334,7 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { def checkFunctionDeclarationBody(FunctionDeclaration functionDeclaration) { if (functionDeclaration.body === null && functionDeclaration.definedType instanceof TFunction && !(functionDeclaration.definedType as TFunction).external) { - addIssue(getMessageForFUN_BODY, functionDeclaration, N4JSPackage.Literals.FUNCTION_DECLARATION__NAME, - FUN_BODY) + addIssue(functionDeclaration, N4JSPackage.Literals.FUNCTION_DECLARATION__NAME, FUN_BODY.toIssueItem()) } } @@ -356,28 +354,24 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { private def internalCheckSetterParameters(T fpar, boolean isVariadic, boolean hasInitializerAssignment){ if (isVariadic) { - val String msg = messageForFUN_SETTER_CANT_BE_VARIADIC - addIssue(msg, fpar, FUN_SETTER_CANT_BE_VARIADIC) + addIssue(fpar, FUN_SETTER_CANT_BE_VARIADIC.toIssueItem()) } if (hasInitializerAssignment) { - val String msg = messageForFUN_SETTER_CANT_BE_DEFAULT - addIssue(msg, fpar, FUN_SETTER_CANT_BE_DEFAULT) + addIssue(fpar, FUN_SETTER_CANT_BE_DEFAULT.toIssueItem()) } } @Check def void checkOptionalModifier(FormalParameter fpar) { if(fpar.declaredTypeRefInAST!==null && fpar.declaredTypeRefInAST.followedByQuestionMark) { - val String msg = getMessageForFUN_PARAM_OPTIONAL_WRONG_SYNTAX(fpar.name) - addIssue(msg, fpar, FUN_PARAM_OPTIONAL_WRONG_SYNTAX) + addIssue(fpar, FUN_PARAM_OPTIONAL_WRONG_SYNTAX.toIssueItem(fpar.name)) } } @Check def void checkOptionalModifierT(TFormalParameter fpar) { if(fpar.typeRef!==null && fpar.typeRef.followedByQuestionMark) { - val String msg = getMessageForFUN_PARAM_OPTIONAL_WRONG_SYNTAX(fpar.typeRef?.declaredType?.name) - addIssue(msg, fpar, FUN_PARAM_OPTIONAL_WRONG_SYNTAX) + addIssue(fpar, FUN_PARAM_OPTIONAL_WRONG_SYNTAX.toIssueItem(fpar.typeRef?.declaredType?.name)) } } @@ -407,7 +401,7 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { for (fp : fpars) { // only 'undefined' as identifier allowed if (fp.hasASTInitializer && !"undefined".equals(fp.astInitializer)) { - addIssue( messageForFUN_PARAM_INITIALIZER_ONLY_UNDEFINED_ALLOWED, fp, FUN_PARAM_INITIALIZER_ONLY_UNDEFINED_ALLOWED ) + addIssue(fp, FUN_PARAM_INITIALIZER_ONLY_UNDEFINED_ALLOWED.toIssueItem()) } } } @@ -434,8 +428,7 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { val idRef = idRefs.next(); if (varDeclNamesInBody.contains(idRef.id.name)) { val fpar = EcoreUtil2.getContainerOfType(idRef, FormalParameter); - val String msg = getMessageForFUN_PARAM_INITIALIZER_ILLEGAL_REFERENCE_TO_BODY_VARIABLE(fpar.name, idRef.id.name); - addIssue(msg, idRef, FUN_PARAM_INITIALIZER_ILLEGAL_REFERENCE_TO_BODY_VARIABLE) + addIssue(idRef, FUN_PARAM_INITIALIZER_ILLEGAL_REFERENCE_TO_BODY_VARIABLE.toIssueItem(fpar.name, idRef.id.name)) } } } @@ -446,7 +439,7 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { for(fp:list) { if(fp.definedVariable.hasInitializerAssignment) { if(fp.variadic) { - addIssue(messageForFUN_PARAM_VARIADIC_WITH_INITIALIZER, fp, FUN_PARAM_VARIADIC_WITH_INITIALIZER) + addIssue(fp, FUN_PARAM_VARIADIC_WITH_INITIALIZER.toIssueItem()) } } @@ -458,7 +451,7 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { for(fp:list) { if(fp.hasInitializerAssignment) { if(fp.variadic) { - addIssue(messageForFUN_PARAM_VARIADIC_WITH_INITIALIZER, fp, FUN_PARAM_VARIADIC_WITH_INITIALIZER) + addIssue(fp, FUN_PARAM_VARIADIC_WITH_INITIALIZER.toIssueItem()) } } } @@ -472,8 +465,7 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { if (funDef.isAsync && (null !== funDef.definedType)) { val TypeRef tfunctionRetType = (funDef.definedType as TFunction).getReturnTypeRef(); if (TypeUtils.isVoid(tfunctionRetType)) { - val message = messageForTYS_NON_VOID_ASYNC - addIssue(message, funDef, TYS_NON_VOID_ASYNC) + addIssue(funDef, TYS_NON_VOID_ASYNC.toIssueItem()) } } } @@ -485,8 +477,7 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { def checkNoThisAsyncMethod(FunctionDefinition funDef) { if (funDef.isAsync) { if (TypeUtils.isOrContainsThisType(funDef.declaredReturnTypeRef)) { - val message = messageForTYS_NON_THIS_ASYNC - addIssue(message, funDef, TYS_NON_THIS_ASYNC) + addIssue(funDef, TYS_NON_THIS_ASYNC.toIssueItem()) } } } @@ -507,11 +498,11 @@ class N4JSFunctionValidator extends AbstractN4JSDeclarativeValidator { val isGeneratorType = TypeUtils.isGenerator(returnTypeRefUB, G.builtInTypeScope); val isAsyncGeneratorType = TypeUtils.isAsyncGenerator(returnTypeRefUB, G.builtInTypeScope); if (async && isGeneratorType) { - addIssue(getMessageForFUN_GENERATOR_RETURN_TYPE_MISMATCH(G.generatorType.name, "synchronous", G.asyncGeneratorType.name), - returnTypeRefInAST, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF__DECLARED_TYPE, FUN_GENERATOR_RETURN_TYPE_MISMATCH); + val IssueItem issueItem = FUN_GENERATOR_RETURN_TYPE_MISMATCH.toIssueItem(G.generatorType.name, "synchronous", G.asyncGeneratorType.name); + addIssue(returnTypeRefInAST, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF__DECLARED_TYPE, issueItem); } else if (!async && isAsyncGeneratorType) { - addIssue(getMessageForFUN_GENERATOR_RETURN_TYPE_MISMATCH(G.asyncGeneratorType.name, "asynchronous", G.generatorType.name), - returnTypeRefInAST, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF__DECLARED_TYPE, FUN_GENERATOR_RETURN_TYPE_MISMATCH); + val IssueItem issueItem = FUN_GENERATOR_RETURN_TYPE_MISMATCH.toIssueItem(G.asyncGeneratorType.name, "asynchronous", G.generatorType.name); + addIssue(returnTypeRefInAST, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF__DECLARED_TYPE, issueItem); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSImportValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSImportValidator.xtend index d41ead21cc..b5204fbda8 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSImportValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSImportValidator.xtend @@ -13,6 +13,7 @@ package org.eclipse.n4js.validation.validators import java.util.List import java.util.Map import javax.inject.Inject +import org.eclipse.emf.common.notify.Notifier import org.eclipse.emf.ecore.EObject import org.eclipse.n4js.n4JS.EmptyStatement import org.eclipse.n4js.n4JS.ExportDeclaration @@ -30,7 +31,9 @@ import org.eclipse.n4js.ts.types.TModule import org.eclipse.n4js.utils.Log import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator import org.eclipse.n4js.validation.IssueCodes +import org.eclipse.n4js.validation.IssueItem import org.eclipse.n4js.validation.JavaScriptVariantHelper +import org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot import org.eclipse.n4js.workspace.WorkspaceAccess import org.eclipse.xtext.nodemodel.util.NodeModelUtils import org.eclipse.xtext.validation.Check @@ -40,8 +43,6 @@ import static org.eclipse.n4js.validation.IssueCodes.* import static extension org.eclipse.n4js.n4JS.N4JSASTUtils.* import static extension org.eclipse.n4js.tooling.organizeImports.ImportSpecifiersUtil.* -import org.eclipse.emf.common.notify.Notifier -import org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot /** Validations for the import statements. */ @Log @@ -73,7 +74,7 @@ class N4JSImportValidator extends AbstractN4JSDeclarativeValidator { def checkMultipleDefaultExports(Script script) { val defaultExports = script.eAllContents.filter(ExportDeclaration).filter[isDefaultExport].toList; defaultExports.tail.forEach[ - addIssue(getMessageForIMP_DEFAULT_EXPORT_DUPLICATE, it, N4JSPackage.eINSTANCE.exportDeclaration_DefaultExport, IMP_DEFAULT_EXPORT_DUPLICATE); + addIssue(it, N4JSPackage.eINSTANCE.exportDeclaration_DefaultExport, IMP_DEFAULT_EXPORT_DUPLICATE.toIssueItem()); ] } @@ -93,20 +94,14 @@ class N4JSImportValidator extends AbstractN4JSDeclarativeValidator { if (impModule !== null && !impModule.eIsProxy()) { if (importSpecifier.declaredDynamic) { if (jsVariantHelper.isN4JSMode(impModule)) { - addIssue( - getMessageForIMP_DYNAMIC_IMPORT_N4JS(impModule.moduleSpecifier), - importSpecifier, IMP_DYNAMIC_IMPORT_N4JS); + addIssue(importSpecifier, IMP_DYNAMIC_IMPORT_N4JS.toIssueItem(impModule.moduleSpecifier)); } else if (jsVariantHelper.isExternalMode(impModule)) { val variant = fileExtensionCalculator.getXpectAwareFileExtension(impModule); - addIssue( - getMessageForIMP_DYNAMIC_IMPORT_N4JSD(variant, impModule.moduleSpecifier), - importSpecifier, IMP_DYNAMIC_IMPORT_N4JSD); + addIssue(importSpecifier, IMP_DYNAMIC_IMPORT_N4JSD.toIssueItem(variant, impModule.moduleSpecifier)); } } else { if (jsVariantHelper.isPlainJS(impModule)) { - addIssue( - getMessageForIMP_STATIC_IMPORT_PLAIN_JS(impModule.moduleSpecifier), - importSpecifier, IMP_STATIC_IMPORT_PLAIN_JS); + addIssue(importSpecifier, IMP_STATIC_IMPORT_PLAIN_JS.toIssueItem(impModule.moduleSpecifier)); } } if (importSpecifier instanceof NamedImportSpecifier) { @@ -119,12 +114,12 @@ class N4JSImportValidator extends AbstractN4JSDeclarativeValidator { if (isDependingOn(importSpecifier, impModulePrj, impElemPrj)) { // that's how it should be: re-export } else { - val msg = getMessageForIMP_IMPORTED_ELEMENT_FROM_REEXPORTING_PROJECT( + val IssueItem issueItem = IMP_IMPORTED_ELEMENT_FROM_REEXPORTING_PROJECT.toIssueItem( importSpecifier.importedElementAsText, impElemPrj.n4JSPackageName.toString, impModulePrj.n4JSPackageName.toString ); - addIssue(msg, importSpecifier, IMP_IMPORTED_ELEMENT_FROM_REEXPORTING_PROJECT); + addIssue(importSpecifier, issueItem); } } } @@ -337,10 +332,9 @@ class N4JSImportValidator extends AbstractN4JSDeclarativeValidator { } private def regUnresolvedImport(ParameterizedTypeRef ref, String name, Map eObjectToIssueCode) { - val issueCode = IssueCodes.IMP_UNRESOLVED + val issueCode = IMP_UNRESOLVED.name(); if (eObjectToIssueCode.put(ref, issueCode) === null) { - val message = IssueCodes.getMessageForIMP_UNRESOLVED(name) - addIssue(message, ref, issueCode) + addIssue(ref, IMP_UNRESOLVED.toIssueItem(name)); } } @@ -375,29 +369,25 @@ class N4JSImportValidator extends AbstractN4JSDeclarativeValidator { * reported for given import declaration. */ private def addIssueScatteredImport(ImportDeclaration importDecl) { - val issueCode = IssueCodes.IMP_DISCOURAGED_PLACEMENT - val message = IssueCodes.getMessageForIMP_DISCOURAGED_PLACEMENT - addIssue(message, importDecl, issueCode) + addIssue(importDecl, IMP_DISCOURAGED_PLACEMENT.toIssueItem()) } private def addLocalNameCollision(ImportSpecifier duplicate, String name, String reason, Map eObjectToIssueCode) { if (eObjectToIssueCode.get(duplicate) === null) { - val issueCode = IssueCodes.IMP_LOCAL_NAME_CONFLICT - val message = IssueCodes.getMessageForIMP_LOCAL_NAME_CONFLICT(name, reason) - addIssue(message, duplicate, issueCode) - eObjectToIssueCode.put(duplicate, issueCode) + val IssueItem issueItem = IMP_LOCAL_NAME_CONFLICT.toIssueItem(name, reason); + addIssue(duplicate, issueItem) + eObjectToIssueCode.put(duplicate, issueItem.ID); } } private def addIssueDuplicateNamespaceImportDeclaration(NamespaceImportSpecifier specifier, NamespaceImportSpecifier duplicate, ImportDeclaration duplicateImportDeclaration, Map eObjectToIssueCode) { - val String issueCode = IssueCodes.IMP_STMT_DUPLICATE_NAMESPACE + val String issueCode = IMP_STMT_DUPLICATE_NAMESPACE.name(); if (eObjectToIssueCode.get(specifier) === null) { - val message = IssueCodes.getMessageForIMP_STMT_DUPLICATE_NAMESPACE(specifier.alias, - duplicate.importedModule.qualifiedName) - addIssue(message, duplicateImportDeclaration, issueCode) + val IssueItem issueItem = IMP_STMT_DUPLICATE_NAMESPACE.toIssueItem(specifier.alias, duplicate.importedModule.qualifiedName); + addIssue(duplicateImportDeclaration, issueItem) } duplicateImportDeclaration.importSpecifiers.forEach [ is | @@ -416,57 +406,52 @@ class N4JSImportValidator extends AbstractN4JSDeclarativeValidator { private def addIssueDuplicateNamedImportDeclaration(NamedImportSpecifier specifier, NamedImportSpecifier duplicate, ImportDeclaration duplicateImportDeclaration, Map eObjectToIssueCode) { - val String issueCode = IssueCodes.IMP_STMT_DUPLICATE_NAMED - if (eObjectToIssueCode.get(specifier) === null) { - val message = IssueCodes.getMessageForIMP_STMT_DUPLICATE_NAMED(specifier.usedName, - duplicate.importedModule.qualifiedName) - addIssue(message, duplicateImportDeclaration, issueCode) - } + + val String issueCode = IMP_STMT_DUPLICATE_NAMED.name(); + if (eObjectToIssueCode.get(specifier) === null) { + val IssueItem issueItem = IMP_STMT_DUPLICATE_NAMED.toIssueItem(specifier.usedName, duplicate.importedModule.qualifiedName); + addIssue(duplicateImportDeclaration, issueItem) + } - duplicateImportDeclaration.importSpecifiers.forEach [ is | - eObjectToIssueCode.put(specifier, issueCode) - ] + duplicateImportDeclaration.importSpecifiers.forEach [ is | + eObjectToIssueCode.put(specifier, issueCode) + ] } private def addIssueDuplicateNamespace(ImportProvidedElement ipe, NamespaceImportSpecifier duplicateImportSpecifier, NamespaceImportSpecifier firstImportSpecifier, Map eObjectToIssueCode) { if (eObjectToIssueCode.get(duplicateImportSpecifier) === null) { - val issueCode = IssueCodes.IMP_DUPLICATE_NAMESPACE - val msg = IssueCodes.getMessageForIMP_DUPLICATE_NAMESPACE(ipe.localName, - firstImportSpecifier.importedModule.qualifiedName, firstImportSpecifier.alias) - addIssue(msg, duplicateImportSpecifier, issueCode) - eObjectToIssueCode.put(duplicateImportSpecifier, issueCode) + val IssueItem issueItem = IMP_DUPLICATE_NAMESPACE.toIssueItem(ipe.localName, firstImportSpecifier.importedModule.qualifiedName, firstImportSpecifier.alias) + addIssue(duplicateImportSpecifier, issueItem) + eObjectToIssueCode.put(duplicateImportSpecifier, issueItem.getID()); } } private def addIssueDuplicate(ImportSpecifier specifier, String actualName, TModule module, String firstImportName, Map eObjectToIssueCode) { - var String issueCode = IssueCodes.IMP_DUPLICATE if (eObjectToIssueCode.get(specifier) === null) { - val message = IssueCodes.getMessageForIMP_DUPLICATE(actualName, module.qualifiedName, - firstImportName) - addIssue(message, specifier, issueCode) - eObjectToIssueCode.put(specifier, issueCode) + val IssueItem issueItem = IMP_DUPLICATE.toIssueItem(actualName, module.qualifiedName, firstImportName); + addIssue(specifier, issueItem); + eObjectToIssueCode.put(specifier, issueItem.getID()); } } private def addIssueUnresolved(ImportSpecifier specifier, Map eObjectToIssueCode) { - var String issueCode = IssueCodes.IMP_UNRESOLVED + var String issueCode = IMP_UNRESOLVED.name(); if (eObjectToIssueCode.get(specifier) === null) { if (!isChildOfUnresolvedImportDecl(specifier)) { // avoid redundant follow-up error messages - val message = IssueCodes.getMessageForIMP_UNRESOLVED(computeUnusedOrUnresolvedMessage(specifier)) - addIssue(message, specifier, issueCode) + val IssueItem issueItem = IMP_UNRESOLVED.toIssueItem(computeUnusedOrUnresolvedMessage(specifier)); + addIssue(specifier, issueItem); } eObjectToIssueCode.put(specifier, issueCode) } } private def addIssueUnusedImport(ImportSpecifier specifier, Map eObjectToIssueCode) { - val issueCode = IssueCodes.IMP_UNUSED_IMPORT if (eObjectToIssueCode.get(specifier) === null) { - val message = IssueCodes.getMessageForIMP_UNUSED_IMPORT(computeUnusedOrUnresolvedMessage(specifier)) - addIssue(message, specifier, issueCode) - eObjectToIssueCode.put(specifier, issueCode) + val IssueItem issueItem = IMP_UNUSED_IMPORT.toIssueItem(computeUnusedOrUnresolvedMessage(specifier)); + addIssue(specifier, issueItem); + eObjectToIssueCode.put(specifier, issueItem.getID()); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSInjectorCallsitesValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSInjectorCallsitesValidator.xtend index ea7112f1db..2a9499686c 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSInjectorCallsitesValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSInjectorCallsitesValidator.xtend @@ -189,8 +189,7 @@ class N4JSInjectorCallsitesValidator extends AbstractN4JSDeclarativeValidator { return } val missing = bindersForWhichInstancesAreNeeded.map[binder| binder.typeAsString].join(", ") - val msg = getMessageForDI_ANN_MISSING_PROVIDED_BINDERS(missing); - addIssue(msg, callExpression, DI_ANN_MISSING_PROVIDED_BINDERS); + addIssue(callExpression, DI_ANN_MISSING_PROVIDED_BINDERS.toIssueItem(missing)); } /** @@ -206,7 +205,7 @@ class N4JSInjectorCallsitesValidator extends AbstractN4JSDeclarativeValidator { } } } - addIssue(getMessageForDI_ANN_INJECTOR_REQUIRED(), ctorOfDICArg, DI_ANN_INJECTOR_REQUIRED); + addIssue(ctorOfDICArg, DI_ANN_INJECTOR_REQUIRED.toIssueItem()); return null } @@ -239,7 +238,7 @@ class N4JSInjectorCallsitesValidator extends AbstractN4JSDeclarativeValidator { return } } - addIssue(getMessageForDI_NOT_INJECTABLE(ctorArgTypeRef.typeRefAsString, ''), ctorArg, DI_NOT_INJECTABLE); + addIssue(ctorArg, DI_NOT_INJECTABLE.toIssueItem(ctorArgTypeRef.typeRefAsString, '')); } /** @@ -278,7 +277,7 @@ class N4JSInjectorCallsitesValidator extends AbstractN4JSDeclarativeValidator { if (isAllowedAsInjectorInstance(tr.declaredType)) { return } - addIssue(getMessageForDI_ANN_INJECTOR_MISSING(), expr, DI_ANN_INJECTOR_MISSING); + addIssue(expr, DI_ANN_INJECTOR_MISSING.toIssueItem()); } /** @@ -303,8 +302,7 @@ class N4JSInjectorCallsitesValidator extends AbstractN4JSDeclarativeValidator { return } val missing = missingBinders.map[binder| binder.typeAsString].join(", ") - val msg = getMessageForDI_ANN_MISSING_NEEDED_BINDERS(missing); - addIssue(msg, callExpression, DI_ANN_MISSING_NEEDED_BINDERS); + addIssue(callExpression, DI_ANN_MISSING_NEEDED_BINDERS.toIssueItem(missing)); } /** diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSInterfaceValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSInterfaceValidator.xtend index ea686a4299..5160a174d4 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSInterfaceValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSInterfaceValidator.xtend @@ -26,7 +26,7 @@ import org.eclipse.n4js.ts.types.TInterface import org.eclipse.n4js.ts.types.TypingStrategy import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator -import org.eclipse.n4js.validation.IssueCodes +import org.eclipse.n4js.validation.IssueItem import org.eclipse.xtext.validation.Check import org.eclipse.xtext.validation.EValidatorRegistrar @@ -75,15 +75,13 @@ class N4JSInterfaceValidator extends AbstractN4JSDeclarativeValidator implements // publish this method. public override void addIssue(String message, EObject source, EStructuralFeature feature, String issueCode, String... issueData) { - super.addIssue(message,source,feature,issueCode,issueData) + super.addIssue(message,source,feature,issueCode,issueData) } def private internalCheckNotFinal(N4InterfaceDeclaration n4InterfaceDeclaration) { if (AnnotationDefinition.FINAL.hasAnnotation(n4InterfaceDeclaration)) { - val msg = IssueCodes.getMessageForITF_NO_FINAL - addIssue(msg, n4InterfaceDeclaration, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, - IssueCodes.ITF_NO_FINAL) + addIssue(n4InterfaceDeclaration, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, ITF_NO_FINAL.toIssueItem()); } } @@ -93,8 +91,7 @@ class N4JSInterfaceValidator extends AbstractN4JSDeclarativeValidator implements for (member : n4Interface.ownedMembers) { if (member instanceof N4FieldDeclaration) { if (member.expression !== null) { - addIssue(IssueCodes.getMessageForITF_NO_FIELD_INITIALIZER(member.name, n4Interface.name), - member.expression, IssueCodes.ITF_NO_FIELD_INITIALIZER) + addIssue(member.expression, ITF_NO_FIELD_INITIALIZER.toIssueItem(member.name, n4Interface.name)); } } if (member instanceof N4MethodDeclaration) { @@ -102,21 +99,18 @@ class N4JSInterfaceValidator extends AbstractN4JSDeclarativeValidator implements if (member.isCallSignature || member.isConstructSignature) { // specialized validation: N4JSMemberValidator#holdsCallConstructSignatureConstraints() } else { - addIssue(IssueCodes.getMessageForITF_NO_PROPERTY_BODY("Methods", "structural "), - member.body, IssueCodes.ITF_NO_PROPERTY_BODY) + addIssue(member.body, ITF_NO_PROPERTY_BODY.toIssueItem("Methods", "structural ")); } } } if (member instanceof N4GetterDeclaration) { if (member.body !== null) { - addIssue(IssueCodes.getMessageForITF_NO_PROPERTY_BODY("Getters", "structural "), - member.body, IssueCodes.ITF_NO_PROPERTY_BODY) + addIssue(member.body, ITF_NO_PROPERTY_BODY.toIssueItem("Getters", "structural ")); } } if (member instanceof N4SetterDeclaration) { if (member.body !== null) { - addIssue(IssueCodes.getMessageForITF_NO_PROPERTY_BODY("Setters", "structural "), - member.body, IssueCodes.ITF_NO_PROPERTY_BODY) + addIssue(member.body, ITF_NO_PROPERTY_BODY.toIssueItem("Setters", "structural ")); } } } @@ -135,27 +129,25 @@ class N4JSInterfaceValidator extends AbstractN4JSDeclarativeValidator implements if (n4Interface.typingStrategy === TypingStrategy.STRUCTURAL && extendedType.typingStrategy !== TypingStrategy.STRUCTURAL ) { - addIssue(IssueCodes.getMessageForSTRCT_ITF_CANNOT_EXTEND_INTERFACE(), superIfc, null, IssueCodes.STRCT_ITF_CANNOT_EXTEND_INTERFACE) + addIssue(superIfc, null, STRCT_ITF_CANNOT_EXTEND_INTERFACE.toIssueItem()); } } else { if (extendedType instanceof PrimitiveType) { if (!N4Scheme.isFromResourceWithN4Scheme(n4Interface)) { // primitive types may be extended in built-in types - val message = getMessageForCLF_EXTENDS_PRIMITIVE_GENERIC_TYPE(extendedType.name); - addIssue(message, superIfc, null, CLF_EXTENDS_PRIMITIVE_GENERIC_TYPE) + addIssue(superIfc, null, CLF_EXTENDS_PRIMITIVE_GENERIC_TYPE.toIssueItem(extendedType.name)); } } else if (RuleEnvironmentExtensions.isAnyDynamic(RuleEnvironmentExtensions.newRuleEnvironment(extendedType), extendedTypeRef)) { // allow any+ as a supertype (motivated from type alias being any+ used in d.ts files } else { - val message = IssueCodes.getMessageForCLF_WRONG_META_TYPE(n4Interface.description, "extend", - extendedType.description); - addIssue(message, superIfc, null, IssueCodes.CLF_WRONG_META_TYPE) + val IssueItem issueItem = CLF_WRONG_META_TYPE.toIssueItem(n4Interface.description, "extend", extendedType.description); + addIssue(superIfc, null, issueItem); } } } else if (extendedTypeRef !== null && extendedTypeRef.isAliasResolved) { // not all aliases are illegal after "extends", but if we get to this point we have an illegal case: - val message = getMessageForCLF_WRONG_META_TYPE(n4Interface.description, "extend", extendedTypeRef.typeRefAsStringWithAliasResolution); - addIssue(message, superIfc, null, CLF_WRONG_META_TYPE); + val IssueItem issueItem = CLF_WRONG_META_TYPE.toIssueItem(n4Interface.description, "extend", extendedTypeRef.typeRefAsStringWithAliasResolution); + addIssue(superIfc, null, issueItem); } } } @@ -165,8 +157,8 @@ class N4JSInterfaceValidator extends AbstractN4JSDeclarativeValidator implements val cycle = findCyclicInheritance(ifc); if(cycle!==null) { val miscreant = n4InterfaceDeclaration.superInterfaceRefs.findFirst[typeRef?.declaredType===cycle.get(1)]; - val message = IssueCodes.getMessageForCLF_INHERITANCE_CYCLE(cycle.map[name].join(", ")); - addIssue(message, miscreant, IssueCodes.CLF_INHERITANCE_CYCLE); + val IssueItem issueItem = CLF_INHERITANCE_CYCLE.toIssueItem(cycle.map[name].join(", ")); + addIssue(miscreant, issueItem); return false; } return true; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSLambdaValidator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSLambdaValidator.java index e9649ff594..e840fed752 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSLambdaValidator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSLambdaValidator.java @@ -63,8 +63,7 @@ private void rejectUsagesOfThisInTopLevelLambda(ArrowFunction topLevelLambda) { Iterator thisUsages = LambdaUtils.thisLiterals(topLevelLambda.getBody()); while (thisUsages.hasNext()) { EObject thisUsage = thisUsages.next(); - String message = IssueCodes.getMessageForKEY_THIS_REJECTED_IN_TOP_LEVEL_LAMBDA(); - addIssue(message, thisUsage, IssueCodes.KEY_THIS_REJECTED_IN_TOP_LEVEL_LAMBDA); + addIssue(thisUsage, IssueCodes.KEY_THIS_REJECTED_IN_TOP_LEVEL_LAMBDA); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSMemberRedefinitionValidator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSMemberRedefinitionValidator.java index 87b50db632..5171506789 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSMemberRedefinitionValidator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSMemberRedefinitionValidator.java @@ -35,31 +35,6 @@ import static org.eclipse.n4js.validation.IssueCodes.CLF_REDEFINED_TYPE_NOT_SAME_TYPE; import static org.eclipse.n4js.validation.IssueCodes.CLF_UNMATCHED_ACCESSOR_OVERRIDE; import static org.eclipse.n4js.validation.IssueCodes.CLF_UNMATCHED_ACCESSOR_OVERRIDE_JS; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_CONSUMED_FIELD_ACCESSOR_PAIR_INCOMPLETE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_CONSUMED_INHERITED_MEMBER_UNSOLVABLE_CONFLICT; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_CONSUMED_MEMBER_SOLVABLE_CONFLICT; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_CONSUMED_MEMBER_UNSOLVABLE_CONFLICT; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_IMPLEMENT_MEMBERTYPE_INCOMPATIBLE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_MISSING_IMPLEMENTATION; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_MISSING_IMPLEMENTATION_EXT; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_NON_ACCESSIBLE_ABSTRACT_MEMBERS; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_OVERRIDEN_CONCRETE_WITH_ABSTRACT; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_OVERRIDE_ANNOTATION; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_OVERRIDE_CONST; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_OVERRIDE_FIELD_REQUIRES_ACCESSOR_PAIR; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_OVERRIDE_FINAL; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_OVERRIDE_MEMBERTYPE_INCOMPATIBLE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_OVERRIDE_NON_EXISTENT; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_OVERRIDE_NON_EXISTENT_INTERFACE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_OVERRIDE_VISIBILITY; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_OVERRIDE_WITH_FINAL_OR_CONST_FIELD; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_PSEUDO_REDEFINED_SPEC_CTOR_INCOMPATIBLE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_REDEFINED_MEMBER_TYPE_INVALID; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_REDEFINED_METHOD_TYPE_CONFLICT; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_REDEFINED_NON_ACCESSIBLE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_REDEFINED_TYPE_NOT_SAME_TYPE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_UNMATCHED_ACCESSOR_OVERRIDE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_UNMATCHED_ACCESSOR_OVERRIDE_JS; import java.util.ArrayList; import java.util.Collection; @@ -117,6 +92,8 @@ import org.eclipse.n4js.utils.N4JSLanguageUtils; import org.eclipse.n4js.utils.UtilN4; import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator; +import org.eclipse.n4js.validation.IssueCodes; +import org.eclipse.n4js.validation.IssueItem; import org.eclipse.n4js.validation.IssueUserDataKeys; import org.eclipse.n4js.validation.JavaScriptVariantHelper; import org.eclipse.n4js.validation.utils.MemberCube; @@ -279,13 +256,12 @@ private boolean checkSpecConstructorOverrideCompatibility(TClassifier tClassifie inheritedConstructor, declMergingHelper); final Result subtypeResult = isSubTypeResult(inheritedConstructor, rightThisContext, inheritedConstructor); if (subtypeResult.isFailure()) { - final String msg = getMessageForCLF_PSEUDO_REDEFINED_SPEC_CTOR_INCOMPATIBLE( + final EObject astNode = tClassifier.getAstElement(); // ok, because tClassifier is coming from AST + addIssue(astNode, N4JSPackage.eINSTANCE.getN4TypeDeclaration_Name(), + CLF_PSEUDO_REDEFINED_SPEC_CTOR_INCOMPATIBLE, validatorMessageHelper.description(inheritedConstructor), validatorMessageHelper.description(tClassifier), validatorMessageHelper.description(rightThisContext)); - final EObject astNode = tClassifier.getAstElement(); // ok, because tClassifier is coming from AST - addIssue(msg, astNode, N4JSPackage.eINSTANCE.getN4TypeDeclaration_Name(), - CLF_PSEUDO_REDEFINED_SPEC_CTOR_INCOMPATIBLE); return false; } return true; @@ -367,18 +343,14 @@ private boolean constraints_66_NonOverride(MemberMatrix mm) { if (member.isStatic() && mm.hasNonImplemented() && !mm.hasInherited() && !mm.hasImplemented()) { // special case of false @Override annotation: "overriding" a static member of an interface final TMember other = mm.nonImplemented().iterator().next(); // simply take the first one - String message = getMessageForCLF_OVERRIDE_NON_EXISTENT_INTERFACE( + addIssue(member.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, + CLF_OVERRIDE_NON_EXISTENT_INTERFACE, validatorMessageHelper.description(member), validatorMessageHelper.description(other)); - addIssue(message, member.getAstElement(), - N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, - CLF_OVERRIDE_NON_EXISTENT_INTERFACE); } else { // standard case of false @Override annotation - String message = getMessageForCLF_OVERRIDE_NON_EXISTENT(keywordProvider.keyword(member), - member.getName()); - addIssue(message, member.getAstElement(), - N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_OVERRIDE_NON_EXISTENT); + addIssue(member.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, + CLF_OVERRIDE_NON_EXISTENT, keywordProvider.keyword(member), member.getName()); } } } @@ -910,20 +882,20 @@ private boolean isClassExtendsInterface(TClassifier classifier, TMember m) { private void messageMissingImplementations(List abstractMembers) { TClassifier classifier = getCurrentClassifier(); if (!jsVariantHelper.allowMissingImplementation(classifier)) { - String message = getMessageForCLF_MISSING_IMPLEMENTATION(classifier.getName(), + addIssue(CLF_MISSING_IMPLEMENTATION, + classifier.getName(), validatorMessageHelper.descriptions(abstractMembers)); - addIssue(message, CLF_MISSING_IMPLEMENTATION); } else { - String message = getMessageForCLF_MISSING_IMPLEMENTATION_EXT(classifier.getName(), + addIssue(CLF_MISSING_IMPLEMENTATION_EXT, + classifier.getName(), validatorMessageHelper.descriptions(abstractMembers)); - addIssue(message, CLF_MISSING_IMPLEMENTATION_EXT); } } - private void addIssue(String message, String issueCode) { + private void addIssue(IssueCodes issueCode, String... msgValues) { N4ClassifierDefinition classifier = getCurrentClassifierDefinition(); EStructuralFeature nameFeature = classifier.eClass().getEStructuralFeature("name"); - addIssue(message, classifier, nameFeature, issueCode); + addIssue(classifier, nameFeature, issueCode, msgValues); } private void messageImpossibleExtendsImplements(N4ClassifierDefinition n4ClassifierDefinition, @@ -934,11 +906,11 @@ private void messageImpossibleExtendsImplements(N4ClassifierDefinition n4Classif final Type type = superTypeRefNode.getTypeRef().getDeclaredType(); final String mode = type instanceof TInterface && !(n4ClassifierDefinition instanceof N4InterfaceDeclaration) ? "implement" : "extend"; - final String message = getMessageForCLF_NON_ACCESSIBLE_ABSTRACT_MEMBERS(mode, + addIssue(superTypeRefNode.eContainer(), superTypeRefNode.eContainingFeature(), + CLF_NON_ACCESSIBLE_ABSTRACT_MEMBERS, + mode, validatorMessageHelper.description(type), validatorMessageHelper.descriptions(entry.getValue())); - addIssue(message, superTypeRefNode.eContainer(), superTypeRefNode.eContainingFeature(), - CLF_NON_ACCESSIBLE_ABSTRACT_MEMBERS); } } @@ -980,13 +952,11 @@ private void messageMissingOverrideAnnotation(MemberMatrix mm, String redefinitionVerb = MemberRedefinitionUtils.getRedefinitionVerb(filteredOverriddenMembers, getCurrentClassifier()); - String message = getMessageForCLF_OVERRIDE_ANNOTATION( + addIssue(overriding.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, + CLF_OVERRIDE_ANNOTATION, validatorMessageHelper.descriptionDifferentFrom(overriding, overriddenMembers), redefinitionVerb, validatorMessageHelper.descriptions(filteredOverriddenMembers)); - - addIssue(message, overriding.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, - CLF_OVERRIDE_ANNOTATION); } } } @@ -994,11 +964,11 @@ private void messageMissingOverrideAnnotation(MemberMatrix mm, private void messageFieldOverrideNeedsAccessorPair(TMember overriding, TMember overridden) { if (overriding.getContainingType() == getCurrentClassifier()) { String missingAccessor = overriding.isGetter() ? "setter" : "getter"; - String message = getMessageForCLF_OVERRIDE_FIELD_REQUIRES_ACCESSOR_PAIR( + addIssue(overriding.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, + CLF_OVERRIDE_FIELD_REQUIRES_ACCESSOR_PAIR, validatorMessageHelper.descriptionDifferentFrom(overriding, overridden), - validatorMessageHelper.descriptionDifferentFrom(overridden, overriding), missingAccessor); - addIssue(message, overriding.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, - CLF_OVERRIDE_FIELD_REQUIRES_ACCESSOR_PAIR); + validatorMessageHelper.descriptionDifferentFrom(overridden, overriding), + missingAccessor); } else { throw new IllegalStateException("must not happen as member is not consumed"); } @@ -1007,8 +977,6 @@ private void messageFieldOverrideNeedsAccessorPair(TMember overriding, TMember o private void messageOverrideMemberTypeConflict(RedefinitionType redefinitionType, TMember overriding, TMember overridden, Result result, MemberMatrix mm) { - String message; - String code; String redefinitionTypeName = redefinitionType.name(); if (redefinitionType == RedefinitionType.implemented && Iterables.contains(mm.implemented(), overriding)) { @@ -1022,28 +990,25 @@ private void messageOverrideMemberTypeConflict(RedefinitionType redefinitionType } String extraMessage = cfOtherImplementedMembers(mm, overriding, overridden); - + IssueItem issueItem; if (overriding.isField() && overridden.isField() && !((TField) overridden).isConst()) { - code = CLF_REDEFINED_TYPE_NOT_SAME_TYPE; - message = getMessageForCLF_REDEFINED_TYPE_NOT_SAME_TYPE( + issueItem = CLF_REDEFINED_TYPE_NOT_SAME_TYPE.toIssueItem( overridingSource + validatorMessageHelper.descriptionDifferentFrom(overriding, overridden), redefinitionTypeName, validatorMessageHelper.descriptionDifferentFrom(overridden, overriding), extraMessage); } else if (overriding.isMethod() && overridden.isMethod()) { - code = CLF_REDEFINED_METHOD_TYPE_CONFLICT; String descRaw = validatorMessageHelper.descriptionDifferentFrom(overriding, overridden); String desc = (descRaw.toLowerCase().contains("signature") ? "" : "signature of ") + overridingSource + descRaw; - message = getMessageForCLF_REDEFINED_METHOD_TYPE_CONFLICT( + issueItem = CLF_REDEFINED_METHOD_TYPE_CONFLICT.toIssueItem( UtilN4.toUpperCaseFirst(desc), redefinitionTypeName, validatorMessageHelper.descriptionDifferentFrom(overridden, overriding), validatorMessageHelper.trimTypesystemMessage(result), extraMessage); } else { - code = CLF_REDEFINED_MEMBER_TYPE_INVALID; - message = getMessageForCLF_REDEFINED_MEMBER_TYPE_INVALID( + issueItem = CLF_REDEFINED_MEMBER_TYPE_INVALID.toIssueItem( overridingSource + validatorMessageHelper.descriptionDifferentFrom(overriding, overridden), validatorMessageHelper.descriptionDifferentFrom(overridden, overriding), redefinitionTypeName, @@ -1051,73 +1016,69 @@ private void messageOverrideMemberTypeConflict(RedefinitionType redefinitionType extraMessage); } - addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, message, code); + addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, issueItem); } private void messageOverrideAbstract(RedefinitionType redefinitionType, TMember overriding, TMember overridden) { - String message = getMessageForCLF_OVERRIDEN_CONCRETE_WITH_ABSTRACT( + IssueItem issueItem = CLF_OVERRIDEN_CONCRETE_WITH_ABSTRACT.toIssueItem( validatorMessageHelper.descriptionDifferentFrom(overriding, overridden), validatorMessageHelper.descriptionDifferentFrom(overridden, overriding)); - addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, message, - CLF_OVERRIDEN_CONCRETE_WITH_ABSTRACT); + addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, issueItem); } private void messageOverrideAccessibilityReduced(RedefinitionType redefinitionType, TMember overriding, TMember overridden) { - String message = getMessageForCLF_OVERRIDE_VISIBILITY( + IssueItem issueItem = CLF_OVERRIDE_VISIBILITY.toIssueItemWithData( + List.of(IssueUserDataKeys.CLF_OVERRIDE_VISIBILITY.OVERRIDDEN_MEMBER_ACCESS_MODIFIER, + overridden.getMemberAccessModifier().getName(), + IssueUserDataKeys.CLF_OVERRIDE_VISIBILITY.OVERRIDDEN_MEMBER_NAME, + overridden.getName(), + IssueUserDataKeys.CLF_OVERRIDE_VISIBILITY.SUPER_CLASS_NAME, + overridden.getContainingType().getName()), validatorMessageHelper.descriptionDifferentFrom(overriding, overridden), validatorMessageHelper.descriptionDifferentFrom(overridden, overriding)); - addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, message, - CLF_OVERRIDE_VISIBILITY, - IssueUserDataKeys.CLF_OVERRIDE_VISIBILITY.OVERRIDDEN_MEMBER_ACCESS_MODIFIER, - overridden.getMemberAccessModifier().getName(), - IssueUserDataKeys.CLF_OVERRIDE_VISIBILITY.OVERRIDDEN_MEMBER_NAME, overridden.getName(), - IssueUserDataKeys.CLF_OVERRIDE_VISIBILITY.SUPER_CLASS_NAME, overridden.getContainingType().getName()); + addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, issueItem); } private void messageOverrideNonAccessible(@SuppressWarnings("unused") RedefinitionType redefinitionType, N4ClassifierDefinition contextDef, Type contextType, TMember overriding, TMember overridden) { - String message = getMessageForCLF_REDEFINED_NON_ACCESSIBLE( + IssueItem issueItem = CLF_REDEFINED_NON_ACCESSIBLE.toIssueItem( validatorMessageHelper.descriptionDifferentFrom(overriding, overridden), validatorMessageHelper.descriptionDifferentFrom(overridden, overriding)); if (overriding.getContainingType() == contextType) { - addIssue(message, overriding.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, - CLF_REDEFINED_NON_ACCESSIBLE); + addIssue(overriding.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem); } else if (contextDef instanceof N4TypeDeclaration) { - addIssue(message, contextDef, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, - CLF_REDEFINED_NON_ACCESSIBLE); + addIssue(contextDef, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, issueItem); } else { - addIssue(message, contextDef, CLF_REDEFINED_NON_ACCESSIBLE); + addIssue(contextDef, issueItem); } } private void messageOverrideFinal(RedefinitionType redefinitionType, TMember overriding, TMember overridden) { - String message = getMessageForCLF_OVERRIDE_FINAL( + IssueItem issueItem = CLF_OVERRIDE_FINAL.toIssueItemWithData( + List.of(CLF_OVERRIDE_FINAL.name(), + IssueUserDataKeys.CLF_OVERRIDE_FINAL.OVERRIDDEN_MEMBER_URI, + EcoreUtil.getURI(overridden).toString()), validatorMessageHelper.descriptionDifferentFrom(overriding, overridden), validatorMessageHelper.descriptionDifferentFrom(overridden, overriding)); - addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, message, - CLF_OVERRIDE_FINAL, - IssueUserDataKeys.CLF_OVERRIDE_FINAL.OVERRIDDEN_MEMBER_URI, - EcoreUtil.getURI(overridden).toString()); + addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, issueItem); } private void messageOverrideWithFinalOrConstField(RedefinitionType redefinitionType, TMember overriding, TMember overridden) { String badModifier = overriding.isConst() ? "const" : "final"; String prefix = overridden instanceof TField ? "non-" + badModifier + " " : ""; - String message = getMessageForCLF_OVERRIDE_WITH_FINAL_OR_CONST_FIELD( + IssueItem issueItem = CLF_OVERRIDE_WITH_FINAL_OR_CONST_FIELD.toIssueItem( prefix + validatorMessageHelper.descriptionDifferentFrom(overridden, overriding), badModifier); - addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, message, - CLF_OVERRIDE_WITH_FINAL_OR_CONST_FIELD); + addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, issueItem); } private void messageOverrideConst(RedefinitionType redefinitionType, TMember overriding, TField overridden) { - String message = getMessageForCLF_OVERRIDE_CONST( + IssueItem issueItem = CLF_OVERRIDE_CONST.toIssueItem( validatorMessageHelper.descriptionDifferentFrom(overriding, overridden), validatorMessageHelper.descriptionDifferentFrom(overridden, overriding)); - addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, message, - CLF_OVERRIDE_CONST); + addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, issueItem); } /** @@ -1126,19 +1087,18 @@ private void messageOverrideConst(RedefinitionType redefinitionType, TMember ove */ private void messageOverrideMetaTypeIncompatible(RedefinitionType redefinitionType, TMember overriding, TMember overridden, MemberMatrix mm) { + if (redefinitionType == RedefinitionType.overridden) { - String message = getMessageForCLF_OVERRIDE_MEMBERTYPE_INCOMPATIBLE( + IssueItem issueItem = CLF_OVERRIDE_MEMBERTYPE_INCOMPATIBLE.toIssueItem( validatorMessageHelper.descriptionDifferentFrom(overriding, overridden), validatorMessageHelper.descriptionDifferentFrom(overridden, overriding)); - addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, message, - CLF_OVERRIDE_MEMBERTYPE_INCOMPATIBLE); + addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, issueItem); } else { // consumed method implicitly overrides: - String message = getMessageForCLF_IMPLEMENT_MEMBERTYPE_INCOMPATIBLE( - validatorMessageHelper.descriptionDifferentFrom(overriding, overridden), + IssueItem issueItem = CLF_IMPLEMENT_MEMBERTYPE_INCOMPATIBLE.toIssueItem( validatorMessageHelper.descriptionDifferentFrom(overridden, overriding), + validatorMessageHelper.descriptionDifferentFrom(overriding, overridden), cfOtherImplementedMembers(mm, overridden)); - addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, message, - CLF_IMPLEMENT_MEMBERTYPE_INCOMPATIBLE); + addIssueToMemberOrInterfaceReference(redefinitionType, overriding, overridden, issueItem); } } @@ -1154,31 +1114,25 @@ private String cfOtherImplementedMembers(MemberMatrix mm, TMember... filteredMem } private void messageIncompatibleMembersToImplement(Iterable implementedMembers) { - String message = getMessageForCLF_CONSUMED_MEMBER_UNSOLVABLE_CONFLICT( - validatorMessageHelper.descriptions(implementedMembers)); - addIssue(message, CLF_CONSUMED_MEMBER_UNSOLVABLE_CONFLICT); + addIssue(CLF_CONSUMED_MEMBER_UNSOLVABLE_CONFLICT, validatorMessageHelper.descriptions(implementedMembers)); } private void messageIncompatibleInheritedMembersToImplement(TMember inheritedMember, Iterable implementedMembers) { - String message = getMessageForCLF_CONSUMED_INHERITED_MEMBER_UNSOLVABLE_CONFLICT( + addIssue(CLF_CONSUMED_INHERITED_MEMBER_UNSOLVABLE_CONFLICT, validatorMessageHelper.description(inheritedMember), validatorMessageHelper.descriptions(implementedMembers)); - addIssue(message, CLF_CONSUMED_INHERITED_MEMBER_UNSOLVABLE_CONFLICT); } private void messageConflictingMixins(List conflictingMembers) { - String message = getMessageForCLF_CONSUMED_MEMBER_SOLVABLE_CONFLICT( - validatorMessageHelper.descriptions(conflictingMembers)); - addIssue(message, CLF_CONSUMED_MEMBER_SOLVABLE_CONFLICT); + addIssue(CLF_CONSUMED_MEMBER_SOLVABLE_CONFLICT, validatorMessageHelper.descriptions(conflictingMembers)); } private void messageMissingAccessor(String missingAccessor, List conflictingMembers) { // CLF_IMPLEMENT_MIXIN_MISSING_ACCESSOR - String message = getMessageForCLF_CONSUMED_FIELD_ACCESSOR_PAIR_INCOMPLETE( + addIssue(CLF_CONSUMED_FIELD_ACCESSOR_PAIR_INCOMPLETE, missingAccessor, validatorMessageHelper.descriptions(conflictingMembers)); - addIssue(message, CLF_CONSUMED_FIELD_ACCESSOR_PAIR_INCOMPLETE); } private void messageMissingOwnedAccessor(FieldAccessor accessor) { @@ -1199,33 +1153,29 @@ private void messageMissingOwnedAccessor(FieldAccessor accessor) { private void messageMissingOwnedAccessorN4JS(String accessorDescription, String verb, String counterpartDescription, FieldAccessor accessor) { - String message = getMessageForCLF_UNMATCHED_ACCESSOR_OVERRIDE(accessorDescription, verb, + IssueItem issueItem = CLF_UNMATCHED_ACCESSOR_OVERRIDE.toIssueItem(accessorDescription, verb, counterpartDescription); - addIssue(message, accessor.getAstElement(), - N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_UNMATCHED_ACCESSOR_OVERRIDE); + addIssue(accessor.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem); } private void messageMissingOwnedAccessorJS(String accessorDescription, String verb, String counterpartDescription, FieldAccessor accessor) { - String message = getMessageForCLF_UNMATCHED_ACCESSOR_OVERRIDE_JS(accessorDescription, verb, + IssueItem issueItem = CLF_UNMATCHED_ACCESSOR_OVERRIDE_JS.toIssueItem(accessorDescription, verb, counterpartDescription); - addIssue(message, accessor.getAstElement(), - N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_UNMATCHED_ACCESSOR_OVERRIDE_JS); + addIssue(accessor.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem); } private void messageMissingOwnedAccessorCorrespondingConsumedAccessor(FieldAccessor accessor, N4ClassifierDefinition definition) { - String message = getMessageForCLF_UNMATCHED_ACCESSOR_OVERRIDE( + IssueItem issueItem = CLF_UNMATCHED_ACCESSOR_OVERRIDE.toIssueItem( org.eclipse.xtext.util.Strings.toFirstUpper(validatorMessageHelper.description(accessor)), "consumed", accessor instanceof TSetter ? "getter" : "setter"); - addIssue(message, definition, - N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, CLF_UNMATCHED_ACCESSOR_OVERRIDE); + addIssue(definition, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, issueItem); } private void addIssueToMemberOrInterfaceReference(RedefinitionType redefinitionType, TMember overriding, - TMember implemented, - String message, String issueCode, String... issueData) { + TMember implemented, IssueItem issueItem) { if (redefinitionType == RedefinitionType.overridden && overriding.getContainingType() != getCurrentClassifier()) { @@ -1234,9 +1184,7 @@ private void addIssueToMemberOrInterfaceReference(RedefinitionType redefinitionT TClassifier currentClassifier = getCurrentClassifier(); if (overriding.getContainingType() == currentClassifier) { - addIssue(message, overriding.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, - issueCode, - issueData); + addIssue(overriding.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueItem); } else { MemberCollector memberCollector = containerTypesHelper.fromContext(getCurrentClassifierDefinition()); ContainerType bequestingType = memberCollector.directSuperTypeBequestingMember(currentClassifier, @@ -1250,7 +1198,7 @@ private void addIssueToMemberOrInterfaceReference(RedefinitionType redefinitionT EStructuralFeature feature = refInAST.eContainingFeature(); List list = (List) getCurrentClassifierDefinition().eGet(feature); int index = list.indexOf(refInAST); - addIssue(message, getCurrentClassifierDefinition(), feature, index, issueCode, issueData); + addIssue(getCurrentClassifierDefinition(), feature, index, issueItem); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSMemberValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSMemberValidator.xtend index c1b8ef36e6..d13f67b191 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSMemberValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSMemberValidator.xtend @@ -49,7 +49,6 @@ import org.eclipse.n4js.utils.ContainerTypesHelper import org.eclipse.n4js.utils.DeclMergingHelper import org.eclipse.n4js.utils.N4JSLanguageUtils import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator -import org.eclipse.n4js.validation.IssueCodes import org.eclipse.n4js.validation.JavaScriptVariantHelper import org.eclipse.xtext.EcoreUtil2 import org.eclipse.xtext.nodemodel.util.NodeModelUtils @@ -126,8 +125,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { val name = owner.name if (name !== null) { if (!owner.isValidName) { - val message = IssueCodes.getMessageForAST_RESERVED_IDENTIFIER(name); - addIssue(message, owner, PROPERTY_NAME_OWNER__DECLARED_NAME, IssueCodes.AST_RESERVED_IDENTIFIER); + addIssue(owner, PROPERTY_NAME_OWNER__DECLARED_NAME, AST_RESERVED_IDENTIFIER.toIssueItem(name)); } } } @@ -237,8 +235,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { return; for (sm : ptrsInAST.astStructuralMembers) { - val message = IssueCodes.getMessageForTYS_ADDITIONAL_STRUCTURAL_MEMBERS_ON_TYPE_VARS() - addIssue(message, sm, TYS_ADDITIONAL_STRUCTURAL_MEMBERS_ON_TYPE_VARS) + addIssue(sm, TYS_ADDITIONAL_STRUCTURAL_MEMBERS_ON_TYPE_VARS.toIssueItem()) } } @@ -262,20 +259,16 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { // name may be null (invalid file), we do not need an NPE here if (name !== null && name.startsWith('$')) { - val message = IssueCodes.getMessageForCLF_NAME_DOLLAR() - addIssue(message, member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_NAME_DOLLAR) + addIssue(member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_NAME_DOLLAR.toIssueItem()); } } def private internalCheckAbstractAndFinal(TMember member) { if (member.final) { if (member.abstract) { - val message = IssueCodes.getMessageForCLF_ABSTRACT_FINAL(member.keyword) - addIssue(message, member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, IssueCodes.CLF_ABSTRACT_FINAL) + addIssue(member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_ABSTRACT_FINAL.toIssueItem(member.keyword)) } else if (member.containingType instanceof TInterface && !(member instanceof TMethod)) { - val message = IssueCodes.getMessageForCLF_NO_FINAL_INTERFACE_MEMBER() - addIssue(message, member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, - IssueCodes.CLF_NO_FINAL_INTERFACE_MEMBER) + addIssue(member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_NO_FINAL_INTERFACE_MEMBER.toIssueItem()); } } } @@ -287,9 +280,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { val parent = member.eContainer; if (parent instanceof TInterface) { if (parent.typingStrategy === TypingStrategy.STRUCTURAL) { - val message = IssueCodes.getMessageForSTRCT_ITF_CANNOT_CONTAIN_STATIC_MEMBERS(); - addIssue(message, member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, - IssueCodes.STRCT_ITF_CANNOT_CONTAIN_STATIC_MEMBERS); + addIssue(member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, STRCT_ITF_CANNOT_CONTAIN_STATIC_MEMBERS.toIssueItem()); return false; } } @@ -322,8 +313,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { private def holdsConstructorModifiers(TMethod constructor) { if ((constructor.abstract && !(constructor.containingType instanceof TInterface)) // ctor in interface may be abstract (actually it *must* be abstract) || constructor.static || constructor.final || constructor.hasIllegalOverride) { - val message = getMessageForCLF_CTOR_ILLEGAL_MODIFIER - addIssue(message, constructor.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_CTOR_ILLEGAL_MODIFIER) + addIssue(constructor.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_CTOR_ILLEGAL_MODIFIER.toIssueItem()) return false; } return true; @@ -340,8 +330,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { */ private def boolean holdsConstructorInInterfaceDoesNotHaveBody(TMethod constructor) { if (constructor.containingType instanceof TInterface && !constructor.hasNoBody) { - addIssue(getMessageForITF_NO_PROPERTY_BODY("Constructors", ""), constructor.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, - ITF_NO_PROPERTY_BODY); + addIssue(constructor.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, ITF_NO_PROPERTY_BODY.toIssueItem("Constructors", "")); return false; } return true; @@ -353,8 +342,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { private def boolean holdsConstructorInInterfaceRequiresCovarianceAnnotation(TMethod constructor) { val container = constructor.containingType; if (container instanceof TInterface && !N4JSLanguageUtils.hasCovariantConstructor(container as TInterface, declMergingHelper)) { - addIssue(getMessageForITF_CONSTRUCTOR_COVARIANCE, constructor.astElement, - PROPERTY_NAME_OWNER__DECLARED_NAME, ITF_CONSTRUCTOR_COVARIANCE); + addIssue(constructor.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, ITF_CONSTRUCTOR_COVARIANCE.toIssueItem()); return false; } return true; @@ -366,8 +354,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { private def boolean holdsConstructorNoReturnType(TMethod constructor) { val constructorDecl = constructor.astElement as N4MethodDeclaration; if (constructorDecl.declaredReturnTypeRefInAST !== null) { - addIssue(getMessageForCLF_CTOR_RETURN_TYPE, constructorDecl, - FUNCTION_DEFINITION__DECLARED_RETURN_TYPE_REF_NODE, CLF_CTOR_RETURN_TYPE); + addIssue(constructorDecl, FUNCTION_DEFINITION__DECLARED_RETURN_TYPE_REF_NODE, CLF_CTOR_RETURN_TYPE.toIssueItem()); return false; } return true; @@ -384,8 +371,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { val constructorDecl = method.astElement as N4MethodDeclaration; val offsetLength = findTypeVariablesOffset(constructorDecl); - addIssue(IssueCodes.messageForCLF_CTOR_NO_TYPE_PARAMETERS, constructorDecl, offsetLength.key, - offsetLength.value, IssueCodes.CLF_CTOR_NO_TYPE_PARAMETERS); + addIssue(constructorDecl, offsetLength.key, offsetLength.value, CLF_CTOR_NO_TYPE_PARAMETERS.toIssueItem()); return false; } @@ -426,10 +412,9 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { if (! existsSuperCall) { val className = (ctor.eContainer as IdentifiableElement).name; addIssue( - getMessageForKEY_SUP_REQUIRE_EXPLICIT_SUPERCTOR_CALL(className), constructor.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, - KEY_SUP_REQUIRE_EXPLICIT_SUPERCTOR_CALL + KEY_SUP_REQUIRE_EXPLICIT_SUPERCTOR_CALL.toIssueItem(className) ) return false; } // else: ok so far, more checks on super call are performed in N4JSExpressionValidator @@ -449,26 +434,26 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { if (isCallSig || isConstructSig) { // constraint: only in .n4jsd files if (!jsVariantHelper.isExternalMode(astNode)) { - addIssue(getMessageForCLF_CALL_CONSTRUCT_SIG_ONLY_IN_N4JSD, astNode, CLF_CALL_CONSTRUCT_SIG_ONLY_IN_N4JSD); + addIssue(astNode, CLF_CALL_CONSTRUCT_SIG_ONLY_IN_N4JSD.toIssueItem()); return false; } // constraint: only in shapes and EcmaScript classes val owner = if (methodInAST.isLeft) methodInAST.getLeft.owner; // owners of TStructMethods are never annotated with @N4JS if (methodInAST.isLeft && !N4JSLanguageUtils.isShapeOrEcmaScript(owner)) { - addIssue(getMessageForCLF_CALL_CONSTRUCT_SIG_NOT_IN_N4JS, astNode, CLF_CALL_CONSTRUCT_SIG_NOT_IN_N4JS); + addIssue(astNode, CLF_CALL_CONSTRUCT_SIG_NOT_IN_N4JS.toIssueItem()); return false; } // constraint: must not have a body val body = if (methodInAST.isLeft) methodInAST.getLeft.body; // TStructMethods never have a body if (body !== null) { - addIssue(getMessageForCLF_CALL_CONSTRUCT_SIG_BODY, astNode, CLF_CALL_CONSTRUCT_SIG_BODY); + addIssue(astNode, CLF_CALL_CONSTRUCT_SIG_BODY.toIssueItem()); return false; } // constraint: not more than one call/construct signature per class val haveDuplicate = (if (isCallSig) allCallSigs else allConstructSigs).size >= 2; if (haveDuplicate) { val kind = if (isCallSig) "call" else "construct"; - addIssue(getMessageForCLF_CALL_CONSTRUCT_SIG_DUPLICATE(kind), astNode, CLF_CALL_CONSTRUCT_SIG_DUPLICATE); + addIssue(astNode, CLF_CALL_CONSTRUCT_SIG_DUPLICATE.toIssueItem(kind)); return false; } // constraint: private not allowed in interfaces @@ -485,7 +470,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { if (isConstructSig) { // constraint: only in classes if (!(astNode.eContainer instanceof N4InterfaceDeclaration || astNode.eContainer instanceof StructuralTypeRef)) { - addIssue(messageForCLF_CONSTRUCT_SIG_ONLY_IN_INTERFACE, astNode, CLF_CONSTRUCT_SIG_ONLY_IN_INTERFACE); + addIssue(astNode, CLF_CONSTRUCT_SIG_ONLY_IN_INTERFACE.toIssueItem()); return false; } // constraint: must have non-void return type @@ -496,7 +481,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { }; val returnTypeRef = definedFunction?.returnTypeRef; if (returnTypeRef === null || TypeUtils.isVoid(returnTypeRef)) { - addIssue(messageForCLF_CONSTRUCT_SIG_VOID_RETURN_TYPE, astNode, CLF_CONSTRUCT_SIG_VOID_RETURN_TYPE); + addIssue(astNode, CLF_CONSTRUCT_SIG_VOID_RETURN_TYPE.toIssueItem()); return false; } } @@ -513,11 +498,9 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { if (requireCheckForMissingBody && !memberIsAbstract && (member.astElement as N4MemberDeclaration).body === null) { if (member.isConstructor) { - addIssue(messageForCLF_MISSING_CTOR_BODY, member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, - IssueCodes.CLF_MISSING_CTOR_BODY) + addIssue(member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_MISSING_CTOR_BODY.toIssueItem()) } else { - val message = IssueCodes.getMessageForCLF_MISSING_BODY(member.keyword, member.name) - addIssue(message, member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, IssueCodes.CLF_MISSING_BODY) + addIssue(member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_MISSING_BODY.toIssueItem(member.keyword, member.name)) } return false; } @@ -532,8 +515,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { if (container instanceof TN4Classifier) { val isStructural = container.typingStrategy === TypingStrategy.STRUCTURAL; if (member.abstract && member.static && !container.external && !isStructural) { - addIssue(getMessageForCLF_STATIC_ABSTRACT(member.keyword, member.name), member.astElement, - PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_STATIC_ABSTRACT) + addIssue(member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_STATIC_ABSTRACT.toIssueItem(member.keyword, member.name)) return false; } } @@ -542,8 +524,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { def private boolean holdsAbstractMethodMustHaveNoBody(TMember member) { if (member.abstract && (member.astElement as N4MemberDeclaration).body !== null) { - val message = IssueCodes.getMessageForCLF_ABSTRACT_BODY - addIssue(message, member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, IssueCodes.CLF_ABSTRACT_BODY) + addIssue(member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_ABSTRACT_BODY.toIssueItem()) return false; } return true; @@ -553,9 +534,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { if (member.abstract) { val classifier = EcoreUtil2.getContainerOfType(member, TClassifier) if (classifier !== null && !classifier.abstract) { - val message = IssueCodes.getMessageForCLF_ABSTRACT_MISSING(member.keyword, member.name, classifier.name) - addIssue(message, member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, - IssueCodes.CLF_ABSTRACT_MISSING) + addIssue(member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_ABSTRACT_MISSING.toIssueItem(member.keyword, member.name, classifier.name)) return false; } } @@ -572,9 +551,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { val hasPrivateModifier = (memberAccessModifier === MemberAccessModifier.PRIVATE) val hasProjectModifier = (memberAccessModifier === MemberAccessModifier.PROJECT) if (hasPrivateModifier || hasProjectModifier) { - val message = IssueCodes.getMessageForCLF_INTERNAL_BAD_WITH_PRIVATE_OR_PROJECT(); - addIssue(message, tmember.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, - IssueCodes.CLF_INTERNAL_BAD_WITH_PRIVATE_OR_PROJECT); + addIssue(tmember.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_INTERNAL_BAD_WITH_PRIVATE_OR_PROJECT.toIssueItem()); } } } @@ -586,9 +563,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { if (member.containingType instanceof TInterface) { val memberAccessModifier = member.memberAccessModifier if (memberAccessModifier === MemberAccessModifier.PRIVATE) { - val message = IssueCodes.getMessageForCLF_MINIMAL_ACCESSIBILITY_IN_INTERFACES(); - addIssue(message, member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, - IssueCodes.CLF_MINIMAL_ACCESSIBILITY_IN_INTERFACES); + addIssue(member.astElement, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_MINIMAL_ACCESSIBILITY_IN_INTERFACES.toIssueItem()); return false; } } @@ -598,8 +573,7 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { def private internalCheckGetterType(N4GetterDeclaration n4GetterDeclaration) { val getterType = n4GetterDeclaration.declaredTypeRef?.declaredType; if (getterType !== null && getterType instanceof VoidType) { - val message = IssueCodes.messageForCLF_VOID_ACCESSOR; - addIssue(message, n4GetterDeclaration, PROPERTY_NAME_OWNER__DECLARED_NAME, IssueCodes.CLF_VOID_ACCESSOR); + addIssue(n4GetterDeclaration, PROPERTY_NAME_OWNER__DECLARED_NAME, CLF_VOID_ACCESSOR.toIssueItem()); } } @@ -626,11 +600,9 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { val structuralFieldDuplicate = structuralMembersByNameAndStatic.get(it).head val existingClassifierMember = membersByNameAndStatic.get(it).headExceptNonExistantGetters(structFieldInitMode) if (existingClassifierMember?.memberAccessModifier == MemberAccessModifier.PUBLIC) { - val message = getMessageForCLF_DUP_MEMBER(structuralFieldDuplicate.descriptionWithLine, - existingClassifierMember.descriptionWithLine); val index = thisTypeRefStructInAST.structuralMembers.indexOf(structuralFieldDuplicate) - addIssue(message, thisTypeRefStructInAST, - TypeRefsPackage.Literals.STRUCTURAL_TYPE_REF__AST_STRUCTURAL_MEMBERS, index, CLF_DUP_MEMBER) + addIssue(thisTypeRefStructInAST, TypeRefsPackage.Literals.STRUCTURAL_TYPE_REF__AST_STRUCTURAL_MEMBERS, index, + CLF_DUP_MEMBER.toIssueItem(structuralFieldDuplicate.descriptionWithLine, existingClassifierMember.descriptionWithLine)); } } ] @@ -662,9 +634,9 @@ class N4JSMemberValidator extends AbstractN4JSDeclarativeValidator { def checkFixmeUsedWithTestAnnotation(N4MethodDeclaration methodDecl) { ANNOTATIONS_REQUIRE_TEST.forEach [ annotation | if (annotation.hasAnnotation(methodDecl) && !TEST_METHOD.hasAnnotation(methodDecl)) { - addIssue(getMessageForANN_REQUIRES_TEST('''@«annotation.name»'''), methodDecl.annotations.findFirst [ + addIssue(methodDecl.annotations.findFirst [ name == annotation.name - ], N4JSPackage.eINSTANCE.annotation_Name, ANN_REQUIRES_TEST); + ], N4JSPackage.eINSTANCE.annotation_Name, ANN_REQUIRES_TEST.toIssueItem('''@«annotation.name»''')); } ]; } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSModuleValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSModuleValidator.xtend index 00d2039fae..7a94be2ef8 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSModuleValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSModuleValidator.xtend @@ -29,7 +29,7 @@ import org.eclipse.n4js.ts.types.TModule import org.eclipse.n4js.ts.types.TypesPackage import org.eclipse.n4js.utils.URIUtils import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator -import org.eclipse.n4js.validation.IssueCodes +import org.eclipse.n4js.validation.IssueItem import org.eclipse.n4js.validation.N4JSResourceValidator import org.eclipse.n4js.workspace.WorkspaceAccess import org.eclipse.xtext.EcoreUtil2 @@ -44,6 +44,8 @@ import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider import org.eclipse.xtext.validation.Check import org.eclipse.xtext.validation.EValidatorRegistrar +import static org.eclipse.n4js.validation.IssueCodes.* + import static extension org.eclipse.n4js.utils.N4JSLanguageUtils.* /** @@ -85,8 +87,7 @@ class N4JSModuleValidator extends AbstractN4JSDeclarativeValidator { if (nodes.size > 0) { val offset = nodes.get(0).offset; if (offset !== 0) { - val message = IssueCodes.getMessageForSCR_HASHBANG_WRONG_LOCATION(); - addIssue(message, script, N4JSPackage.eINSTANCE.script_Hashbang, IssueCodes.SCR_HASHBANG_WRONG_LOCATION); + addIssue(script, N4JSPackage.eINSTANCE.script_Hashbang, SCR_HASHBANG_WRONG_LOCATION.toIssueItem()); } } } @@ -268,14 +269,12 @@ class N4JSModuleValidator extends AbstractN4JSDeclarativeValidator { val filePathStr = sortedMutVisibleResourceURIs .filter[implModule != it] .map[segmentsList.drop(1).join('/')].join("; "); - val message = IssueCodes.getMessageForCLF_DUP_DEF_MODULE(module.qualifiedName, implModuleStr, filePathStr); - addIssue(message, script, IssueCodes.CLF_DUP_DEF_MODULE); + addIssue(script, CLF_DUP_DEF_MODULE.toIssueItem(module.qualifiedName, implModuleStr, filePathStr)); } else { // collision of implementation modules // list all locations - give the user the possibility to check by himself. val filePathStr = sortedMutVisibleResourceURIs.map[segmentsList.drop(1).join('/')].join("; "); - val message = IssueCodes.getMessageForCLF_DUP_MODULE(module.qualifiedName, filePathStr); - addIssue(message, script, IssueCodes.CLF_DUP_MODULE); + addIssue(script, CLF_DUP_MODULE.toIssueItem(module.qualifiedName, filePathStr)); } } } @@ -297,11 +296,11 @@ class N4JSModuleValidator extends AbstractN4JSDeclarativeValidator { /** * Annotates the script with a an error marker on the first AST element or the first none-empty line. */ - private def void addIssue(String message, Script script, String issueCode) { + private def void addIssue(Script script, IssueItem issueItem) { val first = script.scriptElements.head; if(first !== null){ - addIssue(message, first, issueCode); + addIssue(first, issueItem); return; } val resource = script.eResource as XtextResource; @@ -315,7 +314,7 @@ class N4JSModuleValidator extends AbstractN4JSDeclarativeValidator { start = matcher.start; end = matcher.end; } - addIssue(message, script, start, end - start, issueCode); + addIssue(script, start, end - start, issueItem); } private def static String replaceJSXByJS(String ext) { diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSNameValidator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSNameValidator.java index 2e70eeaf0b..842726071a 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSNameValidator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSNameValidator.java @@ -27,14 +27,6 @@ import static org.eclipse.n4js.validation.IssueCodes.CLF_NAME_DOLLAR; import static org.eclipse.n4js.validation.IssueCodes.CLF_NAME_INDISTINGUISHABLE; import static org.eclipse.n4js.validation.IssueCodes.CLF_NAME_RESERVED; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_NAME_CONFLICTS_WITH_CONSTRUCTOR; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_NAME_CONTAINS_DISCOURAGED_CHARACTER; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_NAME_DIFFERS_TYPE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_NAME_DOES_NOT_START_LOWERCASE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_NAME_DOES_NOT_START_UPPERCASE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_NAME_DOLLAR; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_NAME_INDISTINGUISHABLE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_NAME_RESERVED; import java.util.Collection; @@ -51,6 +43,7 @@ import org.eclipse.n4js.typesystem.N4JSTypeSystem; import org.eclipse.n4js.utils.N4JSLanguageHelper; import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator; +import org.eclipse.n4js.validation.IssueItem; import org.eclipse.n4js.validation.JavaScriptVariantHelper; import org.eclipse.xtext.util.Strings; import org.eclipse.xtext.validation.Check; @@ -123,11 +116,10 @@ private boolean isNotChecked(N4TypeDeclaration n4TypeDeclaration) { private boolean holdsTypeNameNotIndistinguishable(N4TypeDeclaration element, String suffix, Collection category) { if (category.contains(element.getName()) && !"yield".equals(element.getName())) { - final String message = getMessageForCLF_NAME_INDISTINGUISHABLE(validatorMessageHelper.description(element), + final IssueItem issueItem = CLF_NAME_INDISTINGUISHABLE.toIssueItem( + Strings.toFirstUpper(validatorMessageHelper.description(element)), suffix); - addIssue(Strings.toFirstUpper(message), element, - N4_TYPE_DECLARATION__NAME, - CLF_NAME_INDISTINGUISHABLE); + addIssue(element, N4_TYPE_DECLARATION__NAME, issueItem); return false; } return true; @@ -135,12 +127,9 @@ private boolean holdsTypeNameNotIndistinguishable(N4TypeDeclaration element, Str private boolean holdsDoesNotStartWithLowerCaseLetter(N4TypeDeclaration declaration) { if (Character.isLowerCase(declaration.getName().charAt(0))) { - final String msg = getMessageForCLF_NAME_DOES_NOT_START_UPPERCASE(keywordProvider.keyword(declaration)); - addIssue( - Strings.toFirstUpper(msg), - declaration, - N4_TYPE_DECLARATION__NAME, - CLF_NAME_DOES_NOT_START_UPPERCASE); + final IssueItem issueItem = CLF_NAME_DOES_NOT_START_UPPERCASE.toIssueItem( + Strings.toFirstUpper(keywordProvider.keyword(declaration))); + addIssue(declaration, N4_TYPE_DECLARATION__NAME, issueItem); return false; } return true; @@ -176,9 +165,8 @@ && holdsNameMayNotBeConfusedWith(n4Member, "access modifier", ACCESS_MODIFIERS) private boolean holdsDoesNotEqualWithConstructor(final N4MemberDeclaration n4Member) { if (n4Member.isStatic() && CONSTRUCTOR.equals(getDeclarationName(n4Member))) { - final String message = getMessageForCLF_NAME_CONFLICTS_WITH_CONSTRUCTOR(); - addIssue(message, n4Member, N4JSMetaModelUtils.getElementNameFeature(n4Member), - CLF_NAME_CONFLICTS_WITH_CONSTRUCTOR); + final IssueItem issueItem = CLF_NAME_CONFLICTS_WITH_CONSTRUCTOR.toIssueItem(); + addIssue(n4Member, N4JSMetaModelUtils.getElementNameFeature(n4Member), issueItem); return false; } return true; @@ -190,11 +178,9 @@ private boolean holdsDoesNotContainDiscouragedCharacter(final N4MemberDeclaratio final String declarationName = getDeclarationName(n4Member); if (!declarationName.startsWith("$") && declarationName.contains(discouragedCharacter)) { final String discouragedCharacterLabel = DISCOURAGED_CHARACTERS.get(discouragedCharacter); - final String message = getMessageForCLF_NAME_CONTAINS_DISCOURAGED_CHARACTER(discouragedCharacterLabel); - addIssue(message, - n4Member, - N4JSMetaModelUtils.getElementNameFeature(n4Member), - CLF_NAME_CONTAINS_DISCOURAGED_CHARACTER); + final IssueItem issueItem = CLF_NAME_CONTAINS_DISCOURAGED_CHARACTER + .toIssueItem(discouragedCharacterLabel); + addIssue(n4Member, N4JSMetaModelUtils.getElementNameFeature(n4Member), issueItem); return false; } } @@ -232,12 +218,9 @@ private boolean holdsDoesNotStartWithUpperCaseLetter(N4MemberDeclaration n4Membe } if (Character.isUpperCase(n4Member.getName().charAt(0))) { - final String msg = getMessageForCLF_NAME_DOES_NOT_START_LOWERCASE(keywordProvider.keyword(n4Member)); - addIssue( - Strings.toFirstUpper(msg), - n4Member, - N4JSMetaModelUtils.getElementNameFeature(n4Member), - CLF_NAME_DOES_NOT_START_LOWERCASE); + final IssueItem issueItem = CLF_NAME_DOES_NOT_START_LOWERCASE.toIssueItem( + Strings.toFirstUpper(keywordProvider.keyword(n4Member))); + addIssue(n4Member, N4JSMetaModelUtils.getElementNameFeature(n4Member), issueItem); return false; } return true; @@ -278,8 +261,8 @@ && holdsDoesNotContainDiscouragedCharacter(variable)) { private boolean holdsDoesNotEqualWithConstructor(final AbstractVariable variable) { if (CONSTRUCTOR.equals(getVariableName(variable))) { - final String message = getMessageForCLF_NAME_CONFLICTS_WITH_CONSTRUCTOR(); - addIssue(message, variable, ABSTRACT_VARIABLE__NAME, CLF_NAME_CONFLICTS_WITH_CONSTRUCTOR); + final IssueItem issueItem = CLF_NAME_CONFLICTS_WITH_CONSTRUCTOR.toIssueItem(); + addIssue(variable, ABSTRACT_VARIABLE__NAME, issueItem); return false; } return true; @@ -288,8 +271,8 @@ private boolean holdsDoesNotEqualWithConstructor(final AbstractVariable varia private boolean holdsDoesNotStartWithDollarSign(final AbstractVariable variable) { // name may be null (invalid file), we do not need an NPE here if (getVariableName(variable).startsWith("$")) { - final String message = getMessageForCLF_NAME_DOLLAR(); - addIssue(message, variable, ABSTRACT_VARIABLE__NAME, CLF_NAME_DOLLAR); + final IssueItem issueItem = CLF_NAME_DOLLAR.toIssueItem(); + addIssue(variable, ABSTRACT_VARIABLE__NAME, issueItem); return false; } return true; @@ -317,12 +300,9 @@ private boolean holdsStartWithLowercaseLetter(AbstractVariable variable) { final char first = variable.getName().charAt(0); if (Character.isLetter(first) && !Character.isLowerCase(first)) { - final String msg = getMessageForCLF_NAME_DOES_NOT_START_LOWERCASE(keywordProvider.keyword(variable)); - addIssue( - Strings.toFirstUpper(msg), - variable, - ABSTRACT_VARIABLE__NAME, - CLF_NAME_DOES_NOT_START_LOWERCASE); + final IssueItem issueItem = CLF_NAME_DOES_NOT_START_LOWERCASE.toIssueItem( + Strings.toFirstUpper(keywordProvider.keyword(variable))); + addIssue(variable, ABSTRACT_VARIABLE__NAME, issueItem); return false; } return true; @@ -336,11 +316,9 @@ private boolean holdsNoTypeNameOrNameEqualsType(NamedElement namedElement) { if (typeRef != null && typeRef.getDeclaredType() != null) { String typeName = typeRef.getDeclaredType().getName(); if (!Strings.isEmpty(typeName) && !name.equals(typeName)) { - final String message = getMessageForCLF_NAME_DIFFERS_TYPE( - validatorMessageHelper.description(namedElement), name, typeName); - addIssue(Strings.toFirstUpper(message), namedElement, - N4JSMetaModelUtils.getElementNameFeature(namedElement), - CLF_NAME_DIFFERS_TYPE); + final IssueItem issueItem = CLF_NAME_DIFFERS_TYPE.toIssueItem( + Strings.toFirstUpper(validatorMessageHelper.description(namedElement)), name, typeName); + addIssue(namedElement, N4JSMetaModelUtils.getElementNameFeature(namedElement), issueItem); return false; } } @@ -352,10 +330,10 @@ private boolean holdsNoTypeNameOrNameEqualsType(NamedElement namedElement) { private boolean holdsNameMayNotBeConfusedWith(NamedElement element, String suffix, Collection category) { // N4JSFV#checkFunctionName is responsible for the validation of function definitions if (category.contains(element.getName()) && !(element instanceof FunctionDefinition)) { - final String message = getMessageForCLF_NAME_RESERVED(validatorMessageHelper.description(element), + final IssueItem issueItem = CLF_NAME_RESERVED.toIssueItem( + Strings.toFirstUpper(validatorMessageHelper.description(element)), suffix); - addIssue(Strings.toFirstUpper(message), element, N4JSMetaModelUtils.getElementNameFeature(element), - CLF_NAME_RESERVED); + addIssue(element, N4JSMetaModelUtils.getElementNameFeature(element), issueItem); return false; } return true; @@ -367,11 +345,9 @@ private boolean holdsDoesNotContainDiscouragedCharacter(final AbstractVariable interfaces = StreamSupport.stream( tclass.getImplementedInterfaceRefs().spliterator(), false) .map(ref -> (TInterface) (ref.getDeclaredType())).collect(Collectors.toList()); - String message = getMessageForSYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP( + IssueItem issueItem = SYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP.toIssueItem( validatorMessageHelper.description(tclass), "extend", "interface" + (interfaces.size() > 1 ? "s " : " ") + validatorMessageHelper.names(interfaces), IMPLEMENTS_KEYWORD); - addIssue(message, n4ClassDefinition, keywordNode.getTotalOffset(), - keywordNode.getLength(), SYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP); + addIssue(n4ClassDefinition, keywordNode.getTotalOffset(), + keywordNode.getLength(), issueItem); } } @@ -255,12 +253,12 @@ public void checkInterfaceDeclaration(N4InterfaceDeclaration n4InterfaceDecl) { return Stream.empty(); }) .collect(Collectors.toList()); - String message = getMessageForSYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP( + IssueItem issueItem = SYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP.toIssueItem( validatorMessageHelper.description(tinterface), "implement", "interface" + (interfaces.size() > 1 ? "s " : " ") + validatorMessageHelper.names(interfaces), EXTENDS_KEYWORD); - addIssue(message, n4InterfaceDecl, keywordNode.getTotalOffset(), - keywordNode.getLength(), SYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP); + addIssue(n4InterfaceDecl, keywordNode.getTotalOffset(), + keywordNode.getLength(), issueItem); } } @@ -283,9 +281,8 @@ private boolean holdsCorrectOrderOfExtendsImplements(N4ClassDefinition semanticE int extendsOffset = extendsNode.getOffset(); int implementsOffset = implementsNode.getOffset(); if (extendsOffset > implementsOffset) { - String message = getMessageForSYN_KW_EXTENDS_IMPLEMENTS_WRONG_ORDER(); - addIssue(message, semanticElement, extendsOffset, EXTENDS_KEYWORD.length(), - IssueCodes.SYN_KW_EXTENDS_IMPLEMENTS_WRONG_ORDER); + addIssue(semanticElement, extendsOffset, EXTENDS_KEYWORD.length(), + SYN_KW_EXTENDS_IMPLEMENTS_WRONG_ORDER.toIssueItem()); return false; } return true; @@ -366,9 +363,8 @@ private ILeafNode doFindLeafWithKeyword(EObject semanticElement, String stopAtKe @Check public void checkCatchVariable(CatchVariable catchVariable) { if (catchVariable.getDeclaredTypeRefInAST() != null) { - addIssue(getMessageForAST_CATCH_VAR_TYPED(), catchVariable, - N4JSPackage.Literals.TYPED_ELEMENT__DECLARED_TYPE_REF_NODE, - AST_CATCH_VAR_TYPED); + addIssue(catchVariable, N4JSPackage.Literals.TYPED_ELEMENT__DECLARED_TYPE_REF_NODE, + AST_CATCH_VAR_TYPED.toIssueItem()); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSTypeAliasValidator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSTypeAliasValidator.java index 9a38804c37..dca081dc2a 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSTypeAliasValidator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSTypeAliasValidator.java @@ -10,6 +10,12 @@ */ package org.eclipse.n4js.validation.validators; +import static org.eclipse.n4js.validation.IssueCodes.ALI_CYCLIC_TYPE_ALIAS; +import static org.eclipse.n4js.validation.IssueCodes.ALI_INVALID_MODIFIER; +import static org.eclipse.n4js.validation.IssueCodes.ALI_INVALID_TYPE_ALIAS_IN_TYPE_TYPE_REF; +import static org.eclipse.n4js.validation.IssueCodes.TYS_PRIMITIVE_TYPE_DYNAMIC; +import static org.eclipse.n4js.validation.IssueCodes.TYS_STRUCTURAL_PRIMITIVE; + import java.util.Collections; import java.util.Stack; import java.util.stream.Collectors; @@ -30,7 +36,6 @@ import org.eclipse.n4js.utils.N4JSLanguageUtils; import org.eclipse.n4js.utils.RecursionGuard; import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator; -import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.validation.Check; import org.eclipse.xtext.validation.EValidatorRegistrar; import org.eclipse.xtext.xbase.lib.IteratorExtensions; @@ -76,9 +81,8 @@ public void checkCyclicAliasDeclaration(N4TypeAliasDeclaration n4TypeAliasDecl) return; // no cycle } String cycleStr = cycle.stream().map(TypeAlias::getName).collect(Collectors.joining(" -> ")); - addIssue(IssueCodes.getMessageForALI_CYCLIC_TYPE_ALIAS(cycleStr), - n4TypeAliasDecl, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, - IssueCodes.ALI_CYCLIC_TYPE_ALIAS); + addIssue(n4TypeAliasDecl, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, + ALI_CYCLIC_TYPE_ALIAS.toIssueItem(cycleStr)); } /** @@ -143,25 +147,21 @@ public void checkTypeModifiersOfAlias(ParameterizedTypeRef typeRefInAST) { final TypeRef typeRefResolved = tsh.resolveTypeAliasFlat(G, typeRefInAST); if (typeRefInAST.isDynamic()) { if (!(typeRefResolved instanceof ParameterizedTypeRef)) { - addIssue(IssueCodes.getMessageForALI_INVALID_MODIFIER("dynamically"), - typeRefInAST, IssueCodes.ALI_INVALID_MODIFIER); + addIssue(typeRefInAST, ALI_INVALID_MODIFIER.toIssueItem("dynamically")); } else { final Type declType = typeRefResolved.getDeclaredType(); if (!N4JSLanguageUtils.mayBeReferencedDynamically(declType)) { - addIssue(IssueCodes.getMessageForTYS_PRIMITIVE_TYPE_DYNAMIC(declType.getName()), - typeRefInAST, IssueCodes.TYS_PRIMITIVE_TYPE_DYNAMIC); + addIssue(typeRefInAST, TYS_PRIMITIVE_TYPE_DYNAMIC.toIssueItem(declType.getName())); } } } if (typeRefInAST.isUseSiteStructuralTyping()) { if (!(typeRefResolved instanceof ParameterizedTypeRef)) { - addIssue(IssueCodes.getMessageForALI_INVALID_MODIFIER("structurally"), - typeRefInAST, IssueCodes.ALI_INVALID_MODIFIER); + addIssue(typeRefInAST, ALI_INVALID_MODIFIER.toIssueItem("structurally")); } else { final Type declType = typeRefResolved.getDeclaredType(); if (!N4JSLanguageUtils.mayBeReferencedStructurally(declType)) { - addIssue(IssueCodes.getMessageForTYS_STRUCTURAL_PRIMITIVE(), - typeRefInAST, IssueCodes.TYS_STRUCTURAL_PRIMITIVE); + addIssue(typeRefInAST, TYS_STRUCTURAL_PRIMITIVE.toIssueItem()); } } } @@ -174,8 +174,7 @@ public void checkTypeModifiersOfAlias(ParameterizedTypeRef typeRefInAST) { // (note: no need to cover cases ThisTypeRefNominal and WildcardOldNotation from rule TypeArgInTypeTypeRef // in TypeExpressions.xtext, because this-types and wildcards cannot appear as actual type of an alias) if (!isValidTypeArgInTypeTypeRef) { - addIssue(IssueCodes.getMessageForALI_INVALID_TYPE_ALIAS_IN_TYPE_TYPE_REF("{}"), - typeRefInAST, IssueCodes.ALI_INVALID_TYPE_ALIAS_IN_TYPE_TYPE_REF); + addIssue(typeRefInAST, ALI_INVALID_TYPE_ALIAS_IN_TYPE_TYPE_REF.toIssueItem("{}")); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSTypeValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSTypeValidator.xtend index c02b89722d..2e7936d725 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSTypeValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSTypeValidator.xtend @@ -102,6 +102,7 @@ import static org.eclipse.n4js.validation.IssueCodes.* import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* import org.eclipse.emf.ecore.EStructuralFeature +import org.eclipse.n4js.validation.IssueItem /** * Class for validating the N4JS types. @@ -159,8 +160,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { return; } val ubInAST = typeVar.declaredUpperBoundNode.typeRefInAST; // never 'null' because 'typeVar.declaredUpperBound' returned non-null value - val message = getMessageForCLF_UPPER_BOUND_FINAL(declType.name, typeVar.name); - addIssue(message, ubInAST, PARAMETERIZED_TYPE_REF__DECLARED_TYPE, CLF_UPPER_BOUND_FINAL); + addIssue(ubInAST, PARAMETERIZED_TYPE_REF__DECLARED_TYPE, CLF_UPPER_BOUND_FINAL.toIssueItem(declType.name, typeVar.name)); } }; ]; @@ -171,7 +171,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { if (script.module === null) { val rootNode = NodeModelUtils.getNode(script) if (rootNode !== null) { - addIssue(IssueCodes.getMessageForTYS_MISSING, script, rootNode.offset, rootNode.length, TYS_MISSING); + addIssue(script, rootNode.offset, rootNode.length, TYS_MISSING.toIssueItem()); } } } @@ -202,7 +202,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { */ def private void internalCheckStructuralPrimitiveTypeRef(ParameterizedTypeRef typeRefInAST) { if (typeRefInAST.typingStrategy != TypingStrategy.NOMINAL && !N4JSLanguageUtils.mayBeReferencedStructurally(typeRefInAST.declaredType)) { - addIssue(IssueCodes.messageForTYS_STRUCTURAL_PRIMITIVE, typeRefInAST, TYS_STRUCTURAL_PRIMITIVE); + addIssue(typeRefInAST, TYS_STRUCTURAL_PRIMITIVE.toIssueItem()); } } @@ -210,14 +210,11 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { // IDE-785 uses ParamterizedTypeRefs in ClassifierTypeRefs. Currently Type Arguments are not supported in ClassifierTypeRefs, so // we actively forbid them here. Will be loosened for IDE-1310 if (!paramTypeRefInAST.declaredTypeArgs.isEmpty) { - addIssue(IssueCodes.getMessageForAST_NO_TYPE_ARGS_IN_CLASSIFIERTYPEREF, paramTypeRefInAST, - AST_NO_TYPE_ARGS_IN_CLASSIFIERTYPEREF) + addIssue(paramTypeRefInAST, AST_NO_TYPE_ARGS_IN_CLASSIFIERTYPEREF.toIssueItem()); } else if (paramTypeRefInAST instanceof FunctionTypeRef) { - addIssue(IssueCodes.getMessageForAST_NO_FUNCTIONTYPEREFS_IN_CLASSIFIERTYPEREF, paramTypeRefInAST, - AST_NO_FUNCTIONTYPEREFS_IN_CLASSIFIERTYPEREF) + addIssue(paramTypeRefInAST, AST_NO_FUNCTIONTYPEREFS_IN_CLASSIFIERTYPEREF.toIssueItem()); } else if (paramTypeRefInAST.declaredType instanceof TFunction) { - addIssue(IssueCodes.getMessageForAST_NO_FUNCTIONTYPEREFS_IN_CLASSIFIERTYPEREF, paramTypeRefInAST, - AST_NO_FUNCTIONTYPEREFS_IN_CLASSIFIERTYPEREF) + addIssue(paramTypeRefInAST, AST_NO_FUNCTIONTYPEREFS_IN_CLASSIFIERTYPEREF.toIssueItem()); } } @@ -232,7 +229,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { if (!(thisTypeRefInAST.isUsedStructurallyAsFormalParametersInTheConstructor || thisTypeRefInAST.isUsedAtCovariantPositionInClassifierDeclaration || thisTypeRefInAST.isUsedInVariableWithSyntaxError)) { - addIssue(IssueCodes.getMessageForAST_THIS_WRONG_PLACE, thisTypeRefInAST, IssueCodes.AST_THIS_WRONG_PLACE); + addIssue(thisTypeRefInAST, AST_THIS_WRONG_PLACE.toIssueItem()); } } @@ -292,7 +289,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { // we have a type reference to 'Symbol' val isAllowed = isExtendsClauseInRuntimeLibrary(typeRefInAST); if (!isAllowed) { - addIssue(IssueCodes.getMessageForBIT_SYMBOL_INVALID_USE, typeRefInAST, BIT_SYMBOL_INVALID_USE); + addIssue(typeRefInAST, BIT_SYMBOL_INVALID_USE.toIssueItem()); } } } @@ -314,8 +311,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { if (refInAST.dynamic) { val Type t = refInAST.declaredType; if (!N4JSLanguageUtils.mayBeReferencedDynamically(t)) { - addIssue(IssueCodes.getMessageForTYS_PRIMITIVE_TYPE_DYNAMIC(t.name), refInAST, - TYS_PRIMITIVE_TYPE_DYNAMIC); + addIssue(refInAST, TYS_PRIMITIVE_TYPE_DYNAMIC.toIssueItem(t.name)); } } } @@ -338,8 +334,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { val hiddenType = hiddenTypeDscr?.getEObjectOrProxy; if (hiddenType instanceof Type && !(IEObjectDescriptionWithError.isErrorDescription(hiddenTypeDscr))) { - val message = getMessageForVIS_TYPE_PARAMETER_HIDES_TYPE(name, hiddenType.keyword); - addIssue(message, it, VIS_TYPE_PARAMETER_HIDES_TYPE); + addIssue(it, VIS_TYPE_PARAMETER_HIDES_TYPE.toIssueItem(name, hiddenType.keyword)); } } ] @@ -376,8 +371,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { if (m === null) { // no getter at all - val message = messageForTYS_COMPOUND_MISSING_GETTER - addIssue(message, assExpr.lhs, TYS_COMPOUND_MISSING_GETTER); + addIssue(assExpr.lhs, TYS_COMPOUND_MISSING_GETTER.toIssueItem()); } else if (m instanceof TGetter) { val TGetter getter = m; var G = assExpr.newRuleEnvironment; @@ -418,10 +412,9 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { val ifcName = (tv.eContainer as TInterface).name; val tvName = "invariant " + tv.name; val typeRefsStr = badSubst.map[typeRefAsString].join(", "); - val message = getMessageForCLF_IMPLEMENT_EXTEND_SAME_INTERFACE_INCONSISTENTLY(mode, + val IssueItem issueItem = CLF_IMPLEMENT_EXTEND_SAME_INTERFACE_INCONSISTENTLY.toIssueItem(mode, ifcName, tvName, typeRefsStr); - addIssue(message, classifierDecl, N4JSPackage.eINSTANCE.n4TypeDeclaration_Name, - CLF_IMPLEMENT_EXTEND_SAME_INTERFACE_INCONSISTENTLY); + addIssue(classifierDecl, N4JSPackage.eINSTANCE.n4TypeDeclaration_Name, issueItem); } } } @@ -466,10 +459,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { return; // all good } if (singleExprArrowFunction.declaredReturnTypeRefInAST === null) { // show specialized error message only if return type of arrow function was inferred (i.e. not declared explicitly) - val message = IssueCodes. - getMessageForFUN_SINGLE_EXP_LAMBDA_IMPLICIT_RETURN_ALLOWED_UNLESS_VOID(); - addIssue(message, expression, - IssueCodes.FUN_SINGLE_EXP_LAMBDA_IMPLICIT_RETURN_ALLOWED_UNLESS_VOID); + addIssue(expression, IssueCodes.FUN_SINGLE_EXP_LAMBDA_IMPLICIT_RETURN_ALLOWED_UNLESS_VOID.toIssueItem()); return; } } @@ -484,9 +474,8 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { if (result.failure) { // use custom error message, because otherwise it will be completely confusing - val message = getMessageForTYS_NO_SUPERTYPE_WRITE_ACCESS(expectedTypeRef.typeRefAsString, - inferredType.typeRefAsString); - addIssue(message, expression, TYS_NO_SUPERTYPE_WRITE_ACCESS) + val IssueItem issueItem = TYS_NO_SUPERTYPE_WRITE_ACCESS.toIssueItem(expectedTypeRef.typeRefAsString, inferredType.typeRefAsString); + addIssue(expression, issueItem); } } else { @@ -607,11 +596,11 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { } } if (isSpecArgument) { - val message = getMessageForCLF_SPEC_SUPERFLUOUS_PROPERTIES(property.name, typeRef.typeRefAsString); - addIssue(message, astElement, feature, CLF_SPEC_SUPERFLUOUS_PROPERTIES); + val IssueItem issueItem = CLF_SPEC_SUPERFLUOUS_PROPERTIES.toIssueItem(property.name, typeRef.typeRefAsString); + addIssue(astElement, feature, issueItem); } else if (!expectedMembersPlusNotAccessibles.contains(property.name)) { - val message = getMessageForCLF_SUPERFLUOUS_PROPERTIES(property.name, typeRef.typeRefAsString, lhsName); - addIssue(message, astElement, feature, CLF_SUPERFLUOUS_PROPERTIES); + val IssueItem issueItem = CLF_SUPERFLUOUS_PROPERTIES.toIssueItem(property.name, typeRef.typeRefAsString, lhsName); + addIssue(astElement, feature, issueItem); } } }; @@ -655,7 +644,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { val isUndefinedLiteral = if (expression instanceof IdentifierRef) expression.id === undefinedField; if (!isUndefinedLiteral) { - addIssue(getMessageForEXP_USE_OF_UNDEF_EXPR, expression, EXP_USE_OF_UNDEF_EXPR); + addIssue(expression, EXP_USE_OF_UNDEF_EXPR.toIssueItem()); } } } @@ -721,7 +710,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { */ @Check def void checkUnionTypeContainsNoAny(UnionTypeExpression ute) { - checkComposedTypeRefContainsNoAny(ute, messageForUNI_ANY_USED, UNI_ANY_USED, true); + checkComposedTypeRefContainsNoAny(ute, UNI_ANY_USED.toIssueItem(), true); } /** @@ -730,11 +719,10 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { */ @Check def void checkIntersectionTypeContainsNoAny(IntersectionTypeExpression ite) { - checkComposedTypeRefContainsNoAny(ite, messageForINTER_ANY_USED, INTER_ANY_USED, false); + checkComposedTypeRefContainsNoAny(ite, INTER_ANY_USED.toIssueItem(), false); } - def private void checkComposedTypeRefContainsNoAny(ComposedTypeRef ctr, String msg, String issueCode, - boolean soleVoidAllowesAny) { + def private void checkComposedTypeRefContainsNoAny(ComposedTypeRef ctr, IssueItem issueItem, boolean soleVoidAllowesAny) { val G = ctr.newRuleEnvironment; val anyType = G.anyType; val voidType = G.voidType; @@ -748,7 +736,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { if (!dontShowWarning) { for (TypeRef anyTR : anyTypeRefs) { - addIssue(msg, anyTR, issueCode); + addIssue(anyTR, issueItem); } } } @@ -768,8 +756,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { tRefs.removeAll(intersectionTR); for (TypeRef tClassR : tRefs) { - val message = messageForUNI_REDUNDANT_SUBTYPE; - addIssue(message, tClassR, UNI_REDUNDANT_SUBTYPE); + addIssue(tClassR, UNI_REDUNDANT_SUBTYPE.toIssueItem()); } } } @@ -807,16 +794,14 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { if (byTypes.keySet.size>1) { if (covariantTypeArgValidation) { - val message = messageForINTER_TYEPARGS_ONLY_ONE_CLASS_ALLOWED; for (TypeRef tClassR : intersectionTR) { if (! (tClassR.eContainer instanceof TypeVariable)) { // nested, type ref coming from def site - addIssue(message, tClassR, INTER_TYEPARGS_ONLY_ONE_CLASS_ALLOWED); + addIssue(tClassR, INTER_TYEPARGS_ONLY_ONE_CLASS_ALLOWED.toIssueItem()); } } } else { - val message = messageForINTER_ONLY_ONE_CLASS_ALLOWED; for (TypeRef tClassR : intersectionTR) { - addIssue(message, tClassR, INTER_ONLY_ONE_CLASS_ALLOWED); + addIssue(tClassR, INTER_ONLY_ONE_CLASS_ALLOWED.toIssueItem()); } } } else { @@ -855,10 +840,9 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { // all common super types, at least Object, as type arg would work! no warning. } else { // instantiation not possible except with undefined - val message = messageForINTER_WITH_ONE_GENERIC; for (TypeRef tClassR : intersectionTR) { if (! (tClassR.eContainer instanceof TypeVariable)) { // nested, type ref coming from def site - addIssue(message, tClassR, INTER_WITH_ONE_GENERIC); + addIssue(tClassR, INTER_WITH_ONE_GENERIC.toIssueItem()); } } } @@ -894,8 +878,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { tClassRefs.removeAll(intersectionTR); for (TypeRef tClassR : tClassRefs) { - val message = messageForINTER_REDUNDANT_SUPERTYPE; - addIssue(message, tClassR, INTER_REDUNDANT_SUPERTYPE); + addIssue(tClassR, INTER_REDUNDANT_SUPERTYPE.toIssueItem()); } } @@ -915,8 +898,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { var haveOptional = false; for (n4TypeParam : genDecl.typeVars) { if (haveOptional && !n4TypeParam.optional) { - val message = messageForTYP_TYPE_PARAM_MANDATORY_AFTER_OPTIONAL; - addIssue(message, n4TypeParam, N4JSPackage.Literals.N4_TYPE_VARIABLE__NAME, TYP_TYPE_PARAM_MANDATORY_AFTER_OPTIONAL); + addIssue(n4TypeParam, N4JSPackage.Literals.N4_TYPE_VARIABLE__NAME, TYP_TYPE_PARAM_MANDATORY_AFTER_OPTIONAL.toIssueItem()); return false; } haveOptional = haveOptional || n4TypeParam.optional; @@ -955,8 +937,7 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { // create error markers if (!forwardReferences.empty) { for (badRef : forwardReferences) { - val message = messageForTYP_TYPE_PARAM_DEFAULT_REFERENCES_LATER_TYPE_PARAM; - addIssue(message, badRef, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF__DECLARED_TYPE, TYP_TYPE_PARAM_DEFAULT_REFERENCES_LATER_TYPE_PARAM); + addIssue(badRef, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF__DECLARED_TYPE, TYP_TYPE_PARAM_DEFAULT_REFERENCES_LATER_TYPE_PARAM.toIssueItem()); } return false; } @@ -974,8 +955,8 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { if (defaultArgInAST !== null && defaultArg !== null && ub !== null) { val result = ts.subtype(G, defaultArg, ub); if (result.failure) { - val message = getMessageForTYP_TYPE_PARAM_DEFAULT_NOT_SUBTYPE_OF_BOUND(n4TypeParam.name, result.compiledFailureMessage); - addIssue(message, n4TypeParam, N4JSPackage.Literals.N4_TYPE_VARIABLE__DECLARED_DEFAULT_ARGUMENT_NODE, TYP_TYPE_PARAM_DEFAULT_NOT_SUBTYPE_OF_BOUND); + val IssueItem issueItem = TYP_TYPE_PARAM_DEFAULT_NOT_SUBTYPE_OF_BOUND.toIssueItem(n4TypeParam.name, result.compiledFailureMessage); + addIssue(n4TypeParam, N4JSPackage.Literals.N4_TYPE_VARIABLE__DECLARED_DEFAULT_ARGUMENT_NODE, issueItem); haveInvalidDefault = true; } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSVariableValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSVariableValidator.xtend index 8de8cbc7d8..15134e5cac 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSVariableValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSVariableValidator.xtend @@ -21,10 +21,11 @@ import org.eclipse.n4js.n4JS.ParenExpression import org.eclipse.n4js.n4JS.VariableDeclaration import org.eclipse.n4js.postprocessing.ASTMetaInfoUtils import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator -import org.eclipse.n4js.validation.IssueCodes import org.eclipse.xtext.validation.Check import org.eclipse.xtext.validation.EValidatorRegistrar +import static org.eclipse.n4js.validation.IssueCodes.* + /** * Validations for variable declarations and variables. */ @@ -47,8 +48,7 @@ class N4JSVariableValidator extends AbstractN4JSDeclarativeValidator { // TODO: GH-331, remove cases where also the 'UsedBeforeDeclared' issue is raised val refs = varDecl.expression.collectIdentifierRefsTo(varDecl,newArrayList); for(IdentifierRef currRef : refs) { - val message = IssueCodes.getMessageForAST_VAR_DECL_RECURSIVE(varDecl.name) - addIssue(message, currRef, null, IssueCodes.AST_VAR_DECL_RECURSIVE) + addIssue(currRef, null, AST_VAR_DECL_RECURSIVE.toIssueItem(varDecl.name)); } } } @@ -61,8 +61,7 @@ class N4JSVariableValidator extends AbstractN4JSDeclarativeValidator { val tVariable = varDecl.definedVariable; if (tVariable !== null && ASTMetaInfoUtils.getLocalVariableReferences(tVariable).empty) { - val message = IssueCodes.getMessageForCFG_LOCAL_VAR_UNUSED(varDecl.name); - addIssue(message, varDecl, findNameFeature(varDecl).value, IssueCodes.CFG_LOCAL_VAR_UNUSED); // deactivated during tests + addIssue(varDecl, findNameFeature(varDecl).value, CFG_LOCAL_VAR_UNUSED.toIssueItem(varDecl.name)); // deactivated during tests } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSXValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSXValidator.xtend index b957b9f799..ce7a7cace4 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSXValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSXValidator.xtend @@ -37,7 +37,7 @@ import org.eclipse.n4js.typesystem.N4JSTypeSystem import org.eclipse.n4js.typesystem.utils.TypeSystemHelper import org.eclipse.n4js.utils.ResourceType import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator -import org.eclipse.n4js.validation.IssueCodes +import org.eclipse.n4js.validation.IssueItem import org.eclipse.xtext.validation.Check import org.eclipse.xtext.validation.EValidatorRegistrar @@ -77,8 +77,7 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { if (resType == ResourceType.N4JSX || resType == ResourceType.JSX) { return; } - val message = getMessageForJSX_JSXELEMENT_IN_NON_JSX_RESOURCE(resType.name) - addIssue(message,jsxElem, JSX_JSXELEMENT_IN_NON_JSX_RESOURCE); + addIssue(jsxElem, JSX_JSXELEMENT_IN_NON_JSX_RESOURCE.toIssueItem(resType.name)); } @@ -97,7 +96,7 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { val firstJSXAbstractElement = script.eAllContents.findFirst[it instanceof JSXAbstractElement] if (firstJSXAbstractElement !== null && reactHelper.getJsxBackendModule(script.eResource) === null) - addIssue(getMessageForJSX_REACT_NOT_RESOLVED(), firstJSXAbstractElement, JSX_REACT_NOT_RESOLVED); + addIssue(firstJSXAbstractElement, JSX_REACT_NOT_RESOLVED.toIssueItem()); } /** Make sure the namespace to react module is React. */ @@ -112,9 +111,7 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { val importedModule = importSpecifier.importedModule; if (reactModule !== null && importedModule === reactModule) { if (importSpecifier.alias != ReactHelper.REACT_NAMESPACE_NAME) { - addIssue( - getMessageForJSX_REACT_NAMESPACE_NOT_ALLOWED(), - importSpecifier, JSX_REACT_NAMESPACE_NOT_ALLOWED); + addIssue(importSpecifier, JSX_REACT_NAMESPACE_NOT_ALLOWED.toIssueItem()); } } } @@ -131,12 +128,10 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { if ((jsxElem.jsxClosingName !==null) && !(openingName == closingName)) { //Only check if the closing element exists, e.g. not null - val message = getMessageForJSX_JSXELEMENT_OPENING_CLOSING_ELEMENT_NOT_MATCH(openingName, closingName); addIssue( - message, jsxElem, JSX_ELEMENT__JSX_CLOSING_NAME, - JSX_JSXELEMENT_OPENING_CLOSING_ELEMENT_NOT_MATCH + JSX_JSXELEMENT_OPENING_CLOSING_ELEMENT_NOT_MATCH.toIssueItem(openingName, closingName) ); } } @@ -160,12 +155,10 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { // If the JSX element name starts with lower case, warning if it is unknown HTML tag if (!N4JSGlobals.HTML_TAGS.contains(refName) && !N4JSGlobals.SVG_TAGS.contains(refName)) { - val message = getMessageForJSX_TAG_UNKNOWN(refName); addIssue( - message, jsxElem, JSX_ELEMENT__JSX_ELEMENT_NAME, - JSX_TAG_UNKNOWN + JSX_TAG_UNKNOWN.toIssueItem(refName) ); } } else if (G.isAnyDynamic(exprTypeRef)) { @@ -176,13 +169,11 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { ) { // JSX element name starts with an upper case, error because it does not bind to a class or function // See Req. IDE-241115 - val message = getMessageForJSX_REACT_ELEMENT_CLASS_MUST_NOT_BE_ABSTRACT(); - addIssue(message, expr, JSX_REACT_ELEMENT_CLASS_MUST_NOT_BE_ABSTRACT); + addIssue(expr, JSX_REACT_ELEMENT_CLASS_MUST_NOT_BE_ABSTRACT.toIssueItem()); } else { // JSX element name starts with an upper case, error because it does not bind to a class or function // See Req. IDE-241115 - val message = getMessageForJSX_REACT_ELEMENT_NOT_FUNCTION_OR_CLASS_ERROR(exprTypeRef.typeRefAsString); - addIssue(message, expr, JSX_REACT_ELEMENT_NOT_FUNCTION_OR_CLASS_ERROR); + addIssue(expr, JSX_REACT_ELEMENT_NOT_FUNCTION_OR_CLASS_ERROR.toIssueItem(exprTypeRef.typeRefAsString)); } return; } @@ -210,20 +201,16 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { val String refName = expr.refName if ((refName !== null) && (!refName.isEmpty) && Character::isLowerCase(refName.charAt(0))) { if (isFunctionalComponent) { - val message = getMessageForJSX_REACT_FUNCTIONAL_COMPONENT_CANNOT_START_WITH_LOWER_CASE(refName); addIssue( - message, jsxElem, JSX_ELEMENT__JSX_ELEMENT_NAME, - JSX_REACT_FUNCTIONAL_COMPONENT_CANNOT_START_WITH_LOWER_CASE + JSX_REACT_FUNCTIONAL_COMPONENT_CANNOT_START_WITH_LOWER_CASE.toIssueItem(refName) ); } else { - val message = IssueCodes.getMessageForJSX_REACT_CLASS_COMPONENT_CANNOT_START_WITH_LOWER_CASE(refName); addIssue( - message, jsxElem, JSX_ELEMENT__JSX_ELEMENT_NAME, - JSX_REACT_CLASS_COMPONENT_CANNOT_START_WITH_LOWER_CASE + JSX_REACT_CLASS_COMPONENT_CANNOT_START_WITH_LOWER_CASE.toIssueItem(refName) ); } } @@ -245,15 +232,11 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { val actualReturnTypeRef = exprTypeRef.returnTypeRef; val result = ts.subtype(G, actualReturnTypeRef, expectedReturnTypeRef); if (result.failure) { - val message = IssueCodes.getMessageForJSX_REACT_ELEMENT_FUNCTION_NOT_REACT_ELEMENT_ERROR( + val IssueItem issueItem = JSX_REACT_ELEMENT_FUNCTION_NOT_REACT_ELEMENT_ERROR.toIssueItem( expectedReturnTypeRef.typeRefAsString, actualReturnTypeRef.typeRefAsString ); - addIssue( - message, - expr, - JSX_REACT_ELEMENT_FUNCTION_NOT_REACT_ELEMENT_ERROR - ); + addIssue(expr, issueItem); } } @@ -274,8 +257,7 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { val actualTypeRef = TypeUtils.createTypeRef(tclass, TypingStrategy.DEFAULT, true); val resultSubType = ts.subtype(G, actualTypeRef, expectedTypeRef) if (resultSubType.failure) { - val message = getMessageForJSX_REACT_ELEMENT_CLASS_NOT_REACT_ELEMENT_ERROR(); - addIssue(message, expr, JSX_REACT_ELEMENT_CLASS_NOT_REACT_ELEMENT_ERROR); + addIssue(expr, JSX_REACT_ELEMENT_CLASS_NOT_REACT_ELEMENT_ERROR.toIssueItem()); } } @@ -295,14 +277,13 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { //they are mainly intended for error cases, not valid code. Probably it should be any+ instead. //This requires refactoring else where if (result instanceof UnknownTypeRef) { - val message = IssueCodes.getMessageForJSX_JSXSPROPERTYATTRIBUTE_NOT_DECLARED_IN_PROPS(propertyAttribute.propertyAsText, + val IssueItem issueItem = JSX_JSXSPROPERTYATTRIBUTE_NOT_DECLARED_IN_PROPS.toIssueItem(propertyAttribute.propertyAsText, jsxElem?.jsxElementName?.expression?.refName); - addIssue( - message, - propertyAttribute, - JSX_PROPERTY_ATTRIBUTE__PROPERTY, - JSX_JSXSPROPERTYATTRIBUTE_NOT_DECLARED_IN_PROPS - ); + addIssue( + propertyAttribute, + JSX_PROPERTY_ATTRIBUTE__PROPERTY, + issueItem + ); } } @@ -341,13 +322,12 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { val fieldOrGetterInPropsTypeRef = ts.tau(fieldOrGetterInProps, propsType); val result = ts.subtype(G, attributeInSpreadOperatorTypeRef, fieldOrGetterInPropsTypeRef); if (result.failure) { - val message = IssueCodes.getMessageForJSX_JSXSPREADATTRIBUTE_WRONG_SUBTYPE(attributeInSpreadOperator.name, + val IssueItem issueItem = JSX_JSXSPREADATTRIBUTE_WRONG_SUBTYPE.toIssueItem(attributeInSpreadOperator.name, attributeInSpreadOperatorTypeRef.typeRefAsString, fieldOrGetterInPropsTypeRef.typeRefAsString); addIssue( - message, spreadAttribute, JSX_SPREAD_ATTRIBUTE__EXPRESSION, - IssueCodes.JSX_JSXSPREADATTRIBUTE_WRONG_SUBTYPE + issueItem ); } } @@ -365,13 +345,11 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { return; if (elem.name == ReactHelper.REACT_NAMESPACE_NAME) { - val message = IssueCodes.getMessageForJSX_NAME_CANNOT_BE_REACT(); - addIssue( - message, - elem, - findNameFeature(elem).value, - IssueCodes.JSX_NAME_CANNOT_BE_REACT - ); + addIssue( + elem, + findNameFeature(elem).value, + JSX_NAME_CANNOT_BE_REACT.toIssueItem() + ); } } @@ -408,13 +386,10 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { ].map [ fieldOrGetter | fieldOrGetter.name ].join(","); if (!missingFieldsStringRep.isEmpty) { - val message = IssueCodes. - getMessageForJSX_JSXPROPERTY_ATTRIBUTE_NON_OPTIONAL_PROPERTY_NOT_SPECIFIED(missingFieldsStringRep); addIssue( - message, jsxElem, JSX_ELEMENT__JSX_ELEMENT_NAME, - JSX_JSXPROPERTY_ATTRIBUTE_NON_OPTIONAL_PROPERTY_NOT_SPECIFIED + JSX_JSXPROPERTY_ATTRIBUTE_NON_OPTIONAL_PROPERTY_NOT_SPECIFIED.toIssueItem(missingFieldsStringRep) ); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/PolyfillValidatorFragment.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/PolyfillValidatorFragment.java index bcbbd81214..71fbb8d08e 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/PolyfillValidatorFragment.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/PolyfillValidatorFragment.java @@ -24,6 +24,7 @@ import static org.eclipse.n4js.validation.IssueCodes.CLF_POLYFILL_EXTEND_MISSING; import static org.eclipse.n4js.validation.IssueCodes.CLF_POLYFILL_FILLED_NOT_PROVIDEDBYRUNTIME; import static org.eclipse.n4js.validation.IssueCodes.CLF_POLYFILL_INCOMPLETE_TYPEARGS; +import static org.eclipse.n4js.validation.IssueCodes.CLF_POLYFILL_MULTIPOLYFILLS_MEMBER_CONFLICT; import static org.eclipse.n4js.validation.IssueCodes.CLF_POLYFILL_NOT_DIRECTLY_EXPORTED; import static org.eclipse.n4js.validation.IssueCodes.CLF_POLYFILL_NOT_PROVIDEDBYRUNTIME; import static org.eclipse.n4js.validation.IssueCodes.CLF_POLYFILL_NO_EXTENDS_ADDITIONAL; @@ -32,23 +33,6 @@ import static org.eclipse.n4js.validation.IssueCodes.CLF_POLYFILL_STATIC_FILLED_TYPE_NOT_AWARE; import static org.eclipse.n4js.validation.IssueCodes.CLF_POLYFILL_TYPEPARS_DIFFER_TYPEARGS; import static org.eclipse.n4js.validation.IssueCodes.POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_DIFFERENT_CLASSIFIER_KIND; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_DIFFERENT_GLOBALS; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_DIFFERENT_MODIFIER; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_DIFFERENT_MODULE_SPECIFIER; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_DIFFERENT_NAME; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_DIFFERENT_TYPEPARS; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_EXTEND_MISSING; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_FILLED_NOT_PROVIDEDBYRUNTIME; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_INCOMPLETE_TYPEARGS; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_NOT_DIRECTLY_EXPORTED; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_NOT_PROVIDEDBYRUNTIME; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_NO_EXTENDS_ADDITIONAL; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_NO_IMPLEMENTS; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_STATIC_DIFFERENT_VARIANT; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_STATIC_FILLED_TYPE_NOT_AWARE; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForCLF_POLYFILL_TYPEPARS_DIFFER_TYPEARGS; -import static org.eclipse.n4js.validation.IssueCodes.getMessageForPOLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES; import java.util.ArrayList; import java.util.Collections; @@ -79,7 +63,7 @@ import org.eclipse.n4js.ts.types.TypesPackage; import org.eclipse.n4js.ts.types.TypingStrategy; import org.eclipse.n4js.utils.N4JSLanguageUtils; -import org.eclipse.n4js.validation.IssueCodes; +import org.eclipse.n4js.validation.IssueItem; import org.eclipse.n4js.validation.N4JSElementKeywordProvider; import org.eclipse.xtext.naming.IQualifiedNameProvider; import org.eclipse.xtext.resource.IContainer; @@ -130,8 +114,8 @@ private static class PolyfillValidationState { String name; } - private void addIssue(PolyfillValidationState state, String msg, String issueCode) { - state.host.addIssue(msg, state.n4Classifier, N4_TYPE_DECLARATION__NAME, issueCode); + private void addIssue(PolyfillValidationState state, IssueItem issueItem) { + state.host.addIssue(issueItem.message, state.n4Classifier, N4_TYPE_DECLARATION__NAME, issueItem.getID()); } /** @@ -206,8 +190,8 @@ && holdsSinglePolyfillSource(state))) // // § 140.1 only static polyfills are allowed in StaticPolyfillModule. if (!isStaticPolyFill && isContainedInStaticPolyfillModule(n4Classifier)) { // n4Classifier is top-level by default - validator.addIssue(getMessageForPOLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES(), n4Classifier, - N4_TYPE_DECLARATION__NAME, POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES); + validator.addIssue(POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES.getMessage(), n4Classifier, + N4_TYPE_DECLARATION__NAME, POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES.name()); return false; } @@ -220,8 +204,7 @@ && holdsSinglePolyfillSource(state))) // private boolean holdsFilledClassIsStaticPolyfillAware(PolyfillValidationState state) { if (!(isContainedInStaticPolyfillAware(state.filledType))) { // (Static Polyfill) 139.5 - final String msg = getMessageForCLF_POLYFILL_STATIC_FILLED_TYPE_NOT_AWARE(state.name); - addIssue(state, msg, CLF_POLYFILL_STATIC_FILLED_TYPE_NOT_AWARE); + addIssue(state, CLF_POLYFILL_STATIC_FILLED_TYPE_NOT_AWARE.toIssueItem(state.name)); return false; } @@ -238,8 +221,7 @@ private boolean holdsSameJavascriptVariant(PolyfillValidationState state) { && fillerModule.isN4jsdModule() != filledModule.isN4jsdModule()) { final String fileExt = fillerModule.isN4jsdModule() ? N4JSGlobals.N4JSD_FILE_EXTENSION : N4JSGlobals.N4JS_FILE_EXTENSION; - final String msg = getMessageForCLF_POLYFILL_STATIC_DIFFERENT_VARIANT(state.name, "." + fileExt); - addIssue(state, msg, CLF_POLYFILL_STATIC_DIFFERENT_VARIANT); + addIssue(state, CLF_POLYFILL_STATIC_DIFFERENT_VARIANT.toIssueItem(state.name, "." + fileExt)); return false; } return true; @@ -251,9 +233,8 @@ private boolean holdsSameJavascriptVariant(PolyfillValidationState state) { private boolean holdsExplicitExtends(PolyfillValidationState state) { final TypeReferenceNode filledTypeRef = state.superClassifierNode; if (filledTypeRef == null) { // (Polyfill Class) 156.1 - final String msg = getMessageForCLF_POLYFILL_EXTEND_MISSING(state.name, - keywordProvider.keywordWithIndefiniteArticle(state.polyType)); - addIssue(state, msg, CLF_POLYFILL_EXTEND_MISSING); + addIssue(state, CLF_POLYFILL_EXTEND_MISSING.toIssueItem(state.name, + keywordProvider.keywordWithIndefiniteArticle(state.polyType))); return false; } return true; @@ -261,11 +242,10 @@ private boolean holdsExplicitExtends(PolyfillValidationState state) { private boolean holdPolyfillClassifierKind(PolyfillValidationState state) { if (state.polyType.eClass() != state.filledType.eClass()) { - final String msg = getMessageForCLF_POLYFILL_DIFFERENT_CLASSIFIER_KIND( + addIssue(state, CLF_POLYFILL_DIFFERENT_CLASSIFIER_KIND.toIssueItem( keywordProvider.keyword(state.filledType), state.name, keywordProvider.keywordWithIndefiniteArticle(state.filledType), - keywordProvider.keywordWithIndefiniteArticle(state.polyType)); - addIssue(state, msg, CLF_POLYFILL_DIFFERENT_CLASSIFIER_KIND); + keywordProvider.keywordWithIndefiniteArticle(state.polyType))); return false; } return true; @@ -276,17 +256,16 @@ private boolean holdPolyfillClassifierKind(PolyfillValidationState state) { */ private boolean holdPolyfillName(PolyfillValidationState state) { if (!state.name.equals(state.filledType.getName())) { // (Polyfill Class) 156.2 - final String msg = getMessageForCLF_POLYFILL_DIFFERENT_NAME(state.name, - keywordProvider.keyword(state.filledType), state.filledType.getName()); - addIssue(state, msg, CLF_POLYFILL_DIFFERENT_NAME); + addIssue(state, CLF_POLYFILL_DIFFERENT_NAME.toIssueItem(state.name, + keywordProvider.keyword(state.filledType), state.filledType.getName())); return false; } final boolean isGlobalFilled = GLOBAL.hasAnnotation(state.filledType); final boolean isGlobalPoly = GLOBAL.hasAnnotation(state.polyType); if (isGlobalFilled != isGlobalPoly) { // (Polyfill Class) 156.2 - final String msg = getMessageForCLF_POLYFILL_DIFFERENT_GLOBALS( + IssueItem issueItem = CLF_POLYFILL_DIFFERENT_GLOBALS.toIssueItem( state.name, isGlobalPoly ? "global" : "not global", isGlobalFilled ? "global" : "not global"); - addIssue(state, msg, CLF_POLYFILL_DIFFERENT_GLOBALS); + addIssue(state, issueItem); return false; } if (!isGlobalFilled) { @@ -295,10 +274,11 @@ private boolean holdPolyfillName(PolyfillValidationState state) { if (polyModule != null && filledModule != null) { // avoid consequential errors if (!polyModule.getModuleSpecifier().equals(filledModule.getModuleSpecifier())) { // (Polyfill Class) // 156.2 - final String msg = getMessageForCLF_POLYFILL_DIFFERENT_MODULE_SPECIFIER(state.name, + final IssueItem issueItem = CLF_POLYFILL_DIFFERENT_MODULE_SPECIFIER.toIssueItem( + state.name, polyModule.getModuleSpecifier(), filledModule.getModuleSpecifier()); - addIssue(state, msg, CLF_POLYFILL_DIFFERENT_MODULE_SPECIFIER); + addIssue(state, issueItem); return false; } } @@ -311,13 +291,11 @@ private boolean holdPolyfillName(PolyfillValidationState state) { */ private boolean holdsProvidedByRuntime(PolyfillValidationState state) { if (!state.polyType.isProvidedByRuntime()) { - final String msg = getMessageForCLF_POLYFILL_NOT_PROVIDEDBYRUNTIME(state.name); - addIssue(state, msg, CLF_POLYFILL_NOT_PROVIDEDBYRUNTIME); + addIssue(state, CLF_POLYFILL_NOT_PROVIDEDBYRUNTIME.toIssueItem(state.name)); return false; } if (!state.filledType.isProvidedByRuntime()) { - final String msg = getMessageForCLF_POLYFILL_FILLED_NOT_PROVIDEDBYRUNTIME(state.name); - addIssue(state, msg, CLF_POLYFILL_FILLED_NOT_PROVIDEDBYRUNTIME); + addIssue(state, CLF_POLYFILL_FILLED_NOT_PROVIDEDBYRUNTIME.toIssueItem(state.name)); return false; } @@ -330,14 +308,12 @@ private boolean holdsProvidedByRuntime(PolyfillValidationState state) { private boolean holdsNoImplementsOrConsumes(PolyfillValidationState state) { if (state.n4Classifier instanceof N4ClassDeclaration) { if (!((N4ClassDeclaration) state.n4Classifier).getImplementedInterfaceRefs().isEmpty()) { - final String msg = getMessageForCLF_POLYFILL_NO_IMPLEMENTS(state.name); - addIssue(state, msg, CLF_POLYFILL_NO_IMPLEMENTS); + addIssue(state, CLF_POLYFILL_NO_IMPLEMENTS.toIssueItem(state.name)); return false; } } else if (state.n4Classifier instanceof N4InterfaceDeclaration) { if (((N4InterfaceDeclaration) state.n4Classifier).getSuperInterfaceRefs().size() > 1) { - final String msg = getMessageForCLF_POLYFILL_NO_EXTENDS_ADDITIONAL(state.name); - addIssue(state, msg, CLF_POLYFILL_NO_EXTENDS_ADDITIONAL); + addIssue(state, CLF_POLYFILL_NO_EXTENDS_ADDITIONAL.toIssueItem(state.name)); return false; } } @@ -346,8 +322,7 @@ private boolean holdsNoImplementsOrConsumes(PolyfillValidationState state) { private boolean holdsIsDirectlyExported(PolyfillValidationState state) { if (!state.polyType.isDirectlyExported()) { - final String msg = getMessageForCLF_POLYFILL_NOT_DIRECTLY_EXPORTED(state.name); - addIssue(state, msg, CLF_POLYFILL_NOT_DIRECTLY_EXPORTED); + addIssue(state, CLF_POLYFILL_NOT_DIRECTLY_EXPORTED.toIssueItem(state.name)); return false; } return true; @@ -359,11 +334,11 @@ private boolean holdsIsDirectlyExported(PolyfillValidationState state) { private boolean holdsEqualModifiers(PolyfillValidationState state) { boolean result = true; if (state.polyType.getTypeAccessModifier() != state.filledType.getTypeAccessModifier()) { - final String msg = getMessageForCLF_POLYFILL_DIFFERENT_MODIFIER(state.name, + final IssueItem issueItem = CLF_POLYFILL_DIFFERENT_MODIFIER.toIssueItem(state.name, keywordProvider.keyword(state.polyType.getTypeAccessModifier()), keywordProvider.keyword(state.filledType.getTypeAccessModifier()), keywordProvider.keyword(state.filledType)); - addIssue(state, msg, CLF_POLYFILL_DIFFERENT_MODIFIER); + addIssue(state, issueItem); result = false; } result &= holdsEqualModifier(state, "abstract", state.polyType.isAbstract(), state.filledType.isAbstract()); @@ -376,11 +351,11 @@ private boolean holdsEqualModifiers(PolyfillValidationState state) { private boolean holdsEqualModifier(PolyfillValidationState state, String modifierName, boolean poly, boolean filled) { if (poly != filled) { - final String msg = getMessageForCLF_POLYFILL_DIFFERENT_MODIFIER(state.name, + final IssueItem issueItem = CLF_POLYFILL_DIFFERENT_MODIFIER.toIssueItem(state.name, (poly ? "" : "non-") + modifierName, (filled ? "" : "non-") + modifierName, keywordProvider.keyword(state.filledType)); - addIssue(state, msg, CLF_POLYFILL_DIFFERENT_MODIFIER); + addIssue(state, issueItem); return false; } return true; @@ -391,11 +366,11 @@ private boolean holdsEqualTypingStrategy(PolyfillValidationState state, TypingSt poly = poly == TypingStrategy.DEFAULT ? TypingStrategy.NOMINAL : poly; filled = filled == TypingStrategy.DEFAULT ? TypingStrategy.NOMINAL : filled; if (poly != filled) { - final String msg = getMessageForCLF_POLYFILL_DIFFERENT_MODIFIER(state.name, + final IssueItem issueItem = CLF_POLYFILL_DIFFERENT_MODIFIER.toIssueItem(state.name, (poly != TypingStrategy.NOMINAL ? "definition-site " : "") + keywordProvider.keyword(poly), (filled != TypingStrategy.NOMINAL ? "definition-site " : "") + keywordProvider.keyword(filled), keywordProvider.keyword(state.filledType)); - addIssue(state, msg, CLF_POLYFILL_DIFFERENT_MODIFIER); + addIssue(state, issueItem); return false; } return true; @@ -411,9 +386,9 @@ private boolean holdsEqualTypeVariables(PolyfillValidationState state) { final String typeVars2 = Joiner.on(',').join( state.filledType.getTypeVars().stream().map(v -> v.getTypeAsString()).toArray()); if (!typeVars1.equals(typeVars2)) { - final String msg = getMessageForCLF_POLYFILL_DIFFERENT_TYPEPARS(state.name, + final IssueItem issueItem = CLF_POLYFILL_DIFFERENT_TYPEPARS.toIssueItem(state.name, keywordProvider.keyword(state.filledType)); - addIssue(state, msg, CLF_POLYFILL_DIFFERENT_TYPEPARS); + addIssue(state, issueItem); return false; } @@ -428,8 +403,8 @@ private boolean holdsEqualTypeVariables(PolyfillValidationState state) { if (args.size() < expectedTypeParamCountMin || args.size() > expectedTypeParamCountMax) { return true; // consequential error } else if (args.size() != expectedTypeParamCountMax) { - final String msg = getMessageForCLF_POLYFILL_INCOMPLETE_TYPEARGS(state.name); - addIssue(state, msg, CLF_POLYFILL_INCOMPLETE_TYPEARGS); + final IssueItem issueItem = CLF_POLYFILL_INCOMPLETE_TYPEARGS.toIssueItem(state.name); + addIssue(state, issueItem); return false; } for (int i = state.polyType.getTypeVars().size() - 1; i >= 0; i--) { @@ -438,8 +413,9 @@ private boolean holdsEqualTypeVariables(PolyfillValidationState state) { String argString = arg.getTypeRefAsString(); String parString = par.getName(); if (!argString.equals(parString)) { - final String msg = getMessageForCLF_POLYFILL_TYPEPARS_DIFFER_TYPEARGS(state.name, parString, argString); - addIssue(state, msg, CLF_POLYFILL_TYPEPARS_DIFFER_TYPEARGS); + final IssueItem issueItem = CLF_POLYFILL_TYPEPARS_DIFFER_TYPEARGS.toIssueItem(state.name, parString, + argString); + addIssue(state, issueItem); return false; } } @@ -522,9 +498,10 @@ private boolean holdsSinglePolyfillSource(PolyfillValidationState state) { String memberAxis = myMember.getContainingType().getName() + "." + myMember.getName(); // Issue on filled Member-name declaration: - String msg = IssueCodes.getMessageForCLF_POLYFILL_MULTIPOLYFILLS_MEMBER_CONFLICT(uris, memberAxis); - state.host.addIssue(msg, myMember.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, - IssueCodes.CLF_POLYFILL_MULTIPOLYFILLS_MEMBER_CONFLICT); + IssueItem issueItem = CLF_POLYFILL_MULTIPOLYFILLS_MEMBER_CONFLICT.toIssueItem(uris, memberAxis); + state.host.addIssue(issueItem.message, myMember.getAstElement(), + N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, + issueItem.getID()); } return true; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/RuntimeDependencyValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/RuntimeDependencyValidator.xtend index ae4dfd4bc1..ec0ad75891 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/RuntimeDependencyValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/RuntimeDependencyValidator.xtend @@ -24,12 +24,12 @@ import org.eclipse.n4js.postprocessing.RuntimeDependencyProcessor import org.eclipse.n4js.resource.N4JSResource import org.eclipse.n4js.ts.types.TModule import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator -import org.eclipse.n4js.validation.IssueCodes import org.eclipse.xtext.EcoreUtil2 import org.eclipse.xtext.validation.Check import org.eclipse.xtext.validation.EValidatorRegistrar import static org.eclipse.n4js.utils.N4JSLanguageUtils.* +import static org.eclipse.n4js.validation.IssueCodes.* /** * Validations related to runtime dependencies (in particular, illegal load-time dependency cycles). @@ -68,9 +68,8 @@ class RuntimeDependencyValidator extends AbstractN4JSDeclarativeValidator { val hasCycle = (targetModule === containingModule && !containingModule.cyclicModulesRuntime.empty) || (targetModule !== containingModule && containingModule.cyclicModulesRuntime.contains(targetModule)); if (hasCycle) { - val message = IssueCodes.getMessageForLTD_ILLEGAL_LOADTIME_REFERENCE() - + '\n' + dependencyCycleToString(containingModule, false, INDENT); - addIssue(message, idRef, IssueCodes.LTD_ILLEGAL_LOADTIME_REFERENCE); + val cycleStr = '\n' + dependencyCycleToString(containingModule, false, INDENT); + addIssue(idRef, LTD_ILLEGAL_LOADTIME_REFERENCE.toIssueItem(cycleStr)); } } @@ -105,9 +104,8 @@ class RuntimeDependencyValidator extends AbstractN4JSDeclarativeValidator { def private boolean holdsNotAnIllegalModuleRefWithinLoadtimeCycle(TModule containingModule, ModuleRef moduleRef) { val targetModule = moduleRef.module; if (containingModule.cyclicModulesLoadtimeForInheritance.contains(targetModule)) { - val message = IssueCodes.getMessageForLTD_LOADTIME_DEPENDENCY_CYCLE() + "\n" - + dependencyCycleToString(targetModule, true, INDENT); - addIssue(message, moduleRef, N4JSPackage.eINSTANCE.moduleRef_Module, IssueCodes.LTD_LOADTIME_DEPENDENCY_CYCLE); + val cycleStr = "\n" + dependencyCycleToString(targetModule, true, INDENT); + addIssue(moduleRef, N4JSPackage.eINSTANCE.moduleRef_Module, LTD_LOADTIME_DEPENDENCY_CYCLE.toIssueItem(cycleStr)); return false; } return true; @@ -143,18 +141,14 @@ class RuntimeDependencyValidator extends AbstractN4JSDeclarativeValidator { // ERROR: referring to a multi-LTD-target from within the dependency cycle cluster (Req. GH-1678, Constraint 2) // --> load-time dependency conflict val otherLTDSources = otherLTDSourcesToString(containingModule, targetModule); - val message = IssueCodes.getMessageForLTD_LOADTIME_DEPENDENCY_CONFLICT(targetModule.simpleName, otherLTDSources) + "\n" - + "Containing runtime dependency cycle cluster:\n" - + dependencyCycleToString(targetModule, false, INDENT); - addIssue(message, moduleRef, N4JSPackage.eINSTANCE.moduleRef_Module, IssueCodes.LTD_LOADTIME_DEPENDENCY_CONFLICT); + val cycleStr = "\nContaining runtime dependency cycle cluster:\n" + dependencyCycleToString(targetModule, false, INDENT); + addIssue(moduleRef, N4JSPackage.eINSTANCE.moduleRef_Module, LTD_LOADTIME_DEPENDENCY_CONFLICT.toIssueItem(targetModule.simpleName, otherLTDSources, cycleStr)); return false; } else { // ERROR: referring to an LTD target from outside the dependency cycle cluster (Req. GH-1678, Constraint 3) val healingModulesStr = healingModulesToString(targetModule); - val message = IssueCodes.getMessageForLTD_REFERENCE_TO_LOADTIME_DEPENDENCY_TARGET(targetModule.simpleName, healingModulesStr) + "\n" - + "Containing runtime dependency cycle cluster:\n" - + dependencyCycleToString(targetModule, false, INDENT); - addIssue(message, moduleRef, N4JSPackage.eINSTANCE.moduleRef_Module, IssueCodes.LTD_REFERENCE_TO_LOADTIME_DEPENDENCY_TARGET); + val cycleStr = "\nContaining runtime dependency cycle cluster:\n" + dependencyCycleToString(targetModule, false, INDENT); + addIssue(moduleRef, N4JSPackage.eINSTANCE.moduleRef_Module, LTD_REFERENCE_TO_LOADTIME_DEPENDENCY_TARGET.toIssueItem(targetModule.simpleName, healingModulesStr, cycleStr)); return true; // because we assume a healing import will be added by transpiler, this module reference can be treated as healing in calling method } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/StaticPolyfillValidatorExtension.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/StaticPolyfillValidatorExtension.xtend index 6493f59c1c..3f8fddb082 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/StaticPolyfillValidatorExtension.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/StaticPolyfillValidatorExtension.xtend @@ -16,9 +16,9 @@ import org.eclipse.n4js.n4JS.N4EnumDeclaration import org.eclipse.n4js.n4JS.N4InterfaceDeclaration import org.eclipse.n4js.n4JS.N4JSPackage import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.validation.IssueCodes import org.eclipse.n4js.n4JS.N4ClassDeclaration +import static org.eclipse.n4js.validation.IssueCodes.* import static extension org.eclipse.n4js.utils.N4JSLanguageUtils.* /** @@ -30,9 +30,8 @@ public class StaticPolyfillValidatorExtension { /** §143 (Restriction on static-polyfilling): §143.1 only classes in staticPolyfillModule allowed. */ public static def internalCheckNotInStaticPolyfillModule(N4InterfaceDeclaration n4InterfaceDeclaration, N4JSInterfaceValidator host) { if (n4InterfaceDeclaration.isContainedInStaticPolyfillModule) { - val msg = IssueCodes.messageForPOLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES; - host.addIssue(msg, n4InterfaceDeclaration, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, - IssueCodes.POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES); + host.addIssue(n4InterfaceDeclaration, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, + POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES.toIssueItem()); } } @@ -40,9 +39,8 @@ public class StaticPolyfillValidatorExtension { /** §143 (Restriction on static-polyfilling): §143.1 only classes in staticPolyfillModule allowed. */ public static def internalCheckNotInStaticPolyfillModule(N4EnumDeclaration n4EnumDecl, N4JSEnumValidator host) { if (n4EnumDecl.isContainedInStaticPolyfillModule) { - val msg = IssueCodes.messageForPOLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES; - host.addIssue(msg, n4EnumDecl, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, - IssueCodes.POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES); + host.addIssue(n4EnumDecl, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, + POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES.toIssueItem()); } } @@ -54,9 +52,8 @@ public class StaticPolyfillValidatorExtension { if( cont instanceof Script) { if ( functionDeclaration.isContainedInStaticPolyfillModule ) { - val msg = IssueCodes.messageForPOLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES; - host.addIssue(msg, functionDeclaration, N4JSPackage.Literals.FUNCTION_DECLARATION__NAME, - IssueCodes.POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES); + host.addIssue(functionDeclaration, N4JSPackage.Literals.FUNCTION_DECLARATION__NAME, + POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES.toIssueItem()); } } } @@ -65,10 +62,8 @@ public class StaticPolyfillValidatorExtension { public static def internalCheckPolyFilledClassWithAdditionalInterface(N4ClassDeclaration classDeclaration, N4JSClassValidator host) { if( classDeclaration.isStaticPolyfill ) { if( ! classDeclaration.implementedInterfaceRefs.isEmpty ) { - val msg = IssueCodes.messageForPOLY_IMPLEMENTING_INTERFACE_NOT_ALLOWED; - host.addIssue(msg, classDeclaration, N4JSPackage.Literals.N4_CLASS_DEFINITION__IMPLEMENTED_INTERFACE_REFS, - IssueCodes.POLY_IMPLEMENTING_INTERFACE_NOT_ALLOWED); - + host.addIssue(classDeclaration, N4JSPackage.Literals.N4_CLASS_DEFINITION__IMPLEMENTED_INTERFACE_REFS, + POLY_IMPLEMENTING_INTERFACE_NOT_ALLOWED.toIssueItem()); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/ThirdPartyValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/ThirdPartyValidator.xtend index 7f7fbcefa3..447b7ae056 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/ThirdPartyValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/ThirdPartyValidator.xtend @@ -52,9 +52,7 @@ class ThirdPartyValidator extends AbstractN4JSDeclarativeValidator { || stmnt.varStmtKeyword === VariableStatementKeyword.CONST) { for (varDecl : stmnt.varDecl) { if (varDecl.name == funName) { - addIssue(messageForTHIRD_PARTY_BABEL_LET_CONST_IN_FUN_EXPR, - varDecl, N4JSPackage.eINSTANCE.abstractVariable_Name, - THIRD_PARTY_BABEL_LET_CONST_IN_FUN_EXPR); + addIssue(varDecl, N4JSPackage.eINSTANCE.abstractVariable_Name, THIRD_PARTY_BABEL_LET_CONST_IN_FUN_EXPR.toIssueItem()); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/UnsupportedFeatureValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/UnsupportedFeatureValidator.xtend index 2b7faf98b6..52c78939c8 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/UnsupportedFeatureValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/UnsupportedFeatureValidator.xtend @@ -30,13 +30,13 @@ 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.IssueCodes 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 static org.eclipse.n4js.utils.N4JSLanguageUtils.* +import static org.eclipse.n4js.validation.IssueCodes.* /** * Validations to show an error for unsupported language features, mostly ECMAScript6 features. @@ -167,16 +167,14 @@ class UnsupportedFeatureValidator extends AbstractN4JSDeclarativeValidator { } def private void unsupported(String msg, EObject source, EStructuralFeature feature) { addIssue( - IssueCodes.getMessageForUNSUPPORTED(msg), source, feature, - IssueCodes.UNSUPPORTED); + UNSUPPORTED.toIssueItem(msg)); } def private void unsupported(String msg, EObject source, int offset, int length) { addIssue( - IssueCodes.getMessageForUNSUPPORTED(msg), source, offset, length, - IssueCodes.UNSUPPORTED); + UNSUPPORTED.toIssueItem(msg)); } /** diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/DeadCodeValidator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/DeadCodeValidator.java index 8c46a5ada3..d604e46f23 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/DeadCodeValidator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/DeadCodeValidator.java @@ -21,6 +21,7 @@ import org.eclipse.n4js.n4JS.ReturnStatement; import org.eclipse.n4js.n4JS.ThrowStatement; import org.eclipse.n4js.validation.IssueCodes; +import org.eclipse.n4js.validation.IssueItem; import org.eclipse.n4js.validation.N4JSElementKeywordProvider; import org.eclipse.n4js.validation.validators.N4JSFlowgraphValidator; @@ -55,13 +56,11 @@ private void internalCheckDeadCode(N4JSFlowgraphValidator fVali) { for (DeadCodeRegion dcRegion : deadCodeRegions) { String stmtDescription = getStatementDescription(dcRegion); - String errCode = IssueCodes.FUN_DEAD_CODE; - String msg = IssueCodes.getMessageForFUN_DEAD_CODE(); + IssueItem issueItem = IssueCodes.FUN_DEAD_CODE.toIssueItem(); if (stmtDescription != null) { - msg = IssueCodes.getMessageForFUN_DEAD_CODE_WITH_PREDECESSOR(stmtDescription); - errCode = IssueCodes.FUN_DEAD_CODE_WITH_PREDECESSOR; + issueItem = IssueCodes.FUN_DEAD_CODE_WITH_PREDECESSOR.toIssueItem(stmtDescription); } - fVali.addIssue(msg, dcRegion.getContainer(), dcRegion.getOffset(), dcRegion.getLength(), errCode); + fVali.addIssue(dcRegion.getContainer(), dcRegion.getOffset(), dcRegion.getLength(), issueItem); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/MissingReturnOrThrowValidator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/MissingReturnOrThrowValidator.java index 3a12eba755..98a355e6cf 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/MissingReturnOrThrowValidator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/MissingReturnOrThrowValidator.java @@ -49,8 +49,7 @@ private void internalCheckMissingReturnDisallowed(N4JSFlowgraphValidator fVali) Collection mrtFunctions = mrta.getMRTFunctions(); for (FunctionOrFieldAccessor fofa : mrtFunctions) { EStructuralFeature highlightFeature = getMarkedElement(fofa); - String msg = IssueCodes.getMessageForFUN_MISSING_RETURN_OR_THROW_STATEMENT(); - fVali.addIssue(msg, fofa, highlightFeature, IssueCodes.FUN_MISSING_RETURN_OR_THROW_STATEMENT); + fVali.addIssue(fofa, highlightFeature, IssueCodes.FUN_MISSING_RETURN_OR_THROW_STATEMENT.toIssueItem()); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/NullUndefinedValidator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/NullUndefinedValidator.java index 00a25f425b..ef4c2a093b 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/NullUndefinedValidator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/NullUndefinedValidator.java @@ -10,6 +10,8 @@ */ package org.eclipse.n4js.validation.validators.flowgraphs; +import static org.eclipse.n4js.validation.IssueCodes.DFG_NULL_DEREFERENCE; + import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -26,7 +28,7 @@ import org.eclipse.n4js.n4JS.FunctionExpression; import org.eclipse.n4js.n4JS.N4JSASTUtils; import org.eclipse.n4js.utils.FindReferenceHelper; -import org.eclipse.n4js.validation.IssueCodes; +import org.eclipse.n4js.validation.IssueItem; import org.eclipse.n4js.validation.validators.N4JSFlowgraphValidator; import org.eclipse.n4js.workspace.N4JSSourceFolderSnapshot; import org.eclipse.n4js.workspace.WorkspaceAccess; @@ -73,8 +75,8 @@ private void internalCheckNullDereference(N4JSFlowgraphValidator fVali) { String isOrMaybe = getAssertionString(ndr, isLeakingToClosure); String nullOrUndefined = getNullOrUndefinedString(ndr); String reason = getReason(ndr); - String msg = IssueCodes.getMessageForDFG_NULL_DEREFERENCE(varName, isOrMaybe, nullOrUndefined, reason); - fVali.addIssue(msg, ndr.cfe, IssueCodes.DFG_NULL_DEREFERENCE); // deactivated during tests + IssueItem issueItem = DFG_NULL_DEREFERENCE.toIssueItem(varName, isOrMaybe, nullOrUndefined, reason); + fVali.addIssue(ndr.cfe, issueItem); // deactivated during tests } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/UsedBeforeDeclaredValidator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/UsedBeforeDeclaredValidator.java index d38153021d..335546f73a 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/UsedBeforeDeclaredValidator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/flowgraphs/UsedBeforeDeclaredValidator.java @@ -44,8 +44,7 @@ private void internalCheckUsedBeforeDeclared(N4JSFlowgraphValidator fVali) { for (IdentifierRef idRef : usedBeforeDeclared) { String varName = idRef.getId().getName(); - String msg = IssueCodes.getMessageForCFG_USED_BEFORE_DECLARED(varName); - fVali.addIssue(msg, idRef, IssueCodes.CFG_USED_BEFORE_DECLARED); + fVali.addIssue(idRef, IssueCodes.CFG_USED_BEFORE_DECLARED.toIssueItem(varName)); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/AbstractPackageJSONValidatorExtension.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/AbstractPackageJSONValidatorExtension.java index f291bcdd9e..bd8b3bcbcf 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/AbstractPackageJSONValidatorExtension.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/AbstractPackageJSONValidatorExtension.java @@ -319,8 +319,8 @@ protected boolean isResponsible(Map context, EObject eObject) { protected void checkIsPresent(EObject issueTarget, Multimap documentValues, String propertyPath) { if (!documentValues.containsKey(propertyPath)) { - addIssue(JSONIssueCodes.getMessageForJSON_MISSING_PROPERTY(propertyPath), issueTarget, - JSONIssueCodes.JSON_MISSING_PROPERTY); + addIssue(JSONIssueCodes.JSON_MISSING_PROPERTY.getMessage(propertyPath), issueTarget, + JSONIssueCodes.JSON_MISSING_PROPERTY.name()); } } @@ -359,9 +359,9 @@ protected void addIssue(String message, EObject source, EStructuralFeature featu * considered and then the issue severities of the bundle that provides an extension. */ private Severity getJSONSeverity(String issueCode) { - final Severity jsonSeverity = JSONIssueCodes.getDefaultSeverity(issueCode); - if (null != jsonSeverity) { - return jsonSeverity; + Severity severity = JSONIssueCodes.getSeverityForName(issueCode); + if (severity != null) { + return severity; } return getIssueSeverities(getContext(), getCurrentObject()).getSeverity(issueCode); } @@ -394,9 +394,9 @@ protected boolean checkIsType(JSONValue value, EClass valueClass, String locatio return false; } if (!valueClass.isInstance(value)) { - addIssue(JSONIssueCodes.getMessageForJSON_EXPECTED_DIFFERENT_VALUE_TYPE(getJSONValueDescription(valueClass), + addIssue(JSONIssueCodes.JSON_EXPECTED_DIFFERENT_VALUE_TYPE.getMessage(getJSONValueDescription(valueClass), getJSONValueDescription(value), locationClause), value, - JSONIssueCodes.JSON_EXPECTED_DIFFERENT_VALUE_TYPE); + JSONIssueCodes.JSON_EXPECTED_DIFFERENT_VALUE_TYPE.name()); return false; } return true; @@ -410,8 +410,8 @@ protected boolean checkIsType(JSONValue value, EClass valueClass, String locatio */ protected boolean checkIsNonEmptyString(JSONStringLiteral stringLiteral, PackageJsonProperties property) { if (stringLiteral.getValue().isEmpty()) { - addIssue(JSONIssueCodes.getMessageForJSON_EMPTY_STRING(property.name), stringLiteral, - JSONIssueCodes.JSON_EMPTY_STRING); + addIssue(JSONIssueCodes.JSON_EMPTY_STRING.getMessage(property.name), stringLiteral, + JSONIssueCodes.JSON_EMPTY_STRING.name()); return false; } return true; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/N4JSProjectSetupJsonValidatorExtension.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/N4JSProjectSetupJsonValidatorExtension.xtend index 6454794096..2bc35b0df2 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/N4JSProjectSetupJsonValidatorExtension.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/N4JSProjectSetupJsonValidatorExtension.xtend @@ -33,6 +33,7 @@ import java.util.Stack import org.apache.log4j.Logger import org.eclipse.emf.common.util.URI import org.eclipse.emf.ecore.EObject +import org.eclipse.emf.ecore.EStructuralFeature import org.eclipse.emf.ecore.resource.Resource import org.eclipse.n4js.N4JSGlobals import org.eclipse.n4js.json.JSON.JSONArray @@ -64,7 +65,7 @@ import org.eclipse.n4js.utils.ModuleFilterUtils import org.eclipse.n4js.utils.NodeModulesDiscoveryHelper import org.eclipse.n4js.utils.ProjectDescriptionLoader import org.eclipse.n4js.utils.Strings -import org.eclipse.n4js.validation.IssueCodes +import org.eclipse.n4js.validation.IssueItem import org.eclipse.n4js.validation.N4JSElementKeywordProvider import org.eclipse.n4js.validation.helper.SourceContainerAwareDependencyProvider import org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot @@ -304,22 +305,19 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV if (keyS.size > 1) { // case a: multiple dependencies clash - val issMsg = if (polyFilledMemberAsStrings.size == 1) { - IssueCodes.getMessageForPOLY_CLASH_IN_RUNTIMEDEPENDENCY(libsString, userPresentablePolyFills) + val IssueItem issueItem = if (polyFilledMemberAsStrings.size == 1) { + POLY_CLASH_IN_RUNTIMEDEPENDENCY.toIssueItem(libsString, userPresentablePolyFills) } else { - IssueCodes. - getMessageForPOLY_CLASH_IN_RUNTIMEDEPENDENCY_MULTI(libsString, userPresentablePolyFills) + POLY_CLASH_IN_RUNTIMEDEPENDENCY_MULTI.toIssueItem(libsString, userPresentablePolyFills) } // add Issue for each keyS.forEach [ - addIssue(issMsg, it, IssueCodes.POLY_CLASH_IN_RUNTIMEDEPENDENCY) + addIssue(it, issueItem) ] } else { // case b: not error-free: - val issMsg = IssueCodes. - getMessageForPOLY_ERROR_IN_RUNTIMEDEPENDENCY(libsString, userPresentablePolyFills) - addIssue(issMsg, keyS.head, IssueCodes.POLY_ERROR_IN_RUNTIMEDEPENDENCY) + addIssue(keyS.head, POLY_ERROR_IN_RUNTIMEDEPENDENCY.toIssueItem(libsString, userPresentablePolyFills)); } @@ -376,8 +374,7 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV for (projectCycleName : projectCycle) { if (projectCycleName.endsWith("/" + dependencyPair.name)) { val dependencyCycle = Strings.join(", ", projectCycle); - val message = getMessageForPROJECT_DEPENDENCY_CYCLE(dependencyCycle); - addIssue(message, dependencyPair, JSONPackage.Literals.NAME_VALUE_PAIR__NAME, PROJECT_DEPENDENCY_CYCLE); + addIssue(dependencyPair, JSONPackage.Literals.NAME_VALUE_PAIR__NAME, PROJECT_DEPENDENCY_CYCLE.toIssueItem(dependencyCycle)); } } } @@ -415,7 +412,7 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV } if(!anyDependsOnTestLibrary(wc, #[project])){ - addIssuePreferred(#[], getMessageForSRCTEST_NO_TESTLIB_DEP(N4JSGlobals.MANGELHAFT), SRCTEST_NO_TESTLIB_DEP); + addIssuePreferred(#[], SRCTEST_NO_TESTLIB_DEP.toIssueItem(N4JSGlobals.MANGELHAFT)); } } @@ -482,9 +479,8 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV return allProjects.containsKey(projectId) && refProjectType != allProjects.get(projectId)?.type ]) { addIssue( - messageForMISMATCHING_TESTED_PROJECT_TYPES, testedProjectsValue, - MISMATCHING_TESTED_PROJECT_TYPES); + MISMATCHING_TESTED_PROJECT_TYPES.toIssueItem()); } } } @@ -515,9 +511,7 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV val dependencyProjectName = pcs.getProjectIdForPackageName(pair.name); val actualImplementationId = allProjects.get(dependencyProjectName)?.implementationId; if (actualImplementationId !== null && actualImplementationId != expectedImplementationId) { - val message = getMessageForMISMATCHING_IMPLEMENTATION_ID(expectedImplementationId, - pair.name, actualImplementationId); - addIssue(message, pair, MISMATCHING_IMPLEMENTATION_ID); + addIssue(pair, MISMATCHING_IMPLEMENTATION_ID.toIssueItem(expectedImplementationId, pair.name, actualImplementationId)); } ]; } @@ -564,11 +558,9 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV val workspaceDependency = actualDirectDependencies.findFirst[!external]; if (null !== workspaceDependency) { val workspaceDependencyId = workspaceDependency.name; - val message = getMessageForEXTERNAL_PROJECT_REFERENCES_WORKSPACE_PROJECT(actualId, workspaceDependencyId); addIssue( - message, dependenciesValue, - EXTERNAL_PROJECT_REFERENCES_WORKSPACE_PROJECT + EXTERNAL_PROJECT_REFERENCES_WORKSPACE_PROJECT.toIssueItem(actualId, workspaceDependencyId) ); return; } @@ -616,15 +608,13 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV val matchingDevDep = devDependencies.findFirst[name == N4JSGlobals.N4JS_RUNTIME.rawName]; if (matchingDevDep === null) { // dependency to 'n4js-runtime' missing entirely - val msg = IssueCodes.getMessageForPKGJ_MISSING_DEPENDENCY_N4JS_RUNTIME; val projectTypeValue = getDocumentValues(PROJECT_TYPE).head; if (projectTypeValue !== null) { // should always be non-null, because we check for 3 non-default project types above! - addIssue(msg, projectTypeValue, IssueCodes.PKGJ_MISSING_DEPENDENCY_N4JS_RUNTIME); + addIssue(projectTypeValue, PKGJ_MISSING_DEPENDENCY_N4JS_RUNTIME.toIssueItem()); } } else { // dependency to 'n4js-runtime' defined in wrong section (under 'devDependencies' instead of 'dependencies') - val msg = IssueCodes.getMessageForPKGJ_WRONG_DEPENDENCY_N4JS_RUNTIME; - addIssue(msg, matchingDevDep, IssueCodes.PKGJ_WRONG_DEPENDENCY_N4JS_RUNTIME); + addIssue(matchingDevDep, PKGJ_WRONG_DEPENDENCY_N4JS_RUNTIME.toIssueItem()); } } } @@ -663,8 +653,7 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV for (projectPair : libraryDependenciesWithImplId) { val reference = projectPair.key; - addIssue(IssueCodes.getMessageForINVALID_API_PROJECT_DEPENDENCY(reference.referencedProjectName), reference.astRepresentation, - IssueCodes.INVALID_API_PROJECT_DEPENDENCY); + addIssue(reference.astRepresentation, INVALID_API_PROJECT_DEPENDENCY.toIssueItem(reference.referencedProjectName)); } } @@ -740,8 +729,7 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV // make sure an implementationId has been declared val JSONValue implementationIdValue = getSingleDocumentValue(IMPLEMENTATION_ID); if (!references.isEmpty() && implementationIdValue === null ) { - addIssue(IssueCodes.getMessageForPKGJ_APIIMPL_MISSING_IMPL_ID(), implementedProjectsValue.eContainer, - JSONPackage.Literals.NAME_VALUE_PAIR__NAME, IssueCodes.PKGJ_APIIMPL_MISSING_IMPL_ID); + addIssue(implementedProjectsValue.eContainer, JSONPackage.Literals.NAME_VALUE_PAIR__NAME, PKGJ_APIIMPL_MISSING_IMPL_ID.toIssueItem()); } } } @@ -797,18 +785,16 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV if (filterSpecifier?.getSpecifierWithWildcard !== null) { if (filterSpecifier.getSpecifierWithWildcard.contains(wrongWildcardPattern)) { addIssue( - getMessageForPKGJ_INVALID_WILDCARD(wrongWildcardPattern), filterSpecifierTraceable.astElement, - PKGJ_INVALID_WILDCARD + PKGJ_INVALID_WILDCARD.toIssueItem(wrongWildcardPattern) ) return false } val wrongRelativeNavigation = "../" if (filterSpecifier.getSpecifierWithWildcard.contains(wrongRelativeNavigation)) { addIssue( - getMessageForPKGJ_NO_RELATIVE_NAVIGATION, filterSpecifierTraceable.astElement, - PKGJ_NO_RELATIVE_NAVIGATION + PKGJ_NO_RELATIVE_NAVIGATION.toIssueItem() ) return false } @@ -829,8 +815,7 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV }; if ((moduleSpecifierWithWildcardFromAST !== null && moduleSpecifierWithWildcardFromAST.empty) || (sourceContainerFromAST !== null && sourceContainerFromAST.empty)) { - addIssue(IssueCodes.getMessageForPKGJ_INVALID_MODULE_FILTER_SPECIFIER_EMPTY(), - filterSpecifierTraceable.astElement, IssueCodes.PKGJ_INVALID_MODULE_FILTER_SPECIFIER_EMPTY); + addIssue(filterSpecifierTraceable.astElement, PKGJ_INVALID_MODULE_FILTER_SPECIFIER_EMPTY.toIssueItem()); return false; } @@ -855,8 +840,7 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV .filter[e | e.value == false].map[e | e.key] for (ASTTraceable filterSpecifier : unmatchedSpecifiers) { - val msg = getMessageForPKGJ_MODULE_FILTER_DOES_NOT_MATCH(filterSpecifier.element.getSpecifierWithWildcard); - addIssue(msg, filterSpecifier.astElement, PKGJ_MODULE_FILTER_DOES_NOT_MATCH); + addIssue(filterSpecifier.astElement, PKGJ_MODULE_FILTER_DOES_NOT_MATCH.toIssueItem(filterSpecifier.element.getSpecifierWithWildcard)); } } @@ -927,8 +911,7 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV private def addNoValidationForN4JSFilesIssue(ASTTraceable filterSpecifier) { val moduleFilterType = (filterSpecifier.astElement.eContainer.eContainer as NameValuePair).name; - addIssue(getMessageForPKGJ_FILTER_NO_N4JS_MATCH(moduleFilterType), filterSpecifier.astElement, - PKGJ_FILTER_NO_N4JS_MATCH); + addIssue(filterSpecifier.astElement, PKGJ_FILTER_NO_N4JS_MATCH.toIssueItem(moduleFilterType)); } /** @@ -958,8 +941,7 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV // check whether the feature can be used with the current project type if (!supportedTypesPredicate.apply(type)) { - addIssue(getMessageForINVALID_FEATURE_FOR_PROJECT_TYPE(featureDescription.toFirstUpper, type.label), - issueTarget, INVALID_FEATURE_FOR_PROJECT_TYPE); + addIssue(issueTarget, INVALID_FEATURE_FOR_PROJECT_TYPE.toIssueItem(featureDescription.toFirstUpper, type.label)); return false; } @@ -1157,8 +1139,7 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV // check for empty project ID if (refId === null || refId.isEmpty) { - addIssue(IssueCodes.getMessageForPKGJ_EMPTY_PROJECT_REFERENCE(), ref.astRepresentation, - IssueCodes.PKGJ_EMPTY_PROJECT_REFERENCE) + addIssue(ref.astRepresentation, PKGJ_EMPTY_PROJECT_REFERENCE.toIssueItem()) return; } @@ -1168,9 +1149,12 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV // type cannot be resolved from index, hence project does not exist in workspace. if (null === project || null === project.type) { if (!currentProject.isExternal) { - val msg = getMessageForNON_EXISTING_PROJECT(refName); val packageVersion = if (ref.npmVersion === null) "" else ref.npmVersion.toString; - addIssue(msg, ref.astRepresentation, null, NON_EXISTING_PROJECT, refName, packageVersion); + val IssueItem issueItem = NON_EXISTING_PROJECT.toIssueItemWithData( + List.of(refName, packageVersion), + refName + ); + addIssue(ref.astRepresentation, null, issueItem); } return; } else { @@ -1208,9 +1192,8 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV val nameOfProjectDefinedByReferencedProject = referencedProject?.definesPackage?.toString; if (nameOfProjectDefinedByReferencedProject !== null) { if (!allReferencedProjectNames.contains(nameOfProjectDefinedByReferencedProject)) { - val msg = IssueCodes.getMessageForPKGJ_IMPL_PROJECT_IS_MISSING_FOR_TYPE_DEF( - nameOfProjectDefinedByReferencedProject, ref.referencedProjectName); - addIssue(msg, ref.astRepresentation, IssueCodes.PKGJ_IMPL_PROJECT_IS_MISSING_FOR_TYPE_DEF); + val IssueItem issueItem = PKGJ_IMPL_PROJECT_IS_MISSING_FOR_TYPE_DEF.toIssueItem(nameOfProjectDefinedByReferencedProject, ref.referencedProjectName); + addIssue(ref.astRepresentation, issueItem); } } } @@ -1251,8 +1234,7 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV references.forEach[reference | if (!declaredDependencies.containsKey(reference.referencedProjectName)) { - addIssue(IssueCodes.getMessageForPKGJ_PROJECT_REFERENCE_MUST_BE_DEPENDENCY(reference.referencedProjectName, sectionLabel), - reference.astRepresentation, IssueCodes.PKGJ_PROJECT_REFERENCE_MUST_BE_DEPENDENCY); + addIssue(reference.astRepresentation, PKGJ_PROJECT_REFERENCE_MUST_BE_DEPENDENCY.toIssueItem(reference.referencedProjectName, sectionLabel)); } ] } @@ -1283,8 +1265,11 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV val desiredStr = SemverSerializer.serialize(desiredVersion); val availableStr = SemverSerializer.serialize(availableVersion); - val msg = getMessageForNO_MATCHING_VERSION(ref.referencedProjectName, desiredStr, availableStr); - addIssue(msg, ref.astRepresentation, null, NO_MATCHING_VERSION, ref.referencedProjectId, desiredVersion.toString); + val IssueItem issueItem = NO_MATCHING_VERSION.toIssueItemWithData( + List.of(ref.referencedProjectId, desiredVersion.toString), + ref.referencedProjectName, desiredStr, availableStr + ); + addIssue(ref.astRepresentation, null, issueItem); } /** @@ -1328,16 +1313,15 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV } private def addProjectReferencesItselfIssue(EObject target) { - addIssue(messageForPROJECT_REFERENCES_ITSELF, target, PROJECT_REFERENCES_ITSELF); + addIssue(target, PROJECT_REFERENCES_ITSELF.toIssueItem()); } private def addInvalidProjectTypeIssue(EObject target, String projectName, ProjectType type, String sectionLabel) { - addIssue(getMessageForINVALID_PROJECT_TYPE_REF(projectName, type.label, sectionLabel), - target, INVALID_PROJECT_TYPE_REF); + addIssue(target, INVALID_PROJECT_TYPE_REF.toIssueItem(projectName, type.label, sectionLabel)); } private def addDuplicateProjectReferenceIssue(EObject target, String name) { - addIssue(getMessageForDUPLICATE_PROJECT_REF(name), target, DUPLICATE_PROJECT_REF); + addIssue(target, DUPLICATE_PROJECT_REF.toIssueItem(name)); } /** @@ -1348,21 +1332,21 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV * * If there is no {@code name} property, adds an issue to the whole document (see {@link #getDocument()}). */ - private def void addIssuePreferred(Iterable preferredTargets, String message, String issueCode) { + private def void addIssuePreferred(Iterable preferredTargets, IssueItem issueItem) { // add issue to preferred targets if (!preferredTargets.filterNull.empty) { preferredTargets.filterNull - .forEach[t | addIssue(message, t, issueCode); ] + .forEach[t | addIssue(t, issueItem); ] return; } // fall back to property 'name' val nameValue = getSingleDocumentValue(NAME); if (nameValue !== null) { - addIssue(message, nameValue, issueCode); + addIssue(nameValue, issueItem); return; } // finally fall back to document - addIssue(message, document, issueCode) + addIssue(document, issueItem) } /** @@ -1384,4 +1368,13 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV private def Predicate forN4jsProjects(Predicate predicate) { return [pcs | predicate.apply(pcs.type)]; } + + + def private void addIssue(EObject source, EStructuralFeature feature, IssueItem issueItem) { + super.addIssue(issueItem.message, source, feature, issueItem.ID, issueItem.data); + } + + def private void addIssue(EObject source, IssueItem issueItem) { + super.addIssue(issueItem.message, source, null, issueItem.ID, issueItem.data); + } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/PackageJsonValidatorExtension.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/PackageJsonValidatorExtension.java index 83aa0d0475..1a39371e4a 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/PackageJsonValidatorExtension.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/PackageJsonValidatorExtension.java @@ -33,6 +33,35 @@ import static org.eclipse.n4js.packagejson.PackageJsonProperties.VENDOR_ID; import static org.eclipse.n4js.packagejson.PackageJsonProperties.VENDOR_NAME; import static org.eclipse.n4js.packagejson.PackageJsonProperties.VERSION; +import static org.eclipse.n4js.validation.IssueCodes.OUTPUT_AND_SOURCES_FOLDER_NESTING; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_APIIMPL_MISSING_IMPL_PROJECTS; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_APIIMPL_REFLEXIVE; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_DEFINES_PROPERTY; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_DUPLICATE_MODULE_FILTER_SPECIFIER; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_DUPLICATE_SOURCE_CONTAINER; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_EMPTY_SOURCE_PATH; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_EXPECTED_DIRECTORY_PATH; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_INVALID_ABSOLUTE_PATH; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_INVALID_MODULE_FILTER_SPECIFIER; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_INVALID_MODULE_FILTER_TYPE; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_INVALID_PATH; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_INVALID_PROJECT_NAME; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_INVALID_PROJECT_TYPE; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_INVALID_SCOPE_NAME; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_INVALID_SOURCE_CONTAINER_TYPE; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_INVALID_VERSION_NUMBER; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_NESTED_SOURCE_CONTAINER; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_NON_EXISTING_MAIN_MODULE; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_NON_EXISTING_SOURCE_PATH; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_PACKAGE_NAME_MISMATCH; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_PROJECT_TYPE_MANDATORY_OUTPUT_AND_SOURCES; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_PROPERTY_UNKNOWN; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_REWRITE_MODULE_SPECIFIERS__EMPTY_SPECIFIER; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_REWRITE_MODULE_SPECIFIERS__INVALID_VALUE; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_SCOPE_NAME_MISMATCH; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_SEMVER_ERROR; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_SEMVER_WARNING; +import static org.eclipse.n4js.validation.IssueCodes.PKGJ_SRC_IN_FILTER_IS_NO_DECLARED_SOURCE; import java.io.File; import java.nio.file.InvalidPathException; @@ -52,6 +81,7 @@ import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.n4js.N4JSGlobals; import org.eclipse.n4js.json.JSON.JSONArray; @@ -81,6 +111,7 @@ import org.eclipse.n4js.utils.ProjectDescriptionUtils.ProjectNameInfo; import org.eclipse.n4js.utils.io.FileUtils; import org.eclipse.n4js.validation.IssueCodes; +import org.eclipse.n4js.validation.IssueItem; import org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot; import org.eclipse.n4js.workspace.WorkspaceAccess; import org.eclipse.n4js.workspace.locations.FileURI; @@ -150,14 +181,12 @@ public void checkName(JSONValue projectNameValue) { // make sure the name conforms to the IDENTIFIER_PATTERN if (!ProjectDescriptionUtils.isValidPlainPackageName(projectNameWithoutScope)) { - addIssue(IssueCodes.getMessageForPKGJ_INVALID_PROJECT_NAME(projectNameWithoutScope), - projectNameValue, IssueCodes.PKGJ_INVALID_PROJECT_NAME); + addIssue(projectNameValue, PKGJ_INVALID_PROJECT_NAME.toIssueItem(projectNameWithoutScope)); } if (scopeName != null) { String scopeNameWithoutPrefix = scopeName.substring(1); if (!ProjectDescriptionUtils.isValidScopeName(scopeNameWithoutPrefix)) { - String msg = IssueCodes.getMessageForPKGJ_INVALID_SCOPE_NAME(scopeNameWithoutPrefix); - addIssue(msg, projectNameValue, IssueCodes.PKGJ_INVALID_SCOPE_NAME); + addIssue(projectNameValue, PKGJ_INVALID_SCOPE_NAME.toIssueItem(scopeNameWithoutPrefix)); } } @@ -167,16 +196,14 @@ public void checkName(JSONValue projectNameValue) { // make sure the project name equals the name of the project folder if (!projectNameWithoutScope.equals(nameInfo.projectFolderName)) { - String msg = IssueCodes.getMessageForPKGJ_PACKAGE_NAME_MISMATCH( - projectNameWithoutScope, nameInfo.projectFolderName); - addIssue(msg, projectNameLiteral, IssueCodes.PKGJ_PACKAGE_NAME_MISMATCH); + addIssue(projectNameLiteral, + PKGJ_PACKAGE_NAME_MISMATCH.toIssueItem(projectNameWithoutScope, nameInfo.projectFolderName)); } // make sure the scope name (if any) equals the name of the parent folder // (i.e. the folder containing the project folder) if (scopeName != null && !scopeName.equals(nameInfo.parentFolderName)) { - String msg = IssueCodes.getMessageForPKGJ_SCOPE_NAME_MISMATCH(scopeName, nameInfo.parentFolderName); - addIssue(msg, projectNameLiteral, IssueCodes.PKGJ_SCOPE_NAME_MISMATCH); + addIssue(projectNameLiteral, PKGJ_SCOPE_NAME_MISMATCH.toIssueItem(scopeName, nameInfo.parentFolderName)); } } @@ -198,8 +225,7 @@ public void checkVersion(JSONValue versionValue) { if (npmVersion != null) { reason = "Given string is parsed as " + getVersionRequirementType(npmVersion); } - String msg = IssueCodes.getMessageForPKGJ_INVALID_VERSION_NUMBER(versionString, reason); - addIssue(msg, versionValue, IssueCodes.PKGJ_INVALID_VERSION_NUMBER); + addIssue(versionValue, PKGJ_INVALID_VERSION_NUMBER.toIssueItem(versionString, reason)); return; } @@ -209,8 +235,7 @@ public void checkVersion(JSONValue versionValue) { if (!simpleVersion.getComparators().isEmpty()) { String comparator = SemverSerializer.serialize(simpleVersion.getComparators().get(0)); String reason = "Version numbers must not have comparators: '" + comparator + "'"; - String msg = IssueCodes.getMessageForPKGJ_INVALID_VERSION_NUMBER(versionString, reason); - addIssue(msg, versionValue, IssueCodes.PKGJ_INVALID_VERSION_NUMBER); + addIssue(versionValue, PKGJ_INVALID_VERSION_NUMBER.toIssueItem(versionString, reason)); return; } } @@ -226,7 +251,6 @@ private IParseResult validateSemver(JSONValue versionValue, String versionString INode firstErrorNode = errorIterator.next(); String reason = firstErrorNode.getSyntaxErrorMessage().getMessage(); - String msg = IssueCodes.getMessageForPKGJ_INVALID_VERSION_NUMBER(versionString, reason); ICompositeNode actualNode = NodeModelUtils.findActualNodeFor(versionValue); int actOffset = actualNode.getOffset(); @@ -234,32 +258,28 @@ private IParseResult validateSemver(JSONValue versionValue, String versionString int offset = actOffset + firstErrorNode.getOffset() + 1; // +1 due to " char int lengthTmp = actLength - firstErrorNode.getOffset() - 2; // -2 due to "" chars int length = Math.max(1, lengthTmp); - addIssue(msg, versionValue, offset, length, IssueCodes.PKGJ_INVALID_VERSION_NUMBER); + addIssue(versionValue, offset, length, PKGJ_INVALID_VERSION_NUMBER.toIssueItem(versionString, reason)); } return parseResult; } List issues = semverHelper.validate(parseResult); for (Issue issue : issues) { - String msg = ""; - String issueCode = IssueCodes.PKGJ_INVALID_VERSION_NUMBER; + IssueItem issueItem; switch (issue.getSeverity()) { case WARNING: - msg = IssueCodes.getMessageForPKGJ_SEMVER_WARNING(issue.getMessage()); - issueCode = IssueCodes.PKGJ_SEMVER_WARNING; - break; - case ERROR: - msg = IssueCodes.getMessageForPKGJ_SEMVER_ERROR(issue.getMessage()); - issueCode = IssueCodes.PKGJ_SEMVER_ERROR; + issueItem = PKGJ_SEMVER_WARNING.toIssueItem(issue.getMessage()); break; default: + case ERROR: + issueItem = PKGJ_SEMVER_ERROR.toIssueItem(issue.getMessage()); break; } ICompositeNode actualNode = NodeModelUtils.findActualNodeFor(versionValue); int offset = actualNode.getOffset() + issue.getOffset() + 1; int length = issue.getLength(); - addIssue(msg, versionValue, offset, length, issueCode); + addIssue(versionValue, offset, length, issueItem); } return parseResult; @@ -348,9 +368,8 @@ public void checkN4JSSection(JSONValue n4jsSection) { for (NameValuePair nameValuePair : n4jsSectionJO.getNameValuePairs()) { String nvpName = nameValuePair.getName(); if (!allN4JSPropertyNames.contains(nvpName)) { - String msg = IssueCodes.getMessageForPKGJ_PROPERTY_UNKNOWN(nvpName); - addIssue(msg, nameValuePair, JSONPackage.Literals.NAME_VALUE_PAIR__NAME, - IssueCodes.PKGJ_PROPERTY_UNKNOWN); + addIssue(nameValuePair, JSONPackage.Literals.NAME_VALUE_PAIR__NAME, + PKGJ_PROPERTY_UNKNOWN.toIssueItem(nvpName)); } } } @@ -371,8 +390,7 @@ public void checkProjectType(JSONValue projectTypeValue) { // check type can be parsed successfully if (type == null) { - addIssue(IssueCodes.getMessageForPKGJ_INVALID_PROJECT_TYPE(projectTypeString), - projectTypeValue, IssueCodes.PKGJ_INVALID_PROJECT_TYPE); + addIssue(projectTypeValue, PKGJ_INVALID_PROJECT_TYPE.toIssueItem(projectTypeString)); return; } @@ -384,8 +402,7 @@ public void checkProjectType(JSONValue projectTypeValue) { if (isDefType != hasDefPck) { EObject issueObj = propDefinesPck == null ? projectTypeValue : propDefinesPck.eContainer(); String not = propDefinesPck == null ? "" : "not "; - String msg = IssueCodes.getMessageForPKGJ_DEFINES_PROPERTY(type.toString(), not, "definesPackage"); - addIssue(msg, issueObj, IssueCodes.PKGJ_DEFINES_PROPERTY); + addIssue(issueObj, PKGJ_DEFINES_PROPERTY.toIssueItem(type.toString(), not, "definesPackage")); } if (isRequiresOutputAndSourceFolder(type)) { @@ -393,8 +410,8 @@ public void checkProjectType(JSONValue projectTypeValue) { final boolean hasSources = getSingleDocumentValue(SOURCES) != null; final boolean hasOutput = getSingleDocumentValue(OUTPUT) != null; if (!hasSources || !hasOutput) { - String msg = IssueCodes.getMessageForPKGJ_PROJECT_TYPE_MANDATORY_OUTPUT_AND_SOURCES(projectTypeString); - addIssue(msg, projectTypeValue, IssueCodes.PKGJ_PROJECT_TYPE_MANDATORY_OUTPUT_AND_SOURCES); + addIssue(projectTypeValue, + PKGJ_PROJECT_TYPE_MANDATORY_OUTPUT_AND_SOURCES.toIssueItem(projectTypeString)); } } } @@ -487,8 +504,7 @@ public void checkSourceContainers() { for (JSONStringLiteral duplicate : duplicateGroup) { final String inClause = createInSourceContainerTypeClause(duplicate, duplicateGroup); - addIssue(IssueCodes.getMessageForPKGJ_DUPLICATE_SOURCE_CONTAINER(normalizedPath, inClause), - duplicate, IssueCodes.PKGJ_DUPLICATE_SOURCE_CONTAINER); + addIssue(duplicate, PKGJ_DUPLICATE_SOURCE_CONTAINER.toIssueItem(normalizedPath, inClause)); } } @@ -535,8 +551,7 @@ private void internalCheckNoNestedSourceContainers(final List .sorted((s1, s2) -> s1.length() - s2.length()) // sort by ascending length .collect(Collectors.joining(", ")); - addIssue(IssueCodes.getMessageForPKGJ_NESTED_SOURCE_CONTAINER(containersDescription), path.astElement, - IssueCodes.PKGJ_NESTED_SOURCE_CONTAINER); + addIssue(path.astElement, PKGJ_NESTED_SOURCE_CONTAINER.toIssueItem(containersDescription)); } } @@ -544,8 +559,7 @@ private void internalCheckNoNestedSourceContainers(final List private boolean internalCheckSourceContainerLiteral(JSONStringLiteral containerLiteral) { // check path for empty strings if (containerLiteral.getValue().isEmpty()) { - addIssue(IssueCodes.getMessageForPKGJ_EMPTY_SOURCE_PATH(), containerLiteral, - IssueCodes.PKGJ_EMPTY_SOURCE_PATH); + addIssue(containerLiteral, PKGJ_EMPTY_SOURCE_PATH.toIssueItem()); return false; } @@ -567,8 +581,7 @@ public void checkMainModule(JSONValue mainModuleValue) { if (mainModuleSpecifier.isEmpty() || !isExistingModule(mainModuleLiteral)) { final String specifierToShow = mainModuleSpecifier.isEmpty() ? "" : mainModuleSpecifier; - addIssue(IssueCodes.getMessageForPKGJ_NON_EXISTING_MAIN_MODULE(specifierToShow), - mainModuleLiteral, IssueCodes.PKGJ_NON_EXISTING_MAIN_MODULE); + addIssue(mainModuleLiteral, PKGJ_NON_EXISTING_MAIN_MODULE.toIssueItem(specifierToShow)); } } @@ -592,9 +605,8 @@ public void checkImplementationId(JSONValue value) { // at this point we may assume that the implementationId was set if ((implementedProjectsValue == null || implementedProjectsValue.getElements().isEmpty())) { // missing implemented projects - addIssue(IssueCodes.getMessageForPKGJ_APIIMPL_MISSING_IMPL_PROJECTS(), - implementationId.eContainer(), JSONPackage.Literals.NAME_VALUE_PAIR__NAME, - IssueCodes.PKGJ_APIIMPL_MISSING_IMPL_PROJECTS); + addIssue(implementationId.eContainer(), JSONPackage.Literals.NAME_VALUE_PAIR__NAME, + PKGJ_APIIMPL_MISSING_IMPL_PROJECTS.toIssueItem()); } } @@ -631,8 +643,7 @@ public void checkImplementedProjects(JSONValue value) { for (JSONStringLiteral implementedProjectLiteral : implementedProjectLiterals) { if (implementedProjectLiteral.getValue().equals(declaredProjectNameValue.getValue())) { // reflexive implementation - addIssue(IssueCodes.getMessageForPKGJ_APIIMPL_REFLEXIVE(), implementedProjectLiteral, - IssueCodes.PKGJ_APIIMPL_REFLEXIVE); + addIssue(implementedProjectLiteral, PKGJ_APIIMPL_REFLEXIVE.toIssueItem()); } } } @@ -664,15 +675,12 @@ public void checkRewriteModuleSpecifiers(JSONValue value) { continue; // syntax error } if (n.isEmpty()) { - addIssue(IssueCodes.getMessageForPKGJ_REWRITE_MODULE_SPECIFIERS__EMPTY_SPECIFIER("Source"), nvp, - JSONPackage.eINSTANCE.getNameValuePair_Name(), - IssueCodes.PKGJ_REWRITE_MODULE_SPECIFIERS__EMPTY_SPECIFIER); + addIssue(nvp, JSONPackage.eINSTANCE.getNameValuePair_Name(), + PKGJ_REWRITE_MODULE_SPECIFIERS__EMPTY_SPECIFIER.toIssueItem("Source")); } else if (!(v instanceof JSONStringLiteral)) { - addIssue(IssueCodes.getMessageForPKGJ_REWRITE_MODULE_SPECIFIERS__INVALID_VALUE(), v, - IssueCodes.PKGJ_REWRITE_MODULE_SPECIFIERS__INVALID_VALUE); + addIssue(v, PKGJ_REWRITE_MODULE_SPECIFIERS__INVALID_VALUE.toIssueItem()); } else if (((JSONStringLiteral) v).getValue().isEmpty()) { - addIssue(IssueCodes.getMessageForPKGJ_REWRITE_MODULE_SPECIFIERS__EMPTY_SPECIFIER("Output code"), v, - IssueCodes.PKGJ_REWRITE_MODULE_SPECIFIERS__EMPTY_SPECIFIER); + addIssue(v, PKGJ_REWRITE_MODULE_SPECIFIERS__EMPTY_SPECIFIER.toIssueItem("Output code")); } } } @@ -735,8 +743,8 @@ private void internalCheckOutput(String outputPath, Optional astOutpu // forbid output folder for 'definition' projects final ProjectType projectType = getProjectType(); if (projectType == ProjectType.DEFINITION && astOutputValue.isPresent()) { - String message = IssueCodes.getMessageForPKGJ_DEFINES_PROPERTY(projectType.name(), "not ", "output"); - addIssue(message, astOutputValue.get().eContainer(), IssueCodes.PKGJ_DEFINES_PROPERTY); + addIssue(astOutputValue.get().eContainer(), + PKGJ_DEFINES_PROPERTY.toIssueItem(projectType.name(), "not ", "output")); } // do not perform check for projects which do not require an output folder if (!isRequiresOutputAndSourceFolder(projectType)) { @@ -761,10 +769,8 @@ private void internalCheckOutput(String outputPath, Optional astOutpu final String containingFolder = ("A " + srcFrgmtName + " folder"); final String nestedFolder = astOutputValue.isPresent() ? "the output folder" : "the default output folder \"" + OUTPUT.defaultValue + "\""; - final String message = IssueCodes - .getMessageForOUTPUT_AND_SOURCES_FOLDER_NESTING(containingFolder, nestedFolder); - - addIssue(message, sourceContainerSpecifier, IssueCodes.OUTPUT_AND_SOURCES_FOLDER_NESTING); + addIssue(sourceContainerSpecifier, + OUTPUT_AND_SOURCES_FOLDER_NESTING.toIssueItem(containingFolder, nestedFolder)); } // if "output" AST element is available (outputPath is not a default value) @@ -773,10 +779,8 @@ private void internalCheckOutput(String outputPath, Optional astOutpu if (isContainedOrEqual(absoluteOutputLocation, absoluteSourceLocation)) { final String containingFolder = "The output folder"; final String nestedFolder = ("a " + srcFrgmtName + " folder"); - final String message = IssueCodes - .getMessageForOUTPUT_AND_SOURCES_FOLDER_NESTING(containingFolder, nestedFolder); - - addIssue(message, astOutputValue.get(), IssueCodes.OUTPUT_AND_SOURCES_FOLDER_NESTING); + addIssue(astOutputValue.get(), + OUTPUT_AND_SOURCES_FOLDER_NESTING.toIssueItem(containingFolder, nestedFolder)); } } } @@ -827,10 +831,8 @@ private void internalCheckModuleFilterEntry(NameValuePair moduleFilterPair) { // make sure the module filter type could be parsed successfully if (filterType == null) { - final String message = IssueCodes.getMessageForPKGJ_INVALID_MODULE_FILTER_TYPE( - moduleFilterPair.getName(), "noValidate"); - addIssue(message, moduleFilterPair, JSONPackage.Literals.NAME_VALUE_PAIR__NAME, - IssueCodes.PKGJ_INVALID_MODULE_FILTER_TYPE); + addIssue(moduleFilterPair, JSONPackage.Literals.NAME_VALUE_PAIR__NAME, + PKGJ_INVALID_MODULE_FILTER_TYPE.toIssueItem(moduleFilterPair.getName(), "noValidate")); } // check type of RHS @@ -877,8 +879,7 @@ private void internalCheckModuleFilterEntry(NameValuePair moduleFilterPair) { .forEach(duplicate -> duplicateFilterSpecifiers.add(duplicate.astRepresentation)); for (JSONValue duplicateFilterSpecifier : duplicateFilterSpecifiers) { - addIssue(IssueCodes.getMessageForPKGJ_DUPLICATE_MODULE_FILTER_SPECIFIER(), - duplicateFilterSpecifier, IssueCodes.PKGJ_DUPLICATE_MODULE_FILTER_SPECIFIER); + addIssue(duplicateFilterSpecifier, PKGJ_DUPLICATE_MODULE_FILTER_SPECIFIER.toIssueItem()); } } @@ -890,9 +891,8 @@ private void checkModuleFilterSpecifier(ValidationModuleFilterSpecifier specifie // make sure moduleFilterSpecifier.sourceContainerPath has been declared as source container if (specifier.sourceContainerPath != null && !sourceContainerPaths.contains(specifier.sourceContainerPath)) { - addIssue( - IssueCodes.getMessageForPKGJ_SRC_IN_FILTER_IS_NO_DECLARED_SOURCE(specifier.sourceContainerPath), - specifier.astRepresentation, IssueCodes.PKGJ_SRC_IN_FILTER_IS_NO_DECLARED_SOURCE); + addIssue(specifier.astRepresentation, + PKGJ_SRC_IN_FILTER_IS_NO_DECLARED_SOURCE.toIssueItem(specifier.sourceContainerPath)); } } } @@ -966,8 +966,7 @@ && checkIsType(moduleFilterPair.getValue(), JSONPackage.Literals.JSON_STRING_LIT } // otherwise 'value' does not represent a valid module filter specifier - addIssue(IssueCodes.getMessageForPKGJ_INVALID_MODULE_FILTER_SPECIFIER(), value, - IssueCodes.PKGJ_INVALID_MODULE_FILTER_SPECIFIER); + addIssue(value, PKGJ_INVALID_MODULE_FILTER_SPECIFIER.toIssueItem()); return null; } @@ -1009,20 +1008,17 @@ private boolean holdsValidRelativePath(JSONStringLiteral pathLiteral) { final Path path = Paths.get(pathLiteral.getValue()); // check for path being relative if (path.isAbsolute()) { - addIssue(IssueCodes.getMessageForPKGJ_INVALID_ABSOLUTE_PATH(pathLiteral.getValue()), - pathLiteral, IssueCodes.PKGJ_INVALID_ABSOLUTE_PATH); + addIssue(pathLiteral, PKGJ_INVALID_ABSOLUTE_PATH.toIssueItem(pathLiteral.getValue())); return false; } // check for the use of the '*' character (e.g. invalid wildcards) if (pathLiteral.getValue().contains("*")) { - addIssue(IssueCodes.getMessageForPKGJ_INVALID_PATH(pathLiteral.getValue()), - pathLiteral, IssueCodes.PKGJ_INVALID_PATH); + addIssue(pathLiteral, PKGJ_INVALID_PATH.toIssueItem(pathLiteral.getValue())); return false; } return true; } catch (InvalidPathException e) { - addIssue(IssueCodes.getMessageForPKGJ_INVALID_PATH(pathLiteral.getValue()), - pathLiteral, IssueCodes.PKGJ_INVALID_PATH); + addIssue(pathLiteral, PKGJ_INVALID_PATH.toIssueItem(pathLiteral.getValue())); return false; } } @@ -1063,14 +1059,12 @@ private boolean holdsExistingDirectoryPath(JSONStringLiteral pathLiteral) { final File file = new File(baseResourcePath.toString(), relativePath); if (!file.exists()) { - addIssue(IssueCodes.getMessageForPKGJ_NON_EXISTING_SOURCE_PATH(relativePath), - pathLiteral, IssueCodes.PKGJ_NON_EXISTING_SOURCE_PATH); + addIssue(pathLiteral, PKGJ_NON_EXISTING_SOURCE_PATH.toIssueItem(relativePath)); return false; } if (!file.isDirectory()) { - addIssue(IssueCodes.getMessageForPKGJ_EXPECTED_DIRECTORY_PATH(relativePath), - pathLiteral, IssueCodes.PKGJ_EXPECTED_DIRECTORY_PATH); + addIssue(pathLiteral, PKGJ_EXPECTED_DIRECTORY_PATH.toIssueItem(relativePath)); return false; } @@ -1200,9 +1194,8 @@ private Multimap> doGetSourceContai // check that sourceContainerType represents a valid source container type if (containerType == null) { - addIssue(IssueCodes.getMessageForPKGJ_INVALID_SOURCE_CONTAINER_TYPE(sourceContainerType), - pair, JSONPackage.Literals.NAME_VALUE_PAIR__NAME, - IssueCodes.PKGJ_INVALID_SOURCE_CONTAINER_TYPE); + addIssue(pair, JSONPackage.Literals.NAME_VALUE_PAIR__NAME, + PKGJ_INVALID_SOURCE_CONTAINER_TYPE.toIssueItem(sourceContainerType)); continue; } @@ -1245,4 +1238,16 @@ private SourceContainerType getSourceContainerType(JSONStringLiteral containerSp .eContainer(); return PackageJsonUtils.parseSourceContainerType(containerTypeAssignment.getName()); } + + private void addIssue(EObject source, int offset, int length, IssueItem issueItem) { + super.addIssue(issueItem.message, source, offset, length, issueItem.getID(), issueItem.data); + } + + private void addIssue(EObject source, EStructuralFeature feature, IssueItem issueItem) { + super.addIssue(issueItem.message, source, feature, issueItem.getID(), issueItem.data); + } + + private void addIssue(EObject source, IssueItem issueItem) { + super.addIssue(issueItem.message, source, null, issueItem.getID(), issueItem.data); + } } diff --git a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/AbstractIdeTest.java b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/AbstractIdeTest.java index 8e3a8cb022..e685512ae6 100644 --- a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/AbstractIdeTest.java +++ b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/AbstractIdeTest.java @@ -1573,9 +1573,10 @@ protected Collection getIssuesInFile(FileURI uri) { */ protected List getIssuesInFile(FileURI fileURI, boolean withIgnoredIssues) { Stream issuesInFile = languageClient.getIssues(fileURI).stream(); + Set ignoredIssueCodes = getIgnoredIssueCodes(); if (!withIgnoredIssues) { issuesInFile = issuesInFile.filter( - issue -> issue.getCode() == null || !getIgnoredIssueCodes().contains(issue.getCode().getLeft())); + issue -> issue.getCode() == null || !ignoredIssueCodes.contains(issue.getCode().getLeft())); } return issuesInFile.collect(Collectors.toList()); } diff --git a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/AbstractOrganizeImportsTest.java b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/AbstractOrganizeImportsTest.java index 847c21f250..4e5686060c 100644 --- a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/AbstractOrganizeImportsTest.java +++ b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/AbstractOrganizeImportsTest.java @@ -48,14 +48,14 @@ public abstract class AbstractOrganizeImportsTest extends AbstractStructuredIdeT private final Set IGNORED_ISSUE_CODES = Sets.newHashSet(Iterables.concat( N4JSLanguageConstants.DEFAULT_SUPPRESSED_ISSUE_CODES_FOR_TESTS, Sets.newHashSet( - IssueCodes.IMP_DUPLICATE, - IssueCodes.IMP_DUPLICATE_ALIAS, - IssueCodes.IMP_DUPLICATE_NAMESPACE, - IssueCodes.IMP_STMT_DUPLICATE_NAMED, - IssueCodes.IMP_STMT_DUPLICATE_NAMESPACE, - IssueCodes.IMP_AMBIGUOUS, - IssueCodes.IMP_UNUSED_IMPORT, - IssueCodes.IMP_UNRESOLVED))); + IssueCodes.IMP_DUPLICATE.name(), + IssueCodes.IMP_DUPLICATE_ALIAS.name(), + IssueCodes.IMP_DUPLICATE_NAMESPACE.name(), + IssueCodes.IMP_STMT_DUPLICATE_NAMED.name(), + IssueCodes.IMP_STMT_DUPLICATE_NAMESPACE.name(), + IssueCodes.IMP_AMBIGUOUS.name(), + IssueCodes.IMP_UNUSED_IMPORT.name(), + IssueCodes.IMP_UNRESOLVED.name()))); /** Configuration of organize imports tests. */ protected static class TestOrganizeImportsConfiguration { diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSParseHelper.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSParseHelper.java index e932b742d9..e9b166fc60 100644 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSParseHelper.java +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSParseHelper.java @@ -25,6 +25,7 @@ import org.eclipse.emf.ecore.resource.Resource.Diagnostic; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.n4js.validation.JavaScriptVariant; import org.eclipse.xtext.diagnostics.AbstractDiagnostic; import org.eclipse.xtext.resource.FileExtensionProvider; @@ -139,7 +140,7 @@ public void assertNoParseErrors(Script script) { /** * Like {@link #assertNoParseErrors(Script)}, but ignoring all issues with the given issue codes. */ - public void assertNoParseErrors(Script script, Set ignoredIssueCodes) { + public void assertNoParseErrors(Script script, Set ignoredIssueCodes) { List errors = script.eResource().getErrors(); if (ignoredIssueCodes != null) { errors = FluentIterable.from(errors) @@ -159,9 +160,14 @@ private void setFileExtension(String ext) { this.fileExtension = ext; } - private String getIssueCode(Diagnostic diagnostic) { + private IssueCodes getIssueCode(Diagnostic diagnostic) { if (diagnostic instanceof AbstractDiagnostic) { - return ((AbstractDiagnostic) diagnostic).getCode(); + String codeName = ((AbstractDiagnostic) diagnostic).getCode(); + try { + return IssueCodes.valueOf(codeName); + } catch (Exception e) { + // ignore + } } return null; } diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSTestHelper.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSTestHelper.java index 287b94bd49..cc831ddb00 100644 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSTestHelper.java +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSTestHelper.java @@ -19,6 +19,7 @@ import org.eclipse.n4js.n4JS.Script; import org.eclipse.n4js.resource.N4JSResource; import org.eclipse.n4js.utils.URIUtils; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.resource.XtextResourceSet; import org.eclipse.xtext.xbase.lib.Pair; import org.junit.Assert; @@ -59,7 +60,7 @@ public Script parseAndValidateSuccessfully(CharSequence code) { /** * Like {@link #parseAndValidateSuccessfully(CharSequence)}, but ignoring issues with the given issue codes. */ - public Script parseAndValidateSuccessfullyIgnoring(CharSequence code, String... ignoredIssueCodes) { + public Script parseAndValidateSuccessfullyIgnoring(CharSequence code, IssueCodes... ignoredIssueCodes) { try { final Script script = parseHelper.parseN4js(code); parseHelper.assertNoParseErrors(script, new HashSet<>(Arrays.asList(ignoredIssueCodes))); diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSValidationTestHelper.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSValidationTestHelper.java index 70c400cf35..8565bc553e 100644 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSValidationTestHelper.java +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSValidationTestHelper.java @@ -13,7 +13,6 @@ import static org.junit.Assert.fail; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -28,6 +27,7 @@ import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.n4js.n4JS.N4JSPackage; import org.eclipse.n4js.tests.issues.IssueUtils; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.diagnostics.Severity; import org.eclipse.xtext.testing.validation.ValidationTestHelper; import org.eclipse.xtext.validation.Issue; @@ -47,7 +47,7 @@ public class N4JSValidationTestHelper extends ValidationTestHelper { * @param ignoredIssueCodes * Issue codes which should be ignored */ - public void assertNoIssuesExcept(EObject model, String... ignoredIssueCodes) { + public void assertNoIssuesExcept(EObject model, IssueCodes... ignoredIssueCodes) { Resource resource = model.eResource(); List issues = validate(resource); issues = removeIssuesWithCode(issues, false, ignoredIssueCodes); @@ -64,7 +64,7 @@ public void assertNoIssuesExcept(EObject model, String... ignoredIssueCodes) { * @param ignoredIssueCodes * Issue codes which should be ignored */ - public void assertNoErrorsExcept(EObject model, String... ignoredIssueCodes) { + public void assertNoErrorsExcept(EObject model, IssueCodes... ignoredIssueCodes) { Resource resource = model.eResource(); List issues = validate(resource); issues = removeIssuesWithCode(issues, true, ignoredIssueCodes); @@ -83,7 +83,7 @@ public void assertNoErrorsExcept(EObject model, String... ignoredIssueCodes) { * @param expectedErrors * The expected errors. */ - public void assertErrorsExcept(EObject model, String[] ignoredIssueCodes, String... expectedErrors) { + public void assertErrorsExcept(EObject model, IssueCodes[] ignoredIssueCodes, String... expectedErrors) { if (expectedErrors.length == 0) { // use above method for better error messages: assertNoErrorsExcept(model, ignoredIssueCodes); @@ -102,8 +102,11 @@ public void assertErrorsExcept(EObject model, String[] ignoredIssueCodes, String Assert.assertEquals("Actual errors differ from expected errors", expectedErrorsSorted, actualErrorsSorted); } - private List removeIssuesWithCode(List issues, boolean removeWarningsAndInfos, String... codes) { - Set excludedIssueCodes = new HashSet<>(Arrays.asList(codes)); + private List removeIssuesWithCode(List issues, boolean removeWarningsAndInfos, IssueCodes... codes) { + Set excludedIssueCodes = new HashSet<>(); + for (IssueCodes issueCode : codes) { + excludedIssueCodes.add(issueCode.name()); + } return issues.stream() .filter(issue -> (!removeWarningsAndInfos || issue.getSeverity() == Severity.ERROR) && !excludedIssueCodes.contains(issue.getCode())) diff --git a/tests/org.eclipse.n4js.bugreports.tests/xt-pending/IDEBUG_0267_thisTypeInFunctionTEofFields.n4js.xt b/tests/org.eclipse.n4js.bugreports.tests/xt-pending/IDEBUG_0267_thisTypeInFunctionTEofFields.n4js.xt index 9a50da5e57..e039119382 100644 --- a/tests/org.eclipse.n4js.bugreports.tests/xt-pending/IDEBUG_0267_thisTypeInFunctionTEofFields.n4js.xt +++ b/tests/org.eclipse.n4js.bugreports.tests/xt-pending/IDEBUG_0267_thisTypeInFunctionTEofFields.n4js.xt @@ -14,6 +14,6 @@ class A {} class Foo { - // XPECT FIXME noerrors --> "The this type isn't allowed on this place. You can only use it as return type of instance methods or structurally on use site in the constructor." + // XPECT FIXME noerrors --> "The 'this' type isn't allowed on this place. You can only use it as return type of instance methods or structurally on use site in the constructor." a: A<{function(this): void}>; } diff --git a/tests/org.eclipse.n4js.bugreports.tests/xt-tests/GHOLD_0021_InstanceOfPrimitiveTypes.n4js.xt b/tests/org.eclipse.n4js.bugreports.tests/xt-tests/GHOLD_0021_InstanceOfPrimitiveTypes.n4js.xt index bd6bdc5d42..a6705abab1 100644 --- a/tests/org.eclipse.n4js.bugreports.tests/xt-tests/GHOLD_0021_InstanceOfPrimitiveTypes.n4js.xt +++ b/tests/org.eclipse.n4js.bugreports.tests/xt-tests/GHOLD_0021_InstanceOfPrimitiveTypes.n4js.xt @@ -20,16 +20,16 @@ var a = new A(); // Use instanceof with class on rhs XPECT noerrors --> a instanceof A; -// Use instanceof with int on rhs XPECT errors --> "instanceof cannot be used with primitive types." at "int" +// Use instanceof with int on rhs XPECT errors --> "'instanceof' cannot be used with primitive types." at "int" a instanceof int; -// Use instanceof with number on rhs XPECT errors --> "instanceof cannot be used with primitive types." at "number" +// Use instanceof with number on rhs XPECT errors --> "'instanceof' cannot be used with primitive types." at "number" a instanceof number; -// Use instanceof with string on rhs XPECT errors --> "instanceof cannot be used with primitive types." at "string" +// Use instanceof with string on rhs XPECT errors --> "'instanceof' cannot be used with primitive types." at "string" a instanceof string; -// Use instanceof with nested paranthesis structure on rhs XPECT errors --> "instanceof cannot be used with primitive types." at "string" +// Use instanceof with nested paranthesis structure on rhs XPECT errors --> "'instanceof' cannot be used with primitive types." at "string" a instanceof (((string))); diff --git a/tests/org.eclipse.n4js.bugreports.tests/xt-tests/IDEBUG_0279_functionTypeBounds.n4js.xt b/tests/org.eclipse.n4js.bugreports.tests/xt-tests/IDEBUG_0279_functionTypeBounds.n4js.xt index be91c56d61..71a33474dc 100644 --- a/tests/org.eclipse.n4js.bugreports.tests/xt-tests/IDEBUG_0279_functionTypeBounds.n4js.xt +++ b/tests/org.eclipse.n4js.bugreports.tests/xt-tests/IDEBUG_0279_functionTypeBounds.n4js.xt @@ -45,7 +45,7 @@ var g : G; g.ptr(a); // XPECT errors --> "any is not a subtype of ? extends A." at "top" g.ptr(top); -// no errors, but a warning XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "bot" +// no errors, but a warning XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "bot" g.ptr(bot); // XPECT noerrors --> diff --git a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Class_x_This/01_in_methods.n4js.xt b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Class_x_This/01_in_methods.n4js.xt index 5bee9858da..2c9badc555 100644 --- a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Class_x_This/01_in_methods.n4js.xt +++ b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Class_x_This/01_in_methods.n4js.xt @@ -16,13 +16,13 @@ ///////////////////////// class A { - // cannot use this as field type XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" + // cannot use this as field type XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" t : this; // this as return type XPECT noerrors --> f() : this { return this; } - // cannot use this in static methods X!PECT errors --> "The this type isn't allowed on this place. You can only use it as return type of instance methods or structurally on use site in the constructor." at "this" + // cannot use this in static methods X!PECT errors --> "The 'this' type isn't allowed on this place. You can only use it as return type of instance methods or structurally on use site in the constructor." at "this" // this in static methods only for n4jsd-files, this in body not instance-type but class type. // XPECT errors --> "constructor{this[A]} is not a subtype of this[A]." at "this" static fStatic() : this { return this; } diff --git a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Role_x_This/01_in_methods.n4js.xt b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Role_x_This/01_in_methods.n4js.xt index 52935d19f7..b8cdd51c79 100644 --- a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Role_x_This/01_in_methods.n4js.xt +++ b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Role_x_This/01_in_methods.n4js.xt @@ -16,7 +16,7 @@ ///////////////////////// interface A { - // cannot use this as field type XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" + // cannot use this as field type XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" t : this; // this as return type XPECT noerrors --> diff --git a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/IssueConfigurationTest.java b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/IssueConfigurationTest.java index 4d3b1e0793..79ff309ba6 100644 --- a/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/IssueConfigurationTest.java +++ b/tests/org.eclipse.n4js.ide.tests.helper.tests/src/org/eclipse/n4js/ide/tests/helper/server/xt/tests/IssueConfigurationTest.java @@ -30,10 +30,10 @@ public void test() throws Exception { // The test file IssuesConfiguration.n4js.xt is based on the assumption that certain issues are suppressed in // all tests by default. Make sure this test fails if the default suppression no longer meets this expectation: Set suppressed = N4JSLanguageConstants.DEFAULT_SUPPRESSED_ISSUE_CODES_FOR_TESTS; - assertTrue(suppressed.contains(IssueCodes.DFG_NULL_DEREFERENCE)); - assertTrue(suppressed.contains(IssueCodes.CFG_LOCAL_VAR_UNUSED)); - assertFalse(suppressed.contains(IssueCodes.CLF_NAME_DOES_NOT_START_UPPERCASE)); - assertFalse(suppressed.contains(IssueCodes.CLF_NAME_DOES_NOT_START_LOWERCASE)); + assertTrue(suppressed.contains(IssueCodes.DFG_NULL_DEREFERENCE.name())); + assertTrue(suppressed.contains(IssueCodes.CFG_LOCAL_VAR_UNUSED.name())); + assertFalse(suppressed.contains(IssueCodes.CLF_NAME_DOES_NOT_START_UPPERCASE.name())); + assertFalse(suppressed.contains(IssueCodes.CLF_NAME_DOES_NOT_START_LOWERCASE.name())); run("probands/IssueConfiguration", suppressed); assertEventNames("testSuiteStarted - org.eclipse.n4js.ide.tests.helper.server.xt.tests.XtTestSetupTestMockup\n" diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/bugreports/GH_1943_ExceptionInCaseOfSemverSyntaxErrorTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/bugreports/GH_1943_ExceptionInCaseOfSemverSyntaxErrorTest.java index d4b668c968..e11d610fdb 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/bugreports/GH_1943_ExceptionInCaseOfSemverSyntaxErrorTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/bugreports/GH_1943_ExceptionInCaseOfSemverSyntaxErrorTest.java @@ -49,8 +49,8 @@ public void testVersionConstraintWithSyntaxError() { startAndWaitForLspServer(); assertIssues2(Pair.of( "ProjectMain/" + PACKAGE_JSON, List.of( - "(Error, [10:19 - 10:21], Invalid version number \"^1..3\": no viable alternative at input '.'.)", - "(Error, [11:17 - 11:21], Invalid version number \"^.2.3\": no viable alternative at input '.'.)"))); + "(Error, [10:19 - 10:21], Invalid version number '^1..3': no viable alternative at input '.'.)", + "(Error, [11:17 - 11:21], Invalid version number '^.2.3': no viable alternative at input '.'.)"))); assertNoErrorsInLogOrOutput(); } } diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/IncrementalBuilderReexportTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/IncrementalBuilderReexportTest.java index 3a09e30e9f..70d9350c89 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/IncrementalBuilderReexportTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/IncrementalBuilderReexportTest.java @@ -29,7 +29,7 @@ public class IncrementalBuilderReexportTest extends AbstractIncrementalBuilderTe protected Set getIgnoredIssueCodes() { // note: this test is testing internal infrastructure for a feature not available in N4JS[D] (only in .d.ts) HashSet iic = new HashSet<>(super.getIgnoredIssueCodes()); - iic.add(IssueCodes.UNSUPPORTED); + iic.add(IssueCodes.UNSUPPORTED.name()); return iic; } diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/IncrementalBuilderWorkspaceChangesTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/IncrementalBuilderWorkspaceChangesTest.java index 4def66d57b..6c246c317f 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/IncrementalBuilderWorkspaceChangesTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/IncrementalBuilderWorkspaceChangesTest.java @@ -214,7 +214,7 @@ class MainClass {}; assertIssues2(Pair.of( "MainProject/package.json", List.of( - "(Warning, [1:9 - 1:25], As a convention the package name \"RenamedProject\" should match the name of the project folder \"MainProject\" on the file system.)"))); + "(Warning, [1:9 - 1:25], As a convention the package name 'RenamedProject' should match the name of the project folder 'MainProject' on the file system.)"))); } @Test @@ -249,7 +249,7 @@ public m() {} assertIssues2( Pair.of("MainProject/package.json", List.of( - "(Warning, [1:9 - 1:25], As a convention the package name \"RenamedProject\" should match the name of the project folder \"MainProject\" on the file system.)"))); + "(Warning, [1:9 - 1:25], As a convention the package name 'RenamedProject' should match the name of the project folder 'MainProject' on the file system.)"))); } @Test @@ -284,7 +284,7 @@ public m() {} assertIssues2(Map.of( "OtherProject/package.json", List.of( - " (Warning, [1:9 - 1:25], As a convention the package name \"RenamedProject\" should match the name of the project folder \"OtherProject\" on the file system.)"), + " (Warning, [1:9 - 1:25], As a convention the package name 'RenamedProject' should match the name of the project folder 'OtherProject' on the file system.)"), "MainProject/package.json", List.of( " (Error, [16:3 - 16:21], Project does not exist with project ID: OtherProject.)"), "Main.n4js", List.of( @@ -302,7 +302,7 @@ public m() {} assertIssues2(Map.of( "OtherProject/package.json", List.of( - "(Warning, [1:9 - 1:25], As a convention the package name \"RenamedProject\" should match the name of the project folder \"OtherProject\" on the file system.)"))); + "(Warning, [1:9 - 1:25], As a convention the package name 'RenamedProject' should match the name of the project folder 'OtherProject' on the file system.)"))); } @Test diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnDifferentPackageNames.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnDifferentPackageNames.java index e288533359..03b341b558 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnDifferentPackageNames.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnDifferentPackageNames.java @@ -68,7 +68,7 @@ public void twoEqualProjectNames() throws Exception { startAndWaitForLspServer(); assertIssues2(Map.of("library-project/package.json", List.of( - "(Warning, [1:10 - 1:38], As a convention the package name \"library-project-other-name\" should match the name of the project folder \"library-project\" on the file system.)"))); + "(Warning, [1:10 - 1:38], As a convention the package name 'library-project-other-name' should match the name of the project folder 'library-project' on the file system.)"))); assertOutputFileExists("main-project", "MainModule"); assertOutputFileExists("library-project", "LibraryModule"); diff --git a/tests/org.eclipse.n4js.jsdoc2spec.tests/src/org/eclipse/n4js/jsdoc2spec/adoc/JSDoc2AdocFullTest.java b/tests/org.eclipse.n4js.jsdoc2spec.tests/src/org/eclipse/n4js/jsdoc2spec/adoc/JSDoc2AdocFullTest.java index 2e7fd8a9fa..022fd9fea1 100644 --- a/tests/org.eclipse.n4js.jsdoc2spec.tests/src/org/eclipse/n4js/jsdoc2spec/adoc/JSDoc2AdocFullTest.java +++ b/tests/org.eclipse.n4js.jsdoc2spec.tests/src/org/eclipse/n4js/jsdoc2spec/adoc/JSDoc2AdocFullTest.java @@ -72,7 +72,7 @@ protected void fullTest(String projectName) FileURI packageJsonURI = toFileURI(getProjectLocation()).appendSegments(projectName, N4JSGlobals.PACKAGE_JSON); assertIssues(Map.of( packageJsonURI, Lists.newArrayList( - "(Error, [4:17 - 4:26], Missing dependency to n4js-runtime (mandatory for all N4JS projects of type library, application, test).)"))); + "(Error, [4:17 - 4:26], Missing dependency to 'n4js-runtime' (mandatory for all N4JS projects of type library, application, test).)"))); String systemSeparator = System.getProperty("line.separator", "\n"); try { diff --git a/tests/org.eclipse.n4js.json.xpect.tests/xt-tests/validation/DuplicateKeys.json.xt b/tests/org.eclipse.n4js.json.xpect.tests/xt-tests/validation/DuplicateKeys.json.xt index 63ad619411..3f0af4aba3 100644 --- a/tests/org.eclipse.n4js.json.xpect.tests/xt-tests/validation/DuplicateKeys.json.xt +++ b/tests/org.eclipse.n4js.json.xpect.tests/xt-tests/validation/DuplicateKeys.json.xt @@ -13,7 +13,7 @@ { "a": 1, "b": 2, - // Duplicate key is detected by validation XPECT warnings --> "Property a duplicates property a (line 14)." at ""a"" + // Duplicate key is detected by validation XPECT warnings --> "Duplicate property a (line 14)." at ""a"" "a": "str", "nested": { // Differently nested key is not detected as duplicate XPECT noerrors diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/n4jsx/lang/tests/parser/JSXParserTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/n4jsx/lang/tests/parser/JSXParserTest.java index c803b3c3e4..c3d45e1ef6 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/n4jsx/lang/tests/parser/JSXParserTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/n4jsx/lang/tests/parser/JSXParserTest.java @@ -218,7 +218,7 @@ public void testInvalidAttributeNames_01() throws Exception { parseWithError(""" """, - "JSX attribute names may not contain whitespace or comments. Attribute names ending with a - and directly followed by another attribute name are merged and must not contain whitespace or comments."); + "JSX attribute names may not contain whitespace or comments. Attribute names ending with a '-' and directly followed by another attribute name are merged and must not contain whitespace or comments."); } @Test @@ -226,7 +226,7 @@ public void testInvalidAttributeNames_02() throws Exception { parseWithError(""" """, - "JSX attribute names may not contain whitespace or comments. Attribute names ending with a - and directly followed by another attribute name are merged and must not contain whitespace or comments."); + "JSX attribute names may not contain whitespace or comments. Attribute names ending with a '-' and directly followed by another attribute name are merged and must not contain whitespace or comments."); } @Test @@ -234,7 +234,7 @@ public void testInvalidAttributeNames_03() throws Exception { parseWithError(""" """, - "JSX attribute names may not contain whitespace or comments. Attribute names ending with a - and directly followed by another attribute name are merged and must not contain whitespace or comments."); + "JSX attribute names may not contain whitespace or comments. Attribute names ending with a '-' and directly followed by another attribute name are merged and must not contain whitespace or comments."); } @Test diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/scoping/builtin/BuiltInTypesDefinitionTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/scoping/builtin/BuiltInTypesDefinitionTest.java index f6bbb1f88e..983ecedcf2 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/scoping/builtin/BuiltInTypesDefinitionTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/scoping/builtin/BuiltInTypesDefinitionTest.java @@ -97,7 +97,8 @@ private void doValidatePredefinedTypes(XtextResourceSet rs, boolean loadOnDemand + join("\n ", allIssues), allIssues.size() == 1 && allIssues.get(0).getSeverity() == Severity.WARNING); validationTestHelper.assertWarning(resource, N4JSPackage.Literals.N4_FIELD_DECLARATION, - IssueCodes.CLF_NO_FINAL_INTERFACE_MEMBER, "In interfaces, only methods may be declared final."); + IssueCodes.CLF_NO_FINAL_INTERFACE_MEMBER.name(), + "In interfaces, only methods may be declared final."); } else { assertTrue(resourceName + " must not contain any validation issues, but got:\n " + join("\n ", allIssues), allIssues.isEmpty()); diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/parser/N4_SyntaxErrorTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/parser/N4_SyntaxErrorTest.java index a88db00f66..8c1ebdfc77 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/parser/N4_SyntaxErrorTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/parser/N4_SyntaxErrorTest.java @@ -10,6 +10,7 @@ */ package org.eclipse.n4js.tests.parser; +import static org.eclipse.n4js.validation.IssueCodes.AST_INVALID_FOR_AWAIT; import static org.eclipse.xtext.xbase.lib.IterableExtensions.last; import java.util.List; @@ -32,7 +33,6 @@ import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression; import org.eclipse.n4js.ts.typeRefs.TypeTypeRef; import org.eclipse.n4js.utils.Strings; -import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.linking.impl.XtextLinkingDiagnostic; import org.eclipse.xtext.nodemodel.ICompositeNode; import org.eclipse.xtext.nodemodel.impl.InvariantChecker; @@ -556,7 +556,7 @@ public void testForAwaitOf01() { """); List errors = script.eResource().getErrors(); assertEquals(1, errors.size()); - assertEquals(IssueCodes.AST_INVALID_FOR_AWAIT, ((XtextLinkingDiagnostic) errors.get(0)).getCode()); + assertEquals(AST_INVALID_FOR_AWAIT.name(), ((XtextLinkingDiagnostic) errors.get(0)).getCode()); } @Test @@ -566,7 +566,7 @@ public void testForAwaitOf02() { """); List errors = script.eResource().getErrors(); assertEquals(1, errors.size()); - assertEquals(IssueCodes.AST_INVALID_FOR_AWAIT, ((XtextLinkingDiagnostic) errors.get(0)).getCode()); + assertEquals(AST_INVALID_FOR_AWAIT.name(), ((XtextLinkingDiagnostic) errors.get(0)).getCode()); } @Test diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/parser/regex/RegexInN4JSParserTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/parser/regex/RegexInN4JSParserTest.java index 3b63286346..a6ccfb006b 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/parser/regex/RegexInN4JSParserTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/parser/regex/RegexInN4JSParserTest.java @@ -58,7 +58,7 @@ public void testRegExCaptureGroupWarning_01() throws Exception { List warnings = script.eResource().getWarnings(); assertEquals(1, warnings.size()); XtextSyntaxDiagnostic error = (XtextSyntaxDiagnostic) warnings.get(0); - assertEquals(IssueCodes.getMessageForVCO_REGEX_NAMED_GROUP(), error.getMessage()); + assertEquals(IssueCodes.VCO_REGEX_NAMED_GROUP.getMessage(), error.getMessage()); assertEquals(3, error.getLength()); assertEquals(1, error.getLine()); assertEquals(4, error.getOffset()); @@ -70,7 +70,7 @@ public void testRegExCaptureGroupWarning_02() throws Exception { List warnings = script.eResource().getWarnings(); assertEquals(2, warnings.size()); XtextSyntaxDiagnostic error = (XtextSyntaxDiagnostic) IterableExtensions.last(warnings); - assertEquals(IssueCodes.getMessageForVCO_REGEX_NAMED_GROUP(), error.getMessage()); + assertEquals(IssueCodes.VCO_REGEX_NAMED_GROUP.getMessage(), error.getMessage()); assertEquals(2, error.getLength()); assertEquals(1, error.getLine()); assertEquals(11, error.getOffset()); @@ -94,7 +94,7 @@ public void testRegExCaptureGroupWarning_04() throws Exception { List warnings = script.eResource().getWarnings(); assertEquals(1, warnings.size()); XtextSyntaxDiagnostic error = (XtextSyntaxDiagnostic) warnings.get(0); - assertEquals(IssueCodes.getMessageForVCO_REGEX_NAMED_GROUP(), error.getMessage()); + assertEquals(IssueCodes.VCO_REGEX_NAMED_GROUP.getMessage(), error.getMessage()); assertEquals(5, error.getLength()); assertEquals(2, error.getLine()); assertEquals(7, error.getOffset()); @@ -106,7 +106,7 @@ public void testRegExCaptureGroupWarningAfterEscapeSequence_01() throws Exceptio List warnings = script.eResource().getWarnings(); assertEquals(1, warnings.size()); XtextSyntaxDiagnostic error = (XtextSyntaxDiagnostic) warnings.get(0); - assertEquals(IssueCodes.getMessageForVCO_REGEX_NAMED_GROUP(), error.getMessage()); + assertEquals(IssueCodes.VCO_REGEX_NAMED_GROUP.getMessage(), error.getMessage()); assertEquals(4, error.getLength()); assertEquals(1, error.getLine()); assertEquals(12, error.getOffset()); @@ -118,7 +118,7 @@ public void testRegExCaptureGroupWarningAfterEscapeSequence_02() throws Exceptio List warnings = script.eResource().getWarnings(); assertEquals(1, warnings.size()); XtextSyntaxDiagnostic error = (XtextSyntaxDiagnostic) warnings.get(0); - assertEquals(IssueCodes.getMessageForVCO_REGEX_NAMED_GROUP(), error.getMessage()); + assertEquals(IssueCodes.VCO_REGEX_NAMED_GROUP.getMessage(), error.getMessage()); assertEquals(4, error.getLength()); assertEquals(1, error.getLine()); assertEquals(14, error.getOffset()); @@ -130,7 +130,7 @@ public void testRegExCaptureGroupWarningAfterEscapeSequence_03() throws Exceptio List warnings = script.eResource().getWarnings(); assertEquals(1, warnings.size()); XtextSyntaxDiagnostic error = (XtextSyntaxDiagnostic) warnings.get(0); - assertEquals(IssueCodes.getMessageForVCO_REGEX_NAMED_GROUP(), error.getMessage()); + assertEquals(IssueCodes.VCO_REGEX_NAMED_GROUP.getMessage(), error.getMessage()); assertEquals(4, error.getLength()); assertEquals(1, error.getLine()); assertEquals(14, error.getOffset()); @@ -142,7 +142,7 @@ public void testRegExCaptureGroupWarningAfterEscapeSequence_04() throws Exceptio List warnings = script.eResource().getWarnings(); assertEquals(1, warnings.size()); XtextSyntaxDiagnostic error = (XtextSyntaxDiagnostic) warnings.get(0); - assertEquals(IssueCodes.getMessageForVCO_REGEX_NAMED_GROUP(), error.getMessage()); + assertEquals(IssueCodes.VCO_REGEX_NAMED_GROUP.getMessage(), error.getMessage()); assertEquals(4, error.getLength()); assertEquals(1, error.getLine()); assertEquals(23, error.getOffset()); @@ -154,7 +154,7 @@ public void testRegExIllegalEscapeSequence_01() throws Exception { List errors = script.eResource().getErrors(); assertEquals(1, errors.size()); XtextSyntaxDiagnostic error = (XtextSyntaxDiagnostic) errors.get(0); - assertEquals(IssueCodes.getMessageForVCO_REGEX_ILLEGAL_ESCAPE("/\\u1/"), error.getMessage()); + assertEquals(IssueCodes.VCO_REGEX_ILLEGAL_ESCAPE.getMessage("/\\u1/"), error.getMessage()); assertEquals(1, error.getLength()); assertEquals(1, error.getLine()); assertEquals(4, error.getOffset()); diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/AT_084_Test.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/AT_084_Test.java index 4916a3b696..b18e470794 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/AT_084_Test.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/AT_084_Test.java @@ -10,6 +10,14 @@ */ package org.eclipse.n4js.tests.scoping; +import static org.eclipse.n4js.validation.IssueCodes.IMP_AMBIGUOUS; +import static org.eclipse.n4js.validation.IssueCodes.IMP_LOCAL_NAME_CONFLICT; +import static org.eclipse.n4js.validation.IssueCodes.IMP_NOT_EXPORTED; +import static org.eclipse.n4js.validation.IssueCodes.IMP_UNUSED_IMPORT; +import static org.eclipse.n4js.validation.IssueCodes.VIS_ILLEGAL_FUN_ACCESS; +import static org.eclipse.n4js.validation.IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS; +import static org.eclipse.n4js.validation.IssueCodes.VIS_ILLEGAL_TYPE_ACCESS; +import static org.eclipse.n4js.validation.IssueCodes.VIS_ILLEGAL_VARIABLE_ACCESS; import static org.eclipse.xtext.xbase.lib.IteratorExtensions.filter; import static org.eclipse.xtext.xbase.lib.IteratorExtensions.head; @@ -20,7 +28,6 @@ import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; import org.eclipse.n4js.ts.typeRefs.TypeRefsPackage; import org.eclipse.n4js.ts.types.TModule; -import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.resource.XtextResourceSet; import org.eclipse.xtext.testing.InjectWith; import org.eclipse.xtext.testing.XtextRunner; @@ -70,10 +77,10 @@ export public class Dup {} var d = new Dup(); """, URI.createURI("C.n4js"), rs), "A", "B"); - valTestHelper.assertError(script, N4JSPackage.Literals.IDENTIFIER_REF, IssueCodes.IMP_AMBIGUOUS, + valTestHelper.assertError(script, N4JSPackage.Literals.IDENTIFIER_REF, IMP_AMBIGUOUS.name(), "The type Dup is ambiguously imported from A and B"); valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, - IssueCodes.IMP_LOCAL_NAME_CONFLICT, "Name Dup is already used as name for named import Dup from A."); + IMP_LOCAL_NAME_CONFLICT.name(), "Name Dup is already used as name for named import Dup from A."); } /** @@ -95,10 +102,10 @@ public void test_02() throws Exception { var d = dup """, URI.createURI("C.n4js"), rs); - valTestHelper.assertError(script, N4JSPackage.Literals.IDENTIFIER_REF, IssueCodes.IMP_AMBIGUOUS, + valTestHelper.assertError(script, N4JSPackage.Literals.IDENTIFIER_REF, IMP_AMBIGUOUS.name(), "The variable dup is ambiguously imported from A and B"); valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, - IssueCodes.IMP_LOCAL_NAME_CONFLICT, "Name dup is already used as name for named import Dup from A."); + IMP_LOCAL_NAME_CONFLICT.name(), "Name dup is already used as name for named import Dup from A."); } @Test @@ -117,13 +124,13 @@ public void test_03() throws Exception { var d = dup """, URI.createURI("C.n4js"), rs); - valTestHelper.assertNoError(script, IssueCodes.IMP_AMBIGUOUS); - valTestHelper.assertNoIssue(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IssueCodes.IMP_UNUSED_IMPORT); + valTestHelper.assertNoError(script, IMP_AMBIGUOUS.name()); + valTestHelper.assertNoIssue(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IMP_UNUSED_IMPORT.name()); // Since A.dup cannot be linked, import is unused, but also marked with linking error; - valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IssueCodes.IMP_NOT_EXPORTED, + valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IMP_NOT_EXPORTED.name(), "Element dup is not exported."); valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, - IssueCodes.IMP_LOCAL_NAME_CONFLICT, "Name dup is already used as name for named import dup from A."); + IMP_LOCAL_NAME_CONFLICT.name(), "Name dup is already used as name for named import dup from A."); } @Test @@ -141,13 +148,13 @@ public void test_04() throws Exception { var d = dup """, URI.createURI("C.n4js"), rs); - valTestHelper.assertNoError(script, IssueCodes.IMP_AMBIGUOUS); - valTestHelper.assertNoIssue(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IssueCodes.IMP_UNUSED_IMPORT); + valTestHelper.assertNoError(script, IMP_AMBIGUOUS.name()); + valTestHelper.assertNoIssue(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IMP_UNUSED_IMPORT.name()); // Since A.dup cannot be linked, an error is shown - valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IssueCodes.IMP_NOT_EXPORTED, + valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IMP_NOT_EXPORTED.name(), "Element dup is not exported."); valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, - IssueCodes.IMP_LOCAL_NAME_CONFLICT, "Name dup is already used as name for named import dup from A."); + IMP_LOCAL_NAME_CONFLICT.name(), "Name dup is already used as name for named import dup from A."); } @Test @@ -164,11 +171,11 @@ public void test_05() throws Exception { import {dup} from "B"; var d = dup """, URI.createURI("C.n4js"), rs), "A", "B"); - valTestHelper.assertNoError(script, IssueCodes.IMP_AMBIGUOUS); + valTestHelper.assertNoError(script, IMP_AMBIGUOUS.name()); valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, - IssueCodes.VIS_ILLEGAL_VARIABLE_ACCESS, "The variable dup is not visible."); + VIS_ILLEGAL_VARIABLE_ACCESS.name(), "The variable dup is not visible."); valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, - IssueCodes.IMP_LOCAL_NAME_CONFLICT, "Name dup is already used as name for named import dup from A."); + IMP_LOCAL_NAME_CONFLICT.name(), "Name dup is already used as name for named import dup from A."); } @Test @@ -186,12 +193,12 @@ public void test_06() throws Exception { var d = dup """, URI.createURI("C.n4js"), rs), "C", "B"); - valTestHelper.assertNoError(script, IssueCodes.IMP_AMBIGUOUS); + valTestHelper.assertNoError(script, IMP_AMBIGUOUS.name()); valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, - IssueCodes.IMP_LOCAL_NAME_CONFLICT, "Name dup is already used as name for named import dup from A."); + IMP_LOCAL_NAME_CONFLICT.name(), "Name dup is already used as name for named import dup from A."); valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, - IssueCodes.VIS_ILLEGAL_VARIABLE_ACCESS, "The variable dup is not visible."); - valTestHelper.assertError(script, N4JSPackage.Literals.IDENTIFIER_REF, IssueCodes.VIS_ILLEGAL_VARIABLE_ACCESS, + VIS_ILLEGAL_VARIABLE_ACCESS.name(), "The variable dup is not visible."); + valTestHelper.assertError(script, N4JSPackage.Literals.IDENTIFIER_REF, VIS_ILLEGAL_VARIABLE_ACCESS.name(), "The variable dup is not visible."); } @@ -210,12 +217,12 @@ public void test_07() throws Exception { var d = dup """, URI.createURI("C.n4js"), rs), "C", "B"); - valTestHelper.assertNoError(script, IssueCodes.IMP_AMBIGUOUS); + valTestHelper.assertNoError(script, IMP_AMBIGUOUS.name()); valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, - IssueCodes.IMP_LOCAL_NAME_CONFLICT, "Name dup is already used as name for named import dup from A."); + IMP_LOCAL_NAME_CONFLICT.name(), "Name dup is already used as name for named import dup from A."); valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, - IssueCodes.VIS_ILLEGAL_VARIABLE_ACCESS, "The variable dup is not visible."); - valTestHelper.assertError(script, N4JSPackage.Literals.IDENTIFIER_REF, IssueCodes.VIS_ILLEGAL_VARIABLE_ACCESS, + VIS_ILLEGAL_VARIABLE_ACCESS.name(), "The variable dup is not visible."); + valTestHelper.assertError(script, N4JSPackage.Literals.IDENTIFIER_REF, VIS_ILLEGAL_VARIABLE_ACCESS.name(), "The variable dup is not visible."); } @@ -243,7 +250,7 @@ class A {} import {A} from "A"; """, URI.createURI("C.n4js"), rs), "C", "B"); - valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IssueCodes.IMP_NOT_EXPORTED, + valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IMP_NOT_EXPORTED.name(), "Element A is not exported."); } @@ -257,7 +264,7 @@ export public class A {} import {A} from "A"; """, URI.createURI("C.n4js"), rs), "C", "B"); - valTestHelper.assertWarning(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IssueCodes.IMP_UNUSED_IMPORT, + valTestHelper.assertWarning(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IMP_UNUSED_IMPORT.name(), "The import of A is unused."); } @@ -272,7 +279,7 @@ class A {} var a: N.A = null """, URI.createURI("C.n4js"), rs), "C", "B"); - valTestHelper.assertError(script, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF, IssueCodes.IMP_NOT_EXPORTED, + valTestHelper.assertError(script, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF, IMP_NOT_EXPORTED.name(), "Element A is not exported."); } @@ -288,7 +295,7 @@ class A {} """, URI.createURI("C.n4js"), rs), "C", "B"); valTestHelper.assertError(script, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF, - IssueCodes.VIS_ILLEGAL_TYPE_ACCESS, "The type A is not visible"); + VIS_ILLEGAL_TYPE_ACCESS.name(), "The type A is not visible"); } @Test @@ -303,7 +310,7 @@ class A {} """, URI.createURI("C.n4js"), rs), "C", "B"); valTestHelper.assertError(script, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION, - IssueCodes.IMP_NOT_EXPORTED, "Element A is not exported."); + IMP_NOT_EXPORTED.name(), "Element A is not exported."); } @Test @@ -317,9 +324,9 @@ class A {} var a = A """, URI.createURI("C.n4js"), rs), "C", "B"); - valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IssueCodes.IMP_NOT_EXPORTED, + valTestHelper.assertError(script, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER, IMP_NOT_EXPORTED.name(), "Element A is not exported."); - valTestHelper.assertError(script, N4JSPackage.Literals.IDENTIFIER_REF, IssueCodes.VIS_ILLEGAL_TYPE_ACCESS, + valTestHelper.assertError(script, N4JSPackage.Literals.IDENTIFIER_REF, VIS_ILLEGAL_TYPE_ACCESS.name(), "The type A is not visible"); } @@ -334,7 +341,7 @@ class A {} var a: N.A = "" """, URI.createURI("C.n4js"), rs), "C", "B"); - valTestHelper.assertError(script, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF, IssueCodes.IMP_NOT_EXPORTED, + valTestHelper.assertError(script, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF, IMP_NOT_EXPORTED.name(), "Element A is not exported."); } @@ -352,7 +359,7 @@ export class A {} var a: N.A = "" """, URI.createURI("C.n4js?C|B"), rs), "C", "B"); - valTestHelper.assertNoError(script, IssueCodes.VIS_ILLEGAL_TYPE_ACCESS); + valTestHelper.assertNoError(script, VIS_ILLEGAL_TYPE_ACCESS.name()); ParameterizedTypeRef typeRef = head(filter(script.eAllContents(), ParameterizedTypeRef.class)); Assert.assertEquals("A.n4js?C|B", typeRef.getDeclaredType().eResource().getURI().toString()); } @@ -383,7 +390,7 @@ public void test_17() throws Exception { """, URI.createURI("B.n4js"), rs), "B", "C"); valTestHelper.assertError(script, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION, - IssueCodes.VIS_ILLEGAL_VARIABLE_ACCESS, "The variable s is not visible"); + VIS_ILLEGAL_VARIABLE_ACCESS.name(), "The variable s is not visible"); } @Test @@ -440,7 +447,7 @@ public void test_21() throws Exception { """, URI.createURI("B.n4js"), rs), "B", "C"); valTestHelper.assertError(script, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION, - IssueCodes.VIS_ILLEGAL_FUN_ACCESS, "The function f is not visible"); + VIS_ILLEGAL_FUN_ACCESS.name(), "The function f is not visible"); } @Test @@ -497,9 +504,9 @@ public void test_25() throws Exception { """, URI.createURI("B.n4js"), rs), "B", "C"); valTestHelper.assertError(script, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION, - IssueCodes.VIS_ILLEGAL_TYPE_ACCESS, "The type E is not visible"); + VIS_ILLEGAL_TYPE_ACCESS.name(), "The type E is not visible"); valTestHelper.assertError(script, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION, - IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS, "The enum literal Literal is not visible"); + VIS_ILLEGAL_MEMBER_ACCESS.name(), "The enum literal Literal is not visible"); } @Test @@ -550,7 +557,7 @@ export public class Sub extends Base {} """, URI.createURI("B.n4js"), rs), "B", "C"); valTestHelper.assertError(script, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION, - IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS, "The method m is not visible"); + VIS_ILLEGAL_MEMBER_ACCESS.name(), "The method m is not visible"); } @Test @@ -585,7 +592,7 @@ private m(): void {} """, URI.createURI("B.n4js"), rs), "A", "B"); valTestHelper.assertError(script, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION, - IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS, "The method m is not visible"); + VIS_ILLEGAL_MEMBER_ACCESS.name(), "The method m is not visible"); } @Test @@ -624,6 +631,6 @@ export class C extends B {} """, URI.createURI("B.n4js"), rs), "A", "C"); valTestHelper.assertError(script, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION, - IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS, "The method m is not visible"); + VIS_ILLEGAL_MEMBER_ACCESS.name(), "The method m is not visible"); } } diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/AT_556_MemberAccessTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/AT_556_MemberAccessTest.java index 85661375cf..8d2ea601b3 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/AT_556_MemberAccessTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/AT_556_MemberAccessTest.java @@ -10,6 +10,7 @@ */ package org.eclipse.n4js.tests.scoping; +import static org.eclipse.n4js.validation.IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS; import static org.junit.Assert.fail; import org.eclipse.emf.common.util.URI; @@ -17,7 +18,6 @@ import org.eclipse.n4js.n4JS.N4JSPackage; import org.eclipse.n4js.n4JS.Script; import org.eclipse.n4js.ts.types.TModule; -import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.resource.XtextResourceSet; import org.eclipse.xtext.testing.InjectWith; import org.eclipse.xtext.testing.XtextRunner; @@ -69,7 +69,7 @@ export public class C { valTestHelper.assertNoErrors(script); else valTestHelper.assertError(script, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION, - IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS, "The method m is not visible"); + VIS_ILLEGAL_MEMBER_ACCESS.name(), "The method m is not visible"); } catch (Exception e) { fail(); } @@ -112,7 +112,7 @@ export public class C { valTestHelper.assertNoErrors(script); else valTestHelper.assertError(script, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION, - IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS, "The method m is not visible"); + VIS_ILLEGAL_MEMBER_ACCESS.name(), "The method m is not visible"); } catch (Exception e) { fail(); @@ -136,7 +136,7 @@ export public class C { valTestHelper.assertNoErrors(script); else valTestHelper.assertError(script, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION, - IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS, "The method m is not visible"); + VIS_ILLEGAL_MEMBER_ACCESS.name(), "The method m is not visible"); } catch (Exception e) { fail(); @@ -192,7 +192,7 @@ class E extends D { valTestHelper.assertNoErrors(scriptNoAPI); else valTestHelper.assertError(scriptNoAPI, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION, - IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS, "The method %s1 is not visible".formatted(member)); + VIS_ILLEGAL_MEMBER_ACCESS.name(), "The method %s1 is not visible".formatted(member)); } catch (Exception e) { fail(); @@ -507,6 +507,6 @@ class C { } """, URI.createURI("B.n4js"), rs), "A", "C"); valTestHelper.assertError(script, N4JSPackage.Literals.PARAMETERIZED_PROPERTY_ACCESS_EXPRESSION, - IssueCodes.VIS_ILLEGAL_MEMBER_ACCESS, "The method a is not visible"); + VIS_ILLEGAL_MEMBER_ACCESS.name(), "The method a is not visible"); } } diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/ExportDefinitionInCyclicResourcesTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/ExportDefinitionInCyclicResourcesTest.java index 0c8c3e4f2c..28d742ee16 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/ExportDefinitionInCyclicResourcesTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/ExportDefinitionInCyclicResourcesTest.java @@ -24,6 +24,7 @@ import org.eclipse.n4js.resource.N4JSResource; import org.eclipse.n4js.tests.scoping.ExportDefinitionInCyclicResourcesTest.N4JSInjectorProviderWithoutCycleDetection; import org.eclipse.n4js.ts.types.ExportDefinition; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.linking.lazy.LazyLinkingResource; import org.eclipse.xtext.resource.XtextResourceSet; import org.eclipse.xtext.testing.InjectWith; @@ -590,7 +591,7 @@ private void assertErrors(Script script, List expectedErrors) { N4JSResource res = (N4JSResource) script.eResource(); res.performPostProcessing(); parserHelper.assertNoParseErrors(script); - validationTestHelper.assertErrorsExcept(script, new String[] { UNSUPPORTED }, + validationTestHelper.assertErrorsExcept(script, new IssueCodes[] { UNSUPPORTED }, expectedErrors.toArray(new String[0])); } diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/ExportDefinitionTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/ExportDefinitionTest.java index 1cac5d7c82..dbb69a7ea8 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/ExportDefinitionTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/ExportDefinitionTest.java @@ -95,7 +95,7 @@ public class Cls {} assertEquals("Cls", elems.get(1).getName().toString()); assertSame(cls, elems.get(1).getEObjectOrProxy()); assertTrue(elems.get(1) instanceof IEObjectDescriptionWithError); - assertEquals(IMP_NOT_EXPORTED, ((IEObjectDescriptionWithError) elems.get(1)).getIssueCode()); + assertEquals(IMP_NOT_EXPORTED.name(), ((IEObjectDescriptionWithError) elems.get(1)).getIssueCode()); } @Test @@ -288,6 +288,6 @@ public void testOnlyIndirectlyExported_variable() throws Exception { assertEquals("v", elems.get(1).getName().toString()); assertSame(v, elems.get(1).getEObjectOrProxy()); assertTrue(elems.get(1) instanceof IEObjectDescriptionWithError); - assertEquals(IMP_NOT_EXPORTED, ((IEObjectDescriptionWithError) elems.get(1)).getIssueCode()); + assertEquals(IMP_NOT_EXPORTED.name(), ((IEObjectDescriptionWithError) elems.get(1)).getIssueCode()); } } diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/StaticScopingTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/StaticScopingTest.java index 2947eac8a5..f056753957 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/StaticScopingTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/scoping/StaticScopingTest.java @@ -10,6 +10,8 @@ */ package org.eclipse.n4js.tests.scoping; +import static org.eclipse.n4js.validation.IssueCodes.CFG_LOCAL_VAR_UNUSED; +import static org.eclipse.n4js.validation.IssueCodes.DFG_NULL_DEREFERENCE; import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; import static org.eclipse.xtext.xbase.lib.IterableExtensions.size; @@ -21,6 +23,7 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; +import java.util.Set; import org.eclipse.n4js.N4JSInjectorProvider; import org.eclipse.n4js.n4JS.N4JSPackage; @@ -39,7 +42,6 @@ import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; import org.eclipse.n4js.utils.Strings; -import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.xtext.resource.IEObjectDescription; import org.eclipse.xtext.scoping.IScopeProvider; import org.eclipse.xtext.testing.InjectWith; @@ -77,8 +79,8 @@ public class StaticScopingTest { IScopeProvider scopeProvider; public List getIssues(Script script) { - return toList(filter(valTestHelper.validate(script), issue -> issue.getCode() != IssueCodes.CFG_LOCAL_VAR_UNUSED - && issue.getCode() != IssueCodes.DFG_NULL_DEREFERENCE)); + return toList(filter(valTestHelper.validate(script), + issue -> !Set.of(CFG_LOCAL_VAR_UNUSED.name(), DFG_NULL_DEREFERENCE.name()).contains(issue.getCode()))); } @Test diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/validation/AT_225_ValidateConflictingImportOnlyOnFirstUsageOfConcreteTypeTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/validation/AT_225_ValidateConflictingImportOnlyOnFirstUsageOfConcreteTypeTest.java index cbc14cdf63..2162583095 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/validation/AT_225_ValidateConflictingImportOnlyOnFirstUsageOfConcreteTypeTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/validation/AT_225_ValidateConflictingImportOnlyOnFirstUsageOfConcreteTypeTest.java @@ -117,7 +117,7 @@ public void test_05() throws Exception { var a: A """, rs); valTestHelper.assertError(script, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF, - IssueCodes.IMP_AMBIGUOUS_WILDCARD, "The type A is ambiguously imported from a.A and b.A"); + IssueCodes.IMP_AMBIGUOUS_WILDCARD.name(), "The type A is ambiguously imported from a.A and b.A"); } @Test @@ -130,7 +130,7 @@ public void test_06() throws Exception { var a: A """, rs); valTestHelper.assertError(script, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF, - IssueCodes.IMP_AMBIGUOUS_WILDCARD, "The type A is ambiguously imported from b.A and a.A"); + IssueCodes.IMP_AMBIGUOUS_WILDCARD.name(), "The type A is ambiguously imported from b.A and a.A"); } // ================ @@ -141,7 +141,7 @@ public void spec_DuplicatedImportStatement_A() throws Exception { import * as N from 'a/X'; """, rs); valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_DECLARATION, - IssueCodes.IMP_STMT_DUPLICATE_NAMESPACE, + IssueCodes.IMP_STMT_DUPLICATE_NAMESPACE.name(), "Duplicate namespace import statement with name N and imported module a/X."); } @@ -151,7 +151,8 @@ public void spec_DuplicatedImportStatement_B() throws Exception { import { X } from 'a/X'; import { X } from 'a/X'; """, rs); - valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_DECLARATION, IssueCodes.IMP_STMT_DUPLICATE_NAMED, + valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_DECLARATION, + IssueCodes.IMP_STMT_DUPLICATE_NAMED.name(), "Duplicate named import statement with local name X and imported module a/X."); } @@ -162,7 +163,8 @@ public void spec_DuplicatedImport_A() throws Exception { import * as N2 from 'a/X'; var x: N1.X; """, rs); - valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_DUPLICATE_NAMESPACE, + valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, + IssueCodes.IMP_DUPLICATE_NAMESPACE.name(), "Element N2.X of a/X is already imported in namespace N1."); } @@ -172,7 +174,7 @@ public void spec_DuplicatedImport_B() throws Exception { import { Z } from 'a/X'; import { Z as Z1 } from 'a/X'; """, rs); - valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_DUPLICATE, + valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_DUPLICATE.name(), "Z from a/X is already imported as Z."); } @@ -182,7 +184,7 @@ public void spec_DuplicatedImport_C() throws Exception { import { Z as Z1 } from 'a/X'; import { Z } from 'a/X'; """, rs); - valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_DUPLICATE, + valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_DUPLICATE.name(), "Z from a/X is already imported as Z1."); } @@ -192,7 +194,7 @@ public void spec_DuplicatedImport_D() throws Exception { import { Z as Z1 } from 'a/X'; import { Z as Z2 } from 'a/X'; """, rs); - valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_DUPLICATE, + valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_DUPLICATE.name(), "Z from a/X is already imported as Z1."); } @@ -202,7 +204,7 @@ public void spec_DuplicatedImport_E() throws Exception { import * as NX from 'a/X'; import { Z } from 'a/X'; """, rs); - valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_DUPLICATE, + valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_DUPLICATE.name(), "Z from a/X is already imported as NX.Z."); } @@ -212,7 +214,7 @@ public void spec_DuplicatedImport_F() throws Exception { import { Z } from 'a/X'; import * as NX from 'a/X'; """, rs); - valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_DUPLICATE, + valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_DUPLICATE.name(), "Z from a/X is already imported as Z."); } @@ -222,7 +224,8 @@ public void spec_NameConflict_A() throws Exception { import * as NX from 'a/X'; import * as NX from 'b/Y'; """, rs); - valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_LOCAL_NAME_CONFLICT, + valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, + IssueCodes.IMP_LOCAL_NAME_CONFLICT.name(), "Name NX is already used as namespace name for a/X."); } @@ -232,7 +235,8 @@ public void spec_NameConflict_B() throws Exception { import { X } from 'a/X'; import { Y as X } from 'b/Y'; """, rs); - valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_LOCAL_NAME_CONFLICT, + valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, + IssueCodes.IMP_LOCAL_NAME_CONFLICT.name(), "Name X is already used as name for named import X from a/X."); } @@ -242,7 +246,8 @@ public void spec_NameConflict_C() throws Exception { import { X as N } from 'a/X'; import * as N from 'b/Y'; """, rs); - valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_LOCAL_NAME_CONFLICT, + valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, + IssueCodes.IMP_LOCAL_NAME_CONFLICT.name(), "Name N is already used as alias name for named import X from a/X."); } @@ -252,7 +257,8 @@ public void spec_NameConflict_D() throws Exception { import * as N from 'a/X'; import { Y as N } from 'b/Y'; """, rs); - valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, IssueCodes.IMP_LOCAL_NAME_CONFLICT, + valTestHelper.assertError(script, N4JSPackage.Literals.IMPORT_SPECIFIER, + IssueCodes.IMP_LOCAL_NAME_CONFLICT.name(), "Name N is already used as namespace name for a/X."); } @@ -262,7 +268,8 @@ public void spec_NameConflict_E() throws Exception { import { X } from 'a/X'; class X{}; """, rs); - valTestHelper.assertError(script, N4JSPackage.Literals.N4_CLASS_DECLARATION, IssueCodes.AST_NAME_DUPLICATE_ERR, + valTestHelper.assertError(script, N4JSPackage.Literals.N4_CLASS_DECLARATION, + IssueCodes.AST_NAME_DUPLICATE_ERR.name(), "Class X duplicates named import X (line 1)."); } @@ -272,7 +279,8 @@ public void spec_NameConflict_F() throws Exception { import * as X from 'a/X'; class X{}; """, rs); - valTestHelper.assertError(script, N4JSPackage.Literals.N4_CLASS_DECLARATION, IssueCodes.AST_NAME_DUPLICATE_ERR, + valTestHelper.assertError(script, N4JSPackage.Literals.N4_CLASS_DECLARATION, + IssueCodes.AST_NAME_DUPLICATE_ERR.name(), "Class X duplicates namespace import specifier X (line 1)."); } @@ -299,7 +307,7 @@ public void spec_AccessAlaisedName() throws Exception { var x: X; """, rs); valTestHelper.assertError(script, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF, - IssueCodes.IMP_PLAIN_ACCESS_OF_ALIASED_TYPE, "X has been imported as XXX."); + IssueCodes.IMP_PLAIN_ACCESS_OF_ALIASED_TYPE.name(), "X has been imported as XXX."); } @Test @@ -309,7 +317,7 @@ public void spec_AccessNamespacedName() throws Exception { var x: X; """, rs); valTestHelper.assertError(script, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF, - IssueCodes.IMP_PLAIN_ACCESS_OF_NAMESPACED_TYPE, "X has been imported as N.X."); + IssueCodes.IMP_PLAIN_ACCESS_OF_NAMESPACED_TYPE.name(), "X has been imported as N.X."); } } diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/validation/AutomaticCancelationTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/validation/AutomaticCancelationTest.java index 7adcaa96b9..1b7a6a876f 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/validation/AutomaticCancelationTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/validation/AutomaticCancelationTest.java @@ -110,7 +110,7 @@ public void testCancelIndicatorGetsInvokedAutomatically() throws Exception { "The field a (line 3) duplicates field a (line 2)." }; for (String expectedErrorMsg : expectedErrorMsgs) { - vth.assertError(s, N4JSPackage.Literals.N4_MEMBER_DECLARATION, IssueCodes.CLF_DUP_MEMBER, + vth.assertError(s, N4JSPackage.Literals.N4_MEMBER_DECLARATION, IssueCodes.CLF_DUP_MEMBER.name(), expectedErrorMsg); } diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/validation/N4JSValidatorTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/validation/N4JSValidatorTest.java index 7b48da982b..b4527a56cd 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/validation/N4JSValidatorTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/validation/N4JSValidatorTest.java @@ -47,7 +47,8 @@ public void testCircularInit() throws Exception { var v = v """); assertTrue(program.eResource().getErrors().isEmpty()); - valTestHelper.assertWarning(program, N4JSPackage.Literals.IDENTIFIER_REF, IssueCodes.AST_VAR_DECL_RECURSIVE); + valTestHelper.assertWarning(program, N4JSPackage.Literals.IDENTIFIER_REF, + IssueCodes.AST_VAR_DECL_RECURSIVE.name()); } @Test @@ -66,8 +67,8 @@ class X { "The field a (line 3) duplicates field a (line 2)."); for (String it : expectedErrorMsgs) { - valTestHelper.assertError(program, N4JSPackage.Literals.N4_MEMBER_DECLARATION, IssueCodes.CLF_DUP_MEMBER, - it); + valTestHelper.assertError(program, N4JSPackage.Literals.N4_MEMBER_DECLARATION, + IssueCodes.CLF_DUP_MEMBER.name(), it); } } @@ -99,8 +100,8 @@ class X { "The setter d (line 9) duplicates field d (line 5)."); for (String it : expectedErrorMsgs) { - valTestHelper.assertError(program, N4JSPackage.Literals.N4_MEMBER_DECLARATION, IssueCodes.CLF_DUP_MEMBER, - it); + valTestHelper.assertError(program, N4JSPackage.Literals.N4_MEMBER_DECLARATION, + IssueCodes.CLF_DUP_MEMBER.name(), it); } } @@ -120,7 +121,8 @@ class A { // bindings ok? valTestHelper.assertNoErrors(program); - valTestHelper.assertNoWarnings(program, N4JSPackage.Literals.N4_MEMBER_DECLARATION, IssueCodes.CLF_DUP_MEMBER); + valTestHelper.assertNoWarnings(program, N4JSPackage.Literals.N4_MEMBER_DECLARATION, + IssueCodes.CLF_DUP_MEMBER.name()); } @Test @@ -145,6 +147,6 @@ class B extends A { // bindings ok? valTestHelper.assertNoErrors(program); valTestHelper.assertNoWarnings(program, N4JSPackage.Literals.N4_MEMBER_DECLARATION, - IssueCodes.CLF_OVERRIDE_ANNOTATION); + IssueCodes.CLF_OVERRIDE_ANNOTATION.name()); } } diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/AbstractScriptAssembler.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/AbstractScriptAssembler.java index efcd43aa06..9f8b57c88f 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/AbstractScriptAssembler.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/AbstractScriptAssembler.java @@ -28,6 +28,8 @@ import org.eclipse.n4js.n4JS.VariableDeclaration; import org.eclipse.n4js.n4JS.VariableStatement; import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.utils.Strings; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.n4js.validation.JavaScriptVariant; import org.eclipse.xtext.EcoreUtil2; import org.eclipse.xtext.testing.util.ParseHelper; @@ -125,11 +127,11 @@ protected Script setupScript(CharSequence scriptSrc, JavaScriptVariant variant, return setupScript(scriptSrc, variant, null, expectedIssueCount); } - protected Script setupScript(CharSequence scriptSrc, JavaScriptVariant variant, String[] expectedMessages) { + protected Script setupScript(CharSequence scriptSrc, JavaScriptVariant variant, IssueCodes[] expectedMessages) { return setupScript(scriptSrc, variant, expectedMessages, -1); } - protected Script setupScript(CharSequence scriptSrc, JavaScriptVariant variant, String[] expectedMessages, + protected Script setupScript(CharSequence scriptSrc, JavaScriptVariant variant, IssueCodes[] expectedMessages, int expectedIssueCount) { try { @@ -140,7 +142,8 @@ protected Script setupScript(CharSequence scriptSrc, JavaScriptVariant variant, assertEquals(join(",", map(issues, Issue::toString)) + "\nin\n" + scriptSrc, expectedIssueCount, issues.size()); } else { - assertEquals(String.join(",", expectedMessages), join(",", map(issues, Issue::getCode))); + assertEquals(Strings.join(",", ic -> ic.name(), expectedMessages), + join(",", map(issues, Issue::getCode))); } // newly created top level vars and diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/AbstractTypeSystemHelperTests.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/AbstractTypeSystemHelperTests.java index 2055696a58..d8ecfd9315 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/AbstractTypeSystemHelperTests.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/AbstractTypeSystemHelperTests.java @@ -37,6 +37,7 @@ import org.eclipse.n4js.typesystem.utils.Result; import org.eclipse.n4js.typesystem.utils.RuleEnvironment; import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.n4js.validation.JavaScriptVariant; import org.eclipse.xtext.xbase.lib.Pair; @@ -135,10 +136,10 @@ public void assertSubTypeOfRef(String propertyRefName, SubTypeRelationForTest su * {@link TypeRef#getTypeRefAsString()} is used. */ public void assertJoin(String expectedType, String... typeExpressionsToBeJoined) { - assertJoin(new String[0], expectedType, typeExpressionsToBeJoined); + assertJoin(new IssueCodes[0], expectedType, typeExpressionsToBeJoined); } - public void assertJoin(String[] expectedMessages, String expectedType, String... typeExpressionsToBeJoined) { + public void assertJoin(IssueCodes[] expectedMessages, String expectedType, String... typeExpressionsToBeJoined) { RuleEnvironment G = assembler.prepareScriptAndCreateRuleEnvironment(expectedMessages, typeExpressionsToBeJoined); Iterable typeRefs = map(Arrays.asList(typeExpressionsToBeJoined), tExp -> assembler.getTypeRef(tExp)); @@ -152,10 +153,10 @@ public void assertJoin(String[] expectedMessages, String expectedType, String... * {@link TypeRef#getTypeRefAsString()} is used. */ public void assertMeet(String expectedType, String... typeExpressionsToBeMeet) { - assertMeet(new String[0], expectedType, typeExpressionsToBeMeet); + assertMeet(new IssueCodes[0], expectedType, typeExpressionsToBeMeet); } - public void assertMeet(String[] expectedMessages, String expectedType, String... typeExpressionsToBeMeet) { + public void assertMeet(IssueCodes[] expectedMessages, String expectedType, String... typeExpressionsToBeMeet) { RuleEnvironment G = assembler.prepareScriptAndCreateRuleEnvironment(expectedMessages, typeExpressionsToBeMeet); Iterable typeRefs = map(Arrays.asList(typeExpressionsToBeMeet), tExp -> assembler.getTypeRef(tExp)); TypeRef meet = TypeUtils.copy(tsh.meet(G, typeRefs)); diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/JoinComputer_IntersectionTypesTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/JoinComputer_IntersectionTypesTest.java index 6a5f3fcc08..b3accfd304 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/JoinComputer_IntersectionTypesTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/JoinComputer_IntersectionTypesTest.java @@ -48,11 +48,11 @@ public void testJoinAssumptions() { @Test public void testJoinIntersectionWithElementFromIntersection() { - assertJoin(new String[] { IssueCodes.INTER_REDUNDANT_SUPERTYPE }, "A", "A", "intersection{A,B}"); - assertJoin(new String[] { IssueCodes.INTER_REDUNDANT_SUPERTYPE }, "B", "B", "intersection{A,B}"); + assertJoin(new IssueCodes[] { IssueCodes.INTER_REDUNDANT_SUPERTYPE }, "A", "A", "intersection{A,B}"); + assertJoin(new IssueCodes[] { IssueCodes.INTER_REDUNDANT_SUPERTYPE }, "B", "B", "intersection{A,B}"); assertJoin("R1", "R1", "intersection{A,R1}"); assertJoin("N4Object", "D", "intersection{A,R1}", "A"); - assertJoin(new String[] { IssueCodes.INTER_REDUNDANT_SUPERTYPE }, "A", "B", "intersection{A,B}", "A"); + assertJoin(new IssueCodes[] { IssueCodes.INTER_REDUNDANT_SUPERTYPE }, "A", "B", "intersection{A,B}", "A"); } @Test @@ -60,7 +60,7 @@ public void testJoinWithIntersections() { assertJoin("intersection{I1,R1}", "intersection{I1,R1}", "intersection{I1,R1}"); assertJoin("intersection{I1,R1}", "intersection{I1,R1,Q1}", "intersection{I1,R1}"); assertJoin("intersection{A,R1}", "intersection{A,R1}", "intersection{B,R1}"); - assertJoin(new String[] { IssueCodes.INTER_REDUNDANT_SUPERTYPE, IssueCodes.INTER_REDUNDANT_SUPERTYPE }, "B", + assertJoin(new IssueCodes[] { IssueCodes.INTER_REDUNDANT_SUPERTYPE, IssueCodes.INTER_REDUNDANT_SUPERTYPE }, "B", "intersection{A,B}", "intersection{A,B}"); } diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/JoinComputer_UnionTypesTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/JoinComputer_UnionTypesTest.java index f2c63d2b3f..75d0df3ce4 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/JoinComputer_UnionTypesTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/JoinComputer_UnionTypesTest.java @@ -47,16 +47,17 @@ public void testJoinAsumptions() { @Test public void testJoinSimpleWithUnions() { - assertJoin(new String[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "A", "A", "union{A,B}"); - assertJoin(new String[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "A", "union{A,B}", "A"); - assertJoin(new String[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "A", "A", "union{B,A}"); + assertJoin(new IssueCodes[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "A", "A", "union{A,B}"); + assertJoin(new IssueCodes[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "A", "union{A,B}", "A"); + assertJoin(new IssueCodes[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "A", "A", "union{B,A}"); } @Test public void testJoinUnionWithUnions() { - assertJoin(new String[] { IssueCodes.UNI_REDUNDANT_SUBTYPE, IssueCodes.UNI_REDUNDANT_SUBTYPE }, "union{A,B,C}", + assertJoin(new IssueCodes[] { IssueCodes.UNI_REDUNDANT_SUBTYPE, IssueCodes.UNI_REDUNDANT_SUBTYPE }, + "union{A,B,C}", "union{A,B}", "union{B,C}"); - assertJoin(new String[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "B", "C", "union{B,C}"); + assertJoin(new IssueCodes[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "B", "C", "union{B,C}"); } @Test @@ -67,9 +68,9 @@ public void testJoinWithUnionsAndGenerics() { // lower A ^ union{A,B} = B // union{A,B} ... B // TODO: why not G? - assertJoin(new String[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "G", "G", "G"); + assertJoin(new IssueCodes[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "G", "G", "G"); - assertJoin(new String[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "union{A,B,G}", "G", "union{A,B}"); + assertJoin(new IssueCodes[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "union{A,B,G}", "G", "union{A,B}"); } } diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/MeetComputer_UnionTypesTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/MeetComputer_UnionTypesTest.java index 8b493a7f4c..6167e65ad2 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/MeetComputer_UnionTypesTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/MeetComputer_UnionTypesTest.java @@ -34,10 +34,10 @@ public void prepareTypeDefs() { @Test public void testMeetWithUnion() { - assertMeet(new String[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "B", "A", "union{A,B}"); - assertMeet(new String[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "B", "B", "union{A,B}"); - assertMeet(new String[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "C", "A", "union{B,C}"); - assertMeet(new String[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "C", "C", "union{B,C}"); + assertMeet(new IssueCodes[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "B", "A", "union{A,B}"); + assertMeet(new IssueCodes[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "B", "B", "union{A,B}"); + assertMeet(new IssueCodes[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "C", "A", "union{B,C}"); + assertMeet(new IssueCodes[] { IssueCodes.UNI_REDUNDANT_SUBTYPE }, "C", "C", "union{B,C}"); } } diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/TypeRefsToVariablesAssembler.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/TypeRefsToVariablesAssembler.java index 70a56e5fdb..7d4e34665d 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/TypeRefsToVariablesAssembler.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/TypeRefsToVariablesAssembler.java @@ -13,6 +13,7 @@ import org.eclipse.n4js.n4JS.Script; import org.eclipse.n4js.typesystem.utils.RuleEnvironment; import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; +import org.eclipse.n4js.validation.IssueCodes; import org.eclipse.n4js.validation.JavaScriptVariant; import org.eclipse.xtext.xbase.lib.Pair; @@ -29,10 +30,10 @@ public class TypeRefsToVariablesAssembler extends AbstractScriptAssembler { /** - * Convenience method for method {@link #prepareScriptAndCreateRuleEnvironment(String[], String...)}. + * Convenience method for method {@link #prepareScriptAndCreateRuleEnvironment(IssueCodes[], String...)}. */ public RuleEnvironment prepareScriptAndCreateRuleEnvironment(String... typeExpressions) { - return prepareScriptAndCreateRuleEnvironment(new String[0], JavaScriptVariant.n4js, typeExpressions); + return prepareScriptAndCreateRuleEnvironment(new IssueCodes[0], JavaScriptVariant.n4js, typeExpressions); } /** @@ -50,21 +51,23 @@ public RuleEnvironment prepareScriptAndCreateRuleEnvironment(String... typeExpre * * @return the rule environment to be used when type system rules are called. */ - public RuleEnvironment prepareScriptAndCreateRuleEnvironment(String[] expectedMessages, String... typeExpressions) { + public RuleEnvironment prepareScriptAndCreateRuleEnvironment(IssueCodes[] expectedMessages, + String... typeExpressions) { return prepareScriptAndCreateRuleEnvironment(expectedMessages, JavaScriptVariant.n4js, typeExpressions); } - public RuleEnvironment prepareScriptAndCreateRuleEnvironment(String[] expectedMessages, JavaScriptVariant variant, + public RuleEnvironment prepareScriptAndCreateRuleEnvironment(IssueCodes[] expectedMessages, + JavaScriptVariant variant, String... typeExpressions) { return doPrepareScriptAndCreateRuleEnvironment(expectedMessages, variant, typeExpressions).getValue(); } public Pair doPrepareScriptAndCreateRuleEnvironment(JavaScriptVariant variant, String... typeExpressions) { - return doPrepareScriptAndCreateRuleEnvironment(new String[0], variant, typeExpressions); + return doPrepareScriptAndCreateRuleEnvironment(new IssueCodes[0], variant, typeExpressions); } - public Pair doPrepareScriptAndCreateRuleEnvironment(String[] expectedMessages, + public Pair doPrepareScriptAndCreateRuleEnvironment(IssueCodes[] expectedMessages, JavaScriptVariant variant, String... typeExpressions) { String completeScript = getScriptPrefix() + "\n" + createVariables(typeExpressions); @SuppressWarnings("hiding") diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/TypeSystemHelper_SimplifyIntersectionTypesTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/TypeSystemHelper_SimplifyIntersectionTypesTest.java index 0250e713e7..2bd5d29be5 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/TypeSystemHelper_SimplifyIntersectionTypesTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/TypeSystemHelper_SimplifyIntersectionTypesTest.java @@ -42,10 +42,10 @@ public void prepareTypeDefs() { * {@link TypeRef#getTypeRefAsString()} is used. */ void assertSimplify(String expectedType, String typeExpressionsToBeSimplified) { - assertSimplify(expectedType, typeExpressionsToBeSimplified, new String[0]); + assertSimplify(expectedType, typeExpressionsToBeSimplified, new IssueCodes[0]); } - void assertSimplify(String expectedType, String typeExpressionsToBeSimplified, String... expectedIssueMsg) { + void assertSimplify(String expectedType, String typeExpressionsToBeSimplified, IssueCodes... expectedIssueMsg) { RuleEnvironment G = assembler.prepareScriptAndCreateRuleEnvironment(expectedIssueMsg, typeExpressionsToBeSimplified); TypeRef typeRef = assembler.getTypeRef(typeExpressionsToBeSimplified); diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/TypeSystemHelper_SimplifyUnionTypesTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/TypeSystemHelper_SimplifyUnionTypesTest.java index 2e914247ba..0700f5ae51 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/TypeSystemHelper_SimplifyUnionTypesTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/TypeSystemHelper_SimplifyUnionTypesTest.java @@ -42,10 +42,10 @@ public void prepareTypeDefs() { * {@link TypeRef#getTypeRefAsString()} is used. */ void assertSimplify(String expectedType, String typeExpressionsToBeSimplified) { - assertSimplify(expectedType, typeExpressionsToBeSimplified, new String[0]); + assertSimplify(expectedType, typeExpressionsToBeSimplified, new IssueCodes[0]); } - void assertSimplify(String expectedType, String typeExpressionsToBeSimplified, String... expectedIssueMsg) { + void assertSimplify(String expectedType, String typeExpressionsToBeSimplified, IssueCodes... expectedIssueMsg) { RuleEnvironment G = assembler.prepareScriptAndCreateRuleEnvironment(expectedIssueMsg, typeExpressionsToBeSimplified); TypeRef typeRef = assembler.getTypeRef(typeExpressionsToBeSimplified); diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_22_CommaExpressionTypesystemTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_22_CommaExpressionTypesystemTest.java index fcf6acddba..b56331e32a 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_22_CommaExpressionTypesystemTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_22_CommaExpressionTypesystemTest.java @@ -118,7 +118,8 @@ public void testValidateLoopWithCommas() { var x = i + " * 10 = " + k; // console.log(i + " * 10 = " + k); } """); - valTestHelper.assertNoErrors(script, N4JSPackage.Literals.N4_MEMBER_DECLARATION, IssueCodes.CLF_DUP_MEMBER); + valTestHelper.assertNoErrors(script, N4JSPackage.Literals.N4_MEMBER_DECLARATION, + IssueCodes.CLF_DUP_MEMBER.name()); } @Test @@ -128,6 +129,7 @@ public void testValidatePlusPlus() { var i; i++ """); - valTestHelper.assertNoErrors(script, N4JSPackage.Literals.N4_MEMBER_DECLARATION, IssueCodes.CLF_DUP_MEMBER); + valTestHelper.assertNoErrors(script, N4JSPackage.Literals.N4_MEMBER_DECLARATION, + IssueCodes.CLF_DUP_MEMBER.name()); } } diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/src/org/eclipse/n4js/packagejson/xpect/tests/PackageJsonXtTest.java b/tests/org.eclipse.n4js.packagejson.xpect.tests/src/org/eclipse/n4js/packagejson/xpect/tests/PackageJsonXtTest.java index b874756e9f..9fe14e1bb2 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/src/org/eclipse/n4js/packagejson/xpect/tests/PackageJsonXtTest.java +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/src/org/eclipse/n4js/packagejson/xpect/tests/PackageJsonXtTest.java @@ -38,7 +38,7 @@ static String getFolder() { @XtSuppressedIssues static Set getSuppressedIssueCodes() { return unmodifiableSet(newHashSet( - JSONIssueCodes.JSON_COMMENT_UNSUPPORTED, - IssueCodes.PKGJ_MISSING_DEPENDENCY_N4JS_RUNTIME)); + JSONIssueCodes.JSON_COMMENT_UNSUPPORTED.name(), + IssueCodes.PKGJ_MISSING_DEPENDENCY_N4JS_RUNTIME.name())); } } diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/api-impl/missing-implementation-id/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/api-impl/missing-implementation-id/package.json.xt index 9f75a51882..74bf75c004 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/api-impl/missing-implementation-id/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/api-impl/missing-implementation-id/package.json.xt @@ -26,7 +26,7 @@ "n4js": { "output": "src-gen", "projectType": "api", - // XPECT errors --> "When defining one or more implemented projects, you also have to define an implementation ID, using property "implementationId"." at ""implementedProjects"" + // XPECT errors --> "When defining one or more implemented projects, you also have to define an implementation ID, using property 'implementationId'." at ""implementedProjects"" "implementedProjects": [ // XPECT errors --> "Project does not exist with project ID: A." at ""A"" "A", diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/api-impl/missing-implemented-projects/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/api-impl/missing-implemented-projects/package.json.xt index c931c0ef20..8566d0ec96 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/api-impl/missing-implemented-projects/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/api-impl/missing-implemented-projects/package.json.xt @@ -26,7 +26,7 @@ "n4js": { "projectType": "validation", "output": "src-gen", - // XPECT errors --> "When defining an implementation ID, you also have to define one or more API projects that are implemented by this project using property n4js.implementedProjects." at ""implementationId"" + // XPECT errors --> "When defining an implementation ID, you also have to define one or more API projects that are implemented by this project using property 'n4js.implementedProjects'." at ""implementationId"" "implementationId": "some-id" } } diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/dependencies/mandatory1/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/dependencies/mandatory1/package.json.xt index 212a7798b6..6d078e7aaf 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/dependencies/mandatory1/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/dependencies/mandatory1/package.json.xt @@ -28,7 +28,7 @@ "name": "mandatory1", "version": "0.0.1", "n4js": { - // XPECT errors --> "Missing dependency to n4js-runtime (mandatory for all N4JS projects of type library, application, test)." at ""library"" + // XPECT errors --> "Missing dependency to 'n4js-runtime' (mandatory for all N4JS projects of type library, application, test)." at ""library"" "projectType": "library", "vendorId": "org.eclipse.n4js", "sources": { diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/dependencies/mandatory2/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/dependencies/mandatory2/package.json.xt index 16907b75c3..828b1fa35d 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/dependencies/mandatory2/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/dependencies/mandatory2/package.json.xt @@ -29,7 +29,7 @@ "name": "mandatory2", "version": "0.0.1", "devDependencies": { - // XPECT errors --> "Dependency to n4js-runtime should be defined below key "dependencies", not "devDependencies"." at ""n4js-runtime": "*"" + // XPECT errors --> "Dependency to 'n4js-runtime' should be defined below key 'dependencies', not 'devDependencies'." at ""n4js-runtime": "*"" "n4js-runtime": "*" }, "n4js": { diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/duplicates/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/duplicates/package.json.xt index 7e4b12a876..1e15ea0969 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/duplicates/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/duplicates/package.json.xt @@ -60,28 +60,28 @@ // TODO re-consider whether this validation is desired X!PECT errors --> "There is no output folder defined, so compilation isn't possible." at ""n4js"" "n4js": { "projectType": "library", - // XPECT warnings --> "Property "projectVersion" is unknown." at ""projectVersion"" + // XPECT warnings --> "Property 'projectVersion' is unknown." at ""projectVersion"" "projectVersion": "0.0.1", - // XPECT warnings --> "Property "hello" is unknown." at ""hello"" + // XPECT warnings --> "Property 'hello' is unknown." at ""hello"" "hello": {}, "vendorId": "MyVendorID", "vendorName": "My Vendor Name", "output": "src-gen", "sources": { "source": [ - // XPECT warnings --> "Duplicate path "src" has already been declared as source container in external." at "\"src\"" + // XPECT warnings --> "Duplicate path 'src' has already been declared as source container in external." at "\"src\"" "src", // IDEBUG-339 XPECT warnings --> "Source container path src_does_not_exist does not exist." at ""src_does_not_exist"" "src_does_not_exist", - // XPECT errors --> ""src/p/q/*.js" is not a valid path." at ""src/p/q/*.js"" + // XPECT errors --> "'src/p/q/*.js' is not a valid path." at ""src/p/q/*.js"" "src/p/q/*.js", - // XPECT errors --> "Path "src/p/O.js" does not point to a directory." at ""src/p/O.js"" + // XPECT errors --> "Path 'src/p/O.js' does not point to a directory." at ""src/p/O.js"" "src/p/O.js", "src2", "src3" ], "external": [ - // XPECT warnings --> "Duplicate path "src" has already been declared as source container in source." at "\"src\"" + // XPECT warnings --> "Duplicate path 'src' has already been declared as source container in source." at "\"src\"" "src", "src-external" ] @@ -94,11 +94,11 @@ "p/q/*", // XPECT errors --> "Duplicate module filter specifier." at ""p/q/*"" "p/q/*", - // XPECT warnings --> "Module filter "p/doesntexist/" does not match any modules." at ""p/doesntexist/"" + // XPECT warnings --> "Module filter 'p/doesntexist/' does not match any modules." at ""p/doesntexist/"" "p/doesntexist/", // External is available in src-external but not in src XPECT errors --> "Module filters of type noValidate must not match N4JS modules/files." at "{ "sourceContainer": "src-external", "module": "p/External" }" { "sourceContainer": "src-external", "module": "p/External" }, - // XPECT errors --> ""***" is not a valid character sequence in a wildcard." at ""***/A"" + // XPECT errors --> "'***' is not a valid character sequence in a wildcard." at ""***/A"" "***/A", // XPECT errors --> "Relative navigation is not allowed in a module filter specifier." at "\"**/../p/A\"" "**/../p/A", @@ -113,7 +113,7 @@ "module": "**/*" } ], - // XPECT warnings --> "Property noValidate duplicates property noValidate (line 90)." at ""noValidate"" + // XPECT warnings --> "Duplicate property noValidate (line 90)." at ""noValidate"" "noValidate": [ "p/A" ] diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/empty-strings/library-project/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/empty-strings/library-project/package.json.xt index 36d81b7849..bce9280768 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/empty-strings/library-project/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/empty-strings/library-project/package.json.xt @@ -45,11 +45,11 @@ }, "n4js": { "projectType": "library", - // XPECT errors --> "Value for property "vendorName" must not be empty." at """" + // XPECT errors --> "Value for property 'vendorName' must not be empty." at """" "vendorName": "", - // XPECT errors --> "Value for property "vendorId" must not be empty." at """" + // XPECT errors --> "Value for property 'vendorId' must not be empty." at """" "vendorId": "", - // XPECT errors --> "Value for property "output" must not be empty." at """" + // XPECT errors --> "Value for property 'output' must not be empty." at """" "output": "", "sources": { "source": [ @@ -78,7 +78,7 @@ }, // XPECT errors --> "Main module specifier does not exist." at """" "mainModule": "", - // XPECT errors --> "Value for property "implementationId" must not be empty." at """" + // XPECT errors --> "Value for property 'implementationId' must not be empty." at """" "implementationId": "", "implementedProjects": [ // XPECT errors --> "A project reference must not be empty." at """" diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/module-filters/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/module-filters/package.json.xt index 0a6cc50568..53c681e56f 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/module-filters/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/module-filters/package.json.xt @@ -45,7 +45,7 @@ // XPECT errors --> "Expected object instead of number as moduleFilters section." at "12" "moduleFilters": 12, "moduleFilters": { - // XPECT errors --> "Invalid module filter type "invalidFilterType". Valid filter types are noValidate." at ""invalidFilterType"" + // XPECT errors --> "Invalid module filter type 'invalidFilterType'. Valid filter types are noValidate." at ""invalidFilterType"" "invalidFilterType": [], // XPECT errors --> "Expected array instead of string as module filter specifiers." at ""Invalid specifier list"" "noValidate": "Invalid specifier list", diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@/MyProject/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@/MyProject/package.json.xt index 6cde903a45..38403a595d 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@/MyProject/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@/MyProject/package.json.xt @@ -22,7 +22,7 @@ */ { - // XPECT errors --> "The name "" is not a valid scope name." at ""@/MyProject"" + // XPECT errors --> "The name '' is not a valid scope name." at ""@/MyProject"" "name": "@/MyProject", "n4js": { "projectType": "validation" diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@_invalidScope/MyProject/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@_invalidScope/MyProject/package.json.xt index be7608a59d..a6f13ebfc6 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@_invalidScope/MyProject/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@_invalidScope/MyProject/package.json.xt @@ -23,7 +23,7 @@ { // note: underscore not allowed at beginning of scope names (according to npm)! - // XPECT errors --> "The name "_invalidScope" is not a valid scope name." at ""@_invalidScope/MyProject"" + // XPECT errors --> "The name '_invalidScope' is not a valid scope name." at ""@_invalidScope/MyProject"" "name": "@_invalidScope/MyProject", "n4js": { "projectType": "validation" diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@_invalidScope/_InvalidProject/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@_invalidScope/_InvalidProject/package.json.xt index e24309cac8..83849bf848 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@_invalidScope/_InvalidProject/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@_invalidScope/_InvalidProject/package.json.xt @@ -23,8 +23,8 @@ { // XPECT errors --- - // "The name "_InvalidProject" is not a valid package name." at ""@_invalidScope/_InvalidProject"" - // "The name "_invalidScope" is not a valid scope name." at ""@_invalidScope/_InvalidProject"" + // "The name '_InvalidProject' is not a valid package name." at ""@_invalidScope/_InvalidProject"" + // "The name '_invalidScope' is not a valid scope name." at ""@_invalidScope/_InvalidProject"" // --- "name": "@_invalidScope/_InvalidProject", "n4js": { diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@myScope/MyProject/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@myScope/MyProject/package.json.xt index b8880e9d08..4591b0c9ed 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@myScope/MyProject/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@myScope/MyProject/package.json.xt @@ -28,9 +28,9 @@ { // XPECT noerrors --> "name": "@myScope/MyProject", - // XPECT warnings --> "As a convention the package name "MyProjectWrong" should match the name of the project folder "MyProject" on the file system." at ""@myScope/MyProjectWrong"" + // XPECT warnings --> "As a convention the package name 'MyProjectWrong' should match the name of the project folder 'MyProject' on the file system." at ""@myScope/MyProjectWrong"" "name": "@myScope/MyProjectWrong", - // XPECT warnings --> "As a convention the scope name "@myScopeWrong" should match the name of the project folder's parent folder "@myScope" on the file system." at ""@myScopeWrong/MyProject"" + // XPECT warnings --> "As a convention the scope name '@myScopeWrong' should match the name of the project folder's parent folder '@myScope' on the file system." at ""@myScopeWrong/MyProject"" "name": "@myScopeWrong/MyProject", "n4js": { "projectType": "validation" diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@myScope/_InvalidProject/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@myScope/_InvalidProject/package.json.xt index 39e13055b5..56db870663 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@myScope/_InvalidProject/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/@myScope/_InvalidProject/package.json.xt @@ -22,7 +22,7 @@ */ { - // XPECT errors --> "The name "_InvalidProject" is not a valid package name." at ""@myScope/_InvalidProject"" + // XPECT errors --> "The name '_InvalidProject' is not a valid package name." at ""@myScope/_InvalidProject"" "name": "@myScope/_InvalidProject", "n4js": { "projectType": "validation" diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/MyProject/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/MyProject/package.json.xt index abe4b5ad29..f6cdeae002 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/MyProject/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/npmScopes/MyProject/package.json.xt @@ -22,7 +22,7 @@ */ { - // XPECT warnings --> "As a convention the scope name "@myScope" should match the name of the project folder's parent folder "test-workspace" on the file system." at ""@myScope/MyProject"" + // XPECT warnings --> "As a convention the scope name '@myScope' should match the name of the project folder's parent folder 'test-workspace' on the file system." at ""@myScope/MyProject"" "name": "@myScope/MyProject", "n4js": { "projectType": "validation" diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-name/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-name/package.json.xt index ef5b881fb9..97011c134d 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-name/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-name/package.json.xt @@ -22,7 +22,7 @@ */ { - // XPECT warnings --> "As a convention the package name "project-name-mismatch" should match the name of the project folder "SomeOtherFolderName" on the file system." at ""project-name-mismatch"" + // XPECT warnings --> "As a convention the package name 'project-name-mismatch' should match the name of the project folder 'SomeOtherFolderName' on the file system." at ""project-name-mismatch"" "name": "project-name-mismatch", "version": "0.0.1", "n4js": { diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.01/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.01/package.json.xt index e5c7d689ce..86f5b337c7 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.01/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.01/package.json.xt @@ -52,7 +52,7 @@ // XPECT noerrors --> "error is reported on subsequent occurances" "test.data.system.project.two": "*", /* XPECT warnings --- - "Property test.data.system.project.two duplicates property test.data.system.project.two (line 53)." at "\"test.data.system.project.two\"" + "Duplicate property test.data.system.project.two (line 53)." at "\"test.data.system.project.two\"" --- */ /* XPECT errors --- diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.03/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.03/package.json.xt index b9a1ac3c00..6af0ac5167 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.03/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.03/package.json.xt @@ -72,7 +72,7 @@ "providedRuntimeLibraries": [""], "requiredRuntimeLibraries": [ /* XPECT errors --- - "The project reference test.data.system.project.one in required runtime libraries must also be declared as explicit project dependency in dependencies or devDependencies." at ""test.data.system.project.one"" + "The project reference test.data.system.project.one in required runtime libraries must also be declared as explicit project dependency in 'dependencies' or 'devDependencies'." at ""test.data.system.project.one"" --- */ /* XPECT warnings --- diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.04/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.04/package.json.xt index c0adcf9367..e37dc679d3 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.04/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.04/package.json.xt @@ -51,7 +51,7 @@ "Duplicate project reference test.data.test.project.two." at ""test.data.test.project.two": "*"" --- */ /* XPECT warnings --- - "Property test.data.test.project.two duplicates property test.data.test.project.two (line 49)." at ""test.data.test.project.two"" + "Duplicate property test.data.test.project.two (line 49)." at ""test.data.test.project.two"" --- */ "test.data.test.project.two": "*", "test.data.system.project.one": "*", diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.13/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.13/package.json.xt index fa10763f4d..d1c6329349 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.13/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/project-references/test.13/package.json.xt @@ -36,7 +36,7 @@ // XPECT noerrors --> "test.data.test.project.two": "*", // XPECT errors --> "Duplicate project reference test.data.test.project.one." at ""test.data.test.project.one": "*"" - // XPECT warnings --> "Property test.data.test.project.one duplicates property test.data.test.project.one (line 35)." at ""test.data.test.project.one"" + // XPECT warnings --> "Duplicate property test.data.test.project.one (line 35)." at ""test.data.test.project.one"" "test.data.test.project.one": "*" }, "devDependencies": { diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/projectName/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/projectName/package.json.xt index ff5035d971..8cf6db8a36 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/projectName/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/projectName/package.json.xt @@ -22,7 +22,7 @@ */ { /** XPECT warnings --- - "As a convention the package name "MyProjectName" should match the name of the project folder "OtherProjectName" on the file system." at ""MyProjectName"" + "As a convention the package name 'MyProjectName' should match the name of the project folder 'OtherProjectName' on the file system." at ""MyProjectName"" --- */ "name": "MyProjectName", diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/projecttype-definition/invalidExample/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/projecttype-definition/invalidExample/package.json.xt index 79ab99282d..c4dad64a53 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/projecttype-definition/invalidExample/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/projecttype-definition/invalidExample/package.json.xt @@ -38,7 +38,7 @@ }, // XPECT noerrors "output" : "src-gen", - // XPECT errors --> "A project of type "VALIDATION" must not define the property "definesPackage"." at ""definesPackage" : "MyLib"" + // XPECT errors --> "A project of type 'VALIDATION' must not define the property 'definesPackage'." at ""definesPackage" : "MyLib"" "definesPackage" : "MyLib" } } diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/projecttype-definition/validExample/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/projecttype-definition/validExample/package.json.xt index 39e58c27c1..c45b4954fd 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/projecttype-definition/validExample/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/projecttype-definition/validExample/package.json.xt @@ -36,7 +36,7 @@ // XPECT noerrors "external": [] }, - // XPECT errors --> "A project of type "DEFINITION" must not define the property "output"." at ""output" : "src-gen"" + // XPECT errors --> "A project of type 'DEFINITION' must not define the property 'output'." at ""output" : "src-gen"" "output" : "src-gen", // XPECT noerrors "definesPackage" : "MyLib" diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/required-runtime-libraries/as-dependency/client/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/required-runtime-libraries/as-dependency/client/package.json.xt index 3cd9f19704..9d552a9d7c 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/required-runtime-libraries/as-dependency/client/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/required-runtime-libraries/as-dependency/client/package.json.xt @@ -43,7 +43,7 @@ "requiredRuntimeLibraries": [ // XPECT noerrors "rl1", - // XPECT errors --> "The project reference rl2 in required runtime libraries must also be declared as explicit project dependency in dependencies or devDependencies." at ""rl2"" + // XPECT errors --> "The project reference rl2 in required runtime libraries must also be declared as explicit project dependency in 'dependencies' or 'devDependencies'." at ""rl2"" "rl2", // XPECT noerrors "rl3" diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/source-containers/nested-containers-top-level-source/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/source-containers/nested-containers-top-level-source/package.json.xt index 9d660f15cd..fd78592182 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/source-containers/nested-containers-top-level-source/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/source-containers/nested-containers-top-level-source/package.json.xt @@ -47,7 +47,7 @@ "src/A", // XPECT errors --> "A source container must not be nested within other source containers (nested in ".", "src/", "src/A")" at ""src/A/B"" "src/A/B", - // XPECT warnings --> "Duplicate path "src3" has already been declared as source container." at ""src3"" + // XPECT warnings --> "Duplicate path 'src3' has already been declared as source container." at ""src3"" // XPECT errors --> "A source container must not be nested within other source containers (nested in ".")" at ""src3"" "src3", // XPECT errors --> "A source container must not be nested within other source containers (nested in ".")" at ""src2/A"" @@ -56,7 +56,7 @@ "src2/B", // XPECT errors --> "A source container must not be nested within other source containers (nested in ".")" at ""src2/C"" "src2/C", - // XPECT warnings --> "Duplicate path "src3" has already been declared as source container." at ""src3"" + // XPECT warnings --> "Duplicate path 'src3' has already been declared as source container." at ""src3"" // XPECT errors --> "A source container must not be nested within other source containers (nested in ".")" at ""src3"" "src3" ] diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/source-containers/nested-containers/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/source-containers/nested-containers/package.json.xt index 6c1b13049a..9a885d0af6 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/source-containers/nested-containers/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/source-containers/nested-containers/package.json.xt @@ -46,7 +46,7 @@ "src/A", // XPECT errors --> "A source container must not be nested within other source containers (nested in "src/", "src/A")" at ""src/A/B"" "src/A/B", - // XPECT warnings --> "Duplicate path "src3" has already been declared as source container." at ""src3"" + // XPECT warnings --> "Duplicate path 'src3' has already been declared as source container." at ""src3"" "src3", // XPECT noerrors "src2/A", @@ -54,7 +54,7 @@ "src2/B", // XPECT noerrors "src2/C", - // XPECT warnings --> "Duplicate path "src3" has already been declared as source container." at ""src3"" + // XPECT warnings --> "Duplicate path 'src3' has already been declared as source container." at ""src3"" "src3" ] }, diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/source-containers/non-top-level/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/source-containers/non-top-level/package.json.xt index 854d19cbc9..3d622c75a4 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/source-containers/non-top-level/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/source-containers/non-top-level/package.json.xt @@ -38,25 +38,25 @@ "output": "src-gen", "sources": { "source": [ - // XPECT warnings --> "Duplicate path "src1" has already been declared as source container in external." at ""src1"" + // XPECT warnings --> "Duplicate path 'src1' has already been declared as source container in external." at ""src1"" "src1", "src2", // XPECT warnings --> "Source container path src-does-not-exist does not exist." at ""src-does-not-exist"" "src-does-not-exist", - // Use file as src XPECT errors --> "Path "src3" does not point to a directory." at ""src3"" + // Use file as src XPECT errors --> "Path 'src3' does not point to a directory." at ""src3"" "src3", // non-top-level XPECT noerrors "folder/src1", - // XPECT errors --> ""in*valid - path" is not a valid path." at ""in*valid - path"" + // XPECT errors --> "'in*valid - path' is not a valid path." at ""in*valid - path"" "in*valid - path" ], "external": [ "src-ext", - // XPECT warnings --> "Duplicate path "src1" has already been declared as source container in source." at ""src1"" + // XPECT warnings --> "Duplicate path 'src1' has already been declared as source container in source." at ""src1"" "src1", // non-top-level source folder XPECT noerrors "folder/src2", - // using absolute paths XPECT errors --> "Path "/Users/dummy/absolute/path" must not be absolute." at ""/Users/dummy/absolute/path"" + // using absolute paths XPECT errors --> "Path '/Users/dummy/absolute/path' must not be absolute." at ""/Users/dummy/absolute/path"" "/Users/dummy/absolute/path" ] } diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/structure/overall/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/structure/overall/package.json.xt index a3a8c997bc..f5a010f67e 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/structure/overall/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/structure/overall/package.json.xt @@ -61,7 +61,7 @@ // XPECT errors --> "Expected string instead of number ." at "123" "projectType": 123, - // XPECT errors --> "Invalid project type "invalid"." at ""invalid"" + // XPECT errors --> "Invalid project type 'invalid'." at ""invalid"" "projectType": "invalid", // XPECT noerrors "projectType": "validation", diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/structure/sources-section/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/structure/sources-section/package.json.xt index 37d1c859d1..50913eb5e0 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/structure/sources-section/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/structure/sources-section/package.json.xt @@ -36,7 +36,7 @@ "n4js": { "projectType": "validation", "sources": { - // XPECT errors --> "Invalid source container type "invalid-type"." at ""invalid-type"" + // XPECT errors --> "Invalid source container type 'invalid-type'." at ""invalid-type"" "invalid-type": [], // XPECT errors --> "Expected array instead of string as source container list." at ""invalid"" "source": "invalid", diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/tested-projects/as-dependency/tests/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/tested-projects/as-dependency/tests/package.json.xt index a4754fed48..95d3a86033 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/tested-projects/as-dependency/tests/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/tested-projects/as-dependency/tests/package.json.xt @@ -37,7 +37,7 @@ "testedProjects": [ // XPECT noerrors "lib1", - // XPECT errors --> "The project reference lib2 in tested projects must also be declared as explicit project dependency in dependencies or devDependencies." at ""lib2"" + // XPECT errors --> "The project reference lib2 in tested projects must also be declared as explicit project dependency in 'dependencies' or 'devDependencies'." at ""lib2"" "lib2", // XPECT errors --> "Project does not exist with project ID: does-not-exist." at ""does-not-exist"" "does-not-exist" diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/version/DependencyVersionRequirement/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/version/DependencyVersionRequirement/package.json.xt index 74fd36f091..9302c9f801 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/version/DependencyVersionRequirement/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/version/DependencyVersionRequirement/package.json.xt @@ -40,11 +40,11 @@ "output": "src-gen" }, "dependencies": { - // XPECT errors --> "Invalid version number "1a.2.3": no viable alternative at input 'a'." at "1a.2.3" + // XPECT errors --> "Invalid version number '1a.2.3': no viable alternative at input 'a'." at "1a.2.3" "XYZ": "1a.2.3", - // XPECT errors --> "Invalid version number "^1..3": no viable alternative at input '.'." at ".3" + // XPECT errors --> "Invalid version number '^1..3': no viable alternative at input '.'." at ".3" "XYZ": "^1..3", - // XPECT errors --> "Invalid version number "^.2.3": no viable alternative at input '.'." at ".2.3" + // XPECT errors --> "Invalid version number '^.2.3': no viable alternative at input '.'." at ".2.3" "XYZ": "^.2.3", // XPECT errors --> "Only zero or one comparator allowed." at "<" "XYZ": "< > 1.2.3", diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/version/PackageVersionNumber/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/version/PackageVersionNumber/package.json.xt index 115d721fcc..7afcc35e62 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/version/PackageVersionNumber/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/version/PackageVersionNumber/package.json.xt @@ -27,9 +27,9 @@ { "name": "PackageVersionNumber", - // XPECT errors --> "Invalid version number "0.1a.2": no viable alternative at input 'a'." at "0.1a.2" + // XPECT errors --> "Invalid version number '0.1a.2': no viable alternative at input 'a'." at "0.1a.2" "version": "0.1a.2", - // XPECT errors --> "Invalid version number ">0.0.1": Version numbers must not have comparators: '>'." at "">0.0.1"" + // XPECT errors --> "Invalid version number '>0.0.1': Version numbers must not have comparators: '>'." at "">0.0.1"" "version": ">0.0.1", // XPECT errors --> "Too many version parts. Semantic versions consist only of major, minor and patch." at "23" "version": "0.0.1.23", diff --git a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/version/error/package.json.xt b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/version/error/package.json.xt index 0a0e83f80d..350f302fbd 100644 --- a/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/version/error/package.json.xt +++ b/tests/org.eclipse.n4js.packagejson.xpect.tests/xpect-xt/version/error/package.json.xt @@ -45,9 +45,9 @@ "one": "> <11.0.0", // XPECT errors --> "Too many version parts. Semantic versions consist only of major, minor and patch." at "7" "two": "<=13.0.0.7", - // XPECT errors --> "Invalid version number "^1..3": no viable alternative at input '.'." at ".3" + // XPECT errors --> "Invalid version number '^1..3': no viable alternative at input '.'." at ".3" "three": "^1..3", - // XPECT errors --> "Invalid version number "^.2.3": no viable alternative at input '.'." at ".2.3" + // XPECT errors --> "Invalid version number '^.2.3': no viable alternative at input '.'." at ".2.3" "four": "^.2.3" }, "n4js": { diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_06_02__VoidType/Req13_LegalUsesOfVoid.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_06_02__VoidType/Req13_LegalUsesOfVoid.n4js.xt index f06477af26..ed82ae7feb 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_06_02__VoidType/Req13_LegalUsesOfVoid.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_06_02__VoidType/Req13_LegalUsesOfVoid.n4js.xt @@ -17,11 +17,11 @@ function foo1a(): void {} /* XPECT errors --- "Missing return or throw statement." at "foo1b" - "Type void may only be used to declare the return type of functions and methods." at "void" + "Type 'void' may only be used to declare the return type of functions and methods." at "void" --- */ function foo1b(): any|void {} -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" function foo1c(p: void) {} @@ -30,14 +30,14 @@ class C1a { // XPECT noerrors --> m1(): void {} /* XPECT errors --- - "Type void may only be used to declare the return type of functions and methods." at "void" + "Type 'void' may only be used to declare the return type of functions and methods." at "void" "Missing return or throw statement." at "m2" --- */ m2(): any|void {} } class C1b { - // XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" + // XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" m(p: void) {} } @@ -47,14 +47,14 @@ let ol1 = { // XPECT noerrors --> void m1() {}, /* XPECT errors --- - "Type void may only be used to declare the return type of functions and methods." at "void" + "Type 'void' may only be used to declare the return type of functions and methods." at "void" "Missing return or throw statement." at "union{any,void} m2() {}" --- */ union{any,void} m2() {} }; let ol2 = { - // XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" + // XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" m(p: void) {} }; @@ -63,10 +63,10 @@ let ol2 = { // XPECT noerrors --> let f1a: {function():void}; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let f1b: {function():any|void}; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let f1c: {function(void)}; @@ -75,12 +75,12 @@ let f1c: {function(void)}; let f2a = function(): void {}; /* XPECT errors --- - "Type void may only be used to declare the return type of functions and methods." at "void" + "Type 'void' may only be used to declare the return type of functions and methods." at "void" "Missing return or throw statement." at "function(): any|void {}" --- */ let f2b = function(): any|void {}; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let f2c = function(p: void) {} @@ -90,22 +90,22 @@ let f3a = (): void => {}; /* XPECT errors --- "Missing return or throw statement." at "(): any|void => {}" - "Type void may only be used to declare the return type of functions and methods." at "void" + "Type 'void' may only be used to declare the return type of functions and methods." at "void" --- */ let f3b = (): any|void => {}; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let f3c = (p: void) => {}; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" class G1a {} -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let g: G1a; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" class G1b {} // XPECT noerrors --> @@ -113,22 +113,22 @@ class G1c {} -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let x: void; class C2 { - // XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" + // XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" field: void; } interface I { - // XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" + // XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" field: void; } -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let ttr: type{void}; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let ctr: constructor{void}; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_06_02__VoidType/VoidUndefined_asTypeArgument.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_06_02__VoidType/VoidUndefined_asTypeArgument.n4js.xt index c315373fe6..6e46abbfdc 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_06_02__VoidType/VoidUndefined_asTypeArgument.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_06_02__VoidType/VoidUndefined_asTypeArgument.n4js.xt @@ -14,61 +14,61 @@ class C {} class CA {} -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" class CAV {} // XPECT noerrors --> let t01: C; // XPECT noerrors --> let t02: C; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let t03: C; // XPECT noerrors --> let t04: CA; // XPECT noerrors --> let t05: CA; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let t06: CA; // XPECT noerrors --> let t07: CAV; // XPECT noerrors --> let t08: CAV; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let t09: CAV; class I {} class IA {} -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" class IAV {} // XPECT noerrors --> let t11: I; // XPECT noerrors --> let t12: I; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let t13: I; // XPECT noerrors --> let t14: IA; // XPECT noerrors --> let t15: IA; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let t16: IA; // XPECT noerrors --> let t17: IAV; // XPECT noerrors --> let t18: IAV; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" let t19: IAV; function fn(p: T) {} function fnA(p: T) {} -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" function fnAV(p: T) {} // XPECT noerrors --> @@ -77,7 +77,7 @@ function fnAV(p: T) {} fn(undefined); // XPECT errors --> "null is not a subtype of undefined." at "null" fn(null); -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" fn(undefined); // XPECT noerrors --> @@ -86,7 +86,7 @@ function fnAV(p: T) {} fnA(undefined); // XPECT errors --> "null is not a subtype of undefined." at "null" fnA(null); -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" fnA(undefined); // XPECT noerrors --> @@ -95,18 +95,18 @@ function fnAV(p: T) {} fnAV(undefined); // XPECT errors --> "null is not a subtype of undefined." at "null" fnAV(null); -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" fnAV(undefined); class Cls { m(p: T) {} mA(p: T) {} - // XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" + // XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" mAV(p: T) {} static sm(p: T) {} static smA(p: T) {} - // XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" + // XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" static smAV(p: T) {} } let cls: Cls; @@ -119,7 +119,7 @@ cls.m(undefined); cls.m(undefined); // XPECT errors --> "null is not a subtype of undefined." at "null" cls.m(null); -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" cls.m(undefined); // XPECT noerrors --> @@ -128,7 +128,7 @@ cls.mA(undefined); cls.mA(undefined); // XPECT errors --> "null is not a subtype of undefined." at "null" cls.mA(null); -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" cls.mA(undefined); // XPECT noerrors --> @@ -137,7 +137,7 @@ cls.mAV(undefined); cls.mAV(undefined); // XPECT errors --> "null is not a subtype of undefined." at "null" cls.mAV(null); -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" cls.mAV(undefined); // static: @@ -148,7 +148,7 @@ Cls.sm(undefined); Cls.sm(undefined); // XPECT errors --> "null is not a subtype of undefined." at "null" Cls.sm(null); -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" Cls.sm(undefined); // XPECT noerrors --> @@ -157,7 +157,7 @@ Cls.smA(undefined); Cls.smA(undefined); // XPECT errors --> "null is not a subtype of undefined." at "null" Cls.smA(null); -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" Cls.smA(undefined); // XPECT noerrors --> @@ -166,5 +166,5 @@ Cls.smAV(undefined); Cls.smAV(undefined); // XPECT errors --> "null is not a subtype of undefined." at "null" Cls.smAV(null); -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" Cls.smAV(undefined); diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_07_09__Symbol/LegalAndIllegalUseOfSymbol.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_07_09__Symbol/LegalAndIllegalUseOfSymbol.n4js.xt index 52689bc19f..ae321cd728 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_07_09__Symbol/LegalAndIllegalUseOfSymbol.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_07_09__Symbol/LegalAndIllegalUseOfSymbol.n4js.xt @@ -123,8 +123,8 @@ var asyncIter4 = myObjStruct[Symbol.asyncIterator]; // wrong location (i.e. other than in a property access expression) is bad ... -// XPECT errors --> "Invalid use of Symbol: may only be used to create symbols (i.e. Symbol()) or to access built-in symbols (e.g. Symbol.iterator)." at "Symbol" +// XPECT errors --> "Invalid use of 'Symbol': may only be used to create symbols (i.e. Symbol()) or to access built-in symbols (e.g. Symbol.iterator)." at "Symbol" var v : Symbol; -// XPECT errors --> "Invalid use of Symbol: may only be used to create symbols (i.e. Symbol()) or to access built-in symbols (e.g. Symbol.iterator)." at "Symbol" +// XPECT errors --> "Invalid use of 'Symbol': may only be used to create symbols (i.e. Symbol()) or to access built-in symbols (e.g. Symbol.iterator)." at "Symbol" function foo(sym : Symbol) {} diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_10__UnionType/Req25_UnionType_AnyTypeDiscouraged.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_10__UnionType/Req25_UnionType_AnyTypeDiscouraged.n4js.xt index 63c15fe30f..2c75b75a98 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_10__UnionType/Req25_UnionType_AnyTypeDiscouraged.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_10__UnionType/Req25_UnionType_AnyTypeDiscouraged.n4js.xt @@ -51,5 +51,5 @@ var c2 : union{union{A, B}, any}; var d1 : intersection{A, union{B, any}}; -// XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" +// XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" var e1 : union{any,void}; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_No_Constructor_This.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_No_Constructor_This.n4js.xt index b145ceaf6c..7271a4b6d0 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_No_Constructor_This.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_No_Constructor_This.n4js.xt @@ -14,7 +14,7 @@ class H { - // XPECT noerrors --> "The this type isn't allowed on this place. You can only use it as return type of instance methods or structurally on use site in the constructor." at "this" + // XPECT noerrors --> "The 'this' type isn't allowed on this place. You can only use it as return type of instance methods or structurally on use site in the constructor." at "this" static getIt(hint : string) : this { // XPECT errors --> "constructor{H} is not a subtype of this[H]." at "H" diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_ThisType_in_static_return.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_ThisType_in_static_return.n4js.xt index d21a220e87..2b7ed90abf 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_ThisType_in_static_return.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_ThisType_in_static_return.n4js.xt @@ -12,7 +12,7 @@ /* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest END_SETUP */ class H { // Makes sense for n4jsd only ! - // XPECT noerrors --> "The this type isn't allowed on this place. You can only use it as return type of instance methods or structurally on use site in the constructor." at "this" + // XPECT noerrors --> "The 'this' type isn't allowed on this place. You can only use it as return type of instance methods or structurally on use site in the constructor." at "this" static getIt(hint : string) : this { return null; } diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_TypeError_for_this-instance-return-type_in_static_method.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_TypeError_for_this-instance-return-type_in_static_method.n4js.xt index 2d50a58287..43e5f5397e 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_TypeError_for_this-instance-return-type_in_static_method.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_TypeError_for_this-instance-return-type_in_static_method.n4js.xt @@ -14,12 +14,12 @@ class S_broken { constructor(n : number) {} - // XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" + // XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" static l_0() : constructor{this} { return null; } // not possible. /* XPECT errors --- ""g" is not a subtype of constructor{this[S_broken]}." at ""g"" - "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" + "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" --- */ static l_01() : constructor{this} { return "g"; } // not possible. } diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_existential_this_type_as_typearg_in_return_type.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_existential_this_type_as_typearg_in_return_type.n4js.xt index cf315dd5dd..1321842a5f 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_existential_this_type_as_typearg_in_return_type.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/AT-IDE0785_existential_this_type_as_typearg_in_return_type.n4js.xt @@ -14,7 +14,7 @@ class C { - // XPECT noerrors --> No error expected: "The this type isn't allowed on this place. You can only use it as return type of instance methods or structurally on use site in the constructor." at "this" + // XPECT noerrors --> No error expected: "The 'this' type isn't allowed on this place. You can only use it as return type of instance methods or structurally on use site in the constructor." at "this" m2() : Array { return null; } diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/Req37_ThisType.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/Req37_ThisType.n4js.xt index cd7384b9fe..40729d0778 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/Req37_ThisType.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_12__ThisType/Req37_ThisType.n4js.xt @@ -11,11 +11,11 @@ /* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest END_SETUP */ -// XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" +// XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" var a : this; class A { - // XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" + // XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" constructor(p : this) {} f() : this { @@ -26,10 +26,10 @@ class A { return new A(); } - // XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" + // XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" g(p : this) : void {} - // XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "~this" + // XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "~this" h(p : ~this) : void {} diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_13_02__StringBasedEnums/Req41_NumberBasedEnums_Usage.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_13_02__StringBasedEnums/Req41_NumberBasedEnums_Usage.n4js.xt index 3762ae0658..f230fc991b 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_13_02__StringBasedEnums/Req41_NumberBasedEnums_Usage.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_13_02__StringBasedEnums/Req41_NumberBasedEnums_Usage.n4js.xt @@ -66,9 +66,9 @@ console.log((((E))).literals); // some INVALID use cases of @NumberBased enums -// XPECT errors --> "A @NumberBased or @StringBased enum may only be used in type annotations and in property access expressions to access either one of its literals or the static getter called literals." at "E" +// XPECT errors --> "A @NumberBased or @StringBased enum may only be used in type annotations and in property access expressions to access either one of its literals or the static getter called 'literals'." at "E" E; -// XPECT errors --> "A @NumberBased or @StringBased enum may only be used in type annotations and in property access expressions to access either one of its literals or the static getter called literals." at "E" +// XPECT errors --> "A @NumberBased or @StringBased enum may only be used in type annotations and in property access expressions to access either one of its literals or the static getter called 'literals'." at "E" console.log(E); // XPECT errors --> "Couldn't resolve reference to IdentifiableElement 'hasOwnProperty'." at "hasOwnProperty" E.hasOwnProperty('foo'); diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_13_02__StringBasedEnums/Req41_StringBasedEnums_Usage.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_13_02__StringBasedEnums/Req41_StringBasedEnums_Usage.n4js.xt index 7bbc23759b..47a5398039 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_13_02__StringBasedEnums/Req41_StringBasedEnums_Usage.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_13_02__StringBasedEnums/Req41_StringBasedEnums_Usage.n4js.xt @@ -58,9 +58,9 @@ console.log((((E))).literals); // some INVALID use cases of @StringBased enums -// XPECT errors --> "A @NumberBased or @StringBased enum may only be used in type annotations and in property access expressions to access either one of its literals or the static getter called literals." at "E" +// XPECT errors --> "A @NumberBased or @StringBased enum may only be used in type annotations and in property access expressions to access either one of its literals or the static getter called 'literals'." at "E" E; -// XPECT errors --> "A @NumberBased or @StringBased enum may only be used in type annotations and in property access expressions to access either one of its literals or the static getter called literals." at "E" +// XPECT errors --> "A @NumberBased or @StringBased enum may only be used in type annotations and in property access expressions to access either one of its literals or the static getter called 'literals'." at "E" console.log(E); // XPECT errors --> "Couldn't resolve reference to IdentifiableElement 'hasOwnProperty'." at "hasOwnProperty" E.hasOwnProperty('foo'); diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_14__TypeAlias/TypeAlias_destructuring_validation.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_14__TypeAlias/TypeAlias_destructuring_validation.n4js.xt index c93dc1ce3b..a4a8a4efae 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_14__TypeAlias/TypeAlias_destructuring_validation.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_14__TypeAlias/TypeAlias_destructuring_validation.n4js.xt @@ -28,7 +28,7 @@ let { field: t01 } = c; let { getter: t02 } = c; // XPECT errors --> "The accessor setter is write-only." at "setter" let { setter: t03 } = c; -// XPECT errors --> "Value to be destructured does not contain a property, field or getter named "missing": C." at "missing" +// XPECT errors --> "Value to be destructured does not contain a property, field or getter named 'missing': C." at "missing" let { missing: t04 } = c; @@ -42,7 +42,7 @@ let { field: t11 } = ac; let { getter: t12 } = ac; // XPECT errors --> "The accessor setter is write-only." at "setter" let { setter: t13 } = ac; -// XPECT errors --> "Value to be destructured does not contain a property, field or getter named "missing": AC." at "missing" +// XPECT errors --> "Value to be destructured does not contain a property, field or getter named 'missing': AC." at "missing" let { missing: t14 } = ac; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_14__TypeAlias/TypeAlias_validation_extendsImplementsClauses.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_14__TypeAlias/TypeAlias_validation_extendsImplementsClauses.n4js.xt index af724e11fd..d13695cca8 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_14__TypeAlias/TypeAlias_validation_extendsImplementsClauses.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_14__TypeAlias/TypeAlias_validation_extendsImplementsClauses.n4js.xt @@ -28,7 +28,7 @@ class SubCls01 extends AliCls {} // XPECT noerrors --> class SubCls02 implements AliIfc {} -// XPECT errors --> "The class SubCls11 cannot extend interface Ifc, use "implements"." at "AliIfc" +// XPECT errors --> "The class SubCls11 cannot extend interface Ifc, use 'implements'." at "AliIfc" class SubCls11 extends AliIfc {} // XPECT errors --> "The class SubCls12 cannot extend enum SomeEnum." at "AliBad1" class SubCls12 extends AliBad1 {} @@ -37,7 +37,7 @@ class SubCls13 extends AliBad2 {} // XPECT errors --> "The class SubCls14 cannot extend {function(string):number}." at "AliBad3" class SubCls14 extends AliBad3 {} -// XPECT errors --> "The class SubCls21 cannot implement class Cls, use "extends"." at "AliCls" +// XPECT errors --> "The class SubCls21 cannot implement class Cls, use 'extends'." at "AliCls" class SubCls21 implements AliCls {} // XPECT errors --> "The class SubCls22 cannot implement enum SomeEnum." at "AliBad1" class SubCls22 implements AliBad1 {} diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_03_06__SuperClass/Req47_SuperClass/01_SuperClassMustBeAClass.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_03_06__SuperClass/Req47_SuperClass/01_SuperClassMustBeAClass.n4js.xt index 06bfaed543..0cf8daa54b 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_03_06__SuperClass/Req47_SuperClass/01_SuperClassMustBeAClass.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_03_06__SuperClass/Req47_SuperClass/01_SuperClassMustBeAClass.n4js.xt @@ -20,16 +20,16 @@ var a : A; // XPECT noerrors --> "ok" at "A" class X1 extends A {} -// XPECT errors --> "The class X2 cannot extend interface I, use "implements"." at "I" +// XPECT errors --> "The class X2 cannot extend interface I, use 'implements'." at "I" class X2 extends I {} -// XPECT errors --> "The class X4 cannot implement class A, use "extends"." at "A" +// XPECT errors --> "The class X4 cannot implement class A, use 'extends'." at "A" class X4 implements A {} // XPECT noerrors --> "ok" at "I" class X5 implements I {} -// XPECT errors --> "The class X7 cannot implement class A, use "extends"." at "A" +// XPECT errors --> "The class X7 cannot implement class A, use 'extends'." at "A" class X7 implements A {} // XPECT noerrors --> "Keyword implements must be used with interfaces but I is a interface." at "I" diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_04__Interfaces/Req48_MembersOfAnInterface/05_NoThisInFieldInitializerOfInterface.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_04__Interfaces/Req48_MembersOfAnInterface/05_NoThisInFieldInitializerOfInterface.n4js.xt index 8025fd87d8..67475a17ff 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_04__Interfaces/Req48_MembersOfAnInterface/05_NoThisInFieldInitializerOfInterface.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_04__Interfaces/Req48_MembersOfAnInterface/05_NoThisInFieldInitializerOfInterface.n4js.xt @@ -15,10 +15,10 @@ interface I { f1 = 42; - // XPECT errors --> "In interfaces, the this literal may not be used in initializers of data fields." at "this" + // XPECT errors --> "In interfaces, the 'this' literal may not be used in initializers of data fields." at "this" f2 = this.f1; static f1 = 42; - // XPECT errors --> "In interfaces, the this literal may not be used in static methods or field accessors and in initializers of static data fields." at "this" + // XPECT errors --> "In interfaces, the 'this' literal may not be used in static methods or field accessors and in initializers of static data fields." at "this" static f2 = this.f1; } diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_04__Interfaces/Req50_Warning_In_DefinitionProjects.n4jsd.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_04__Interfaces/Req50_Warning_In_DefinitionProjects.n4jsd.xt index c8d66f6514..74ce1b285c 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_04__Interfaces/Req50_Warning_In_DefinitionProjects.n4jsd.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_04__Interfaces/Req50_Warning_In_DefinitionProjects.n4jsd.xt @@ -30,12 +30,12 @@ // XPECT warnings --> "Class declarations in definition projects should be annotated with @EcmaScript." at "NominalClassN4" export external public class NominalClassN4 {} -// XPECT warnings --> "Nominal interface declarations in definition projects should instead be structural (use ~)." at "NominalInterface1" +// XPECT warnings --> "Nominal interface declarations in definition projects should instead be structural (use '~')." at "NominalInterface1" export external public interface NominalInterface1 {} // XPECT warnings --> "This annotation is deprecated and has no effect." at "N4JS" @N4JS -// XPECT warnings --> "Nominal interface declarations in definition projects should instead be structural (use ~)." at "NominalInterface2" +// XPECT warnings --> "Nominal interface declarations in definition projects should instead be structural (use '~')." at "NominalInterface2" export external public interface NominalInterface2 {} diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_02_01__StructuralThisTypeInCtorAndSpecParameter/Req59_3_SpecParameterCorrectType.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_02_01__StructuralThisTypeInCtorAndSpecParameter/Req59_3_SpecParameterCorrectType.n4js.xt index 87cf807f1e..9f1a5c3723 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_02_01__StructuralThisTypeInCtorAndSpecParameter/Req59_3_SpecParameterCorrectType.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_02_01__StructuralThisTypeInCtorAndSpecParameter/Req59_3_SpecParameterCorrectType.n4js.xt @@ -33,7 +33,7 @@ class C { // not allowed: nominal this // XPECT errors --- // "Annotation @Spec may only be used with formal parameters of type ~i~this." at "Spec" - // "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" + // "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" // --- constructor(a : string, @Spec b : this, c : number) {} } diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_03_01__AssignmentModifiers/Req62_ConstDataFields.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_03_01__AssignmentModifiers/Req62_ConstDataFields.n4js.xt index 4055d7ad1c..4b81af278f 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_03_01__AssignmentModifiers/Req62_ConstDataFields.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_03_01__AssignmentModifiers/Req62_ConstDataFields.n4js.xt @@ -18,7 +18,7 @@ class A { // XPECT errors --> "Const field s2 must be provided with an initializer." at "s2" const s2; - // XPECT errors --> "All const fields are static. Remove unnecessary modifier static." at "s3" + // XPECT errors --> "All const fields are static. Remove unnecessary modifier 'static'." at "s3" static const s3 = "Hello"; static m = "Hello"; @@ -48,7 +48,7 @@ interface I { // XPECT errors --> "Const field s2 must be provided with an initializer." at "s2" const s2; - // XPECT errors --> "All const fields are static. Remove unnecessary modifier static." at "s3" + // XPECT errors --> "All const fields are static. Remove unnecessary modifier 'static'." at "s3" static const s3 = "Hello"; static m = "Hello"; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_04__FieldAccessors/Req64_FieldAccessors.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_04__FieldAccessors/Req64_FieldAccessors.n4js.xt index 33dd4b265c..f3665d07a6 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_04__FieldAccessors/Req64_FieldAccessors.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_04__FieldAccessors/Req64_FieldAccessors.n4js.xt @@ -20,7 +20,7 @@ class A { --- */ public get name() : void {} - // XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" + // XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" public set name(p : void) {} } @@ -30,7 +30,7 @@ interface I { // XPECT errors --> "Void is not a valid type for getters and setters." at "name" public get name() : void - // XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" + // XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" public set name(p : void) } diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_03__StructuralTyping/Req76_3_StructuralAndInstanceof.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_03__StructuralTyping/Req76_3_StructuralAndInstanceof.n4js.xt index 75adf32ff1..ebc46387a9 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_03__StructuralTyping/Req76_3_StructuralAndInstanceof.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_03__StructuralTyping/Req76_3_StructuralAndInstanceof.n4js.xt @@ -20,10 +20,10 @@ class A { var a: ~A = { a: 2, f: function () {} }; let x = 5; -// XPECT errors --> "instanceof cannot be used with use site structural typing." at "~A" +// XPECT errors --> "'instanceof' cannot be used with use site structural typing." at "~A" a instanceof ~A; -// XPECT errors --> "instanceof cannot be used with use site structural typing." at "~~A" +// XPECT errors --> "'instanceof' cannot be used with use site structural typing." at "~~A" a instanceof ~~A; // The following tests are only to ensure that existing correct functionality is maintained: @@ -40,7 +40,7 @@ a instanceof ~(3 + 4) // This needs to work! XPECT noerrors --> a instanceof A; -// XPECT errors --> "instanceof cannot be used with primitive types." at "number" +// XPECT errors --> "'instanceof' cannot be used with primitive types." at "number" a instanceof number; // XPECT errors --- diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_02__Generator_Functions/generators-throw-next-return.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_02__Generator_Functions/generators-throw-next-return.n4js.xt index 276ea388c5..142dd77b17 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_02__Generator_Functions/generators-throw-next-return.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_02__Generator_Functions/generators-throw-next-return.n4js.xt @@ -50,9 +50,9 @@ ag20o.next("1"); // return type of next value is undefined -// XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "g20o.next().value" +// XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "g20o.next().value" let g20on = g20o.next().value; -// XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "entry.value" +// XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "entry.value" ag20o.next().then(entry => { let ag20on = entry.value; }); @@ -92,9 +92,9 @@ ag20o.return("1"); // return type of return value is undefined -// XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "g20o.return().value" +// XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "g20o.return().value" let g20or = g20o.return().value; -// XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "entry.value" +// XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "entry.value" ag20o.return().then(entry => { let ag20or = entry.value; }); diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_02__Generator_Functions/generators-yield-star.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_02__Generator_Functions/generators-yield-star.n4js.xt index 28f8b097e9..50b15c25c6 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_02__Generator_Functions/generators-yield-star.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_02__Generator_Functions/generators-yield-star.n4js.xt @@ -25,11 +25,11 @@ async function * ag3a() { // yield* has return type undefined, by default (warning case) function * g3b() { - // XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "yield * g3b()" + // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "yield * g3b()" let x : string = yield * g3b(); } async function * ag3b() { - // XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "yield * ag3b()" + // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "yield * ag3b()" let x : string = yield * ag3b(); } diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_03__ArrowFunctionExpression/Req84_No_This_In_Top_Level_Arrow_Function.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_03__ArrowFunctionExpression/Req84_No_This_In_Top_Level_Arrow_Function.n4js.xt index 47d13b5bf8..a6de1ab16c 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_03__ArrowFunctionExpression/Req84_No_This_In_Top_Level_Arrow_Function.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_03__ArrowFunctionExpression/Req84_No_This_In_Top_Level_Arrow_Function.n4js.xt @@ -11,7 +11,7 @@ /* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest END_SETUP */ -// XPECT errors ---> "In a top-level arrow function, the this keyword refers to nothing." at "this" +// XPECT errors ---> "In a top-level arrow function, the 'this' keyword refers to nothing." at "this" var fn = (n : number)=>this console.log(fn(1)); diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_05_02__PromisifiableFunctions/Promisify_useCases.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_05_02__PromisifiableFunctions/Promisify_useCases.n4js.xt index 4656ba71ef..814943ad8a 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_05_02__PromisifiableFunctions/Promisify_useCases.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_05_02__PromisifiableFunctions/Promisify_useCases.n4js.xt @@ -121,12 +121,12 @@ async function testWithMethod(allDone : {function()}) { console.log('****** method mNone:'); console.log('use case #1: with await, long syntax'); - // XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "(await @Promisify c.mNone('some path'))" + // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "(await @Promisify c.mNone('some path'))" var res31 = (await @Promisify c.mNone('some path')); // assigning undefined to Object here to be able to assert that 'undefined' is returned at runtime console.log('-> res31:', res31); console.log('use case #2: with await, short syntax'); - // XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "(await @Promisify c.mNone('some path'))" + // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "(await @Promisify c.mNone('some path'))" var res32 = (await @Promisify c.mNone('some path')); // assigning undefined to Object here to be able to assert that 'undefined' is returned at runtime console.log('-> res32:', res32); @@ -155,12 +155,12 @@ async function testWithMethod(allDone : {function()}) { console.log('****** method mNoneNoErr:'); console.log('use case #1: with await, long syntax'); - // XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "(await @Promisify c.mNoneNoErr('some path'))" + // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "(await @Promisify c.mNoneNoErr('some path'))" var res61 = (await @Promisify c.mNoneNoErr('some path')); // assigning undefined to Object here to be able to assert that 'undefined' is returned at runtime console.log('-> res61:', res61); console.log('use case #2: with await, short syntax'); - // XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "(await @Promisify c.mNoneNoErr('some path'))" + // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "(await @Promisify c.mNoneNoErr('some path'))" var res62 = (await @Promisify c.mNoneNoErr('some path')); // assigning undefined to Object here to be able to assert that 'undefined' is returned at runtime console.log('-> res62:', res62); diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_05_02__PromisifiableFunctions/Req88_PromisifableCombinations.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_05_02__PromisifiableFunctions/Req88_PromisifableCombinations.n4js.xt index 0b3d075fcc..0d9a138cdf 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_05_02__PromisifiableFunctions/Req88_PromisifableCombinations.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_05_02__PromisifiableFunctions/Req88_PromisifableCombinations.n4js.xt @@ -18,7 +18,7 @@ class C { @Promisifiable b(path : string, cb : {function(Error)}) : void {} @Promisifiable - // this case is no longer allowed XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" + // this case is no longer allowed XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" c(path : string, cb : {function(Error, void)}) : void {} @Promisifiable d(path : string, cb : {function(Error, string, int)}) : void {} @@ -27,7 +27,7 @@ class C { @Promisifiable f(path : string, cb : {function()}) : void {} @Promisifiable - // this case is no longer allowed XPECT errors --> "Type void may only be used to declare the return type of functions and methods." at "void" + // this case is no longer allowed XPECT errors --> "Type 'void' may only be used to declare the return type of functions and methods." at "void" g(path : string, cb : {function(void)}) : void {} } diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_01__The_This_Literal/Req173_ValidLocationForThisLiteral.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_01__The_This_Literal/Req173_ValidLocationForThisLiteral.n4js.xt index c91ec2e0a0..563c52c453 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_01__The_This_Literal/Req173_ValidLocationForThisLiteral.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_01__The_This_Literal/Req173_ValidLocationForThisLiteral.n4js.xt @@ -16,7 +16,7 @@ interface I_nonStatic { f2 = 39; - // XPECT errors --> "In interfaces, the this literal may not be used in initializers of data fields." at "this" + // XPECT errors --> "In interfaces, the 'this' literal may not be used in initializers of data fields." at "this" f = 3 + this.f2; get g() { @@ -46,27 +46,27 @@ interface I_static { static f2 = 39; - // XPECT errors --> "In interfaces, the this literal may not be used in static methods or field accessors and in initializers of static data fields." at "this" + // XPECT errors --> "In interfaces, the 'this' literal may not be used in static methods or field accessors and in initializers of static data fields." at "this" static f = 3 + this.f2; static get g() { - // XPECT errors --> "In interfaces, the this literal may not be used in static methods or field accessors and in initializers of static data fields." at "this" + // XPECT errors --> "In interfaces, the 'this' literal may not be used in static methods or field accessors and in initializers of static data fields." at "this" this; return null; } static set s(value : any) { - // XPECT errors --> "In interfaces, the this literal may not be used in static methods or field accessors and in initializers of static data fields." at "this" + // XPECT errors --> "In interfaces, the 'this' literal may not be used in static methods or field accessors and in initializers of static data fields." at "this" this; } static m() { - // XPECT errors --> "In interfaces, the this literal may not be used in static methods or field accessors and in initializers of static data fields." at "this" + // XPECT errors --> "In interfaces, the 'this' literal may not be used in static methods or field accessors and in initializers of static data fields." at "this" this; } // in case of return type, there is already another validation in place to disallow 'this' for all static methods: - // XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" + // XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" static mRet() : this { return null; } @@ -107,7 +107,7 @@ class C_static { static f2 = 39; - // XPECT errors --> "The this literal may not be used in initializers of static data fields." at "this" + // XPECT errors --> "The 'this' literal may not be used in initializers of static data fields." at "this" static f = 3 + this.f2; static get g() { diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_01__The_This_Literal/Req173_ValidLocationForThisLiteralAndArrowExpressions.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_01__The_This_Literal/Req173_ValidLocationForThisLiteralAndArrowExpressions.n4js.xt index 8a5ec21a6f..01b893db68 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_01__The_This_Literal/Req173_ValidLocationForThisLiteralAndArrowExpressions.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_01__The_This_Literal/Req173_ValidLocationForThisLiteralAndArrowExpressions.n4js.xt @@ -13,20 +13,20 @@ interface J { static s = 5; - // XPECT errors --> "In interfaces, the this literal may not be used in static methods or field accessors and in initializers of static data fields." at "this" + // XPECT errors --> "In interfaces, the 'this' literal may not be used in static methods or field accessors and in initializers of static data fields." at "this" static fn = () => console.log(this.uups); num = 5; - // XPECT errors --> "In interfaces, the this literal may not be used in initializers of data fields." at "this" + // XPECT errors --> "In interfaces, the 'this' literal may not be used in initializers of data fields." at "this" fnx = () => console.log(this.num); } class C { i = 5; static s = 5; - // XPECT errors --> "The this literal may not be used in initializers of static data fields." at "this" + // XPECT errors --> "The 'this' literal may not be used in initializers of static data fields." at "this" static fn = () => console.log(this.uups); - // XPECT errors --> "The this literal may not be used in initializers of static data fields." at "this" + // XPECT errors --> "The 'this' literal may not be used in initializers of static data fields." at "this" static fn2 = () => console.log(this.i); // XPECT errors --> "The static member s cannot be accessed from a non-static context." at "s" diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_10__FunctionCalls/CallExpressionValidTarget.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_10__FunctionCalls/CallExpressionValidTarget.n4js.xt index bc2f67f4fe..2cc6b8d878 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_10__FunctionCalls/CallExpressionValidTarget.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_10__FunctionCalls/CallExpressionValidTarget.n4js.xt @@ -19,11 +19,11 @@ fBad(); class C {} -// XPECT errors --> "Cannot directly invoke class constructor functions; use new instead." at "C" +// XPECT errors --> "Cannot directly invoke class constructor functions; use 'new' instead." at "C" C(); abstract class CA {} -// XPECT errors --> "Cannot directly invoke class constructor functions; use new instead." at "CA" +// XPECT errors --> "Cannot directly invoke class constructor functions; use 'new' instead." at "CA" CA(); interface I {} diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_17__EqualityExpression/Equality_Classes.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_17__EqualityExpression/Equality_Classes.n4js.xt index c78530b0ba..fe191c700e 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_17__EqualityExpression/Equality_Classes.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_17__EqualityExpression/Equality_Classes.n4js.xt @@ -119,7 +119,7 @@ anA === aB; anA === funcB(); // OK, anA could be undefined -// XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "udef" +// XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "udef" anA === udef; // OK, structural comparison: A is basically an empty Object. diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch09_02_05__ExportStatements/ExportSeparateFromDecl03_asDefault.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch09_02_05__ExportStatements/ExportSeparateFromDecl03_asDefault.n4js.xt index aaafa081aa..c25d163117 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch09_02_05__ExportStatements/ExportSeparateFromDecl03_asDefault.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch09_02_05__ExportStatements/ExportSeparateFromDecl03_asDefault.n4js.xt @@ -30,6 +30,7 @@ // note: this test is testing internal infrastructure for a feature not available in N4JS[D] (only in .d.ts) IssueConfiguration { IssueCode "UNSUPPORTED" { enabled = false } + IssueCode "IMP_UNUSED_IMPORT" { enabled = false } } END_SETUP diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch09_02_05__ExportStatements/ExportSeparateFromDecl05_cannotImportNonExportedElement.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch09_02_05__ExportStatements/ExportSeparateFromDecl05_cannotImportNonExportedElement.n4js.xt index bff6704468..8fb576aa3a 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch09_02_05__ExportStatements/ExportSeparateFromDecl05_cannotImportNonExportedElement.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch09_02_05__ExportStatements/ExportSeparateFromDecl05_cannotImportNonExportedElement.n4js.xt @@ -45,6 +45,7 @@ // note: this test is testing internal infrastructure for a feature not available in N4JS[D] (only in .d.ts) IssueConfiguration { IssueCode "UNSUPPORTED" { enabled = false } + IssueCode "IMP_UNUSED_IMPORT" { enabled = false } } END_SETUP diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch09_02_05__ExportStatements/ExportSeparateFromDecl06_exportFromNamespace.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch09_02_05__ExportStatements/ExportSeparateFromDecl06_exportFromNamespace.n4js.xt index 3b4eddcaab..a653d54a51 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch09_02_05__ExportStatements/ExportSeparateFromDecl06_exportFromNamespace.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch09_02_05__ExportStatements/ExportSeparateFromDecl06_exportFromNamespace.n4js.xt @@ -24,6 +24,7 @@ // note: this test is testing internal infrastructure for a feature not available in N4JS[D] (only in .d.ts) IssueConfiguration { IssueCode "UNSUPPORTED" { enabled = false } + IssueCode "IMP_UNUSED_IMPORT" { enabled = false } } END_SETUP diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_Object_propMustBeVisible.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_Object_propMustBeVisible.n4js.xt index b1a8cc0a83..eb31cc69d2 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_Object_propMustBeVisible.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_Object_propMustBeVisible.n4js.xt @@ -31,7 +31,7 @@ var {fieldPublic:a1, fieldProject:b1, fieldPrivate:c1} = cls; ({fieldPublic:a1, fieldProject:b1, fieldPrivate:c1} = cls); -// public and project should be ok XPECT errors --> "Property named "fieldPrivate" is not readable: The field fieldPrivate is not visible." at "fieldPrivate" +// public and project should be ok XPECT errors --> "Property named 'fieldPrivate' is not readable: The field fieldPrivate is not visible." at "fieldPrivate" var {fieldPublic, fieldProject, fieldPrivate} = cls; -// public and project should be ok XPECT errors --> "Property named "fieldPrivate" is not readable: The field fieldPrivate is not visible." at "fieldPrivate" +// public and project should be ok XPECT errors --> "Property named 'fieldPrivate' is not readable: The field fieldPrivate is not visible." at "fieldPrivate" ({fieldPublic, fieldProject, fieldPrivate} = cls); diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_Object_propMustExist.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_Object_propMustExist.n4js.xt index 61a15bc66b..8a1b4adb77 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_Object_propMustExist.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_Object_propMustExist.n4js.xt @@ -16,13 +16,13 @@ var obj = {one:1, two:2}; var arr = [ {first:1, second:2} ]; -// XPECT errors --> "Value to be destructured does not contain a property, field or getter named "three": ~Object with { one: int; two: int }." at "three" +// XPECT errors --> "Value to be destructured does not contain a property, field or getter named 'three': ~Object with { one: int; two: int }." at "three" var {one:a1,two:b1,three:c1} = obj; -// XPECT errors --> "Value to be destructured does not contain a property, field or getter named "three": ~Object with { one: int; two: int }." at "three" +// XPECT errors --> "Value to be destructured does not contain a property, field or getter named 'three': ~Object with { one: int; two: int }." at "three" ({one:a1,two:b1,three:c1} = obj); -// XPECT errors --> "Value to be destructured does not contain a property, field or getter named "third": ~Object with { first: int; second: int }." at "third" +// XPECT errors --> "Value to be destructured does not contain a property, field or getter named 'third': ~Object with { first: int; second: int }." at "third" for(var {first:a2,second:b2,third:c2} of arr) {} -// XPECT errors --> "Value to be destructured does not contain a property, field or getter named "third": ~Object with { first: int; second: int }." at "third" +// XPECT errors --> "Value to be destructured does not contain a property, field or getter named 'third': ~Object with { first: int; second: int }." at "third" for({first:a2,second:b2,third:c2} of arr) {} @@ -31,13 +31,13 @@ for({first:a2,second:b2,third:c2} of arr) {} // correct position of error message in case of single name bindings: -// XPECT errors --> "Value to be destructured does not contain a property, field or getter named "three": ~Object with { one: int; two: int }." at "three" +// XPECT errors --> "Value to be destructured does not contain a property, field or getter named 'three': ~Object with { one: int; two: int }." at "three" var {one,two,three} = obj; -// XPECT errors --> "Value to be destructured does not contain a property, field or getter named "three": ~Object with { one: int; two: int }." at "three" +// XPECT errors --> "Value to be destructured does not contain a property, field or getter named 'three': ~Object with { one: int; two: int }." at "three" ({one,two,three} = obj); -// XPECT errors --> "Value to be destructured does not contain a property, field or getter named "third": ~Object with { first: int; second: int }." at "third" +// XPECT errors --> "Value to be destructured does not contain a property, field or getter named 'third': ~Object with { first: int; second: int }." at "third" for(var {first,second,third} of arr) {} -// XPECT errors --> "Value to be destructured does not contain a property, field or getter named "third": ~Object with { first: int; second: int }." at "third" +// XPECT errors --> "Value to be destructured does not contain a property, field or getter named 'third': ~Object with { first: int; second: int }." at "third" for({first,second,third} of arr) {} @@ -67,6 +67,6 @@ var { getterI: [b6i,b6ii,b6iii], fieldC: c6, getterC: d6, - // XPECT errors --> "Value to be destructured does not contain a property, field or getter named "notFound": Cls." at "notFound" + // XPECT errors --> "Value to be destructured does not contain a property, field or getter named 'notFound': Cls." at "notFound" notFound: e6 } = cls; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_Object_propUnionIntersectionType.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_Object_propUnionIntersectionType.n4js.xt index dae7b847fd..2952f8b5ea 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_Object_propUnionIntersectionType.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_Object_propUnionIntersectionType.n4js.xt @@ -39,7 +39,7 @@ var {fieldSimple:a11 : A} = value; var {fieldDifferentTypes:a12 : X} = value; // XPECT errors --> "Variable a13 cannot hold destructured value of property 'fieldGetter': A is not a subtype of X." at "a13" var {fieldGetter:a13 : X} = value; -// XPECT errors --> "Property named "fieldOnlyInClsA" is not readable: Member fieldOnlyInClsA not present in all types of union; missing from: ClsB." at "fieldOnlyInClsA" +// XPECT errors --> "Property named 'fieldOnlyInClsA' is not readable: Member fieldOnlyInClsA not present in all types of union; missing from: ClsB." at "fieldOnlyInClsA" var {fieldOnlyInClsA:a14 : X} = value; -// XPECT errors --> "Value to be destructured does not contain a property, field or getter named "fieldNotFound": union{ClsA,ClsB}." at "fieldNotFound" +// XPECT errors --> "Value to be destructured does not contain a property, field or getter named 'fieldNotFound': union{ClsA,ClsB}." at "fieldNotFound" var {fieldNotFound: a15} = value; diff --git a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/dirtystate/AbstractCanLoadFromDescriptionTest.java b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/dirtystate/AbstractCanLoadFromDescriptionTest.java index 4cd5d74daa..ef3e994a78 100644 --- a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/dirtystate/AbstractCanLoadFromDescriptionTest.java +++ b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/dirtystate/AbstractCanLoadFromDescriptionTest.java @@ -43,7 +43,7 @@ abstract public class AbstractCanLoadFromDescriptionTest extends ConvertedIdeTes @Override protected Set getIgnoredIssueCodes() { Set ignoredIssueCodes = super.getIgnoredIssueCodes(); - ignoredIssueCodes.add(IssueCodes.LTD_ILLEGAL_LOADTIME_REFERENCE); + ignoredIssueCodes.add(IssueCodes.LTD_ILLEGAL_LOADTIME_REFERENCE.name()); return ignoredIssueCodes; } diff --git a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/realworld/ListBaseIdeTest.java b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/realworld/ListBaseIdeTest.java index 9542aa025b..622609cc33 100644 --- a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/realworld/ListBaseIdeTest.java +++ b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/realworld/ListBaseIdeTest.java @@ -32,7 +32,7 @@ public class ListBaseIdeTest extends ConvertedIdeTest { public Set getIgnoredIssueCodes() { return FluentIterable.concat( super.getIgnoredIssueCodes(), - Collections.singleton(IssueCodes.CLF_NAME_CONTAINS_DISCOURAGED_CHARACTER)).toSet(); + Collections.singleton(IssueCodes.CLF_NAME_CONTAINS_DISCOURAGED_CHARACTER.name())).toSet(); } @Test diff --git a/tests/org.eclipse.n4js.utils.tests/src/org/eclipse/n4js/utils/DiffBuilderTest2.java b/tests/org.eclipse.n4js.utils.tests/src/org/eclipse/n4js/utils/DiffBuilderTest2.java deleted file mode 100644 index bc47f5ae16..0000000000 --- a/tests/org.eclipse.n4js.utils.tests/src/org/eclipse/n4js/utils/DiffBuilderTest2.java +++ /dev/null @@ -1,246 +0,0 @@ -/** - * 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.utils; - -import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.List; -import java.util.function.Function; - -import org.eclipse.xtend.lib.annotations.Accessors; -import org.eclipse.xtext.xbase.lib.IterableExtensions; -import org.eclipse.xtext.xbase.lib.Pure; -import org.eclipse.xtext.xbase.lib.util.ToStringBuilder; -import org.junit.Test; - -/** - * Test for {@link DiffBuilder}. - */ -public class DiffBuilderTest2 { - - @Test - public void testAddExistingExpectZeroAdded() { - DiffBuilder builder = new NodeDiffBuilder(newInput(List.of(1, 2, 3))) - .add(newNode(1)); - - assertTrue("Expected empty added items. Was «builder.addedItems»", builder.addedItems.isEmpty()); - } - - @Test - public void testAddNewThenRemoveExpectZeroAdded() { - DiffBuilder builder = new NodeDiffBuilder(newInput(List.of(1, 2, 3))) - .add(newNode(36)) - .delete(newNode(36)); - - assertTrue("Expected empty added items. Was «builder.addedItems»", builder.addedItems.isEmpty()); - } - - @Test - public void testAddNewThenRemoveExpectZeroRemoved() { - DiffBuilder builder = new NodeDiffBuilder(newInput(List.of(1, 2, 3))) - .add(newNode(36)) - .delete(newNode(36)); - - assertTrue("Expected empty deleted items. Was «builder.deletedItems»", builder.deletedItems.isEmpty()); - } - - @Test - public void testEditExistingThenRemoveExpectZeroEdited() { - DiffBuilder builder = new NodeDiffBuilder(newInput(List.of(1, 2, 3))) - .edit(newNode(2), newNode(36)) - .delete(newNode(36)); - - assertTrue("Expected empty edited items. Was «builder.editedItems»", builder.editedItems.isEmpty()); - } - - @Test - public void testEditExistingThenRemoveExpectOriginalIsDeleted() { - DiffBuilder builder = new NodeDiffBuilder(newInput(List.of(1, 2, 3))) - .edit(newNode(2), newNode(36)) - .delete(newNode(36)); - - assertTrue("Expected «newNode(2)» among deleted items. Was «builder.deletedItems»", - builder.deletedItems.contains(newNode(2))); - } - - @Test - public void testEditExistingThenRemoveThenReAddExpectNoChanges() { - DiffBuilder builder = new NodeDiffBuilder(newInput(List.of(1, 2, 3))) - .edit(newNode(2), newNode(36)) - .delete(newNode(36)) - .add(newNode(2)); - - assertTrue("Expected empty added items. Was «builder.addedItems»", builder.addedItems.isEmpty()); - assertTrue("Expected empty edited items. Was «builder.editedItems»", builder.editedItems.isEmpty()); - assertTrue("Expected empty deleted items. Was «builder.deletedItems»", builder.deletedItems.isEmpty()); - } - - private Input newInput(List ids) { - return newInput(ids, ids); - } - - private Input newInput(List ids, List allIds) { - - return new Input(map(ids, id -> newNode(id)), map(allIds, id -> newNode(id))); - } - - private Node newNode(Integer id) { - return newNode(id, "«id»"); - } - - private Node newNode(Integer id, String label) { - return new Node(id, label); - } - - static class Node { - final Integer id; - String label; - - Node(Integer id, String label) { - this.id = id; - this.label = label; - } - - @Override - public String toString() { - return "ID: " + id + " | Label: " + label; - } - - public Node(final Integer id) { - super(); - this.id = id; - } - - @Pure - public String getLabel() { - return this.label; - } - - public void setLabel(final String label) { - this.label = label; - } - - @Pure - public Integer getId() { - return this.id; - } - - @Override - @Pure - public boolean equals(final Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Node other = (Node) obj; - if (this.label == null) { - if (other.label != null) - return false; - } else if (!this.label.equals(other.label)) - return false; - if (this.id == null) { - if (other.id != null) - return false; - } else if (!this.id.equals(other.id)) - return false; - return true; - } - - @Override - @Pure - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.label == null) ? 0 : this.label.hashCode()); - return prime * result + ((this.id == null) ? 0 : this.id.hashCode()); - } - } - - static class Input { - Node[] oldItems; - Node[] oldAllItems; - - public Input(Iterable oldItems, Iterable oldAllItems) { - this.oldItems = IterableExtensions.toList(oldItems).toArray(new Node[0]); - this.oldAllItems = IterableExtensions.toList(oldAllItems).toArray(new Node[0]); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.oldItems == null) ? 0 : Arrays.deepHashCode(this.oldItems)); - return prime * result + ((this.oldAllItems == null) ? 0 : Arrays.deepHashCode(this.oldAllItems)); - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Input other = (Input) obj; - if (this.oldItems == null) { - if (other.oldItems != null) - return false; - } else if (!Arrays.deepEquals(this.oldItems, other.oldItems)) - return false; - if (this.oldAllItems == null) { - if (other.oldAllItems != null) - return false; - } else if (!Arrays.deepEquals(this.oldAllItems, other.oldAllItems)) - return false; - return true; - } - - @Override - public String toString() { - ToStringBuilder b = new ToStringBuilder(this); - b.add("oldItems", this.oldItems); - b.add("oldAllItems", this.oldAllItems); - return b.toString(); - } - - public Node[] getOldItems() { - return this.oldItems; - } - - public Node[] getOldAllItems() { - return this.oldAllItems; - } - } - - @Accessors - static class NodeDiffBuilder extends DiffBuilder { - - NodeDiffBuilder(Input f) { - super(f); - } - - @Override - protected Function getOldItemsFunction() { - return input -> input.oldItems; - } - - @Override - protected Function getAllOldItemsFunction() { - return input -> input.oldAllItems; - } - - } - -} diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typemodifier/GHOLD411_optional_field_ternay_expression_object_literals.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typemodifier/GHOLD411_optional_field_ternay_expression_object_literals.n4js.xt index 077a6db483..7ff18a8896 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typemodifier/GHOLD411_optional_field_ternay_expression_object_literals.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typemodifier/GHOLD411_optional_field_ternay_expression_object_literals.n4js.xt @@ -23,7 +23,7 @@ var jvar: J = { }; const jconst: J = {}; var b: boolean; -// XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "b ? undefined : undefined" +// XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "b ? undefined : undefined" i = b ? undefined : undefined; // XPECT errors --> "J is not a structural subtype of I: missing field optional." at "b ? jvar : null" diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typemodifier/GHOLD411_optional_field_ternay_expression_object_new_expression_final_nominal.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typemodifier/GHOLD411_optional_field_ternay_expression_object_new_expression_final_nominal.n4js.xt index f8a02744e7..4b7e263a00 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typemodifier/GHOLD411_optional_field_ternay_expression_object_new_expression_final_nominal.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typemodifier/GHOLD411_optional_field_ternay_expression_object_new_expression_final_nominal.n4js.xt @@ -36,7 +36,7 @@ i = b? c: null; // XPECT noerrors i = b? new C() : new C(); -// XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "b? undefined : undefined" +// XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "b? undefined : undefined" i = b? undefined : undefined; // XPECT noerrors diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/AT_IDEBUG_228_this_type_in_functionexpression.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/AT_IDEBUG_228_this_type_in_functionexpression.n4js.xt index 0b10bacfb2..ac12e5a45d 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/AT_IDEBUG_228_this_type_in_functionexpression.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/AT_IDEBUG_228_this_type_in_functionexpression.n4js.xt @@ -18,11 +18,11 @@ class A { /* FTE in formal parameters of method declaration */ // XPECT noerrors --> m1( param : {function(this)}) : string { return null; } // ok - // XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" + // XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" m2( param : {function():this}) : string { return null; } // disallow /* FTE as returntype of method declaration */ - // XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" + // XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" m3( ) : {function(this)} { return null; } // disallow // XPECT noerrors --> @@ -32,11 +32,11 @@ class A { /* FTE in formal parameters of method declaration */ // XPECT noerrors --> set a ( x : {function(this)} ){ } // ok - // XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" + // XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" set b ( x : {function():this} ){ } // disallow /* FTE as returntype of getter declaration */ - // XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" + // XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" get b () : {function(this)} { return null; } // disallow // XPECT noerrors --> diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/IDE_657_external/ExternalInN4JS.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/IDE_657_external/ExternalInN4JS.n4js.xt index 11b87fb32a..b0e9ebd87e 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/IDE_657_external/ExternalInN4JS.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/IDE_657_external/ExternalInN4JS.n4js.xt @@ -11,12 +11,12 @@ /* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest END_SETUP */ -// XPECT errors --> "Classes declared as external have to be placed in a file with file extension n4jsd." at "Point" +// XPECT errors --> "Classes declared as external have to be placed in a file with file extension 'n4jsd'." at "Point" export external class Point { } -// XPECT errors --> "Interfaces declared as external have to be placed in a file with file extension n4jsd." at "Clonable" +// XPECT errors --> "Interfaces declared as external have to be placed in a file with file extension 'n4jsd'." at "Clonable" export external interface Clonable { } diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/IDE_784_external/Enum.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/IDE_784_external/Enum.n4js.xt index 414cb3ff31..dba929c261 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/IDE_784_external/Enum.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/IDE_784_external/Enum.n4js.xt @@ -11,7 +11,7 @@ /* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest END_SETUP */ -// XPECT errors --> "Enumerations declared as external have to be placed in a file with file extension n4jsd." at "EnumWithExternal" +// XPECT errors --> "Enumerations declared as external have to be placed in a file with file extension 'n4jsd'." at "EnumWithExternal" export external public enum EnumWithExternal { MayBug, Cockroach: "another bug" @@ -24,14 +24,14 @@ export public enum EnumWithoutExternal { /* XPECT errors --- "Unsupported feature: non-exported enum with a visibility higher than private." at "public" - "Enumerations declared as external have to be placed in a file with file extension n4jsd." at "EnumWithoutExport" + "Enumerations declared as external have to be placed in a file with file extension 'n4jsd'." at "EnumWithoutExport" --- */ external public enum EnumWithoutExport { MayBug, Cockroach } -// XPECT errors --> "Enumerations declared as external have to be placed in a file with file extension n4jsd." at "EnumWithoutPublic" +// XPECT errors --> "Enumerations declared as external have to be placed in a file with file extension 'n4jsd'." at "EnumWithoutPublic" export external enum EnumWithoutPublic { MayBug, Cockroach diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/IDE_784_external/Funs.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/IDE_784_external/Funs.n4js.xt index c9651f0306..8c6306aa0e 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/IDE_784_external/Funs.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/IDE_784_external/Funs.n4js.xt @@ -16,17 +16,17 @@ export public function funWithoutExternal(s : string): number { return 0; } // XPECT errors --> "Functions have to have a body." at "funWithoutExternalAndWithoutBody" export public function funWithoutExternalAndWithoutBody(s : string): number -// XPECT errors --> "Functions declared as external have to be placed in a file with file extension n4jsd." at "funWithExternal" +// XPECT errors --> "Functions declared as external have to be placed in a file with file extension 'n4jsd'." at "funWithExternal" export external public function funWithExternal(s : string): number -// XPECT errors --> "Functions declared as external have to be placed in a file with file extension n4jsd." at "funWithoutExport" +// XPECT errors --> "Functions declared as external have to be placed in a file with file extension 'n4jsd'." at "funWithoutExport" external function funWithoutExport(s : string) -// XPECT errors --> "Functions declared as external have to be placed in a file with file extension n4jsd." at "funWithoutPublic" +// XPECT errors --> "Functions declared as external have to be placed in a file with file extension 'n4jsd'." at "funWithoutPublic" export external function funWithoutPublic(s : string): number -// XPECT errors --> "Functions declared as external have to be placed in a file with file extension n4jsd." at "funWithBody" +// XPECT errors --> "Functions declared as external have to be placed in a file with file extension 'n4jsd'." at "funWithBody" export external public function funWithBody(s : string): number { return 0; } -// XPECT errors --> "Functions declared as external have to be placed in a file with file extension n4jsd." at "funWithoutModifier" +// XPECT errors --> "Functions declared as external have to be placed in a file with file extension 'n4jsd'." at "funWithoutModifier" external function funWithoutModifier(s : string): number diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/dataflow/NullUndefined_SpecialExpressions.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/dataflow/NullUndefined_SpecialExpressions.n4js.xt index 5a5b2743be..5317a1ed95 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/dataflow/NullUndefined_SpecialExpressions.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/dataflow/NullUndefined_SpecialExpressions.n4js.xt @@ -71,7 +71,7 @@ function f2b() { function f2c() { let a : int = 0; - // XPECT warnings --> "The type of this expression is undefined, so it will never evaluate to a value other than undefined." at "a = undefined" + // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "a = undefined" let b : int = a = undefined; // XPECT warnings --> "Variable a is undefined" at "a" a.toString(); diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/return_behaviour/IDEBUG_155_functions_UnionReturnType.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/return_behaviour/IDEBUG_155_functions_UnionReturnType.n4js.xt index cf40fd8fbb..aa6eef620c 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/return_behaviour/IDEBUG_155_functions_UnionReturnType.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/return_behaviour/IDEBUG_155_functions_UnionReturnType.n4js.xt @@ -18,7 +18,7 @@ function fu1(): union{string,int} {} /* XPECT errors --- "Missing return or throw statement." at "fu2" - "Type void may only be used to declare the return type of functions and methods." at "void" + "Type 'void' may only be used to declare the return type of functions and methods." at "void" --- */ function fu2(): union{string,void} {} diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/super/arrowExpression.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/super/arrowExpression.n4js.xt index 8a9729c907..4a3b8ab879 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/super/arrowExpression.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/super/arrowExpression.n4js.xt @@ -22,7 +22,7 @@ let a; function f() { -// XPECT errors --> "Value to be destructured does not contain a property, field or getter named "a": ~Object." at "a" +// XPECT errors --> "Value to be destructured does not contain a property, field or getter named 'a': ~Object." at "a" ({a = (0, // XPECT errors --> "A default value is only allowed within a destructuring pattern." at "0" diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/super/useStrict.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/super/useStrict.n4js.xt index 40b66310c4..110702095c 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/super/useStrict.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/super/useStrict.n4js.xt @@ -52,7 +52,7 @@ // XPECT errors --> "octal literals and octal escape sequences are not allowed in strict mode." at "0129" -// XPECT warnings --> "Don't use extra leading zeros 0129."" at "0129" +// XPECT warnings --> "Don't use extra leading zeros 0129." at "0129" 0129; diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/this/AT_538_ThisTypeAllowedOccurences.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/this/AT_538_ThisTypeAllowedOccurences.n4js.xt index 550dee4529..90833ce123 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/this/AT_538_ThisTypeAllowedOccurences.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/this/AT_538_ThisTypeAllowedOccurences.n4js.xt @@ -25,23 +25,23 @@ class A { return this.test1(); } -// XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" +// XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" test3(myParameter : this) : void { } test4() : void { - // XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" + // XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" var x : this; } } -// XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" +// XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" function fun1() : this { return null } -// XPECT errors --> "The this type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" +// XPECT errors --> "The 'this' type isn't allowed on this place. (Please refer to Spec for valid use cases.)" at "this" function fun2(param : this) { return null } diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/userfriendlyParserIssues/ExtendsVsImplements.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/userfriendlyParserIssues/ExtendsVsImplements.n4js.xt index 3fc6e54481..adfd2a340d 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/userfriendlyParserIssues/ExtendsVsImplements.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/userfriendlyParserIssues/ExtendsVsImplements.n4js.xt @@ -22,10 +22,10 @@ class A0 extends C implements I {} interface J0 extends I, I1 {} -// XPECT errors --> "The class A1 cannot implement class C, use "extends"." at "C" +// XPECT errors --> "The class A1 cannot implement class C, use 'extends'." at "C" class A1 implements C {} -// XPECT errors --> "The class A2 cannot extend interface I, use "implements"." at "I" +// XPECT errors --> "The class A2 cannot extend interface I, use 'implements'." at "I" class A2 extends I {} // XPECT errors --> "The interface A3 cannot extend class C." at "C" @@ -40,6 +40,6 @@ class A5 implements I extends C {} // XPECT errors --- // "The class A6 cannot implement class C." at "C" // "Extended class must be declared before implemented interfaces." at "extends" -// "The class A6 cannot extend interface I, use "implements"." at "I" +// "The class A6 cannot extend interface I, use 'implements'." at "I" // --- class A6 implements C extends I {} From d7c8d062c6a84c4eeccfaf5248c32476ec2bdbbd Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Mon, 11 Dec 2023 17:26:27 +0100 Subject: [PATCH 07/26] GH-2584: As a developer I want updated dependencies in n4js-cli --- n4js-libs/package.json | 2 +- n4js-libs/packages/n4js-cli/package.json | 10 +- .../packages/n4js-mangelhaft-cli/package.json | 8 +- .../package.json | 2 +- .../package.json | 2 +- n4js-libs/yarn.lock | 1163 ++++++++--------- 6 files changed, 576 insertions(+), 611 deletions(-) diff --git a/n4js-libs/package.json b/n4js-libs/package.json index e43131907a..e6a4d23f56 100644 --- a/n4js-libs/package.json +++ b/n4js-libs/package.json @@ -3,7 +3,7 @@ "devDependencies": { "json": "11.0.0", "lerna": "7.1.0", - "semver": "7.5.3" + "semver": "7.5.4" }, "scripts": { "bundle": "yarn workspace n4js-runtime bundle", diff --git a/n4js-libs/packages/n4js-cli/package.json b/n4js-libs/packages/n4js-cli/package.json index e067d44660..f293a8027a 100644 --- a/n4js-libs/packages/n4js-cli/package.json +++ b/n4js-libs/packages/n4js-cli/package.json @@ -27,12 +27,12 @@ }, "dependencies": { "@types/node": "^16", - "@types/debug": "4.1.7", - "@types/npmlog": "4.1.4", - "follow-redirects": "1.14.9", + "@types/debug": "4.1.12", + "@types/npmlog": "7.0.0", + "follow-redirects": "1.15.3", "decompress": "4.2.1", - "debug": "~4.3.1", - "npmlog": "4.1.2", + "debug": "~4.3.4", + "npmlog": "7.0.1", "n4js-runtime": "^0.1.0", "n4js-runtime-es2015": "^0.1.0", "n4js-runtime-esnext": "^0.1.0" diff --git a/n4js-libs/packages/n4js-mangelhaft-cli/package.json b/n4js-libs/packages/n4js-mangelhaft-cli/package.json index caf780a5ae..11444c0ed5 100644 --- a/n4js-libs/packages/n4js-mangelhaft-cli/package.json +++ b/n4js-libs/packages/n4js-mangelhaft-cli/package.json @@ -17,13 +17,13 @@ "type": "module", "dependencies": { "@types/node": "^16", - "@types/debug": "4.1.7", + "@types/debug": "4.1.12", "@types/glob": "7.2.0", "cli-color": "~1.2.0", - "debug": "~4.3.1", + "debug": "~4.3.4", "glob": "^7.2.3", - "istanbul-lib-coverage": "^3.2.0", - "minimatch": "9.0.2", + "istanbul-lib-coverage": "^3.2.2", + "minimatch": "9.0.3", "n4js-runtime": "^0.1.0", "n4js-runtime-es2015": "^0.1.0", "n4js-runtime-esnext": "^0.1.0", diff --git a/n4js-libs/packages/org.eclipse.n4js.mangelhaft.reporter.sonar/package.json b/n4js-libs/packages/org.eclipse.n4js.mangelhaft.reporter.sonar/package.json index 98120f8dd7..114fa885f9 100644 --- a/n4js-libs/packages/org.eclipse.n4js.mangelhaft.reporter.sonar/package.json +++ b/n4js-libs/packages/org.eclipse.n4js.mangelhaft.reporter.sonar/package.json @@ -23,7 +23,7 @@ "dependencies": { "@types/node": "^16", "org.eclipse.n4js.mangelhaft": "^0.1.0", - "xmlbuilder2": "^3.0.2", + "xmlbuilder2": "^3.1.1", "n4js-runtime": "^0.1.0", "n4js-runtime-es2015": "^0.1.0" }, diff --git a/n4js-libs/packages/org.eclipse.n4js.mangelhaft.reporter.xunit/package.json b/n4js-libs/packages/org.eclipse.n4js.mangelhaft.reporter.xunit/package.json index 49367b98af..43bc7fcb11 100644 --- a/n4js-libs/packages/org.eclipse.n4js.mangelhaft.reporter.xunit/package.json +++ b/n4js-libs/packages/org.eclipse.n4js.mangelhaft.reporter.xunit/package.json @@ -23,7 +23,7 @@ "dependencies": { "@types/node": "^16", "org.eclipse.n4js.mangelhaft": "^0.1.0", - "xmlbuilder2": "^3.0.2", + "xmlbuilder2": "^3.1.1", "n4js-runtime": "^0.1.0", "n4js-runtime-es2015": "^0.1.0" }, diff --git a/n4js-libs/yarn.lock b/n4js-libs/yarn.lock index 059bc7a59e..56e7be32d3 100644 --- a/n4js-libs/yarn.lock +++ b/n4js-libs/yarn.lock @@ -3,24 +3,25 @@ "@babel/code-frame@^7.0.0": - version "7.21.4" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" - integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== + version "7.23.5" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== dependencies: - "@babel/highlight" "^7.18.6" + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" -"@babel/helper-validator-identifier@^7.18.6": - version "7.19.1" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" js-tokens "^4.0.0" "@gar/promisify@^1.1.3": @@ -45,12 +46,12 @@ wrap-ansi "^8.1.0" wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" -"@jest/schemas@^29.4.3": - version "29.4.3" - resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788" - integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg== +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== dependencies: - "@sinclair/typebox" "^0.25.16" + "@sinclair/typebox" "^0.27.8" "@lerna/child-process@7.1.0": version "7.1.0" @@ -117,9 +118,9 @@ semver "^7.3.5" "@npmcli/git@^4.0.0": - version "4.0.4" - resolved "https://registry.npmjs.org/@npmcli/git/-/git-4.0.4.tgz#cdf74f21b1d440c0756fb28159d935129d9daa33" - integrity sha512-5yZghx+u5M47LghaybLCkdSyFzV/w4OuH12d96HO389Ik9CDsLaDZJVynSGGVJOLn6gy/k7Dz5XYcplM3uxXRg== + version "4.1.0" + resolved "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz#ab0ad3fd82bc4d8c1351b6c62f0fa56e8fe6afa6" + integrity sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ== dependencies: "@npmcli/promise-spawn" "^6.0.0" lru-cache "^7.4.4" @@ -158,7 +159,7 @@ dependencies: which "^3.0.0" -"@npmcli/run-script@6.0.2": +"@npmcli/run-script@6.0.2", "@npmcli/run-script@^6.0.0": version "6.0.2" resolved "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.2.tgz#a25452d45ee7f7fb8c16dfaf9624423c0c0eb885" integrity sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA== @@ -169,99 +170,88 @@ read-package-json-fast "^3.0.0" which "^3.0.0" -"@npmcli/run-script@^6.0.0": - version "6.0.0" - resolved "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.0.tgz#f89e322c729e26ae29db6cc8cc76559074aac208" - integrity sha512-ql+AbRur1TeOdl1FY+RAwGW9fcr4ZwiVKabdvm93mujGREVuVLbdkXRJDrkTXSdCjaxYydr1wlA2v67jxWG5BQ== - dependencies: - "@npmcli/node-gyp" "^3.0.0" - "@npmcli/promise-spawn" "^6.0.0" - node-gyp "^9.0.0" - read-package-json-fast "^3.0.0" - which "^3.0.0" - -"@nrwl/devkit@16.4.0": - version "16.4.0" - resolved "https://registry.npmjs.org/@nrwl/devkit/-/devkit-16.4.0.tgz#0bd16834e09d1b01fadf5c68fd19410893e61ac8" - integrity sha512-KUu9oNrMB8DP78BAO8XWJC5HOSS6dO6ocMWj2DtuNVgMgABviy+ih/TmrGKxQQBH0Ib4cxTeMIQVRdAak5c1UA== +"@nrwl/devkit@16.10.0": + version "16.10.0" + resolved "https://registry.npmjs.org/@nrwl/devkit/-/devkit-16.10.0.tgz#ac8c5b4db00f12c4b817c937be2f7c4eb8f2593c" + integrity sha512-fRloARtsDQoQgQ7HKEy0RJiusg/HSygnmg4gX/0n/Z+SUS+4KoZzvHjXc6T5ZdEiSjvLypJ+HBM8dQzIcVACPQ== dependencies: - "@nx/devkit" "16.4.0" + "@nx/devkit" "16.10.0" -"@nrwl/tao@16.4.0": - version "16.4.0" - resolved "https://registry.npmjs.org/@nrwl/tao/-/tao-16.4.0.tgz#81a844c8c707ff747b26ea7d23f6bed005b72967" - integrity sha512-6n4chOOv6jqact07NvIDRQfsnaiYYhi+mrqSuJKs6fL+c5kx/VCryndTP0MDTBbazfL6H7vwiQUkTja2sQDuwA== +"@nrwl/tao@16.10.0": + version "16.10.0" + resolved "https://registry.npmjs.org/@nrwl/tao/-/tao-16.10.0.tgz#94642a0380709b8e387e1e33705a5a9624933375" + integrity sha512-QNAanpINbr+Pod6e1xNgFbzK1x5wmZl+jMocgiEFXZ67KHvmbD6MAQQr0MMz+GPhIu7EE4QCTLTyCEMlAG+K5Q== dependencies: - nx "16.4.0" + nx "16.10.0" + tslib "^2.3.0" -"@nx/devkit@16.4.0", "@nx/devkit@>=16.1.3 < 17": - version "16.4.0" - resolved "https://registry.npmjs.org/@nx/devkit/-/devkit-16.4.0.tgz#e8e5d6c6e4f6964387d418a4b48588528a021517" - integrity sha512-/Y+tC2IBxVEf3EKB80G9mF27ZBAFEBBmDMn1MPzfGX9AB2GGNCqgvSkSHT5DlkyxJOMqbE7DpMyHxubALyenEA== +"@nx/devkit@16.10.0", "@nx/devkit@>=16.1.3 < 17": + version "16.10.0" + resolved "https://registry.npmjs.org/@nx/devkit/-/devkit-16.10.0.tgz#7e466be2dee2dcb1ccaf286786ca2a0a639aa007" + integrity sha512-IvKQqRJFDDiaj33SPfGd3ckNHhHi6ceEoqCbAP4UuMXOPPVOX6H0KVk+9tknkPb48B7jWIw6/AgOeWkBxPRO5w== dependencies: - "@nrwl/devkit" "16.4.0" + "@nrwl/devkit" "16.10.0" ejs "^3.1.7" + enquirer "~2.3.6" ignore "^5.0.4" semver "7.5.3" tmp "~0.2.1" tslib "^2.3.0" -"@nx/nx-darwin-arm64@16.4.0": - version "16.4.0" - resolved "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.4.0.tgz#72d5cbeb585aa05b4035f1de8f92ba562b180137" - integrity sha512-/ZXuF8M3u8DSNmjYstQKorzo7uIETNhnFinwWlO8mzz+SyR+Xs5G6penJ4+cB1ju3Hf3lZkXd5U6pEiW4OAAkA== - -"@nx/nx-darwin-x64@16.4.0": - version "16.4.0" - resolved "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-16.4.0.tgz#24f8b9946c77ec1d66e42ffe2f84623e4072167c" - integrity sha512-0Fo58qZzHgRs4SRVaAOBipdJQNew57YQbpFaLHKhCTyKc0Pe6THEYaaT/x9QVkcFO0x4AzNr9T7iJTrneNwcKg== - -"@nx/nx-freebsd-x64@16.4.0": - version "16.4.0" - resolved "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.4.0.tgz#a82954fe4bc6a74cd6b7e0cb89e1486ac4c06e27" - integrity sha512-Qoes/NifE4zb5Gb6ZdC32HvxZBzO0xo74j7EozUV5rZEm3bCtKbKqThPV9Uuu+8S4j718r5vlob/IMXqRcWK4g== - -"@nx/nx-linux-arm-gnueabihf@16.4.0": - version "16.4.0" - resolved "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.4.0.tgz#77911992e38c1aee51d4a075545ea2828d074c45" - integrity sha512-m8uklbettj8RnLtasjQPiYxqJotDSfO3LO1II8Bds53C7OT8TDnTkW68MEx+CxuSCQFy2Aa0Oih3jSvDzfnZzA== - -"@nx/nx-linux-arm64-gnu@16.4.0": - version "16.4.0" - resolved "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.4.0.tgz#ee2b7208083cf3fc63121ee079ab3e0c2bbe5fa4" - integrity sha512-bAs2T/zZQDTCzzhciE8kCrkwgXbeX3K83cGRacB7PDZZl/O4jr5TRO4zYHi6doytyLONjqhvWNLbIo4cEEcfZA== - -"@nx/nx-linux-arm64-musl@16.4.0": - version "16.4.0" - resolved "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.4.0.tgz#afaf514d3df0bc31c4a6545d254502c661e3d347" - integrity sha512-K1D8j4lRZDBVuW8iomeJjCznFz7rfP3qaB3RHjKZU5qrZBq1uYohhdfT7dzwWFNWEvt6WytfhGCl2S9PsQ37Wg== - -"@nx/nx-linux-x64-gnu@16.4.0": - version "16.4.0" - resolved "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.4.0.tgz#fba4991ac27f0c342157445259485c06fca686f2" - integrity sha512-v1NJ3ESaw5bdSeuh5Xslq1dXGWztf0mSLwZP510Rt9+ulr5LQ/X1Rri8zefU0gZNLcmJL0G2Qq7UTnppYGRTEg== - -"@nx/nx-linux-x64-musl@16.4.0": - version "16.4.0" - resolved "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.4.0.tgz#9bbdb590a49de9667e2e26dc173fe6d303e165be" - integrity sha512-+8YLVWZFq+k6YJ2ZDwR5sGaRnZhUVYtR8aPbGyonMnJ8VEQJNEqsm1KT6nt0gd3JJdxyphm3VsMQWBMo42jM+w== - -"@nx/nx-win32-arm64-msvc@16.4.0": - version "16.4.0" - resolved "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.4.0.tgz#a2e06890c70afdd339d0d95516ae8bbc222d9ce6" - integrity sha512-HwE6AxlrfWvODT49vVX6NGMYc3zdMVXETCdZb0jZ/oz28XXTAPvVb/8DJgKSyCs0DPirEeCHiPwbdcJA1Bqw8A== - -"@nx/nx-win32-x64-msvc@16.4.0": - version "16.4.0" - resolved "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.4.0.tgz#d98b4087b696b524461fc142f656a337ed00a520" - integrity sha512-ISL3c6i/v+JOsUHEbngDHaobmbgu6oSY0htKas1RjLWGkWXDLgEXMRjQ/xDbNVYH00Mto7mmq+nrjkNNbqOrfQ== +"@nx/nx-darwin-arm64@16.10.0": + version "16.10.0" + resolved "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.10.0.tgz#0c73010cac7a502549483b12bad347da9014e6f1" + integrity sha512-YF+MIpeuwFkyvM5OwgY/rTNRpgVAI/YiR0yTYCZR+X3AAvP775IVlusNgQ3oedTBRUzyRnI4Tknj1WniENFsvQ== + +"@nx/nx-darwin-x64@16.10.0": + version "16.10.0" + resolved "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-16.10.0.tgz#2ccf270418d552fd0a8e0d6089aee4944315adaa" + integrity sha512-ypi6YxwXgb0kg2ixKXE3pwf5myVNUgWf1CsV5OzVccCM8NzheMO51KDXTDmEpXdzUsfT0AkO1sk5GZeCjhVONg== + +"@nx/nx-freebsd-x64@16.10.0": + version "16.10.0" + resolved "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.10.0.tgz#c3ee6914256e69493fed9355b0d6661d0e86da44" + integrity sha512-UeEYFDmdbbDkTQamqvtU8ibgu5jQLgFF1ruNb/U4Ywvwutw2d4ruOMl2e0u9hiNja9NFFAnDbvzrDcMo7jYqYw== + +"@nx/nx-linux-arm-gnueabihf@16.10.0": + version "16.10.0" + resolved "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.10.0.tgz#a961eccbb38acb2da7fc125b29d1fead0b39152f" + integrity sha512-WV3XUC2DB6/+bz1sx+d1Ai9q2Cdr+kTZRN50SOkfmZUQyEBaF6DRYpx/a4ahhxH3ktpNfyY8Maa9OEYxGCBkQA== + +"@nx/nx-linux-arm64-gnu@16.10.0": + version "16.10.0" + resolved "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.10.0.tgz#795f20072549d03822b5c4639ef438e473dbb541" + integrity sha512-aWIkOUw995V3ItfpAi5FuxQ+1e9EWLS1cjWM1jmeuo+5WtaKToJn5itgQOkvSlPz+HSLgM3VfXMvOFALNk125g== + +"@nx/nx-linux-arm64-musl@16.10.0": + version "16.10.0" + resolved "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.10.0.tgz#f2428ee6dbe2b2c326e8973f76c97666def33607" + integrity sha512-uO6Gg+irqpVcCKMcEPIQcTFZ+tDI02AZkqkP7koQAjniLEappd8DnUBSQdcn53T086pHpdc264X/ZEpXFfrKWQ== + +"@nx/nx-linux-x64-gnu@16.10.0": + version "16.10.0" + resolved "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.10.0.tgz#d36c2bcf94d49eaa24e3880ddaf6f1f617de539b" + integrity sha512-134PW/u/arNFAQKpqMJniC7irbChMPz+W+qtyKPAUXE0XFKPa7c1GtlI/wK2dvP9qJDZ6bKf0KtA0U/m2HMUOA== + +"@nx/nx-linux-x64-musl@16.10.0": + version "16.10.0" + resolved "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.10.0.tgz#78bd2ab97a583b3d4ea3387b67fd7b136907493c" + integrity sha512-q8sINYLdIJxK/iUx9vRk5jWAWb/2O0PAbOJFwv4qkxBv4rLoN7y+otgCZ5v0xfx/zztFgk/oNY4lg5xYjIso2Q== + +"@nx/nx-win32-arm64-msvc@16.10.0": + version "16.10.0" + resolved "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.10.0.tgz#ef20ec8d0c83d66e73e20df12d2c788b8f866396" + integrity sha512-moJkL9kcqxUdJSRpG7dET3UeLIciwrfP08mzBQ12ewo8K8FzxU8ZUsTIVVdNrwt01CXOdXoweGfdQLjJ4qTURA== + +"@nx/nx-win32-x64-msvc@16.10.0": + version "16.10.0" + resolved "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz#7410a51d0f8be631eec9552f01b2e5946285927c" + integrity sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA== "@octokit/auth-token@^3.0.0": - version "3.0.3" - resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.3.tgz#ce7e48a3166731f26068d7a7a7996b5da58cbe0c" - integrity sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA== - dependencies: - "@octokit/types" "^9.0.0" + version "3.0.4" + resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz#70e941ba742bdd2b49bdb7393e821dea8520a3db" + integrity sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ== "@octokit/core@^4.2.1": version "4.2.4" @@ -277,32 +267,27 @@ universal-user-agent "^6.0.0" "@octokit/endpoint@^7.0.0": - version "7.0.5" - resolved "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.5.tgz#2bb2a911c12c50f10014183f5d596ce30ac67dd1" - integrity sha512-LG4o4HMY1Xoaec87IqQ41TQ+glvIeTKqfjkCEmt5AIwDZJwQeVZFIEYXrYY6yLwK+pAScb9Gj4q+Nz2qSw1roA== + version "7.0.6" + resolved "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz#791f65d3937555141fb6c08f91d618a7d645f1e2" + integrity sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg== dependencies: "@octokit/types" "^9.0.0" is-plain-object "^5.0.0" universal-user-agent "^6.0.0" "@octokit/graphql@^5.0.0": - version "5.0.5" - resolved "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.5.tgz#a4cb3ea73f83b861893a6370ee82abb36e81afd2" - integrity sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ== + version "5.0.6" + resolved "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz#9eac411ac4353ccc5d3fca7d76736e6888c5d248" + integrity sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw== dependencies: "@octokit/request" "^6.0.0" "@octokit/types" "^9.0.0" universal-user-agent "^6.0.0" -"@octokit/openapi-types@^16.1.0": - version "16.1.0" - resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.1.0.tgz#c0a65a89bb67389dbe2dd7960cc8a86e42d5f4d5" - integrity sha512-+m6+376kp4gZAYtg64aXGHK2qM2LtIiZctqtbTnETdUaD7OSuX7zDV5kciqw1QIN13lg9jWz039OF7NZUdYEeQ== - "@octokit/openapi-types@^18.0.0": - version "18.0.0" - resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz#f43d765b3c7533fd6fb88f3f25df079c24fccf69" - integrity sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw== + version "18.1.1" + resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz#09bdfdabfd8e16d16324326da5148010d765f009" + integrity sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw== "@octokit/plugin-enterprise-rest@6.0.1": version "6.0.1" @@ -339,9 +324,9 @@ once "^1.4.0" "@octokit/request@^6.0.0": - version "6.2.3" - resolved "https://registry.npmjs.org/@octokit/request/-/request-6.2.3.tgz#76d5d6d44da5c8d406620a4c285d280ae310bdb4" - integrity sha512-TNAodj5yNzrrZ/VxP+H5HiYaZep0H3GU0O7PaF+fhDrt8FPrnkei9Aal/txsN/1P7V3CPiThG0tIvpPDYUsyAA== + version "6.2.8" + resolved "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz#aaf480b32ab2b210e9dadd8271d187c93171d8eb" + integrity sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw== dependencies: "@octokit/endpoint" "^7.0.0" "@octokit/request-error" "^3.0.0" @@ -372,14 +357,7 @@ dependencies: "@octokit/openapi-types" "^18.0.0" -"@octokit/types@^9.0.0": - version "9.1.0" - resolved "https://registry.npmjs.org/@octokit/types/-/types-9.1.0.tgz#c81f85c00b1b1b499f262097838f126612665068" - integrity sha512-MPKlN20dSKZ2JGV8KHNO4Y9z6xs74p5sQ2a5++5/uVme44K/5UEntIpai2n1WIrVtMlafYLdfN27BiBs2taY6g== - dependencies: - "@octokit/openapi-types" "^16.1.0" - -"@octokit/types@^9.2.3": +"@octokit/types@^9.0.0", "@octokit/types@^9.2.3": version "9.3.2" resolved "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz#3f5f89903b69f6a2d196d78ec35f888c0013cac5" integrity sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA== @@ -428,24 +406,39 @@ resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== -"@sigstore/protobuf-specs@^0.1.0": - version "0.1.0" - resolved "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.1.0.tgz#957cb64ea2f5ce527cc9cf02a096baeb0d2b99b4" - integrity sha512-a31EnjuIDSX8IXBUib3cYLDRlPMU36AWX4xS8ysLaNu4ZzUesDiPt83pgrW2X1YLMe5L2HbDyaKK5BrL4cNKaQ== +"@sigstore/bundle@^1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@sigstore/bundle/-/bundle-1.1.0.tgz#17f8d813b09348b16eeed66a8cf1c3d6bd3d04f1" + integrity sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog== + dependencies: + "@sigstore/protobuf-specs" "^0.2.0" + +"@sigstore/protobuf-specs@^0.2.0": + version "0.2.1" + resolved "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz#be9ef4f3c38052c43bd399d3f792c97ff9e2277b" + integrity sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A== -"@sigstore/tuf@^1.0.0": +"@sigstore/sign@^1.0.0": version "1.0.0" - resolved "https://registry.npmjs.org/@sigstore/tuf/-/tuf-1.0.0.tgz#13b69323e7bf8de458cd6c952c57acd1169772a5" - integrity sha512-bLzi9GeZgMCvjJeLUIfs8LJYCxrPRA8IXQkzUtaFKKVPTz0mucRyqFcV2U20yg9K+kYAD0YSitzGfRZCFLjdHQ== + resolved "https://registry.npmjs.org/@sigstore/sign/-/sign-1.0.0.tgz#6b08ebc2f6c92aa5acb07a49784cb6738796f7b4" + integrity sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA== dependencies: - "@sigstore/protobuf-specs" "^0.1.0" + "@sigstore/bundle" "^1.1.0" + "@sigstore/protobuf-specs" "^0.2.0" make-fetch-happen "^11.0.1" - tuf-js "^1.1.3" -"@sinclair/typebox@^0.25.16": - version "0.25.24" - resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" - integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== +"@sigstore/tuf@^1.0.3": + version "1.0.3" + resolved "https://registry.npmjs.org/@sigstore/tuf/-/tuf-1.0.3.tgz#2a65986772ede996485728f027b0514c0b70b160" + integrity sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg== + dependencies: + "@sigstore/protobuf-specs" "^0.2.0" + tuf-js "^1.1.7" + +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== "@tootallnate/once@2": version "2.0.0" @@ -457,18 +450,18 @@ resolved "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz#eade9fd1f537993bc1f0949f3aea276ecc4fab31" integrity sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ== -"@tufjs/models@1.0.3": - version "1.0.3" - resolved "https://registry.npmjs.org/@tufjs/models/-/models-1.0.3.tgz#e6cb8a86834da7459a7c836cd892dee56b4bab44" - integrity sha512-mkFEqqRisi13DmR5pX4x+Zk97EiU8djTtpNW1GeuX410y/raAsq/T3ZCjwoRIZ8/cIBfW0olK/sywlAiWevDVw== +"@tufjs/models@1.0.4": + version "1.0.4" + resolved "https://registry.npmjs.org/@tufjs/models/-/models-1.0.4.tgz#5a689630f6b9dbda338d4b208019336562f176ef" + integrity sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A== dependencies: "@tufjs/canonical-json" "1.0.0" - minimatch "^7.4.6" + minimatch "^9.0.0" -"@types/debug@4.1.7": - version "4.1.7" - resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" - integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== +"@types/debug@4.1.12": + version "4.1.12" + resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" + integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== dependencies: "@types/ms" "*" @@ -491,44 +484,48 @@ integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== "@types/minimist@^1.2.0": - version "1.2.2" - resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" - integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== + version "1.2.5" + resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" + integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== "@types/ms@*": - version "0.7.31" - resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== + version "0.7.34" + resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" + integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== "@types/node@*": - version "18.15.12" - resolved "https://registry.npmjs.org/@types/node/-/node-18.15.12.tgz#833756634e78c829e1254db006468dadbb0c696b" - integrity sha512-Wha1UwsB3CYdqUm2PPzh/1gujGCNtWVUYF0mB00fJFoR4gTyWTDPjSm+zBF787Ahw8vSGgBja90MkgFwvB86Dg== + version "20.10.4" + resolved "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz#b246fd84d55d5b1b71bf51f964bd514409347198" + integrity sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg== + dependencies: + undici-types "~5.26.4" "@types/node@^16": - version "16.18.24" - resolved "https://registry.npmjs.org/@types/node/-/node-16.18.24.tgz#f21925dd56cd3467b4e1e0c5071d0f2af5e9a316" - integrity sha512-zvSN2Esek1aeLdKDYuntKAYjti9Z2oT4I8bfkLLhIxHlv3dwZ5vvATxOc31820iYm4hQRCwjUgDpwSMFjfTUnw== + version "16.18.68" + resolved "https://registry.npmjs.org/@types/node/-/node-16.18.68.tgz#3155f64a961b3d8d10246c80657f9a7292e3421a" + integrity sha512-sG3hPIQwJLoewrN7cr0dwEy+yF5nD4D/4FxtQpFciRD/xwUzgD+G05uxZHv5mhfXo4F9Jkp13jjn0CC2q325sg== "@types/normalize-package-data@^2.4.0": - version "2.4.1" - resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== + version "2.4.4" + resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== -"@types/npmlog@4.1.4": - version "4.1.4" - resolved "https://registry.npmjs.org/@types/npmlog/-/npmlog-4.1.4.tgz#30eb872153c7ead3e8688c476054ddca004115f6" - integrity sha512-WKG4gTr8przEZBiJ5r3s8ZIAoMXNbOgQ+j/d5O4X3x6kZJRLNvyUJuUK/KoG3+8BaOHPhp2m7WC6JKKeovDSzQ== +"@types/npmlog@7.0.0": + version "7.0.0" + resolved "https://registry.npmjs.org/@types/npmlog/-/npmlog-7.0.0.tgz#76602f187ee5f36f77c1a221b2cc9391c76f3dfd" + integrity sha512-hJWbrKFvxKyWwSUXjZMYTINsSOY6IclhvGOZ97M8ac2tmR9hMwmTnYaMdpGhvju9ctWLTPhCS+eLfQNluiEjQQ== + dependencies: + "@types/node" "*" "@yarnpkg/lockfile@^1.1.0": version "1.1.0" resolved "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== -"@yarnpkg/parsers@^3.0.0-rc.18": - version "3.0.0-rc.42" - resolved "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.42.tgz#3814e90a81bb1f9c06cc83c6a009139c55efe94d" - integrity sha512-eW9Mbegmb5bJjwawJM9ghjUjUqciNMhC6L7XrQPF/clXS5bbP66MstsgCT5hy9VlfUh/CfBT+0Wucf531dMjHA== +"@yarnpkg/parsers@3.0.0-rc.46": + version "3.0.0-rc.46" + resolved "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz#03f8363111efc0ea670e53b0282cd3ef62de4e01" + integrity sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q== dependencies: js-yaml "^3.10.0" tslib "^2.4.0" @@ -553,6 +550,13 @@ abbrev@^1.0.0: resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + add-stream@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" @@ -566,12 +570,10 @@ agent-base@6, agent-base@^6.0.2: debug "4" agentkeepalive@^4.2.1: - version "4.3.0" - resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz#bb999ff07412653c1803b3ced35e50729830a255" - integrity sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg== + version "4.5.0" + resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" + integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== dependencies: - debug "^4.1.0" - depd "^2.0.0" humanize-ms "^1.2.1" aggregate-error@^3.0.0: @@ -599,7 +601,7 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.21.3" -ansi-regex@^2.0.0, ansi-regex@^2.1.1: +ansi-regex@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== @@ -651,11 +653,6 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - "aproba@^1.0.3 || ^2.0.0": version "2.0.0" resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" @@ -669,13 +666,13 @@ are-we-there-yet@^3.0.0: delegates "^1.0.0" readable-stream "^3.6.0" -are-we-there-yet@~1.1.2: - version "1.1.7" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" - integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== +are-we-there-yet@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-4.0.1.tgz#05a6fc0e5f70771b673e82b0f915616e0ace8fd3" + integrity sha512-2zuA+jpOYBRgoBCfa+fB87Rk0oGJjDX6pxGzqH6f33NzUhG25Xur6R0u0Z9VVAq8Z5JvQpQI6j6rtonuivC8QA== dependencies: delegates "^1.0.0" - readable-stream "^2.0.6" + readable-stream "^4.1.0" argparse@^1.0.7: version "1.0.10" @@ -715,9 +712,9 @@ arrify@^2.0.1: integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== async@^3.2.3: - version "3.2.4" - resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + version "3.2.5" + resolved "https://registry.npmjs.org/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" + integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== asynckit@^0.4.0: version "0.4.0" @@ -725,9 +722,9 @@ asynckit@^0.4.0: integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== axios@^1.0.0: - version "1.3.6" - resolved "https://registry.npmjs.org/axios/-/axios-1.3.6.tgz#1ace9a9fb994314b5f6327960918406fa92c6646" - integrity sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg== + version "1.6.2" + resolved "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2" + integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== dependencies: follow-redirects "^1.15.0" form-data "^4.0.0" @@ -833,6 +830,14 @@ buffer@^5.2.1, buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + builtins@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" @@ -875,20 +880,19 @@ cacache@^16.1.0: unique-filename "^2.0.0" cacache@^17.0.0: - version "17.0.5" - resolved "https://registry.npmjs.org/cacache/-/cacache-17.0.5.tgz#6dbec26c11f1f6a2b558bc11ed3316577c339ebc" - integrity sha512-Y/PRQevNSsjAPWykl9aeGz8Pr+OI6BYM9fYDNMvOkuUiG9IhG4LEmaYrZZZvioMUEQ+cBCxT0v8wrnCURccyKA== + version "17.1.4" + resolved "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" + integrity sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A== dependencies: "@npmcli/fs" "^3.1.0" fs-minipass "^3.0.0" - glob "^9.3.1" + glob "^10.2.2" lru-cache "^7.7.1" - minipass "^4.0.0" + minipass "^7.0.3" minipass-collect "^1.0.2" minipass-flush "^1.0.5" minipass-pipeline "^1.2.4" p-map "^4.0.0" - promise-inflight "^1.0.1" ssri "^10.0.0" tar "^6.1.11" unique-filename "^3.0.0" @@ -925,7 +929,7 @@ chalk@4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^2.0.0: +chalk@^2.4.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -977,9 +981,9 @@ chownr@^2.0.0: integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== ci-info@^3.2.0, ci-info@^3.6.1: - version "3.8.0" - resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" - integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + version "3.9.0" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== clean-stack@^2.0.0: version "2.2.0" @@ -1011,9 +1015,9 @@ cli-spinners@2.6.1: integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== cli-spinners@^2.5.0: - version "2.8.0" - resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.8.0.tgz#e97a3e2bd00e6d85aa0c13d7f9e3ce236f7787fc" - integrity sha512-/eG5sJcvEIwxcdYM86k5tPwn0MUzkX5YY3eImTGpJOZgVe4SdTMY14vQpcxgBzJ0wXwAYrS8E+c3uHeK4JNyzQ== + version "2.9.2" + resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== cli-width@^3.0.0: version "3.0.0" @@ -1057,11 +1061,6 @@ cmd-shim@6.0.1: resolved "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.1.tgz#a65878080548e1dca760b3aea1e21ed05194da9d" integrity sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q== -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== - color-convert@^1.9.0: version "1.9.3" resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -1134,7 +1133,7 @@ concat-stream@^2.0.0: readable-stream "^3.0.2" typedarray "^0.0.6" -console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0: +console-control-strings@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== @@ -1169,16 +1168,16 @@ conventional-changelog-preset-loader@^3.0.0: integrity sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA== conventional-changelog-writer@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.0.tgz#8c8dea0441c6e648c9b25bb784e750d02f8002d5" - integrity sha512-8PyWTnn7zBIt9l4hj4UusFs1TyG+9Ulu1zlOAc72L7Sdv9Hsc8E86ot7htY3HXCVhXHB/NO0pVGvZpwsyJvFfw== + version "6.0.1" + resolved "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz#d8d3bb5e1f6230caed969dcc762b1c368a8f7b01" + integrity sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ== dependencies: conventional-commits-filter "^3.0.0" dateformat "^3.0.3" handlebars "^4.7.7" json-stringify-safe "^5.0.1" meow "^8.1.2" - semver "^6.3.0" + semver "^7.0.0" split "^1.0.1" conventional-commits-filter@^3.0.0: @@ -1218,13 +1217,13 @@ core-util-is@~1.0.0: integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== cosmiconfig@^8.2.0: - version "8.2.0" - resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz#f7d17c56a590856cd1e7cee98734dca272b0d8fd" - integrity sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ== + version "8.3.6" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== dependencies: - import-fresh "^3.2.1" + import-fresh "^3.3.0" js-yaml "^4.1.0" - parse-json "^5.0.0" + parse-json "^5.2.0" path-type "^4.0.0" cross-spawn@^7.0.0, cross-spawn@^7.0.3: @@ -1254,7 +1253,7 @@ dateformat@^3.0.3: resolved "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.3.3, debug@~4.3.1: +debug@4, debug@4.3.4, debug@^4.3.3, debug@^4.3.4, debug@~4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -1359,11 +1358,6 @@ delegates@^1.0.0: resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== -depd@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - deprecation@^2.0.0: version "2.3.1" resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" @@ -1374,10 +1368,10 @@ detect-indent@^5.0.0: resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== -diff-sequences@^29.4.3: - version "29.4.3" - resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" - integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== diff@5.0.0: version "5.0.0" @@ -1398,10 +1392,15 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" -dotenv@~10.0.0: +dotenv-expand@~10.0.0: version "10.0.0" - resolved "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" - integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== + resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" + integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== + +dotenv@~16.3.1: + version "16.3.1" + resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== duplexer@^0.1.1: version "0.1.2" @@ -1537,11 +1536,21 @@ event-emitter@^0.3.5: d "1" es5-ext "~0.10.14" +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== +events@^3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + execa@5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" @@ -1572,6 +1581,11 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +exponential-backoff@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" + integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + ext@^1.1.2: version "1.7.0" resolved "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" @@ -1588,21 +1602,10 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" -fast-glob@3.2.7: - version "3.2.7" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" - integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + version "3.3.2" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -1646,7 +1649,7 @@ file-type@^6.1.0: resolved "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== -filelist@^1.0.1: +filelist@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== @@ -1688,15 +1691,10 @@ flat@^5.0.2: resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== -follow-redirects@1.14.9: - version "1.14.9" - resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" - integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== - -follow-redirects@^1.15.0: - version "1.15.2" - resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== +follow-redirects@1.15.3, follow-redirects@^1.15.0: + version "1.15.3" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" + integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== foreground-child@^3.1.0: version "3.1.1" @@ -1721,9 +1719,9 @@ fs-constants@^1.0.0: integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== fs-extra@^11.1.0, fs-extra@^11.1.1: - version "11.1.1" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" - integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== + version "11.2.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -1737,11 +1735,11 @@ fs-minipass@^2.0.0, fs-minipass@^2.1.0: minipass "^3.0.0" fs-minipass@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.1.tgz#853809af15b6d03e27638d1ab6432e6b378b085d" - integrity sha512-MhaJDcFRTuLidHrIttu0RDGyyXs/IYHVmlcxfLAEFIWjc1vdLAkdwT7Ace2u7DbitWC0toKMl5eJZRYNVreIMw== + version "3.0.3" + resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" + integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== dependencies: - minipass "^4.0.0" + minipass "^7.0.3" fs.realpath@^1.0.0: version "1.0.0" @@ -1749,14 +1747,14 @@ fs.realpath@^1.0.0: integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + version "2.3.3" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== gauge@^4.0.3: version "4.0.4" @@ -1772,19 +1770,19 @@ gauge@^4.0.3: strip-ansi "^6.0.1" wide-align "^1.1.5" -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg== +gauge@^5.0.0: + version "5.0.1" + resolved "https://registry.npmjs.org/gauge/-/gauge-5.0.1.tgz#1efc801b8ff076b86ef3e9a7a280a975df572112" + integrity sha512-CmykPMJGuNan/3S4kZOpvvPYSNqSHANiWnh9XcMU2pSjtBfF0XzZ2p1bFAxTbnFxyBuPxQYHhzwaoOmUdqzvxQ== dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^4.0.1" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" get-caller-file@^2.0.5: version "2.0.5" @@ -1842,12 +1840,12 @@ git-remote-origin-url@^2.0.0: pify "^2.3.0" git-semver-tags@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.0.tgz#775ff55effae0b50b755448408de6cd56ce293e2" - integrity sha512-fZ+tmZ1O5aXW/T5nLzZLbxWAHdQTLLXalOECMNAmhoEQSfqZjtaeMjpsXH4C5qVhrICTkVQeQFujB1lKzIHljA== + version "5.0.1" + resolved "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.1.tgz#db748aa0e43d313bf38dcd68624d8443234e1c15" + integrity sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA== dependencies: meow "^8.1.2" - semver "^6.3.0" + semver "^7.0.0" git-up@^7.0.0: version "7.0.0" @@ -1903,15 +1901,15 @@ glob@7.2.0: path-is-absolute "^1.0.0" glob@^10.2.2: - version "10.3.1" - resolved "https://registry.npmjs.org/glob/-/glob-10.3.1.tgz#9789cb1b994515bedb811a6deca735b5c37d2bf4" - integrity sha512-9BKYcEeIs7QwlCYs+Y3GBvqAMISufUS0i2ELd11zpZjxI5V9iyRj0HgzB5/cLf2NY4vcYBTYzJ7GIui7j/4DOw== + version "10.3.10" + resolved "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== dependencies: foreground-child "^3.1.0" - jackspeak "^2.0.3" + jackspeak "^2.3.5" minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2" - path-scurry "^1.10.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" glob@^7.1.3, glob@^7.1.4, glob@^7.2.3: version "7.2.3" @@ -1936,7 +1934,7 @@ glob@^8.0.1: minimatch "^5.0.1" once "^1.3.0" -glob@^9.2.0, glob@^9.3.0, glob@^9.3.1: +glob@^9.2.0: version "9.3.5" resolved "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz#ca2ed8ca452781a3009685607fdf025a899dfe21" integrity sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q== @@ -1964,12 +1962,12 @@ graceful-fs@4.2.11, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.1 integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== handlebars@^4.7.7: - version "4.7.7" - resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + version "4.7.8" + resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== dependencies: minimist "^1.2.5" - neo-async "^2.6.0" + neo-async "^2.6.2" source-map "^0.6.1" wordwrap "^1.0.0" optionalDependencies: @@ -1995,17 +1993,17 @@ has-flag@^4.0.0: resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-unicode@2.0.1, has-unicode@^2.0.0, has-unicode@^2.0.1: +has-unicode@2.0.1, has-unicode@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== dependencies: - function-bind "^1.1.1" + function-bind "^1.1.2" he@1.2.0: version "1.2.0" @@ -2086,7 +2084,7 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -ieee754@^1.1.13: +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -2099,18 +2097,18 @@ ignore-walk@^5.0.1: minimatch "^5.0.1" ignore-walk@^6.0.0: - version "6.0.2" - resolved "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.2.tgz#c48f48397cf8ef6174fcc28aa5f8c1de6203d389" - integrity sha512-ezmQ1Dg2b3jVZh2Dh+ar6Eu2MqNSTkyb32HU2MAQQQX9tKM3q/UQ/9lf03lQ5hW+fOeoMnwxwkleZ0xcNp0/qg== + version "6.0.4" + resolved "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.4.tgz#89950be94b4f522225eb63a13c56badb639190e9" + integrity sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw== dependencies: - minimatch "^7.4.2" + minimatch "^9.0.0" ignore@^5.0.4, ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + version "5.3.0" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== -import-fresh@^3.2.1: +import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -2173,9 +2171,9 @@ init-package-json@5.0.0: validate-npm-package-name "^5.0.0" inquirer@^8.2.4: - version "8.2.5" - resolved "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz#d8654a7542c35a9b9e069d27e2df4858784d54f8" - integrity sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ== + version "8.2.6" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz#733b74888195d8d400a67ac332011b5fae5ea562" + integrity sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg== dependencies: ansi-escapes "^4.2.1" chalk "^4.1.1" @@ -2191,7 +2189,7 @@ inquirer@^8.2.4: string-width "^4.1.0" strip-ansi "^6.0.0" through "^2.3.6" - wrap-ansi "^7.0.0" + wrap-ansi "^6.0.1" ip@^2.0.0: version "2.0.0" @@ -2217,12 +2215,12 @@ is-ci@3.0.1: dependencies: ci-info "^3.2.0" -is-core-module@^2.11.0, is-core-module@^2.5.0, is-core-module@^2.8.1: - version "2.12.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4" - integrity sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ== +is-core-module@^2.13.0, is-core-module@^2.5.0, is-core-module@^2.8.1: + version "2.13.1" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== dependencies: - has "^1.0.3" + hasown "^2.0.0" is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" @@ -2234,13 +2232,6 @@ is-extglob@^2.1.1: resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== - dependencies: - number-is-nan "^1.0.0" - is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -2361,54 +2352,54 @@ isobject@^3.0.1: resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== +istanbul-lib-coverage@^3.2.2: + version "3.2.2" + resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== -jackspeak@^2.0.3: - version "2.2.1" - resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz#655e8cf025d872c9c03d3eb63e8f0c024fef16a6" - integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== dependencies: "@isaacs/cliui" "^8.0.2" optionalDependencies: "@pkgjs/parseargs" "^0.11.0" jake@^10.8.5: - version "10.8.5" - resolved "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" - integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== + version "10.8.7" + resolved "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" + integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== dependencies: async "^3.2.3" chalk "^4.0.2" - filelist "^1.0.1" - minimatch "^3.0.4" + filelist "^1.0.4" + minimatch "^3.1.2" -"jest-diff@>=29.4.3 < 30": - version "29.5.0" - resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz#e0d83a58eb5451dcc1fa61b1c3ee4e8f5a290d63" - integrity sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw== +"jest-diff@>=29.4.3 < 30", jest-diff@^29.4.1: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== dependencies: chalk "^4.0.0" - diff-sequences "^29.4.3" - jest-get-type "^29.4.3" - pretty-format "^29.5.0" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" -jest-get-type@^29.4.3: - version "29.4.3" - resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" - integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@3.14.0: - version "3.14.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== +js-yaml@3.14.1, js-yaml@^3.10.0: + version "3.14.1" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -2420,14 +2411,6 @@ js-yaml@4.1.0, js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -js-yaml@^3.10.0: - version "3.14.1" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -2439,9 +2422,9 @@ json-parse-even-better-errors@^2.3.0: integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-parse-even-better-errors@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz#2cb2ee33069a78870a0c7e3da560026b89669cf7" - integrity sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA== + version "3.0.1" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz#02bb29fb5da90b5444581749c22cedd3597c6cb0" + integrity sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg== json-stringify-safe@^5.0.1: version "5.0.1" @@ -2590,9 +2573,9 @@ lines-and-columns@^1.1.6: integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== lines-and-columns@~2.0.3: - version "2.0.3" - resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz#b2f0badedb556b747020ab8ea7f0373e22efac1b" - integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w== + version "2.0.4" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz#d00318855905d2660d8c0822e3f5a4715855fc42" + integrity sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A== load-json-file@6.2.0: version "6.2.0" @@ -2666,15 +2649,10 @@ lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== -lru-cache@^9.0.0: - version "9.1.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.0.tgz#19efafa9d08d1c08eb8efd78876075f0b8b1b07b" - integrity sha512-qFXQEwchrZcMVen2uIDceR8Tii6kCJak5rzDStfEM0qA3YLMswaxIEZO0DhIbJ3aqaJiDjt+3crlplOb0tDtKQ== - "lru-cache@^9.1.1 || ^10.0.0": - version "10.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" - integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== + version "10.1.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" + integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== lru-queue@^0.1.0: version "0.1.0" @@ -2727,10 +2705,10 @@ make-fetch-happen@^10.0.3: socks-proxy-agent "^7.0.0" ssri "^9.0.0" -make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1: - version "11.1.0" - resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.0.tgz#f26b05e89317e960b75fd5e080e40d40f8d7b2a5" - integrity sha512-7ChuOzCb1LzdQZrTy0ky6RsCoMYeM+Fh4cY0+4zsJVhNcH5Q3OJojLY1mGkD0xAhWB29lskECVb6ZopofwjldA== +make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1, make-fetch-happen@^11.1.1: + version "11.1.1" + resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" + integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== dependencies: agentkeepalive "^4.2.1" cacache "^17.0.0" @@ -2739,7 +2717,7 @@ make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1: https-proxy-agent "^5.0.0" is-lambda "^1.0.1" lru-cache "^7.7.1" - minipass "^4.0.0" + minipass "^5.0.0" minipass-fetch "^3.0.0" minipass-flush "^1.0.5" minipass-pipeline "^1.2.4" @@ -2843,14 +2821,14 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@9.0.2, minimatch@^9.0.1: - version "9.0.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz#397e387fff22f6795844d00badc903a3d5de7057" - integrity sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg== +minimatch@9.0.3, minimatch@^9.0.0, minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== dependencies: brace-expansion "^2.0.1" -minimatch@^3.0.4, minimatch@^3.1.1: +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -2864,13 +2842,6 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^7.4.2, minimatch@^7.4.6: - version "7.4.6" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz#845d6f254d8f4a5e4fd6baf44d5f10c8448365fb" - integrity sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw== - dependencies: - brace-expansion "^2.0.1" - minimatch@^8.0.2: version "8.0.4" resolved "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz#847c1b25c014d4e9a7f68aaf63dedd668a626229" @@ -2911,11 +2882,11 @@ minipass-fetch@^2.0.3: encoding "^0.1.13" minipass-fetch@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.2.tgz#2f7275ae13f2fb0f2a469cee4f78250c25c80ab3" - integrity sha512-/ZpF1CQaWYqjbhfFgKNt3azxztEpc/JUPuMkqOgrnMQqcU8CbE409AUdJYTIWryl3PP5CBaTJZT71N49MXP/YA== + version "3.0.4" + resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" + integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== dependencies: - minipass "^4.0.0" + minipass "^7.0.3" minipass-sized "^1.0.3" minizlib "^2.1.2" optionalDependencies: @@ -2957,7 +2928,7 @@ minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: dependencies: yallist "^4.0.0" -minipass@^4.0.0, minipass@^4.2.4: +minipass@^4.2.4: version "4.2.8" resolved "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz#f0010f64393ecfc1d1ccb5f582bcaf45f48e1a3a" integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== @@ -2967,10 +2938,10 @@ minipass@^5.0.0: resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== -"minipass@^5.0.0 || ^6.0.2": - version "6.0.2" - resolved "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz#542844b6c4ce95b202c0995b0a471f1229de4c81" - integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3: + version "7.0.4" + resolved "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" @@ -3058,7 +3029,7 @@ negotiator@^0.6.3: resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -neo-async@^2.6.0: +neo-async@^2.6.2: version "2.6.2" resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== @@ -3080,24 +3051,32 @@ node-fetch@2.6.7: dependencies: whatwg-url "^5.0.0" -node-fetch@^2.6.7, node-fetch@~2.6.1: - version "2.6.9" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" - integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== +node-fetch@^2.6.7: + version "2.7.0" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +node-fetch@~2.6.1: + version "2.6.13" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz#a20acbbec73c2e09f9007de5cda17104122e0010" + integrity sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA== dependencies: whatwg-url "^5.0.0" node-gyp-build@^4.3.0: - version "4.6.0" - resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" - integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== + version "4.7.1" + resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.1.tgz#cd7d2eb48e594874053150a9418ac85af83ca8f7" + integrity sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg== node-gyp@^9.0.0: - version "9.3.1" - resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-9.3.1.tgz#1e19f5f290afcc9c46973d68700cbd21a96192e4" - integrity sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg== + version "9.4.1" + resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" + integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== dependencies: env-paths "^2.2.0" + exponential-backoff "^3.1.1" glob "^7.1.4" graceful-fs "^4.2.6" make-fetch-happen "^10.0.3" @@ -3108,6 +3087,11 @@ node-gyp@^9.0.0: tar "^6.1.2" which "^2.0.2" +node-machine-id@1.1.12: + version "1.1.12" + resolved "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267" + integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ== + nomnom-patched@~1.8.2: version "1.8.2" resolved "https://registry.npmjs.org/nomnom-patched/-/nomnom-patched-1.8.2.tgz#a0dbf2412844fc453c485c7b3341e68cd89379e1" @@ -3173,9 +3157,9 @@ npm-bundled@^3.0.0: npm-normalize-package-bin "^3.0.0" npm-install-checks@^6.0.0: - version "6.1.1" - resolved "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.1.1.tgz#b459b621634d06546664207fde16810815808db1" - integrity sha512-dH3GmQL4vsPtld59cOn8uY0iOqRmqKvV+DLGwNXV/Q7MDgD2QfOADWd/mFXcIE5LVhYYGjA3baz6W9JneqnuCw== + version "6.3.0" + resolved "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz#046552d8920e801fa9f919cad569545d60e826fe" + integrity sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw== dependencies: semver "^7.1.1" @@ -3185,9 +3169,9 @@ npm-normalize-package-bin@^1.0.1: integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== npm-normalize-package-bin@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.0.tgz#6097436adb4ef09e2628b59a7882576fe53ce485" - integrity sha512-g+DPQSkusnk7HYXr75NtzkIP4+N81i3RPsGFidF3DzHd9MT9wWngmqoeg/fnHFz5MNdtG4w03s+QnhewSLTT2Q== + version "3.0.1" + resolved "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz#25447e32a9a7de1f51362c61a559233b89947832" + integrity sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ== npm-package-arg@8.1.1: version "8.1.1" @@ -3226,29 +3210,16 @@ npm-packlist@^7.0.0: ignore-walk "^6.0.0" npm-pick-manifest@^8.0.0: - version "8.0.1" - resolved "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz#c6acd97d1ad4c5dbb80eac7b386b03ffeb289e5f" - integrity sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA== + version "8.0.2" + resolved "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz#2159778d9c7360420c925c1a2287b5a884c713aa" + integrity sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg== dependencies: npm-install-checks "^6.0.0" npm-normalize-package-bin "^3.0.0" npm-package-arg "^10.0.0" semver "^7.3.5" -npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3: - version "14.0.4" - resolved "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.4.tgz#43dfa55ce7c0d0c545d625c7a916bab5b95f7038" - integrity sha512-pMS2DRkwg+M44ct65zrN/Cr9IHK1+n6weuefAo6Er4lc+/8YBCU0Czq04H3ZiSigluh7pb2rMM5JpgcytctB+Q== - dependencies: - make-fetch-happen "^11.0.0" - minipass "^4.0.0" - minipass-fetch "^3.0.0" - minipass-json-stream "^1.0.1" - minizlib "^2.1.2" - npm-package-arg "^10.0.0" - proc-log "^3.0.0" - -npm-registry-fetch@^14.0.5: +npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3, npm-registry-fetch@^14.0.5: version "14.0.5" resolved "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz#fe7169957ba4986a4853a650278ee02e568d115d" integrity sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA== @@ -3268,15 +3239,15 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -npmlog@4.1.2: - version "4.1.2" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== +npmlog@7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/npmlog/-/npmlog-7.0.1.tgz#7372151a01ccb095c47d8bf1d0771a4ff1f53ac8" + integrity sha512-uJ0YFk/mCQpLBt+bxN88AKd+gyqZvZDbtiNxk6Waqcj2aPRyfVx8ITawkyQynxUagInjdYT1+qj4NfA5KJJUxg== dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" + are-we-there-yet "^4.0.0" + console-control-strings "^1.1.0" + gauge "^5.0.0" + set-blocking "^2.0.0" npmlog@^6.0.0, npmlog@^6.0.2: version "6.0.2" @@ -3288,38 +3259,35 @@ npmlog@^6.0.0, npmlog@^6.0.2: gauge "^4.0.3" set-blocking "^2.0.0" -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== - -nx@16.4.0, "nx@>=16.1.3 < 17": - version "16.4.0" - resolved "https://registry.npmjs.org/nx/-/nx-16.4.0.tgz#cd136a3ebadf77138dce421b0c0e0944527fe9b3" - integrity sha512-HhJnOAm2wlaIVMmxK1HcdcKfX5DlnQc1RAHFf+QostvQQ/SmUg9f7LoStxpNm01JhQTehb01tH9zAsXKcKzO4A== +nx@16.10.0, "nx@>=16.1.3 < 17": + version "16.10.0" + resolved "https://registry.npmjs.org/nx/-/nx-16.10.0.tgz#b070461f7de0a3d7988bd78558ea84cda3543ace" + integrity sha512-gZl4iCC0Hx0Qe1VWmO4Bkeul2nttuXdPpfnlcDKSACGu3ZIo+uySqwOF8yBAxSTIf8xe2JRhgzJN1aFkuezEBg== dependencies: - "@nrwl/tao" "16.4.0" + "@nrwl/tao" "16.10.0" "@parcel/watcher" "2.0.4" "@yarnpkg/lockfile" "^1.1.0" - "@yarnpkg/parsers" "^3.0.0-rc.18" + "@yarnpkg/parsers" "3.0.0-rc.46" "@zkochan/js-yaml" "0.0.6" axios "^1.0.0" chalk "^4.1.0" cli-cursor "3.1.0" cli-spinners "2.6.1" - cliui "^7.0.2" - dotenv "~10.0.0" + cliui "^8.0.1" + dotenv "~16.3.1" + dotenv-expand "~10.0.0" enquirer "~2.3.6" - fast-glob "3.2.7" figures "3.2.0" flat "^5.0.2" fs-extra "^11.1.0" glob "7.1.4" ignore "^5.0.4" + jest-diff "^29.4.1" js-yaml "4.1.0" jsonc-parser "3.2.0" lines-and-columns "~2.0.3" minimatch "3.0.5" + node-machine-id "1.1.12" npm-run-path "^4.0.1" open "^8.4.0" semver "7.5.3" @@ -3333,18 +3301,18 @@ nx@16.4.0, "nx@>=16.1.3 < 17": yargs "^17.6.2" yargs-parser "21.1.1" optionalDependencies: - "@nx/nx-darwin-arm64" "16.4.0" - "@nx/nx-darwin-x64" "16.4.0" - "@nx/nx-freebsd-x64" "16.4.0" - "@nx/nx-linux-arm-gnueabihf" "16.4.0" - "@nx/nx-linux-arm64-gnu" "16.4.0" - "@nx/nx-linux-arm64-musl" "16.4.0" - "@nx/nx-linux-x64-gnu" "16.4.0" - "@nx/nx-linux-x64-musl" "16.4.0" - "@nx/nx-win32-arm64-msvc" "16.4.0" - "@nx/nx-win32-x64-msvc" "16.4.0" - -object-assign@^4.0.1, object-assign@^4.1.0: + "@nx/nx-darwin-arm64" "16.10.0" + "@nx/nx-darwin-x64" "16.10.0" + "@nx/nx-freebsd-x64" "16.10.0" + "@nx/nx-linux-arm-gnueabihf" "16.10.0" + "@nx/nx-linux-arm64-gnu" "16.10.0" + "@nx/nx-linux-arm64-musl" "16.10.0" + "@nx/nx-linux-x64-gnu" "16.10.0" + "@nx/nx-linux-x64-musl" "16.10.0" + "@nx/nx-win32-arm64-msvc" "16.10.0" + "@nx/nx-win32-x64-msvc" "16.10.0" + +object-assign@^4.0.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -3532,7 +3500,7 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -3581,21 +3549,13 @@ path-parse@^1.0.7: resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.10.0: - version "1.10.0" - resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.0.tgz#0ffbd4c1f7de9600f98a1405507d9f9acb438ab3" - integrity sha512-tZFEaRQbMLjwrsmidsGJ6wDMv0iazJWk6SfIKnY4Xru8auXgmJkOBa5DUbYFcFD2Rzk2+KDlIiF0GVXNCbgC7g== +path-scurry@^1.10.1, path-scurry@^1.6.1: + version "1.10.1" + resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== dependencies: lru-cache "^9.1.1 || ^10.0.0" - minipass "^5.0.0 || ^6.0.2" - -path-scurry@^1.6.1: - version "1.7.0" - resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.7.0.tgz#99c741a2cfbce782294a39994d63748b5a24f6db" - integrity sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg== - dependencies: - lru-cache "^9.0.0" - minipass "^5.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-type@^3.0.0: version "3.0.0" @@ -3658,12 +3618,12 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -pretty-format@^29.5.0: - version "29.5.0" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz#283134e74f70e2e3e7229336de0e4fce94ccde5a" - integrity sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw== +pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== dependencies: - "@jest/schemas" "^29.4.3" + "@jest/schemas" "^29.6.3" ansi-styles "^5.0.0" react-is "^18.0.0" @@ -3677,6 +3637,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process@^0.11.10: + version "0.11.10" + resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" @@ -3742,7 +3707,7 @@ read-package-json-fast@^3.0.0: json-parse-even-better-errors "^3.0.0" npm-normalize-package-bin "^3.0.0" -read-package-json@6.0.4: +read-package-json@6.0.4, read-package-json@^6.0.0: version "6.0.4" resolved "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz#90318824ec456c287437ea79595f4c2854708836" integrity sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw== @@ -3752,16 +3717,6 @@ read-package-json@6.0.4: normalize-package-data "^5.0.0" npm-normalize-package-bin "^3.0.0" -read-package-json@^6.0.0: - version "6.0.1" - resolved "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.1.tgz#566cb06bc05dbddefba4607e9096d5a9efbcd836" - integrity sha512-AaHqXxfAVa+fNL07x8iAghfKOds/XXsu7zoouIVsbm7PEbQ3nMWXlvjcbrNLjElnUHWQtAo4QEa0RXuvD4XlpA== - dependencies: - glob "^9.3.0" - json-parse-even-better-errors "^3.0.0" - normalize-package-data "^5.0.0" - npm-normalize-package-bin "^3.0.0" - read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" @@ -3805,7 +3760,7 @@ read@^2.0.0: dependencies: mute-stream "~1.0.0" -readable-stream@^2.0.6, readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@~2.3.6: +readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@~2.3.6: version "2.3.8" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== @@ -3827,6 +3782,17 @@ readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.1.1, readable string_decoder "^1.1.1" util-deprecate "^1.0.1" +readable-stream@^4.1.0: + version "4.4.2" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz#e6aced27ad3b9d726d8308515b9a1b98dc1b9d13" + integrity sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA== + dependencies: + abort-controller "^3.0.0" + buffer "^6.0.3" + events "^3.3.0" + process "^0.11.10" + string_decoder "^1.3.0" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -3865,11 +3831,11 @@ resolve-from@^4.0.0: integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve@^1.10.0: - version "1.22.2" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" - integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== + version "1.22.8" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: - is-core-module "^2.11.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -3918,9 +3884,9 @@ run-parallel@^1.1.9: queue-microtask "^1.2.2" rxjs@^7.5.5: - version "7.8.0" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" - integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== + version "7.8.1" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== dependencies: tslib "^2.1.0" @@ -3947,9 +3913,9 @@ seek-bzip@^1.0.5: commander "^2.8.1" "semver@2 || 3 || 4 || 5", semver@^5.6.0: - version "5.7.1" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + version "5.7.2" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== semver@7.5.3: version "7.5.3" @@ -3958,18 +3924,18 @@ semver@7.5.3: dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^7.0.0, semver@^7.1.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: - version "7.5.2" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz#5b851e66d1be07c1cdaf37dfc856f543325a2beb" - integrity sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ== +semver@7.5.4, semver@^7.0.0, semver@^7.1.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: + version "7.5.4" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" +semver@^6.0.0: + version "6.3.1" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -3977,7 +3943,7 @@ serialize-javascript@6.0.0: dependencies: randombytes "^2.1.0" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== @@ -4001,25 +3967,26 @@ shebang-regex@^3.0.0: resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -signal-exit@3.0.7, signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: +signal-exit@3.0.7, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== signal-exit@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967" - integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== + version "4.1.0" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== sigstore@^1.3.0, sigstore@^1.4.0: - version "1.6.0" - resolved "https://registry.npmjs.org/sigstore/-/sigstore-1.6.0.tgz#887a4007c6ee83f3ef3fd844be1a0840e849c301" - integrity sha512-QODKff/qW/TXOZI6V/Clqu74xnInAS6it05mufj4/fSewexLtfEntgLZZcBtUK44CDQyUE5TUXYy1ARYzlfG9g== + version "1.9.0" + resolved "https://registry.npmjs.org/sigstore/-/sigstore-1.9.0.tgz#1e7ad8933aa99b75c6898ddd0eeebc3eb0d59875" + integrity sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A== dependencies: - "@sigstore/protobuf-specs" "^0.1.0" - "@sigstore/tuf" "^1.0.0" + "@sigstore/bundle" "^1.1.0" + "@sigstore/protobuf-specs" "^0.2.0" + "@sigstore/sign" "^1.0.0" + "@sigstore/tuf" "^1.0.3" make-fetch-happen "^11.0.1" - tuf-js "^1.1.3" slash@3.0.0, slash@^3.0.0: version "3.0.0" @@ -4082,9 +4049,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.13" - resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" - integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== + version "3.0.16" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" + integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== split2@^3.2.2: version "3.2.2" @@ -4106,11 +4073,11 @@ sprintf-js@~1.0.2: integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== ssri@^10.0.0, ssri@^10.0.1: - version "10.0.3" - resolved "https://registry.npmjs.org/ssri/-/ssri-10.0.3.tgz#7f83da39058ca1d599d174e9eee4237659710bf4" - integrity sha512-lJtX/BFPI/VEtxZmLfeh7pzisIs6micwZ3eruD3+ds9aPsXKlYpwDS2Q7omD6WC42WO9+bnUSzlMmfv8uK8meg== + version "10.0.5" + resolved "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c" + integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== dependencies: - minipass "^4.0.0" + minipass "^7.0.3" ssri@^9.0.0, ssri@^9.0.1: version "9.0.1" @@ -4128,15 +4095,6 @@ ssri@^9.0.0, ssri@^9.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" @@ -4146,7 +4104,7 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string_decoder@^1.1.1: +string_decoder@^1.1.1, string_decoder@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -4167,13 +4125,6 @@ string_decoder@~1.1.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== - dependencies: - ansi-regex "^2.0.0" - strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -4292,13 +4243,13 @@ tar@6.1.11: yallist "^4.0.0" tar@^6.1.11, tar@^6.1.2: - version "6.1.13" - resolved "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b" - integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw== + version "6.2.0" + resolved "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" + integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" - minipass "^4.0.0" + minipass "^5.0.0" minizlib "^2.1.1" mkdirp "^1.0.3" yallist "^4.0.0" @@ -4380,17 +4331,18 @@ tsconfig-paths@^4.1.2: strip-bom "^3.0.0" tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0: - version "2.5.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== + version "2.6.2" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== -tuf-js@^1.1.3: - version "1.1.4" - resolved "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.4.tgz#e85a936b16859c7fae23e5f040bc0f7b559b3192" - integrity sha512-Lw2JRM3HTYhEtQJM2Th3aNCPbnXirtWMl065BawwmM2pX6XStH/ZO9e8T2hh0zk/HUa+1i6j+Lv6eDitKTau6A== +tuf-js@^1.1.7: + version "1.1.7" + resolved "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.7.tgz#21b7ae92a9373015be77dfe0cb282a80ec3bbe43" + integrity sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg== dependencies: - "@tufjs/models" "1.0.3" - make-fetch-happen "^11.0.1" + "@tufjs/models" "1.0.4" + debug "^4.3.4" + make-fetch-happen "^11.1.1" type-fest@^0.18.0: version "0.18.1" @@ -4433,9 +4385,9 @@ typedarray@^0.0.6: integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== "typescript@>=3 < 6": - version "5.1.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.5.tgz#a3ae755082488b6046fe64345d293ef26af08671" - integrity sha512-FOH+WN/DQjUvN6WgW+c4Ml3yi0PH+a/8q+kNIfRehv1wLhWONedw85iu+vQ39Wp49IzTJEsZ2lyLXpBF7mkF1g== + version "5.3.3" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== uglify-js@^3.1.4: version "3.17.4" @@ -4455,6 +4407,11 @@ underscore@^1.13.1: resolved "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441" integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + unique-filename@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" @@ -4484,14 +4441,14 @@ unique-slug@^4.0.0: imurmurhash "^0.1.4" universal-user-agent@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" - integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== + version "6.0.1" + resolved "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz#15f20f55da3c930c57bddbf1734c6654d5fd35aa" + integrity sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ== universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + version "2.0.1" + resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== upath@2.0.1: version "2.0.1" @@ -4504,9 +4461,9 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== uuid@^9.0.0: - version "9.0.0" - resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" - integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== + version "9.0.1" + resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== v8-compile-cache@2.3.0: version "2.3.0" @@ -4563,13 +4520,13 @@ which@^2.0.1, which@^2.0.2: isexe "^2.0.0" which@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/which/-/which-3.0.0.tgz#a9efd016db59728758a390d23f1687b6e8f59f8e" - integrity sha512-nla//68K9NU6yRiwDY/Q8aU6siKlSs64aEC7+IV56QoAuyQT2ovsJcgGYGyqMOmI/CGN1BOR6mM5EN0FBO+zyQ== + version "3.0.1" + resolved "https://registry.npmjs.org/which/-/which-3.0.1.tgz#89f1cd0c23f629a8105ffe69b8172791c87b4be1" + integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== dependencies: isexe "^2.0.0" -wide-align@^1.1.0, wide-align@^1.1.5: +wide-align@^1.1.5: version "1.1.5" resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== @@ -4595,6 +4552,15 @@ workerpool@6.2.1: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^6.0.1: + version "6.2.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" @@ -4647,16 +4613,15 @@ write-pkg@4.0.0: type-fest "^0.4.1" write-json-file "^3.2.0" -xmlbuilder2@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-3.0.2.tgz#fc499688b35a916f269e7b459c2fa02bb5c0822a" - integrity sha512-h4MUawGY21CTdhV4xm3DG9dgsqyhDkZvVJBx88beqX8wJs3VgyGQgAn5VreHuae6unTQxh115aMK5InCVmOIKw== +xmlbuilder2@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-3.1.1.tgz#b977ef8a6fb27a1ea7ffa7d850d2c007ff343bc0" + integrity sha512-WCSfbfZnQDdLQLiMdGUQpMxxckeQ4oZNMNhLVkcekTu7xhD4tuUDyAPoY8CwXvBYE6LwBHd6QW2WZXlOWr1vCw== dependencies: "@oozcitak/dom" "1.15.10" "@oozcitak/infra" "1.0.8" "@oozcitak/util" "8.3.8" - "@types/node" "*" - js-yaml "3.14.0" + js-yaml "3.14.1" xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" @@ -4712,9 +4677,9 @@ yargs@16.2.0, yargs@^16.2.0: yargs-parser "^20.2.2" yargs@^17.6.2: - version "17.7.1" - resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" - integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== + version "17.7.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== dependencies: cliui "^8.0.1" escalade "^3.1.1" From 3403473cf1080af47f57d027d1033a986405049f Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Wed, 20 Dec 2023 07:40:27 +0100 Subject: [PATCH 08/26] GH-2582: As a smith I want to migrate some Xtend files to Java (part 7) (#2583) * migrate some transpiler transformations * migrate more * migrate some * migrate files * migrate files * migration of package es.transform complete * fix migration issues * another migration fix * migrate file * migrate remaining files in bundle transpiler.es * remove xtend nature from bundle transpiler.es * fix and migration * migrate bundle transpiler * remove xtend nature from bundle transpiler * remove xtend nature from semver.ide and semver.model * migrate files and remove xtend nature from regex.ide * migrate files and remove xtend nature from regex * migrate files and remove xtend nature from n4js.model * clean-up obsolete xtend natures * migrate files and remove xtend nature from n4js.json * migrate files and remove xtend nature from n4js.jsdoc2spec * migrate files and remove xtend nature from n4js.common.unicode * cleanup obsolete xtend bundle natures * migrate files and remove xtend nature from tests.helper * two fixes * adjust test expectations * another fix * test adjustments * fixes * fix * fix --- plugins/org.eclipse.n4js.cli/pom.xml | 4 - .../.classpath | 1 - .../build.properties | 3 +- .../org.eclipse.n4js.common.unicode/pom.xml | 6 - ...Module.xtend => UnicodeRuntimeModule.java} | 6 +- ...etup.xtend => UnicodeStandaloneSetup.java} | 10 +- .../generator/UnicodeGrammarGenerator.java | 179 ++++ .../generator/UnicodeGrammarGenerator.xtend | 174 ---- .../xtend-gen/.gitignore | 2 - plugins/org.eclipse.n4js.dts/pom.xml | 6 +- .../dataflow/AssignmentRelationFactory.java | 2 +- .../dataflow/DestructureUtilsForSymbols.java | 4 +- .../codeActions/util/ChangeProvider.java | 2 +- .../org.eclipse.n4js.jsdoc2spec/.classpath | 1 - .../build.properties | 3 +- plugins/org.eclipse.n4js.jsdoc2spec/pom.xml | 4 - .../{ADocFactory.xtend => ADocFactory.java} | 21 +- .../n4js/jsdoc2spec/adoc/ADocSerializer.java | 726 +++++++++++++ .../n4js/jsdoc2spec/adoc/ADocSerializer.xtend | 607 ----------- .../xtend-gen/.gitignore | 2 - plugins/org.eclipse.n4js.json.ide/.classpath | 1 - .../build.properties | 3 +- plugins/org.eclipse.n4js.json.ide/pom.xml | 4 - .../xtend-gen/.gitignore | 2 - plugins/org.eclipse.n4js.json.model/pom.xml | 5 - plugins/org.eclipse.n4js.json/.classpath | 5 - .../org.eclipse.n4js.json/build.properties | 3 +- plugins/org.eclipse.n4js.json/pom.xml | 5 - .../n4js/json/formatting2/JSONFormatter.java | 161 +++ .../n4js/json/formatting2/JSONFormatter.xtend | 114 --- .../JSONResourceDescriptionManager.java | 34 + .../JSONResourceDescriptionManager.xtend | 31 - .../JSONResourceDescriptionStrategy.java | 33 + .../JSONResourceDescriptionStrategy.xtend | 31 - .../xtend-gen/.gitignore | 2 - plugins/org.eclipse.n4js.model/.classpath | 1 - .../org.eclipse.n4js.model/build.properties | 3 +- plugins/org.eclipse.n4js.model/pom.xml | 5 - .../org/eclipse/n4js/n4JS/DestructNode.java | 641 ++++++++++++ .../org/eclipse/n4js/n4JS/DestructNode.xtend | 547 ---------- .../eclipse/n4js/n4JS/DestructureUtils.java | 2 +- .../xtend-gen/.gitignore | 2 - plugins/org.eclipse.n4js.regex.ide/.classpath | 1 - .../build.properties | 3 +- plugins/org.eclipse.n4js.regex.ide/pom.xml | 4 - ....xtend => RegularExpressionIdeModule.java} | 6 +- .../regex/ide/RegularExpressionIdeSetup.java | 31 + .../regex/ide/RegularExpressionIdeSetup.xtend | 27 - .../xtend-gen/.gitignore | 2 - plugins/org.eclipse.n4js.regex/.classpath | 1 - .../org.eclipse.n4js.regex/build.properties | 3 +- plugins/org.eclipse.n4js.regex/pom.xml | 5 - ...nd => RegularExpressionRuntimeModule.java} | 10 +- ... => RegularExpressionStandaloneSetup.java} | 10 +- .../generator/RegularExpressionGenerator.java | 33 + .../RegularExpressionGenerator.xtend | 32 - ...nd => RegularExpressionScopeProvider.java} | 9 +- ....xtend => RegularExpressionValidator.java} | 24 +- .../xtend-gen/.gitignore | 2 - .../org.eclipse.n4js.semver.ide/.classpath | 1 - .../build.properties | 3 +- plugins/org.eclipse.n4js.semver.ide/pom.xml | 4 - .../xtend-gen/.gitignore | 2 - plugins/org.eclipse.n4js.semver.model/pom.xml | 5 - .../org.eclipse.n4js.transpiler.es/.classpath | 1 - .../build.properties | 3 +- .../org.eclipse.n4js.transpiler.es/pom.xml | 5 - .../es/assistants/BlockAssistant.java | 50 + .../es/assistants/BlockAssistant.xtend | 46 - .../assistants/ClassConstructorAssistant.java | 580 +++++++++++ .../ClassConstructorAssistant.xtend | 517 ---------- .../es/assistants/ClassifierAssistant.java | 163 +++ .../es/assistants/ClassifierAssistant.xtend | 123 --- .../es/assistants/DelegationAssistant.java | 435 ++++++++ .../es/assistants/DelegationAssistant.xtend | 376 ------- .../es/assistants/DestructuringAssistant.java | 112 ++ .../assistants/DestructuringAssistant.xtend | 104 -- .../es/assistants/ReflectionAssistant.java | 110 ++ .../es/assistants/ReflectionAssistant.xtend | 93 -- .../ApiImplStubGenerationTransformation.java | 356 +++++++ .../ApiImplStubGenerationTransformation.xtend | 301 ------ .../ArrowFunction_Part1_Transformation.java | 67 ++ .../ArrowFunction_Part1_Transformation.xtend | 57 -- .../ArrowFunction_Part2_Transformation.java | 79 ++ .../ArrowFunction_Part2_Transformation.xtend | 67 -- .../es/transform/BlockTransformation.java | 101 ++ .../es/transform/BlockTransformation.xtend | 86 -- .../ClassDeclarationTransformation.java | 190 ++++ .../ClassDeclarationTransformation.xtend | 155 --- .../CommonJsImportsTransformation.java | 291 ++++++ .../CommonJsImportsTransformation.xtend | 254 ----- .../DependencyInjectionTransformation.java | 296 ++++++ .../DependencyInjectionTransformation.xtend | 268 ----- .../DestructuringTransformation.java | 478 +++++++++ .../DestructuringTransformation.xtend | 406 -------- .../transform/EnumAccessTransformation.java | 221 ++++ .../transform/EnumAccessTransformation.xtend | 178 ---- .../EnumDeclarationTransformation.java | 157 +++ .../EnumDeclarationTransformation.xtend | 130 --- .../transform/ExpressionTransformation.java | 314 ++++++ .../transform/ExpressionTransformation.xtend | 233 ----- .../InterfaceDeclarationTransformation.java | 443 ++++++++ .../InterfaceDeclarationTransformation.xtend | 368 ------- .../es/transform/JSXTransformation.java | 314 ++++++ .../es/transform/JSXTransformation.xtend | 268 ----- .../MemberPatchingTransformation.java | 194 ++++ .../MemberPatchingTransformation.xtend | 159 --- .../ModuleSpecifierTransformation.java | 243 +++++ .../ModuleSpecifierTransformation.xtend | 226 ----- .../ModuleWrappingTransformation.java | 104 ++ .../ModuleWrappingTransformation.xtend | 86 -- .../RestParameterTransformation.java | 111 ++ .../RestParameterTransformation.xtend | 94 -- .../SanitizeImportsTransformation.java | 193 ++++ .../SanitizeImportsTransformation.xtend | 171 ---- .../es/transform/SimplifyTransformation.java | 106 ++ .../es/transform/SimplifyTransformation.xtend | 94 -- .../StaticPolyfillTransformation.java | 278 +++++ .../StaticPolyfillTransformation.xtend | 217 ---- .../TemplateStringTransformation.java | 149 +++ .../TemplateStringTransformation.xtend | 120 --- .../es/transform/TrimTransformation.java | 68 ++ .../es/transform/TrimTransformation.xtend | 60 -- .../xtend-gen/.gitignore | 2 - .../org.eclipse.n4js.transpiler/.classpath | 1 - .../build.properties | 1 - plugins/org.eclipse.n4js.transpiler/pom.xml | 4 - .../transpiler/SymbolTableManagement.java | 484 +++++++++ .../transpiler/SymbolTableManagement.xtend | 451 --------- .../transpiler/TranspilerBuilderBlocks.java | 954 ++++++++++++++++++ .../transpiler/TranspilerBuilderBlocks.xtend | 870 ---------------- .../n4js/transpiler/TranspilerComponent.java | 19 +- .../transpiler/TranspilerStateOperations.java | 653 ++++++++++++ .../TranspilerStateOperations.xtend | 571 ----------- .../transpiler/assistants/TypeAssistant.java | 228 +++++ .../transpiler/assistants/TypeAssistant.xtend | 204 ---- .../utils/TranspilerDebugUtils.java | 233 +++++ .../utils/TranspilerDebugUtils.xtend | 207 ---- .../xtend-gen/.gitignore | 2 - .../n4js/utils/FindReferenceHelper.java | 6 +- .../helper/server/TestWorkspaceManager.java | 6 +- .../org.eclipse.n4js.tests.helper/.classpath | 1 - .../build.properties | 3 +- .../org.eclipse.n4js.tests.helper/pom.xml | 4 - .../org/eclipse/n4js/tests/codegen/Class.java | 111 ++ .../eclipse/n4js/tests/codegen/Class.xtend | 80 -- .../n4js/tests/codegen/Classifier.java | 212 ++++ .../n4js/tests/codegen/Classifier.xtend | 190 ---- .../org/eclipse/n4js/tests/codegen/Field.java | 67 ++ .../eclipse/n4js/tests/codegen/Field.xtend | 52 - .../codegen/{Folder.xtend => Folder.java} | 90 +- .../codegen/{Fragment.xtend => Fragment.java} | 70 +- .../eclipse/n4js/tests/codegen/Getter.java | 74 ++ .../eclipse/n4js/tests/codegen/Getter.xtend | 52 - .../eclipse/n4js/tests/codegen/Interface.java | 76 ++ .../n4js/tests/codegen/Interface.xtend | 59 -- .../codegen/{Member.xtend => Member.java} | 202 ++-- .../eclipse/n4js/tests/codegen/Method.java | 129 +++ .../eclipse/n4js/tests/codegen/Method.xtend | 98 -- .../eclipse/n4js/tests/codegen/Module.java | 156 +++ .../eclipse/n4js/tests/codegen/Module.xtend | 133 --- .../{OtherFile.xtend => OtherFile.java} | 92 +- .../eclipse/n4js/tests/codegen/Project.java | 462 +++++++++ .../eclipse/n4js/tests/codegen/Project.xtend | 402 -------- .../eclipse/n4js/tests/codegen/Setter.java | 57 ++ .../eclipse/n4js/tests/codegen/Setter.xtend | 41 - .../eclipse/n4js/tests/codegen/Workspace.java | 92 ++ .../n4js/tests/codegen/Workspace.xtend | 82 -- .../tests/codegen/YarnWorkspaceProject.java | 159 +++ .../tests/codegen/YarnWorkspaceProject.xtend | 145 --- .../xtend-gen/.gitignore | 2 - .../tests/ScenarioGenerator.java | 3 +- ...04_ReviewImportedNamesComputationTest.java | 2 +- ...yclicDependenciesBuilderNoRebuildTest.java | 12 +- .../CyclicDependenciesBuilderTest.java | 52 +- ...ncrementalBuilderWorkspaceChangesTest.java | 8 +- .../ide/tests/builder/InitialBuildTest.java | 2 +- .../RebuildFindsNewNpmPackageTest.java | 2 +- .../ide/tests/spec/ImportsUnresolvedTest.java | 2 +- .../tests/project/MultiProjectIdeTest.java | 14 +- .../tests/project/NoValidationIdeTest.java | 2 +- .../tests/project/SingleProjectIdeTest.java | 2 +- 182 files changed, 12583 insertions(+), 10892 deletions(-) rename plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/{UnicodeRuntimeModule.xtend => UnicodeRuntimeModule.java} (79%) rename plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/{UnicodeStandaloneSetup.xtend => UnicodeStandaloneSetup.java} (76%) create mode 100644 plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/generator/UnicodeGrammarGenerator.java delete mode 100644 plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/generator/UnicodeGrammarGenerator.xtend delete mode 100644 plugins/org.eclipse.n4js.common.unicode/xtend-gen/.gitignore rename plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/{ADocFactory.xtend => ADocFactory.java} (60%) create mode 100644 plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocSerializer.java delete mode 100644 plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocSerializer.xtend delete mode 100644 plugins/org.eclipse.n4js.jsdoc2spec/xtend-gen/.gitignore delete mode 100644 plugins/org.eclipse.n4js.json.ide/xtend-gen/.gitignore create mode 100644 plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/formatting2/JSONFormatter.java delete mode 100644 plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/formatting2/JSONFormatter.xtend create mode 100644 plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionManager.java delete mode 100644 plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionManager.xtend create mode 100644 plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionStrategy.java delete mode 100644 plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionStrategy.xtend delete mode 100644 plugins/org.eclipse.n4js.json/xtend-gen/.gitignore create mode 100644 plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/DestructNode.java delete mode 100644 plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/DestructNode.xtend delete mode 100644 plugins/org.eclipse.n4js.model/xtend-gen/.gitignore rename plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/{RegularExpressionIdeModule.xtend => RegularExpressionIdeModule.java} (76%) create mode 100644 plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeSetup.java delete mode 100644 plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeSetup.xtend delete mode 100644 plugins/org.eclipse.n4js.regex.ide/xtend-gen/.gitignore rename plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/{RegularExpressionRuntimeModule.xtend => RegularExpressionRuntimeModule.java} (65%) rename plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/{RegularExpressionStandaloneSetup.xtend => RegularExpressionStandaloneSetup.java} (74%) create mode 100644 plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/generator/RegularExpressionGenerator.java delete mode 100644 plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/generator/RegularExpressionGenerator.xtend rename plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/scoping/{RegularExpressionScopeProvider.xtend => RegularExpressionScopeProvider.java} (71%) rename plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/validation/{RegularExpressionValidator.xtend => RegularExpressionValidator.java} (54%) delete mode 100644 plugins/org.eclipse.n4js.regex/xtend-gen/.gitignore delete mode 100644 plugins/org.eclipse.n4js.semver.ide/xtend-gen/.gitignore create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/BlockAssistant.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/BlockAssistant.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassConstructorAssistant.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassConstructorAssistant.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassifierAssistant.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassifierAssistant.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DelegationAssistant.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DelegationAssistant.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DestructuringAssistant.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DestructuringAssistant.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ReflectionAssistant.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ReflectionAssistant.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ApiImplStubGenerationTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ApiImplStubGenerationTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part1_Transformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part1_Transformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part2_Transformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part2_Transformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/BlockTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/BlockTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ClassDeclarationTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ClassDeclarationTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/CommonJsImportsTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/CommonJsImportsTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DependencyInjectionTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DependencyInjectionTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DestructuringTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DestructuringTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumAccessTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumAccessTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumDeclarationTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumDeclarationTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ExpressionTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ExpressionTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/InterfaceDeclarationTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/InterfaceDeclarationTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/MemberPatchingTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/MemberPatchingTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleSpecifierTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleSpecifierTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleWrappingTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleWrappingTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/RestParameterTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/RestParameterTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SimplifyTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SimplifyTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/StaticPolyfillTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/StaticPolyfillTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TemplateStringTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TemplateStringTransformation.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TrimTransformation.java delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TrimTransformation.xtend delete mode 100644 plugins/org.eclipse.n4js.transpiler.es/xtend-gen/.gitignore create mode 100644 plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/SymbolTableManagement.java delete mode 100644 plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/SymbolTableManagement.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerBuilderBlocks.java delete mode 100644 plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerBuilderBlocks.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.java delete mode 100644 plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/assistants/TypeAssistant.java delete mode 100644 plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/assistants/TypeAssistant.xtend create mode 100644 plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/utils/TranspilerDebugUtils.java delete mode 100644 plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/utils/TranspilerDebugUtils.xtend delete mode 100644 plugins/org.eclipse.n4js.transpiler/xtend-gen/.gitignore create mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Class.java delete mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Class.xtend create mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Classifier.java delete mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Classifier.xtend create mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Field.java delete mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Field.xtend rename testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/{Folder.xtend => Folder.java} (52%) rename testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/{Fragment.xtend => Fragment.java} (54%) create mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Getter.java delete mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Getter.xtend create mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Interface.java delete mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Interface.xtend rename testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/{Member.xtend => Member.java} (52%) create mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Method.java delete mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Method.xtend create mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Module.java delete mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Module.xtend rename testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/{OtherFile.xtend => OtherFile.java} (60%) create mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Project.java delete mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Project.xtend create mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Setter.java delete mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Setter.xtend create mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Workspace.java delete mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Workspace.xtend create mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/YarnWorkspaceProject.java delete mode 100644 testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/YarnWorkspaceProject.xtend delete mode 100644 testhelpers/org.eclipse.n4js.tests.helper/xtend-gen/.gitignore diff --git a/plugins/org.eclipse.n4js.cli/pom.xml b/plugins/org.eclipse.n4js.cli/pom.xml index 9b93d26146..d33c735548 100644 --- a/plugins/org.eclipse.n4js.cli/pom.xml +++ b/plugins/org.eclipse.n4js.cli/pom.xml @@ -34,10 +34,6 @@ Contributors: org.apache.maven.plugins maven-clean-plugin - - org.eclipse.xtend - xtend-maven-plugin - org.apache.maven.plugins maven-dependency-plugin diff --git a/plugins/org.eclipse.n4js.common.unicode/.classpath b/plugins/org.eclipse.n4js.common.unicode/.classpath index 3947fc4c6b..3cfbdf7de5 100644 --- a/plugins/org.eclipse.n4js.common.unicode/.classpath +++ b/plugins/org.eclipse.n4js.common.unicode/.classpath @@ -6,7 +6,6 @@ - diff --git a/plugins/org.eclipse.n4js.common.unicode/build.properties b/plugins/org.eclipse.n4js.common.unicode/build.properties index b7d1cdc73c..a73891df20 100644 --- a/plugins/org.eclipse.n4js.common.unicode/build.properties +++ b/plugins/org.eclipse.n4js.common.unicode/build.properties @@ -1,7 +1,6 @@ source.. = src/,\ src-gen/,\ - grammar-gen/,\ - xtend-gen/ + grammar-gen/ bin.includes = META-INF/,\ .,\ about.html diff --git a/plugins/org.eclipse.n4js.common.unicode/pom.xml b/plugins/org.eclipse.n4js.common.unicode/pom.xml index 665e2ad854..6d0236149e 100644 --- a/plugins/org.eclipse.n4js.common.unicode/pom.xml +++ b/plugins/org.eclipse.n4js.common.unicode/pom.xml @@ -61,12 +61,6 @@ Contributors: - - - org.eclipse.xtend - xtend-maven-plugin - - diff --git a/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/UnicodeRuntimeModule.xtend b/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/UnicodeRuntimeModule.java similarity index 79% rename from plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/UnicodeRuntimeModule.xtend rename to plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/UnicodeRuntimeModule.java index f244e94392..9f7264bea1 100644 --- a/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/UnicodeRuntimeModule.xtend +++ b/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/UnicodeRuntimeModule.java @@ -8,11 +8,11 @@ * Contributors: * NumberFour AG - Initial API and implementation */ -package org.eclipse.n4js.common.unicode - +package org.eclipse.n4js.common.unicode; /** * Use this class to register components to be used at runtime / without the Equinox extension registry. */ -class UnicodeRuntimeModule extends AbstractUnicodeRuntimeModule { +public class UnicodeRuntimeModule extends AbstractUnicodeRuntimeModule { + // empty } diff --git a/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/UnicodeStandaloneSetup.xtend b/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/UnicodeStandaloneSetup.java similarity index 76% rename from plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/UnicodeStandaloneSetup.xtend rename to plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/UnicodeStandaloneSetup.java index 5438dc513d..461932a613 100644 --- a/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/UnicodeStandaloneSetup.xtend +++ b/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/UnicodeStandaloneSetup.java @@ -8,15 +8,15 @@ * Contributors: * NumberFour AG - Initial API and implementation */ -package org.eclipse.n4js.common.unicode - +package org.eclipse.n4js.common.unicode; /** * Initialization support for running Xtext languages without Equinox extension registry. */ -class UnicodeStandaloneSetup extends UnicodeStandaloneSetupGenerated { +public class UnicodeStandaloneSetup extends UnicodeStandaloneSetupGenerated { - def static void doSetup() { - new UnicodeStandaloneSetup().createInjectorAndDoEMFRegistration() + /***/ + static public void doSetup() { + new UnicodeStandaloneSetup().createInjectorAndDoEMFRegistration(); } } diff --git a/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/generator/UnicodeGrammarGenerator.java b/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/generator/UnicodeGrammarGenerator.java new file mode 100644 index 0000000000..69d5c253df --- /dev/null +++ b/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/generator/UnicodeGrammarGenerator.java @@ -0,0 +1,179 @@ +/** + * 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.common.unicode.generator; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.function.Function; + +import com.google.common.base.Charsets; +import com.google.common.base.Strings; +import com.google.common.io.Files; + +/***/ +public class UnicodeGrammarGenerator { + + /** + * This generator isn't called by the GenerateUnicode.mwe2, this have to be done manually + */ + @SuppressWarnings("unused") + static void main(String[] args) throws IOException { + // if (args.head == '-file') + new UnicodeGrammarGenerator(); + // else + // println(generateUnicodeRules) + } + + /** + * The write-on-instantiation allows to use this generator in mwe2 as #bean + */ + UnicodeGrammarGenerator() throws IOException { + Files.asCharSink(new File("grammar-gen/org/eclipse/n4js/common/unicode/Unicode.xtext"), Charsets.UTF_8) + .write(generateUnicodeRules()); + } + + static String generateUnicodeRules() { + return """ + /** + * 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 + */ + + // Important note: + // This grammar is auto generated by the + // org.eclipse.n4js.common.unicode.generator.UnicodeGrammarGenerator + // + // Rather than editing this manually, update the generator instead! + + grammar org.eclipse.n4js.common.unicode.Unicode + + import "http://www.eclipse.org/emf/2002/Ecore" as ecore + + terminal fragment HEX_DIGIT: + (DECIMAL_DIGIT_FRAGMENT|'a'..'f'|'A'..'F') + ; + terminal fragment DECIMAL_INTEGER_LITERAL_FRAGMENT: + '0' + | '1'..'9' DECIMAL_DIGIT_FRAGMENT* + ; + terminal fragment DECIMAL_DIGIT_FRAGMENT: + '0'..'9' + ; + terminal fragment ZWJ: + '\u200D' + ; + terminal fragment ZWNJ: + '\u200C' + ; + terminal fragment BOM: + '\uFEFF' + ; + terminal fragment WHITESPACE_FRAGMENT: + '\u0009' | '\u000B' | '\u000C' | '\u0020' | '\u00A0' | BOM | UNICODE_SPACE_SEPARATOR_FRAGMENT + ; + terminal fragment LINE_TERMINATOR_FRAGMENT: + '\u000A' | '\u000D' | '\u2028' | '\u2029' + ; + terminal fragment LINE_TERMINATOR_SEQUENCE_FRAGMENT: + '\u000A' | '\u000D' '\u000A'? | '\u2028' | '\u2029' + ; + terminal fragment SL_COMMENT_FRAGMENT: + '//' (!LINE_TERMINATOR_FRAGMENT)* + ; + terminal fragment ML_COMMENT_FRAGMENT: + '/*' -> '*/' + ; + + terminal fragment UNICODE_COMBINING_MARK_FRAGMENT: + // any character in the Unicode categories + // ―Non-spacing mark (Mn) + // ―Combining spacing mark (Mc) + «generateUnicodeRules [ isCombiningMark ]» + ; + terminal fragment UNICODE_DIGIT_FRAGMENT: + // any character in the Unicode categories + // ―Decimal number (Nd) + «generateUnicodeRules [ isDigit ]» + ; + terminal fragment UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT: + // any character in the Unicode categories + // ―Connector punctuation (Pc) + «generateUnicodeRules [ isConnectorPunctuation ]» + ; + terminal fragment UNICODE_LETTER_FRAGMENT: + // any character in the Unicode categories + // ―Uppercase letter (Lu) + // ―Lowercase letter (Ll) + // ―Titlecase letter (Lt) + // ―Modifier letter (Lm) + // ―Other letter (Lo) + // ―Letter number (Nl) + «generateUnicodeRules [ isLetter ]» + ; + terminal fragment UNICODE_SPACE_SEPARATOR_FRAGMENT: + // any character in the Unicode categories + // ―space separator (Zs) + «generateUnicodeRules [ isSpaceSeparator ]» + ; + terminal fragment ANY_OTHER: + . + ; + """; + } + + static StringWriter generateUnicodeRules(Function guard) { + Character prev = null; + boolean run = false; + boolean first = true; + char c = Character.MIN_VALUE; + StringWriter result = new StringWriter(); + PrintWriter printer = new PrintWriter(result, true); + while (true) { + if (guard.apply((int) c)) { + if (!run) { + prev = c; + run = true; + } + } else { + if (run && prev != null) { + if (!first) { + printer.print("| "); + } else { + printer.print(" "); + first = false; + } + printer.print("'\\u" + Strings.padStart(Integer.toHexString(prev).toUpperCase(), 4, '0') + "'"); + if (prev.charValue() == c - 1) { + printer.println(); + } else { + printer.println( + "..'\\u" + Strings.padStart(Integer.toHexString(c - 1).toUpperCase(), 4, '0') + "'"); + } + prev = null; + run = false; + } + } + c = (char) (c + 1); + if (c == Character.MAX_VALUE) { + return result; + } + } + } + +} diff --git a/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/generator/UnicodeGrammarGenerator.xtend b/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/generator/UnicodeGrammarGenerator.xtend deleted file mode 100644 index aaf742462e..0000000000 --- a/plugins/org.eclipse.n4js.common.unicode/src/org/eclipse/n4js/common/unicode/generator/UnicodeGrammarGenerator.xtend +++ /dev/null @@ -1,174 +0,0 @@ -/** - * 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.common.unicode.generator - -import com.google.common.base.Charsets -import com.google.common.base.Strings -import com.google.common.io.Files -import java.io.File -import java.io.PrintWriter -import java.io.StringWriter - -import static extension org.eclipse.n4js.common.unicode.CharTypes.* -import java.io.IOException - -class UnicodeGrammarGenerator { - - /** - * This generator isn't called by the GenerateUnicode.mwe2, this have to be done manually - */ - def static void main(String[] args) throws IOException { -// if (args.head == '-file') - new UnicodeGrammarGenerator -// else -// println(generateUnicodeRules) - } - - /** - * The write-on-instantiation allows to use this generator in mwe2 as #bean - */ - new() throws IOException { - Files.asCharSink(new File('grammar-gen/org/eclipse/n4js/common/unicode/Unicode.xtext'), Charsets.UTF_8).write(generateUnicodeRules); - } - - def static generateUnicodeRules() ''' - /** - * 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 - */ - - // Important note: - // This grammar is auto generated by the - // org.eclipse.n4js.common.unicode.generator.UnicodeGrammarGenerator - // - // Rather than editing this manually, update the generator instead! - - grammar org.eclipse.n4js.common.unicode.Unicode - - import "http://www.eclipse.org/emf/2002/Ecore" as ecore - - terminal fragment HEX_DIGIT: - (DECIMAL_DIGIT_FRAGMENT|'a'..'f'|'A'..'F') - ; - terminal fragment DECIMAL_INTEGER_LITERAL_FRAGMENT: - '0' - | '1'..'9' DECIMAL_DIGIT_FRAGMENT* - ; - terminal fragment DECIMAL_DIGIT_FRAGMENT: - '0'..'9' - ; - terminal fragment ZWJ: - '\u200D' - ; - terminal fragment ZWNJ: - '\u200C' - ; - terminal fragment BOM: - '\uFEFF' - ; - terminal fragment WHITESPACE_FRAGMENT: - '\u0009' | '\u000B' | '\u000C' | '\u0020' | '\u00A0' | BOM | UNICODE_SPACE_SEPARATOR_FRAGMENT - ; - terminal fragment LINE_TERMINATOR_FRAGMENT: - '\u000A' | '\u000D' | '\u2028' | '\u2029' - ; - terminal fragment LINE_TERMINATOR_SEQUENCE_FRAGMENT: - '\u000A' | '\u000D' '\u000A'? | '\u2028' | '\u2029' - ; - terminal fragment SL_COMMENT_FRAGMENT: - '//' (!LINE_TERMINATOR_FRAGMENT)* - ; - terminal fragment ML_COMMENT_FRAGMENT: - '/*' -> '*/' - ; - - terminal fragment UNICODE_COMBINING_MARK_FRAGMENT: - // any character in the Unicode categories - // ―Non-spacing mark (Mn) - // ―Combining spacing mark (Mc) - «generateUnicodeRules [ isCombiningMark ]» - ; - terminal fragment UNICODE_DIGIT_FRAGMENT: - // any character in the Unicode categories - // ―Decimal number (Nd) - «generateUnicodeRules [ isDigit ]» - ; - terminal fragment UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT: - // any character in the Unicode categories - // ―Connector punctuation (Pc) - «generateUnicodeRules [ isConnectorPunctuation ]» - ; - terminal fragment UNICODE_LETTER_FRAGMENT: - // any character in the Unicode categories - // ―Uppercase letter (Lu) - // ―Lowercase letter (Ll) - // ―Titlecase letter (Lt) - // ―Modifier letter (Lm) - // ―Other letter (Lo) - // ―Letter number (Nl) - «generateUnicodeRules [ isLetter ]» - ; - terminal fragment UNICODE_SPACE_SEPARATOR_FRAGMENT: - // any character in the Unicode categories - // ―space separator (Zs) - «generateUnicodeRules [ isSpaceSeparator ]» - ; - terminal fragment ANY_OTHER: - . - ; - ''' - def static generateUnicodeRules((int)=>boolean guard) { - var Character prev = null; - var run = false; - var first = true; - var char c = Character.MIN_VALUE - val result = new StringWriter - val printer = new PrintWriter(result, true) - while(true) { - if (guard.apply(c as int)) { - if (!run) { - prev = c; - run = true; - } - } else { - if (run) { - if (!first) { - printer.print("| "); - } else { - printer.print(" "); - first = false; - } - printer.print("'\\u" + Strings.padStart(Integer.toHexString(prev).toUpperCase(), 4, '0') + "'"); - if (prev.charValue() == c - 1) { - printer.println(); - } else { - printer.println("..'\\u" + Strings.padStart(Integer.toHexString(c - 1).toUpperCase(), 4, '0') + "'"); - } - prev = null; - run = false; - } - } - c = (c + 1) as char - if (c == Character.MAX_VALUE) { - return result; - } - } - - } - - -} diff --git a/plugins/org.eclipse.n4js.common.unicode/xtend-gen/.gitignore b/plugins/org.eclipse.n4js.common.unicode/xtend-gen/.gitignore deleted file mode 100644 index c96a04f008..0000000000 --- a/plugins/org.eclipse.n4js.common.unicode/xtend-gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/plugins/org.eclipse.n4js.dts/pom.xml b/plugins/org.eclipse.n4js.dts/pom.xml index 0b20fe0301..b9645b1212 100644 --- a/plugins/org.eclipse.n4js.dts/pom.xml +++ b/plugins/org.eclipse.n4js.dts/pom.xml @@ -37,11 +37,7 @@ Contributors: org.apache.maven.plugins maven-clean-plugin - - - org.eclipse.xtend - xtend-maven-plugin - + org.apache.maven.plugins maven-dependency-plugin diff --git a/plugins/org.eclipse.n4js.flowgraphs/src/org/eclipse/n4js/flowgraphs/dataflow/AssignmentRelationFactory.java b/plugins/org.eclipse.n4js.flowgraphs/src/org/eclipse/n4js/flowgraphs/dataflow/AssignmentRelationFactory.java index c50d5e9ff1..7148457f77 100644 --- a/plugins/org.eclipse.n4js.flowgraphs/src/org/eclipse/n4js/flowgraphs/dataflow/AssignmentRelationFactory.java +++ b/plugins/org.eclipse.n4js.flowgraphs/src/org/eclipse/n4js/flowgraphs/dataflow/AssignmentRelationFactory.java @@ -207,7 +207,7 @@ private void findInCorrespondingDestructNodes(Multimap assgns, C private void findInDestructNodes(Multimap assgns, DestructNode dNode) { for (Iterator dnIter = dNode.stream().iterator(); dnIter.hasNext();) { DestructNode dnChild = dnIter.next(); - ControlFlowElement lhs = dnChild.getVarRef() != null ? dnChild.getVarRef() : dnChild.getVarDecl(); + ControlFlowElement lhs = dnChild.varRef != null ? dnChild.varRef : dnChild.varDecl; EObject rhs = DestructureUtilsForSymbols.getValueFromDestructuring(dnChild); if (rhs == null) { Symbol undefinedSymbol = symbolFactory.getUndefined(); diff --git a/plugins/org.eclipse.n4js.flowgraphs/src/org/eclipse/n4js/flowgraphs/dataflow/DestructureUtilsForSymbols.java b/plugins/org.eclipse.n4js.flowgraphs/src/org/eclipse/n4js/flowgraphs/dataflow/DestructureUtilsForSymbols.java index c751d3bab0..93b0ef8b75 100644 --- a/plugins/org.eclipse.n4js.flowgraphs/src/org/eclipse/n4js/flowgraphs/dataflow/DestructureUtilsForSymbols.java +++ b/plugins/org.eclipse.n4js.flowgraphs/src/org/eclipse/n4js/flowgraphs/dataflow/DestructureUtilsForSymbols.java @@ -43,8 +43,8 @@ public static EObject getValueFromDestructuring(DestructNode dNode) { return null; } - EObject assignedValue = dNode.getAssignedElem(); - EObject defaultValue = dNode.getDefaultExpr(); + EObject assignedValue = dNode.assignedElem; + EObject defaultValue = dNode.defaultExpr; return respectDefaultValue(assignedValue, defaultValue); } diff --git a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/util/ChangeProvider.java b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/util/ChangeProvider.java index ec312225d6..eeef172f27 100644 --- a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/util/ChangeProvider.java +++ b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/codeActions/util/ChangeProvider.java @@ -193,7 +193,7 @@ public static TextEdit removeText(Document doc, int offset, int length, boolean String resultLineContent = startLineContent + endLineContent; - if (resultLineContent.isBlank()) { + if (resultLineContent.isBlank() && doc.getLineCount() > posEnd.getLine() + 1) { posStart = new Position(posStart.getLine(), 0); posEnd = new Position(posEnd.getLine() + 1, 0); } diff --git a/plugins/org.eclipse.n4js.jsdoc2spec/.classpath b/plugins/org.eclipse.n4js.jsdoc2spec/.classpath index a2e7d69e3d..3628e33687 100644 --- a/plugins/org.eclipse.n4js.jsdoc2spec/.classpath +++ b/plugins/org.eclipse.n4js.jsdoc2spec/.classpath @@ -6,7 +6,6 @@ - diff --git a/plugins/org.eclipse.n4js.jsdoc2spec/build.properties b/plugins/org.eclipse.n4js.jsdoc2spec/build.properties index 0470e65b92..fb36160409 100644 --- a/plugins/org.eclipse.n4js.jsdoc2spec/build.properties +++ b/plugins/org.eclipse.n4js.jsdoc2spec/build.properties @@ -1,5 +1,4 @@ -source.. = src/,\ - xtend-gen/ +source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ diff --git a/plugins/org.eclipse.n4js.jsdoc2spec/pom.xml b/plugins/org.eclipse.n4js.jsdoc2spec/pom.xml index 4750cb5dd4..b3206816bc 100644 --- a/plugins/org.eclipse.n4js.jsdoc2spec/pom.xml +++ b/plugins/org.eclipse.n4js.jsdoc2spec/pom.xml @@ -49,10 +49,6 @@ Contributors: --> - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocFactory.xtend b/plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocFactory.java similarity index 60% rename from plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocFactory.xtend rename to plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocFactory.java index 21f14197a8..8b175069e6 100644 --- a/plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocFactory.xtend +++ b/plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocFactory.java @@ -10,9 +10,11 @@ */ package org.eclipse.n4js.jsdoc2spec.adoc; -import com.google.inject.Inject -import org.eclipse.n4js.jsdoc.N4JSDocHelper -import java.util.Map +import java.util.Map; + +import org.eclipse.n4js.jsdoc.N4JSDocHelper; + +import com.google.inject.Inject; /** * Creates AsciiDoc spec fragments for spec region entries. @@ -25,20 +27,21 @@ public class ADocFactory { @Inject ADocSerializer ADocSerializer; - /** * Creates the spec of the given entry for the AsciiDoc document. */ - public def CharSequence createSpecRegionString(SpecRequirementSection spec, Map specsByKey) { - return ADocSerializer.process(spec, specsByKey); + public CharSequence createSpecRegionString(SpecRequirementSection spec, + @SuppressWarnings("unused") Map specsByKey) { + return ADocSerializer.process(spec); } /** * Creates the spec of the given entry for the AsciiDoc document. */ - public def CharSequence createSpecRegionString(SpecIdentifiableElementSection spec, Map specsByKey) { - if (spec.getDoclet === null) { - spec.doclet = n4jsDocHelper.getDoclet(spec.identifiableElement); + public CharSequence createSpecRegionString(SpecIdentifiableElementSection spec, + Map specsByKey) { + if (spec.getDoclet() == null) { + spec.setDoclet(n4jsDocHelper.getDoclet(spec.getIdentifiableElement())); } return ADocSerializer.process(spec, specsByKey); } diff --git a/plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocSerializer.java b/plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocSerializer.java new file mode 100644 index 0000000000..fcc0a417c7 --- /dev/null +++ b/plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocSerializer.java @@ -0,0 +1,726 @@ +/** + * 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.jsdoc2spec.adoc; + +import static com.google.common.base.Strings.isNullOrEmpty; +import static org.eclipse.n4js.jsdoc.N4JSDocletParser.TAG_CODE; +import static org.eclipse.n4js.jsdoc.N4JSDocletParser.TAG_LINK; +import static org.eclipse.n4js.jsdoc.N4JSDocletParser.TAG_REQID; +import static org.eclipse.n4js.jsdoc.N4JSDocletParser.TAG_SPEC; +import static org.eclipse.n4js.jsdoc.N4JSDocletParser.TAG_SPECFROMDESCR; +import static org.eclipse.n4js.jsdoc.N4JSDocletParser.TAG_TASK; +import static org.eclipse.n4js.jsdoc.N4JSDocletParser.TAG_TODO; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.groupBy; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.isNullOrEmpty; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.sortBy; +import static org.eclipse.xtext.xbase.lib.StringExtensions.toFirstUpper; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Set; +import java.util.SortedSet; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.jsdoc.dom.Composite; +import org.eclipse.n4js.jsdoc.dom.Doclet; +import org.eclipse.n4js.jsdoc.dom.InlineTag; +import org.eclipse.n4js.jsdoc.dom.LineTag; +import org.eclipse.n4js.jsdoc.dom.Literal; +import org.eclipse.n4js.jsdoc.dom.SimpleTypeReference; +import org.eclipse.n4js.jsdoc.dom.TagValue; +import org.eclipse.n4js.jsdoc.dom.Text; +import org.eclipse.n4js.jsdoc.dom.VariableReference; +import org.eclipse.n4js.jsdoc.tags.DefaultLineTagDefinition; +import org.eclipse.n4js.jsdoc2spec.KeyUtils; +import org.eclipse.n4js.jsdoc2spec.RepoRelativePath; +import org.eclipse.n4js.jsdoc2spec.SpecTestInfo; +import org.eclipse.n4js.ts.types.ContainerType; +import org.eclipse.n4js.ts.types.FieldAccessor; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.SyntaxRelatedTElement; +import org.eclipse.n4js.ts.types.TAnnotation; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TEnum; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TInterface; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TMemberWithAccessModifier; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.TN4Classifier; +import org.eclipse.n4js.ts.types.TVariable; +import org.eclipse.n4js.typesystem.utils.AllSuperTypesCollector; +import org.eclipse.n4js.utils.DeclMergingHelper; +import org.eclipse.n4js.utils.Strings; +import org.eclipse.n4js.validation.N4JSElementKeywordProvider; +import org.eclipse.n4js.validation.ValidatorMessageHelper; + +import com.google.inject.Inject; + +/** + * Print AsciiDoc code of specification JSDoc. Start and end markers are printed by client. + * + * Needs to be injected. + */ +class ADocSerializer { + @Inject + Html2ADocConverter html2aDocConverter; + @Inject + ValidatorMessageHelper validatorMessageHelper; + @Inject + N4JSElementKeywordProvider keywordProvider; + @Inject + RepoRelativePathHolder repoPathHolder; + @Inject + DeclMergingHelper declMergingHelper; + + String process(SpecRequirementSection spec) { + StringBuilder strb = new StringBuilder(); + appendSpecElementPost(strb, spec); + return Strings.stripAllTrailing(strb.toString()); + } + + String process(SpecIdentifiableElementSection spec, Map specsByKey) { + StringBuilder strb = new StringBuilder(); + appendSpecElementPre(strb, spec); + appendSpec(strb, spec); + appendSpecElementPost(strb, spec, specsByKey); + return Strings.stripAllTrailing(strb.toString()); + } + + private StringBuilder appendSpecElementPost(StringBuilder strb, SpecRequirementSection spec) { + if (!isNullOrEmpty(spec.getTestInfosForType())) { + Map> groupdTests = groupBy(spec.getTestInfosForType(), sti -> sti.testTitle); + appendApiConstraints(strb, groupdTests); + } + return strb; + } + + private StringBuilder appendSpec(StringBuilder strb, SpecIdentifiableElementSection spec) { + strb.append("\n"); + + boolean addedTaskLinks = false; + List taskTags = spec.getDoclet().lineTags(TAG_TASK.getTitle()); + for (LineTag tag : taskTags) { + String taskID = TAG_TASK.getValue(tag, ""); + if (!taskID.isEmpty()) { + if (taskID.startsWith("*")) { + appendTaskLink(strb, taskID.substring(1)); + } else { + appendTaskLink(strb, taskID); + } + strb.append(" "); + addedTaskLinks = true; + } + } + if (addedTaskLinks) + strb.append("\n\n"); + + appendSpecDescription(strb, spec); + return strb; + } + + private StringBuilder appendSpecDescription(StringBuilder strb, SpecIdentifiableElementSection spec) { + Doclet doclet = spec.getDoclet(); + boolean bSpecFromDescr = doclet.hasLineTag(TAG_SPECFROMDESCR.getTitle()); + String reqID = getReqId(doclet); + List specTags = doclet.lineTags(TAG_SPEC.getTitle()); + + if (specTags.isEmpty() && !bSpecFromDescr && reqID.isEmpty()) { + return strb; + } + + if (!(spec.idElement instanceof TN4Classifier || spec.idElement instanceof TEnum)) + strb.append("==== Description\n\n"); + + if (!reqID.isEmpty()) { + strb.append("See req:" + reqID + "[].\n"); + } + + appendContents(strb, doclet); + for (LineTag tag : specTags) { + appendContents(strb, tag.getValueByKey(DefaultLineTagDefinition.CONTENTS)); + } + + strb.append("\n"); + + return strb; + } + + private StringBuilder appendSpecDescriptions(StringBuilder strb, Iterable doclets) { + for (Doclet doclet : doclets) { + boolean bSpecFromDescr = doclet.hasLineTag(TAG_SPECFROMDESCR.getTitle()); + List specTags = doclet.lineTags(TAG_SPEC.getTitle()); + if (!specTags.isEmpty() || bSpecFromDescr) { + appendContents(strb, doclet); + for (LineTag tag : specTags) { + appendContents(strb, tag.getValueByKey(DefaultLineTagDefinition.CONTENTS)); + } + } + } + return strb; + } + + private StringBuilder appendContents(StringBuilder strb, Composite composite) { + boolean contentAdded = false; + for (EObject c : composite.eContents()) { + String newContent = processContent(c).toString(); + strb.append(newContent); + contentAdded |= !newContent.isBlank(); + } + if (contentAdded) { + strb.append("\n"); + } + return strb; + } + + private CharSequence processContent(EObject node) { + if (node instanceof Text) { + return processContent((Text) node); + } + if (node instanceof Literal) { + return processContent((Literal) node); + } + if (node instanceof SimpleTypeReference) { + return processContent((SimpleTypeReference) node); + } + if (node instanceof VariableReference) { + return processContent((VariableReference) node); + } + if (node instanceof InlineTag) { + return processContent((InlineTag) node); + } + + return ""; + } + + private CharSequence processContent(Text node) { + return html2aDocConverter.transformHTML(node.getText()); + } + + private CharSequence processContent(Literal node) { + return html2aDocConverter.transformHTML(node.getValue()); + } + + private CharSequence processContent(SimpleTypeReference node) { + return html2aDocConverter.passThenMonospace(html2aDocConverter.transformHTML(node.getTypeName())); + } + + private CharSequence processContent(VariableReference node) { + return html2aDocConverter.passThenMonospace(html2aDocConverter.transformHTML(node.getVariableName())); + } + + private CharSequence processContent(InlineTag node) { + if (Objects.equals(TAG_CODE.getTitle(), node.getTitle().getTitle())) { + return html2aDocConverter.passThenMonospace(html2aDocConverter.transformHTML(TAG_CODE.getValue(node, ""))); + } + if (Objects.equals(TAG_LINK.getTitle(), node.getTitle().getTitle())) { + return html2aDocConverter.passThenMonospace(html2aDocConverter.transformHTML(TAG_LINK.getValue(node, ""))); + } + + StringBuilder strb = new StringBuilder(); + for (TagValue tv : node.getValues()) { + appendContents(strb, tv); + } + return strb; + } + + private StringBuilder appendSpecElementPre(StringBuilder strb, SpecIdentifiableElementSection spec) { + IdentifiableElement element = spec.getIdentifiableElement(); + if (element instanceof TMember) { + return appendElementCodePre(strb, (TMember) element, spec); + } + if (element instanceof TMethod) { + return appendElementCodePre(strb, (TMethod) element, spec); + } + if (element instanceof TFunction) { + return appendElementCodePre(strb, (TFunction) element, spec); + } + if (element instanceof TVariable) { + return appendElementCodePre(strb, (TVariable) element, spec); + } + return appendElementCodePre(strb, element, spec); + } + + /** + * E.g. classes + */ + private StringBuilder appendElementCodePre(StringBuilder strb, + @SuppressWarnings("unused") IdentifiableElement element, SpecIdentifiableElementSection spec) { + + if (hasTodo(spec.getDoclet())) { + strb.append(getTodoLink(spec.getDoclet())); + } + return strb; + } + + private StringBuilder appendElementCodePre(StringBuilder strb, TMember element, + SpecIdentifiableElementSection spec) { + return appendMemberOrVarOrFuncPre(strb, + validatorMessageHelper.shortDescription(element), + element, + spec); + } + + private StringBuilder appendElementCodePre(StringBuilder strb, TMethod element, + SpecIdentifiableElementSection spec) { + return appendMemberOrVarOrFuncPre(strb, + validatorMessageHelper.shortDescription((TMember) element), + element, + spec); + } + + private StringBuilder appendElementCodePre(StringBuilder strb, TFunction element, + SpecIdentifiableElementSection spec) { + return appendMemberOrVarOrFuncPre(strb, + validatorMessageHelper.shortDescription(element), + element, + spec); + } + + private StringBuilder appendElementCodePre(StringBuilder strb, TVariable element, + SpecIdentifiableElementSection spec) { + return appendMemberOrVarOrFuncPre(strb, + validatorMessageHelper.shortDescription(element), + element, + spec); + } + + private StringBuilder appendMemberOrVarOrFuncPre(StringBuilder strb, String shortDescr, + SyntaxRelatedTElement element, SpecIdentifiableElementSection spec) { + + boolean isIntegratedFromPolyfill = !Objects.equals(spec.sourceEntry.trueFolder, spec.sourceEntry.folder); + String trueSrcFolder = spec.sourceEntry.repository + ":" + spec.sourceEntry.trueFolder; + String todoLink = hasTodo(spec.getDoclet()) ? "\n" + getTodoLink(spec.getDoclet()) : ""; + String polyfill = isIntegratedFromPolyfill + ? "\n\n[.small]#(Integrated from static polyfill aware class in: %s)#".formatted(trueSrcFolder) + : ""; + + strb.append(""" + + [[gsec:spec_%s]] + [role=memberdoc] + === %s%s%s + + ==== Signature + + %s + + """.formatted( + spec.sourceEntry.getAdocCompatibleAnchorID(), + html2aDocConverter.pass(toFirstUpper(shortDescr)), + todoLink, + polyfill, + codeLink(element))); + return strb; + } + + private CharSequence codeLink(EObject element) { + if (element instanceof TVariable) { + return codeLink((TVariable) element); + } + if (element instanceof TMethod) { + return codeLink((TMethod) element); + } + if (element instanceof TFunction) { + return codeLink((TFunction) element); + } + if (element instanceof TMember) { + return codeLink((TMember) element); + } + + throw new IllegalArgumentException(); + } + + private CharSequence codeLink(TMember member) { + return doCodeLink(member, fullSignature(member)); + } + + private CharSequence codeLink(TMethod method) { + return doCodeLink(method, fullSignature(method)); + } + + private CharSequence codeLink(TFunction func) { + return doCodeLink(func, fullSignature(func)); + } + + private CharSequence codeLink(TVariable tvar) { + return doCodeLink(tvar, fullSignature(tvar)); + } + + private String fullSignature(TMember member) { + StringBuilder strb = new StringBuilder(); + for (TAnnotation a : filter(member.getAnnotations(), + ann -> !AnnotationDefinition.INTERNAL.name.equals(ann.getName()))) { + + strb.append(a.getAnnotationAsString() + " "); + } + strb.append(keywordProvider.keyword(member.getMemberAccessModifier()) + " "); + if (member.isAbstract()) { + strb.append("@abstract "); + } + strb.append(member.getMemberAsString()); + + return strb.toString(); + } + + private String fullSignature(TMethod method) { + return validatorMessageHelper.fullFunctionSignature(method); + } + + private String fullSignature(TFunction func) { + return validatorMessageHelper.fullFunctionSignature(func); + } + + private String fullSignature(TVariable tvar) { + if (tvar.getTypeRef() == null) { + return tvar.getName(); + } + return tvar.getName() + ": " + tvar.getTypeRef().getTypeRefAsString(); + } + + private CharSequence doCodeLink(IdentifiableElement element, String signature) { + RepoRelativePath rrp = repoPathHolder.get(element); + StringBuilder strb = new StringBuilder(); + + if (rrp != null) { + SourceEntry se = SourceEntryFactory.create(repoPathHolder, rrp, element); + appendSourceLink(strb, se, html2aDocConverter.passThenMonospace(signature)); + } + + return strb.toString(); + } + + private boolean isInSpec(TMember member, Map specsByKey) { + if (member == null) { + return false; + } + return specsByKey.containsKey(KeyUtils.getSpecKey(repoPathHolder, member)); + } + + private String getFormattedID(Entry> entry, List superTypes) { + int index = superTypes.indexOf(entry.getKey().getContainingType()); + return String.format("%04d", index) + entry.getKey().getName(); + } + + private StringBuilder appendSpecElementPost(StringBuilder strb, SpecIdentifiableElementSection specRegion, + Map specsByKey) { + + IdentifiableElement element = specRegion.getIdentifiableElement(); + if (element instanceof TMember) { + return appendElementPost(strb, (TMember) element, specRegion, specsByKey); + } + if (element instanceof TMethod) { + return appendElementPost(strb, (TMethod) element, specRegion, specsByKey); + } + if (element instanceof TFunction) { + return appendElementPost(strb, (TFunction) element, specRegion, specsByKey); + } + if (element instanceof TVariable) { + return appendElementPost(strb, (TVariable) element, specRegion, specsByKey); + } + return appendElementPost(strb, element, specRegion, specsByKey); + } + + private StringBuilder appendElementPost(StringBuilder strb, + IdentifiableElement element, SpecIdentifiableElementSection specRegion, + Map specsByKey) { + + if (element instanceof ContainerType) { + Map> testsForInherited = specRegion.getTestInfosForInheritedMember(); + if (testsForInherited == null || testsForInherited.isEmpty()) { + return strb; + } + + String typeName = element.getName(); + List superTypes = AllSuperTypesCollector.collect((ContainerType) element, + declMergingHelper); + + Iterable>> tests = filter(testsForInherited.entrySet(), + e -> e.getValue() != null && !e.getValue().isEmpty()); + Iterable>> sortedTests = sortBy(tests, + e -> getFormattedID(e, superTypes)); + + for (Entry> tmemberSpecs : sortedTests) { + String shortDescr = validatorMessageHelper.shortDescription(tmemberSpecs.getKey()); + String secSpecLink = typeName + "." + validatorMessageHelper.shortQualifiedName(tmemberSpecs.getKey()); + String secSpecLinkEsc = SourceEntry.getEscapedAdocAnchorString(secSpecLink); + String description = validatorMessageHelper.description(tmemberSpecs.getKey().getContainingType()); + String shortQualName = validatorMessageHelper.shortQualifiedName(tmemberSpecs.getKey()); + String gsecSpec = isInSpec(tmemberSpecs.getKey(), specsByKey) + ? "\n\t<>\n".formatted(html2aDocConverter.pass(shortQualName)) + : ""; + + strb.append(""" + + [[gsec:spec_%s]] + [role=memberdoc] + === %s + + Inherited from + %s%s + + """.formatted( + secSpecLinkEsc, + html2aDocConverter.pass(toFirstUpper(shortDescr)), + html2aDocConverter.pass(description), + gsecSpec)); + + appendConstraints(strb, tmemberSpecs.getKey(), specRegion, tmemberSpecs.getValue(), false); + } + + } + return strb; + + } + + private StringBuilder appendElementPost(StringBuilder strb, TMember element, + SpecIdentifiableElementSection specRegion, + @SuppressWarnings("unused") Map specsByKey) { + + appendConstraints(strb, element, specRegion, specRegion.getTestInfosForMember(), + !hasReqId(specRegion.getDoclet())); + return strb; + } + + private StringBuilder appendElementPost(StringBuilder strb, TMethod element, + SpecIdentifiableElementSection specRegion, + @SuppressWarnings("unused") Map specsByKey) { + + appendConstraints(strb, element, specRegion, specRegion.getTestInfosForMember(), + !hasReqId(specRegion.getDoclet())); + return strb; + } + + private StringBuilder appendElementPost(StringBuilder strb, TFunction element, + SpecIdentifiableElementSection specRegion, + @SuppressWarnings("unused") Map specsByKey) { + + if (!isNullOrEmpty(specRegion.getTestInfosForType())) { + Map> groupdTests = groupBy(specRegion.getTestInfosForType(), + sti -> sti.testTitle); + + strb.append("==== Semantics\n"); + appendApiConstraints(strb, groupdTests); + } else { + + String reqID = getReqId(specRegion.getDoclet()); + if (reqID.isEmpty()) { + String todoLink = getTodoLink( + "Add tests specifying semantics for " + html2aDocConverter.passThenMonospace(element.getName()), + "test function " + html2aDocConverter.pass(element.getName())); + + strb.append(""" + + ==== Semantics + %s + """.formatted(todoLink)); + } else { + strb.append("% tests see " + reqID); + } + } + + return strb; + } + + private StringBuilder appendElementPost(StringBuilder strb, @SuppressWarnings("unused") TVariable element, + SpecIdentifiableElementSection specRegion, + @SuppressWarnings("unused") Map specsByKey) { + + if (!isNullOrEmpty(specRegion.getTestInfosForType())) { + Map> groupdTests = groupBy(specRegion.getTestInfosForType(), + sti -> sti.testTitle); + + strb.append("==== Semantics\n"); + appendApiConstraints(strb, groupdTests); + } + return strb; // test are optional for variables. + } + + private StringBuilder appendConstraints(StringBuilder strb, TMember element, + SpecIdentifiableElementSection specRegion, Set specTestInfos, boolean addTodo) { + + if (!isNullOrEmpty(specTestInfos)) { + Map> groupdTests = groupBy(specTestInfos, sti -> sti.testTitle); + strb.append("==== Semantics\n"); + appendApiConstraints(strb, groupdTests); + + } else if (addTodo) { + + if (elementMayNeedsTest(element, specRegion)) { + String todoLink = getTodoLink( + "Add tests specifying semantics for " + + html2aDocConverter.passThenMonospace(element.getMemberAsString()), + "test " + html2aDocConverter + .pass(element.getContainingType().getName() + "." + element.getName())); + + strb.append(""" + + ==== Semantics + %s + """.formatted(todoLink)); + } + } + return strb; + } + + private boolean elementMayNeedsTest(TMember element, SpecIdentifiableElementSection spec) { + // there are tests, so we show them + if (!isNullOrEmpty(spec.getTestInfosForType())) { + return true; + } + if ((element instanceof TMethod) || (element instanceof FieldAccessor)) { + if (element.getContainingType() instanceof TInterface) { + if (element instanceof TMemberWithAccessModifier) { + return !((TMemberWithAccessModifier) element).isHasNoBody(); + } + } + return !element.isAbstract(); + } + return false; + } + + /** + * List of tests in apiConstraint macros. + */ + private StringBuilder appendApiConstraints(StringBuilder strb, + Map> groupdTests) { + for (Map.Entry> group : sortBy(groupdTests.entrySet(), + e -> e.getKey().toString())) { + strb.append("\n"); + strb.append(". *"); + String key = group.getKey().toString(); + String keyWithoutPrecedingNumber = removePrecedingNumber(key); + strb.append(html2aDocConverter.pass(keyWithoutPrecedingNumber)); + strb.append("* ("); + Iterator iter = group.getValue().iterator(); + while (iter.hasNext()) { + SpecTestInfo testSpec = iter.next(); + strb.append(nfgitTest(testSpec)); + if (iter.hasNext()) { + strb.append(", \n"); + } + } + strb.append(")\n"); + Iterable doclets = map(filter(group.getValue(), spi -> spi.doclet != null), spi -> spi.doclet); + StringBuilder strbTmp = new StringBuilder(); + appendSpecDescriptions(strbTmp, doclets); + if (strbTmp.length() > 0) { + strb.append("+\n"); + strb.append("[.generatedApiConstraint]\n"); + strb.append("====\n\n"); + strb.append(strbTmp); + strb.append("\n====\n"); + } + } + return strb; + } + + private CharSequence nfgitTest(SpecTestInfo testInfo) { + StringBuilder strb = new StringBuilder(); + if (testInfo.rrp == null) { + strb.append(small(testInfo.testModuleSpec() + ".")); + strb.append(testInfo.testMethodTypeName() + "." + testInfo.testMethodName()); + } else { + SourceEntry pc = SourceEntryFactory.create(testInfo); + String strCase = "Test"; + if (!isNullOrEmpty(testInfo.testCase)) { + String formattedCase = removePrecedingNumber(testInfo.testCase); + if (isNullOrEmpty(formattedCase)) { + formattedCase = testInfo.testCase; + } + html2aDocConverter.pass(formattedCase); + } + StringBuilder strbTmp = new StringBuilder(); + appendSourceLink(strbTmp, pc, strCase); + strb.append(small(strbTmp)); + } + return strb.toString(); + } + + /** + * Reminder: Escaping the caption using the method {@link Html2ADocConverter#pass} is recommended. + */ + private StringBuilder appendSourceLink(StringBuilder strb, SourceEntry pc, String caption) { + strb.append("srclnk:++" + pc.toPQN() + "++[" + caption + "]"); + return strb; + } + + /** + * Returns req id, may be an empty string but never null. + */ + private String getReqId(Doclet doclet) { + return TAG_REQID.getValue(doclet, ""); + } + + /** + * Returns true, if spec contains a reference to a requirement id. + */ + private boolean hasReqId(Doclet doclet) { + return !getReqId(doclet).isEmpty(); + } + + /** + * Returns true, if spec contains a reference to a todo. + */ + private boolean hasTodo(Doclet doclet) { + return !getTodo(doclet).isEmpty(); + } + + /** + * Returns todo, may be an empty string but never null. + */ + private String getTodo(Doclet doclet) { + return TAG_TODO.getValue(doclet, ""); + } + + private String getTodoLink(String todoText, String sideText) { + String str = isNullOrEmpty(sideText) ? "" : ", title=\"" + sideText + "\""; + String todo = """ + + [TODO%s] + -- + %s + -- + """.formatted(str, todoText); + return todo; + } + + private String getTodoLink(Doclet doclet) { + return getTodoLink(getTodo(doclet), ""); + } + + private StringBuilder appendTaskLink(StringBuilder strb, String taskID) { + strb.append("task:" + taskID + "[]"); + return strb; + } + + private String small(CharSequence smallString) { + return "[.small]#" + smallString + "#"; + } + + private String removePrecedingNumber(String key) { + for (var i = 0; i < key.length(); i++) { + String stringAt = Character.toString(key.charAt(i)); + if (!"0123456789 ".contains(stringAt)) { + return key.substring(i); + } + } + return ""; + } + +} diff --git a/plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocSerializer.xtend b/plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocSerializer.xtend deleted file mode 100644 index b5bc565c81..0000000000 --- a/plugins/org.eclipse.n4js.jsdoc2spec/src/org/eclipse/n4js/jsdoc2spec/adoc/ADocSerializer.xtend +++ /dev/null @@ -1,607 +0,0 @@ -/** - * 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.jsdoc2spec.adoc; - -import com.google.inject.Inject -import java.util.Collection -import java.util.List -import java.util.Map -import java.util.Map.Entry -import java.util.Set -import java.util.SortedSet -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.jsdoc.dom.Composite -import org.eclipse.n4js.jsdoc.dom.ContentNode -import org.eclipse.n4js.jsdoc.dom.Doclet -import org.eclipse.n4js.jsdoc.dom.InlineTag -import org.eclipse.n4js.jsdoc.dom.Literal -import org.eclipse.n4js.jsdoc.dom.SimpleTypeReference -import org.eclipse.n4js.jsdoc.dom.Text -import org.eclipse.n4js.jsdoc.dom.VariableReference -import org.eclipse.n4js.jsdoc.tags.DefaultLineTagDefinition -import org.eclipse.n4js.jsdoc2spec.KeyUtils -import org.eclipse.n4js.jsdoc2spec.RepoRelativePath -import org.eclipse.n4js.jsdoc2spec.SpecTestInfo -import org.eclipse.n4js.ts.types.ContainerType -import org.eclipse.n4js.ts.types.FieldAccessor -import org.eclipse.n4js.ts.types.IdentifiableElement -import org.eclipse.n4js.ts.types.SyntaxRelatedTElement -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TEnum -import org.eclipse.n4js.ts.types.TFunction -import org.eclipse.n4js.ts.types.TInterface -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.ts.types.TMemberWithAccessModifier -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.ts.types.TN4Classifier -import org.eclipse.n4js.ts.types.TVariable -import org.eclipse.n4js.typesystem.utils.AllSuperTypesCollector -import org.eclipse.n4js.utils.DeclMergingHelper -import org.eclipse.n4js.utils.Strings -import org.eclipse.n4js.validation.N4JSElementKeywordProvider -import org.eclipse.n4js.validation.ValidatorMessageHelper - -import static org.eclipse.n4js.jsdoc.N4JSDocletParser.* - -/** - * Print AsciiDoc code of specification JSDoc. Start and end markers are printed by client. - * - * Needs to be injectd. - */ -class ADocSerializer { - @Inject extension Html2ADocConverter; - @Inject ValidatorMessageHelper validatorMessageHelper; - @Inject N4JSElementKeywordProvider keywordProvider; - @Inject RepoRelativePathHolder repoPathHolder; - @Inject DeclMergingHelper declMergingHelper; - - - def String process(SpecRequirementSection spec, Map specsByKey) { - val strb = new StringBuilder(); - strb.appendSpecElementPost(spec, specsByKey); - return Strings.stripAllTrailing(strb.toString()); - } - - def String process(SpecIdentifiableElementSection spec, Map specsByKey) { - val strb = new StringBuilder(); - strb.appendSpecElementPre(spec); - strb.appendSpec(spec); - strb.appendSpecElementPost(spec, specsByKey); - return Strings.stripAllTrailing(strb.toString()); - } - - private def StringBuilder appendSpecElementPost(StringBuilder strb, SpecRequirementSection spec, Map map) { - if (! spec.getTestInfosForType.isNullOrEmpty) { - val Map> groupdTests = spec.getTestInfosForType.groupBy[testTitle]; - strb.appendApiConstraints(groupdTests); - } - return strb - } - - private def StringBuilder appendSpec(StringBuilder strb, SpecIdentifiableElementSection spec) { - strb.append("\n"); - - var addedTaskLinks = false; - val taskTags = spec.getDoclet.lineTags(TAG_TASK.title); - for (tag : taskTags) { - val taskID = TAG_TASK.getValue(tag, ""); - if (!taskID.empty) { - if (taskID.startsWith("*")) { - strb.appendTaskLink(taskID.substring(1)); - } else { - strb.appendTaskLink(taskID); - } - strb.append(" "); - addedTaskLinks = true; - } - } - if(addedTaskLinks) - strb.append("\n\n"); - - strb.appendSpecDescription(spec); - return strb - } - - private def StringBuilder appendSpecDescription(StringBuilder strb, SpecIdentifiableElementSection spec) { - val doclet = spec.getDoclet; - val bSpecFromDescr = doclet.hasLineTag(TAG_SPECFROMDESCR.title); - val reqID = getReqId(doclet); - val specTags = doclet.lineTags(TAG_SPEC.title); - - if (specTags.empty && !bSpecFromDescr && reqID.isEmpty) - return strb; - - if (!(spec.idElement instanceof TN4Classifier || spec.idElement instanceof TEnum)) - strb.append("==== Description\n\n"); - - if (!reqID.isEmpty) { - strb.append("See req:"+reqID +"[].\n"); - } - - strb.appendContents(doclet); - for (tag : specTags) { - strb.appendContents(tag.getValueByKey(DefaultLineTagDefinition.CONTENTS)); - } - - strb.append("\n"); - - return strb; - } - - private def StringBuilder appendSpecDescriptions(StringBuilder strb, Iterable doclets) { - for (doclet : doclets) { - var bSpecFromDescr = doclet.hasLineTag(TAG_SPECFROMDESCR.title); - val specTags = doclet.lineTags(TAG_SPEC.title); - if (! specTags.empty || bSpecFromDescr) { - strb.appendContents(doclet); - for (tag : specTags) { - strb.appendContents(tag.getValueByKey(DefaultLineTagDefinition.CONTENTS)); - } - } - } - return strb; - } - - private def StringBuilder appendContents(StringBuilder strb, Composite composite) { - for (c : composite.contents) { - strb.append(processContent(c)); - } - if (!composite.contents.isEmpty) { - strb.append("\n"); - } - return strb; - } - - - private def dispatch CharSequence processContent(ContentNode node) {} - private def dispatch CharSequence processContent(Text node) { - return transformHTML(node.text); - } - private def dispatch CharSequence processContent(Literal node) { - return transformHTML(node.value); - } - private def dispatch CharSequence processContent(SimpleTypeReference node) { - return passThenMonospace(transformHTML(node.typeName)); - } - private def dispatch CharSequence processContent(VariableReference node) { - return passThenMonospace(transformHTML(node.variableName)); - } - private def dispatch CharSequence processContent(InlineTag node) { - switch (node.title.title) { - case TAG_CODE.title: passThenMonospace(transformHTML(TAG_CODE.getValue(node, ""))) - case TAG_LINK.title: passThenMonospace(transformHTML(TAG_LINK.getValue(node, ""))) - default: { - val StringBuilder strb = new StringBuilder(); - node.values.forEach[strb.appendContents(it)]; - return strb; - } - } - } - - - private def StringBuilder appendSpecElementPre(StringBuilder strb, SpecIdentifiableElementSection spec) { - return strb.appendElementCodePre(spec.identifiableElement, spec); - } - - - /** - * E.g. classes - */ - private def dispatch StringBuilder appendElementCodePre(StringBuilder strb, IdentifiableElement element, SpecIdentifiableElementSection spec) { - if (hasTodo(spec.doclet)) - strb.append(getTodoLink(spec.doclet)); - return strb; - } - private def dispatch StringBuilder appendElementCodePre(StringBuilder strb, TMember element, SpecIdentifiableElementSection spec) { - return strb.appendMemberOrVarOrFuncPre( - validatorMessageHelper.shortDescription(element), - validatorMessageHelper.shortQualifiedName(element), - element.memberAsString, - element, - spec - ); - } - private def dispatch StringBuilder appendElementCodePre(StringBuilder strb, TMethod element, SpecIdentifiableElementSection spec) { - return strb.appendMemberOrVarOrFuncPre( - validatorMessageHelper.shortDescription(element as TMember), - validatorMessageHelper.shortQualifiedName(element as TMember), - element.memberAsString, - element, - spec - ); - } - private def dispatch StringBuilder appendElementCodePre(StringBuilder strb, TFunction element, SpecIdentifiableElementSection spec) { - return strb.appendMemberOrVarOrFuncPre( - validatorMessageHelper.shortDescription(element), - validatorMessageHelper.shortQualifiedName(element), - element.name, - element, - spec - ); - } - private def dispatch StringBuilder appendElementCodePre(StringBuilder strb, TVariable element, SpecIdentifiableElementSection spec) { - return strb.appendMemberOrVarOrFuncPre( - validatorMessageHelper.shortDescription(element), - validatorMessageHelper.shortQualifiedName(element), - element.name, - element, - spec - ); - } - - - private def StringBuilder appendMemberOrVarOrFuncPre(StringBuilder strb, String shortDescr, String shortQN, - String reqName, SyntaxRelatedTElement element, SpecIdentifiableElementSection spec) { - - val boolean isIntegratedFromPolyfill = spec.sourceEntry.trueFolder != spec.sourceEntry.folder; - val String trueSrcFolder = spec.sourceEntry.repository + ":" + spec.sourceEntry.trueFolder; - - strb.append( - ''' - - [[gsec:spec_«spec.sourceEntry.adocCompatibleAnchorID»]] - [role=memberdoc] - === «pass(shortDescr.toFirstUpper)» - «IF hasTodo(spec.doclet)» - «getTodoLink(spec.doclet)» - «ENDIF» - «IF isIntegratedFromPolyfill» - - [.small]#(Integrated from static polyfill aware class in: «trueSrcFolder»)# - «ENDIF» - - ==== Signature - - «codeLink(element)» - - '''); - return strb; - } - - - private def dispatch CharSequence codeLink(TMember member) { - return doCodeLink(member, fullSignature(member)); - } - private def dispatch CharSequence codeLink(TMethod method) { - return doCodeLink(method, fullSignature(method)); - } - private def dispatch CharSequence codeLink(TFunction func) { - return doCodeLink(func, fullSignature(func)); - } - private def dispatch CharSequence codeLink(TVariable tvar) { - return doCodeLink(tvar, fullSignature(tvar)); - } - - - private def fullSignature(TMember member) { - val StringBuilder strb = new StringBuilder(); - for (a: member.annotations.filter[it.name!=AnnotationDefinition.INTERNAL.name]) { - strb.append(a.annotationAsString + " "); - } - strb.append(keywordProvider.keyword(member.memberAccessModifier) + " "); - if (member.abstract) { - strb.append("@abstract "); - } - strb.append(member.memberAsString); - - return strb.toString; - } - private def fullSignature(TMethod method) { - return validatorMessageHelper.fullFunctionSignature(method); - } - private def fullSignature(TFunction func) { - return validatorMessageHelper.fullFunctionSignature(func); - } - private def fullSignature(TVariable tvar) { - if (tvar.typeRef===null) { - return tvar.name; - } - return '''«tvar.name»: «tvar.typeRef.typeRefAsString»'''; - } - - - private def CharSequence doCodeLink(IdentifiableElement element, String signature) { - val RepoRelativePath rrp = repoPathHolder.get(element); - val strb = new StringBuilder(); - - if (rrp !== null) { - val SourceEntry se = SourceEntryFactory.create(repoPathHolder, rrp, element); - strb.appendSourceLink(se, passThenMonospace(signature)); - } - - return strb.toString(); - } - - - private def StringBuilder appendSpecElementPost(StringBuilder strb, SpecIdentifiableElementSection spec, Map map) { - return strb.appendElementPost(spec.identifiableElement, spec, map); - } - - private def dispatch StringBuilder appendElementPost(StringBuilder strb, - IdentifiableElement element, SpecIdentifiableElementSection specRegion, Map specsByKey) { - - if (element instanceof ContainerType) { - var Map> testsForInherited = specRegion.getTestInfosForInheritedMember - if (testsForInherited === null || testsForInherited.empty) { - return strb; - } - - val typeName = element.name; - val superTypes = AllSuperTypesCollector.collect( - element, declMergingHelper - ) - - val tests = testsForInherited.entrySet.filter[value!==null && !value.empty]; - val sortedTests = tests.sortBy[getFormattedID(it, superTypes)]; - for (tmemberSpecs : sortedTests) { - val shortDescr = validatorMessageHelper.shortDescription(tmemberSpecs.key); - val secSpecLink = typeName + "." + validatorMessageHelper.shortQualifiedName(tmemberSpecs.key); - val secSpecLinkEsc = SourceEntry.getEscapedAdocAnchorString(secSpecLink); - val description = validatorMessageHelper.description(tmemberSpecs.key.containingType); - val shortQualName = validatorMessageHelper.shortQualifiedName(tmemberSpecs.key); - - strb.append( - ''' - - [[gsec:spec_«secSpecLinkEsc»]] - [role=memberdoc] - === «pass(shortDescr.toFirstUpper)» - - Inherited from - «pass(description)» - «IF isInSpec(tmemberSpecs.key, specsByKey)» - <> - «ENDIF» - - '''); - - strb.appendConstraints(tmemberSpecs.key, specRegion, tmemberSpecs.value, false); - } - } - return strb - } - - - private def boolean isInSpec(TMember member, Map specsByKey) { - if (member === null) { - return false; - } - return specsByKey.containsKey(KeyUtils.getSpecKey(repoPathHolder, member)); - } - - private def String getFormattedID(Entry> entry, List superTypes) { - val index = superTypes.indexOf(entry.key.containingType); - return String.format("%04d", index) + entry.key.name - } - - - private def dispatch StringBuilder appendElementPost(StringBuilder strb, TMember element, SpecIdentifiableElementSection specRegion, Map specsByKey) { - strb.appendConstraints(element, specRegion, specRegion.getTestInfosForMember, ! hasReqId(specRegion.getDoclet)); - return strb; - } - private def dispatch StringBuilder appendElementPost(StringBuilder strb, TMethod element, SpecIdentifiableElementSection specRegion, Map specsByKey) { - strb.appendConstraints(element, specRegion, specRegion.getTestInfosForMember, ! hasReqId(specRegion.getDoclet)); - return strb; - } - private def dispatch StringBuilder appendElementPost(StringBuilder strb, TFunction element, SpecIdentifiableElementSection specRegion, Map specsByKey) { - - if (! specRegion.getTestInfosForType.isNullOrEmpty) { - val Map> groupdTests = specRegion.getTestInfosForType.groupBy[testTitle]; - strb.append("==== Semantics\n"); - strb.appendApiConstraints(groupdTests); - } else { - - val reqID = getReqId(specRegion.getDoclet); - if (reqID.isEmpty) { - val String todoLink = getTodoLink( - "Add tests specifying semantics for " + passThenMonospace(element.name), - "test function " + pass(element.name)); - - strb.append( - ''' - - ==== Semantics - «todoLink» - '''); - } else { - strb.append('''% tests see «reqID»'''); - } - } - - return strb; - } - private def dispatch StringBuilder appendElementPost(StringBuilder strb, TVariable element, SpecSection specRegion, Map specsByKey) { - if (! specRegion.getTestInfosForType.isNullOrEmpty) { - val Map> groupdTests = specRegion.getTestInfosForType.groupBy[testTitle]; - strb.append("==== Semantics\n"); - strb.appendApiConstraints(groupdTests) - } - return strb; // test are optional for variables. - } - - - private def StringBuilder appendConstraints(StringBuilder strb, TMember element, SpecIdentifiableElementSection specRegion, Set specTestInfos, boolean addTodo) { - if (! specTestInfos.isNullOrEmpty) { - val Map> groupdTests = specTestInfos.groupBy[testTitle]; - strb.append("==== Semantics\n"); - strb.appendApiConstraints(groupdTests); - - } else if (addTodo) { - - if (elementMayNeedsTest(element, specRegion)) { - val String todoLink = getTodoLink( - "Add tests specifying semantics for " + passThenMonospace(element.memberAsString), - "test " + pass(element.containingType.name + "." + element.name)); - - strb.append( - ''' - - ==== Semantics - «todoLink» - '''); - } - } - return strb - } - - private def boolean elementMayNeedsTest(TMember element, SpecIdentifiableElementSection spec) { - // there are tests, so we show them - if (! spec.getTestInfosForType.isNullOrEmpty) { - return true; - } - if ((element instanceof TMethod) || (element instanceof FieldAccessor)) { - if (element.containingType instanceof TInterface) { - if (element instanceof TMemberWithAccessModifier) { - return ! element.hasNoBody - } - } - return !element.isAbstract; - } - return false; - } - - /** - * List of tests in apiConstraint macros. - */ - private def StringBuilder appendApiConstraints(StringBuilder strb, Map> groupdTests) { - for (group : groupdTests.entrySet.sortBy[it.key.toString]) { - strb.append("\n"); - strb.append(". *"); - val key = group.key.toString; - val keyWithoutPrecedingNumber = removePrecedingNumber(key); - strb.append(pass(keyWithoutPrecedingNumber)); - strb.append("* ("); - val iter = group.value.iterator; - while (iter.hasNext) { - val SpecTestInfo testSpec = iter.next; - strb.append(nfgitTest(testSpec)); - if (iter.hasNext) { - strb.append(", \n"); - } - } - strb.append(")\n"); - val Iterable doclets = group.value.filter[doclet !== null].map[doclet]; - val strbTmp = new StringBuilder(); - strbTmp.appendSpecDescriptions(doclets); - if (strbTmp.length > 0) { - strb.append("+\n"); - strb.append("[.generatedApiConstraint]\n"); - strb.append("====\n\n"); - strb.append(strbTmp); - strb.append("\n====\n"); - } - } - return strb - } - - private def CharSequence nfgitTest(SpecTestInfo testInfo) { - val strb = new StringBuilder(); - if (testInfo.rrp === null) { - strb.append(small(testInfo.testModuleSpec() + ".")); - strb.append(testInfo.testMethodTypeName() + "." + testInfo.testMethodName()); - } else { - val pc = SourceEntryFactory.create(testInfo); - val strCase = if (testInfo.testCase.nullOrEmpty) "Test" else { - var formattedCase = removePrecedingNumber(testInfo.testCase); - if (formattedCase.nullOrEmpty) { - formattedCase = testInfo.testCase; - } - pass(formattedCase); - } - val strbTmp = new StringBuilder(); - strbTmp.appendSourceLink(pc, strCase); - strb.append(small(strbTmp)); - } - return strb.toString(); - } - - /** - * Reminder: Escaping the caption using the method {@link Html2ADocConverter#pass} is recommended. - */ - private def StringBuilder appendSourceLink(StringBuilder strb, SourceEntry pc, String caption) { - strb.append( - '''srclnk:++« - pc.toPQN - »++[« - caption - »]'''); - return strb; - } - - /** - * Returns req id, may be an empty string but never null. - */ - private def String getReqId(Doclet doclet) { - return TAG_REQID.getValue(doclet, ""); - } - - /** - * Returns true, if spec contains a reference to a requirement id. - */ - private def boolean hasReqId(Doclet doclet) { - return ! getReqId(doclet).isEmpty; - } - - /** - * Returns true, if spec contains a reference to a todo. - */ - private def boolean hasTodo(Doclet doclet) { - return ! getTodo(doclet).isEmpty; - } - - /** - * Returns todo, may be an empty string but never null. - */ - private def String getTodo(Doclet doclet) { - return TAG_TODO.getValue(doclet, ""); - } - - private def String getTodoLink(String todoText, String sideText) { - val todo = - ''' - - [TODO« - IF !sideText.isNullOrEmpty - », title="«sideText»"« - ENDIF - »] - -- - «todoText» - -- - - ''' - return todo; - } - - private def String getTodoLink(Doclet doclet) { - return getTodoLink(getTodo(doclet), ""); - } - - private def StringBuilder appendTaskLink(StringBuilder strb, String taskID) { - strb.append('''task:«taskID»[]'''); - return strb; - } - - private def String small(CharSequence smallString) { - return '''[.small]#«smallString»#'''; - } - - private def String removePrecedingNumber(String key) { - for (var i=0; i - diff --git a/plugins/org.eclipse.n4js.json.ide/build.properties b/plugins/org.eclipse.n4js.json.ide/build.properties index bef28d3d93..ec65859a4c 100644 --- a/plugins/org.eclipse.n4js.json.ide/build.properties +++ b/plugins/org.eclipse.n4js.json.ide/build.properties @@ -1,5 +1,4 @@ source.. = src/,\ - src-gen/,\ - xtend-gen/ + src-gen/ bin.includes = META-INF/,\ . diff --git a/plugins/org.eclipse.n4js.json.ide/pom.xml b/plugins/org.eclipse.n4js.json.ide/pom.xml index dca382ed36..a041e9011a 100644 --- a/plugins/org.eclipse.n4js.json.ide/pom.xml +++ b/plugins/org.eclipse.n4js.json.ide/pom.xml @@ -30,10 +30,6 @@ Contributors: org.apache.maven.plugins maven-clean-plugin - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/plugins/org.eclipse.n4js.json.ide/xtend-gen/.gitignore b/plugins/org.eclipse.n4js.json.ide/xtend-gen/.gitignore deleted file mode 100644 index d6b7ef32c8..0000000000 --- a/plugins/org.eclipse.n4js.json.ide/xtend-gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/plugins/org.eclipse.n4js.json.model/pom.xml b/plugins/org.eclipse.n4js.json.model/pom.xml index 50cd02cef3..41b5a2c6e1 100644 --- a/plugins/org.eclipse.n4js.json.model/pom.xml +++ b/plugins/org.eclipse.n4js.json.model/pom.xml @@ -38,11 +38,6 @@ Contributors: maven-resources-plugin ${maven-resources-plugin.version} - - org.eclipse.xtend - xtend-maven-plugin - - diff --git a/plugins/org.eclipse.n4js.json/.classpath b/plugins/org.eclipse.n4js.json/.classpath index 4305a21582..7f20dda608 100644 --- a/plugins/org.eclipse.n4js.json/.classpath +++ b/plugins/org.eclipse.n4js.json/.classpath @@ -6,11 +6,6 @@ - - - - - diff --git a/plugins/org.eclipse.n4js.json/build.properties b/plugins/org.eclipse.n4js.json/build.properties index 4f8080dec2..1ee90b0954 100644 --- a/plugins/org.eclipse.n4js.json/build.properties +++ b/plugins/org.eclipse.n4js.json/build.properties @@ -1,6 +1,5 @@ source.. = src/,\ - src-gen/,\ - xtend-gen/ + src-gen/ bin.includes = .,\ META-INF/,\ plugin.xml diff --git a/plugins/org.eclipse.n4js.json/pom.xml b/plugins/org.eclipse.n4js.json/pom.xml index 6f1f1701a9..327b7983eb 100644 --- a/plugins/org.eclipse.n4js.json/pom.xml +++ b/plugins/org.eclipse.n4js.json/pom.xml @@ -78,11 +78,6 @@ Contributors: - - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/formatting2/JSONFormatter.java b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/formatting2/JSONFormatter.java new file mode 100644 index 0000000000..c0994b46ee --- /dev/null +++ b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/formatting2/JSONFormatter.java @@ -0,0 +1,161 @@ +/** + * Copyright (c) 2017 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.json.formatting2; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.json.JSON.JSONArray; +import org.eclipse.n4js.json.JSON.JSONDocument; +import org.eclipse.n4js.json.JSON.JSONObject; +import org.eclipse.n4js.json.JSON.JSONValue; +import org.eclipse.n4js.json.JSON.NameValuePair; +import org.eclipse.xtext.formatting2.AbstractFormatter2; +import org.eclipse.xtext.formatting2.IFormattableDocument; +import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion; +import org.eclipse.xtext.resource.XtextResource; +import org.eclipse.xtext.xbase.lib.Pair; + +/** + * A simple formatter for JSON files. + * + * Generally, puts name-value-pairs of objects and array elements on a separate line. + */ +public class JSONFormatter extends AbstractFormatter2 { + + @Override + public void format(Object al, IFormattableDocument document) { + if (al instanceof XtextResource) { + super._format((XtextResource) al, document); + return; + } else if (al instanceof JSONArray) { + format((JSONArray) al, document); + return; + } else if (al instanceof JSONObject) { + format((JSONObject) al, document); + return; + } else if (al instanceof JSONDocument) { + format((JSONDocument) al, document); + return; + } else if (al instanceof NameValuePair) { + format((NameValuePair) al, document); + return; + } else if (al instanceof EObject) { + super._format((EObject) al, document); + return; + } else if (al == null) { + super._format((Void) null, document); + return; + } else { + super._format(al, document); + return; + } + } + + /** */ + public void format(JSONDocument jSONDocument, IFormattableDocument document) { + // make sure all document elements are formatted + document.format(jSONDocument.getContent()); + for (ISemanticRegion sr : textRegionExtensions.allSemanticRegions(jSONDocument)) { + document.append(sr, f -> f.indent()); + } + } + + /** Put both brackets and every element of a JSONArray on a separate line. */ + public void format(JSONArray al, IFormattableDocument document) { + // avoid comma-only lines + configureCommas(al, document); + + Pair bracketPair = textRegionExtensions.regionFor(al).keywordPairs("[", "]") + .get(0); + + // if bracePair can be determined + if (bracketPair != null) { + // indent array elements + document.interior(bracketPair, f -> f.indent()); + + // format empty arrays to be a bracket pair without space (nor newline) in between + if (al.getElements().isEmpty()) { + document.append(bracketPair.getKey(), f -> f.noSpace()); + document.prepend(bracketPair.getValue(), f -> f.noSpace()); + return; + } + + // put closing bracket on a separate line + document.prepend(bracketPair.getValue(), f -> f.newLine()); + } + + // put every array element on a separate line + for (JSONValue val : al.getElements()) { + document.prepend(val, f -> f.newLine()); + } + // recursively format each element + for (JSONValue val : al.getElements()) { + document.format(val); + } + } + + /** On the direct level of an semantic Object enforce commas to ", " with autoWrap option. */ + private void configureCommas(EObject semEObject, IFormattableDocument document) { + for (ISemanticRegion sr : textRegionExtensions.regionFor(semEObject).keywords(",")) { + document.prepend(sr, f -> f.noSpace()); + document.append(sr, f -> { + f.oneSpace(); + f.autowrap(); + }); + } + } + + /** Put both curly braces and every name-value-pair of a JSONObject on a separate line. */ + public void format(JSONObject ol, IFormattableDocument document) { + configureCommas(ol, document); + + Pair bracePair = textRegionExtensions.regionFor(ol).keywordPairs("{", "}") + .get(0); + + // if bracePair can be determined + if (bracePair != null) { + document.interior(bracePair, f -> f.indent()); + + // format empty objects to be a brace pair without space (nor newline) in between + if (ol.getNameValuePairs().isEmpty()) { + document.append(bracePair.getKey(), f -> f.noSpace()); + document.prepend(bracePair.getValue(), f -> f.noSpace()); + return; + } + + document.prepend(bracePair.getValue(), f -> f.newLine()); // format WS in front of closing brace + for (NameValuePair nvp : ol.getNameValuePairs()) { + document.prepend(nvp, f -> f.newLine()); + } + + if (bracePair.getKey() != null + && bracePair.getKey().getNextSemanticRegion() == bracePair.getValue()) { + // empty multiline, trigger formatting: + document.append(bracePair.getKey(), f -> f.newLine()); + } + } + + // recursively format each name-value pair + for (NameValuePair nvp : ol.getNameValuePairs()) { + document.format(nvp); + } + } + + /***/ + public void format(NameValuePair nameValuePair, IFormattableDocument document) { + ISemanticRegion colon = textRegionExtensions.regionFor(nameValuePair).keyword(":"); + JSONValue value = nameValuePair.getValue(); + + document.prepend(colon, f -> f.noSpace()); + document.append(colon, f -> f.oneSpace()); + + document.format(value); + } +} diff --git a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/formatting2/JSONFormatter.xtend b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/formatting2/JSONFormatter.xtend deleted file mode 100644 index f1b089761f..0000000000 --- a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/formatting2/JSONFormatter.xtend +++ /dev/null @@ -1,114 +0,0 @@ -/** - * Copyright (c) 2017 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.json.formatting2 - -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.json.JSON.JSONArray -import org.eclipse.n4js.json.JSON.JSONDocument -import org.eclipse.n4js.json.JSON.JSONObject -import org.eclipse.n4js.json.JSON.NameValuePair -import org.eclipse.xtext.formatting2.AbstractFormatter2 -import org.eclipse.xtext.formatting2.IFormattableDocument - -/** - * A simple formatter for JSON files. - * - * Generally, puts name-value-pairs of objects and array elements - * on a separate line. - */ -class JSONFormatter extends AbstractFormatter2 { - - /** */ - def dispatch void format(JSONDocument jSONDocument, extension IFormattableDocument document) { - // make sure all document elements are formatted - jSONDocument.getContent.format; - jSONDocument.allSemanticRegions.forEach[it.append[indent]] - } - - /** Put both brackets and every element of a JSONArray on a separate line. */ - def dispatch void format(JSONArray al, extension IFormattableDocument document) { - // avoid comma-only lines - al.configureCommas(document); - - val bracketPair = al.regionFor.keywordPairs("[", "]").head; - - // if bracePair can be determined - if (bracketPair !== null) { - // indent array elements - bracketPair.interior[indent]; - - // format empty arrays to be a bracket pair without space (nor newline) in between - if (al.elements.empty) { - bracketPair.key.append[noSpace] - bracketPair.value.prepend[noSpace] - return; - } - - // put closing bracket on a separate line - bracketPair.value.prepend[newLine]; - } - - // put every array element on a separate line - al.elements.forEach[it, num|prepend[newLine]]; - // recursively format each element - al.elements.forEach[it|format(it)] - - - } - - /** On the direct level of an semantic Object enforce commas to ", " with autoWrap option. */ - private def void configureCommas(EObject semEObject, extension IFormattableDocument document) { - semEObject.regionFor.keywords(",").forEach [ - prepend[noSpace]; - append[oneSpace; autowrap]; - ]; - } - - /** Put both curly braces and every name-value-pair of a JSONObject on a separate line. */ - def dispatch void format(JSONObject ol, extension IFormattableDocument document) { - ol.configureCommas(document); - - val bracePair = ol.regionFor.keywordPairs("{", "}").head; - - // if bracePair can be determined - if (bracePair !== null) { - bracePair?.interior[indent]; - - // format empty objects to be a brace pair without space (nor newline) in between - if (ol.nameValuePairs.empty) { - bracePair.key.append[noSpace] - bracePair.value.prepend[noSpace] - return; - } - - bracePair?.value.prepend[newLine]; // format WS in front of closing brace - ol.nameValuePairs.forEach[it, num|prepend[newLine]]; - - if (bracePair?.key?.nextSemanticRegion == bracePair?.value) { - // empty multiline, trigger formatting: - bracePair.key.append[newLine]; - } - } - - // recursively format each name-value pair - ol.nameValuePairs.forEach[format(it)]; - } - - def dispatch void format(NameValuePair nameValuePair, extension IFormattableDocument document) { - val colon = nameValuePair.regionFor.keyword(":"); - val value = nameValuePair.value; - - colon.prepend[noSpace]; - colon.append[oneSpace]; - - format(value) - } -} diff --git a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionManager.java b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionManager.java new file mode 100644 index 0000000000..19028a488a --- /dev/null +++ b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionManager.java @@ -0,0 +1,34 @@ +package org.eclipse.n4js.json.resource; + +import java.util.Collection; + +import org.eclipse.n4js.json.extension.IJSONResourceDescriptionExtension; +import org.eclipse.n4js.json.extension.JSONExtensionRegistry; +import org.eclipse.xtext.resource.IResourceDescription; +import org.eclipse.xtext.resource.IResourceDescription.Delta; +import org.eclipse.xtext.resource.IResourceDescriptions; +import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionManager; + +import com.google.inject.Inject; + +/** + * Resource description manager for JSON files. Delegates to registered JSON extensions. + */ +public class JSONResourceDescriptionManager extends DefaultResourceDescriptionManager { + + @Inject + private JSONExtensionRegistry extensionRegistry; + + /** + * Delegates to registered resource description extensions. + */ + @Override + public boolean isAffected(Collection deltas, IResourceDescription candidate, IResourceDescriptions context) { + for (IJSONResourceDescriptionExtension ext : extensionRegistry.getResourceDescriptionExtensions()) { + if (ext.isAffected(deltas, candidate, context)) { + return true; + } + } + return false; + } +} diff --git a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionManager.xtend b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionManager.xtend deleted file mode 100644 index 8ee0858a32..0000000000 --- a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionManager.xtend +++ /dev/null @@ -1,31 +0,0 @@ -package org.eclipse.n4js.json.resource - -import com.google.inject.Inject -import java.util.Collection -import org.eclipse.n4js.json.^extension.JSONExtensionRegistry -import org.eclipse.xtext.resource.IResourceDescription -import org.eclipse.xtext.resource.IResourceDescription.Delta -import org.eclipse.xtext.resource.IResourceDescriptions -import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionManager - -/** - * Resource description manager for JSON files. Delegates to registered JSON extensions. - */ -class JSONResourceDescriptionManager extends DefaultResourceDescriptionManager { - - @Inject - private JSONExtensionRegistry extensionRegistry; - - /** - * Delegates to registered resource description extensions. - */ - override boolean isAffected(Collection deltas, IResourceDescription candidate, - IResourceDescriptions context) { - for (ext : extensionRegistry.resourceDescriptionExtensions) { - if (ext.isAffected(deltas, candidate, context)) { - return true; - } - } - return false; - } -} diff --git a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionStrategy.java b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionStrategy.java new file mode 100644 index 0000000000..be70273c80 --- /dev/null +++ b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionStrategy.java @@ -0,0 +1,33 @@ +package org.eclipse.n4js.json.resource; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.json.JSON.JSONDocument; +import org.eclipse.n4js.json.extension.IJSONResourceDescriptionExtension; +import org.eclipse.n4js.json.extension.JSONExtensionRegistry; +import org.eclipse.xtext.resource.IEObjectDescription; +import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionStrategy; +import org.eclipse.xtext.util.IAcceptor; + +import com.google.inject.Inject; + +/** + * JSON resource description strategy based on {@link IJSONResourceDescriptionExtension}. + * + * Does nothing per default, except for the case in which an extension provides a custom resource description. + */ +public class JSONResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy { + + @Inject + private JSONExtensionRegistry extensionRegistry; + + /** Delegates to registered resource description extensions. */ + @Override + public boolean createEObjectDescriptions(EObject eObject, IAcceptor acceptor) { + if (eObject instanceof JSONDocument) { + for (IJSONResourceDescriptionExtension ext : extensionRegistry.getResourceDescriptionExtensions()) { + ext.createJSONDocumentDescriptions((JSONDocument) eObject, acceptor); + } + } + return false; + } +} diff --git a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionStrategy.xtend b/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionStrategy.xtend deleted file mode 100644 index d30ef6a95b..0000000000 --- a/plugins/org.eclipse.n4js.json/src/org/eclipse/n4js/json/resource/JSONResourceDescriptionStrategy.xtend +++ /dev/null @@ -1,31 +0,0 @@ -package org.eclipse.n4js.json.resource - -import com.google.inject.Inject -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.json.JSON.JSONDocument -import org.eclipse.n4js.json.^extension.IJSONResourceDescriptionExtension -import org.eclipse.n4js.json.^extension.JSONExtensionRegistry -import org.eclipse.xtext.resource.IEObjectDescription -import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionStrategy -import org.eclipse.xtext.util.IAcceptor - -/** - * JSON resource description strategy based on {@link IJSONResourceDescriptionExtension}. - * - * Does nothing per default, except for the case in which an extension provides a custom resource description. - */ -public class JSONResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy { - - @Inject - private JSONExtensionRegistry extensionRegistry; - - /** Delegates to registered resource description extensions. */ - override createEObjectDescriptions(EObject eObject, IAcceptor acceptor) { - if (eObject instanceof JSONDocument) { - for (ext : extensionRegistry.resourceDescriptionExtensions) { - ext.createJSONDocumentDescriptions(eObject, acceptor); - } - } - return false; - } -} diff --git a/plugins/org.eclipse.n4js.json/xtend-gen/.gitignore b/plugins/org.eclipse.n4js.json/xtend-gen/.gitignore deleted file mode 100644 index d6b7ef32c8..0000000000 --- a/plugins/org.eclipse.n4js.json/xtend-gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/plugins/org.eclipse.n4js.model/.classpath b/plugins/org.eclipse.n4js.model/.classpath index 8b5d45b17c..af27bdbd59 100644 --- a/plugins/org.eclipse.n4js.model/.classpath +++ b/plugins/org.eclipse.n4js.model/.classpath @@ -1,6 +1,5 @@ - diff --git a/plugins/org.eclipse.n4js.model/build.properties b/plugins/org.eclipse.n4js.model/build.properties index 974cddd650..4bd779cde3 100644 --- a/plugins/org.eclipse.n4js.model/build.properties +++ b/plugins/org.eclipse.n4js.model/build.properties @@ -1,6 +1,5 @@ source.. = src/,\ - emf-gen/,\ - xtend-gen + emf-gen/ bin.includes = META-INF/,\ .,\ plugin.xml,\ diff --git a/plugins/org.eclipse.n4js.model/pom.xml b/plugins/org.eclipse.n4js.model/pom.xml index 936d0056b1..6d70b4cdff 100644 --- a/plugins/org.eclipse.n4js.model/pom.xml +++ b/plugins/org.eclipse.n4js.model/pom.xml @@ -38,11 +38,6 @@ Contributors: maven-resources-plugin ${maven-resources-plugin.version} - - org.eclipse.xtend - xtend-maven-plugin - - diff --git a/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/DestructNode.java b/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/DestructNode.java new file mode 100644 index 0000000000..4592294f0d --- /dev/null +++ b/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/DestructNode.java @@ -0,0 +1,641 @@ +/** + * 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.n4JS; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.head; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Stream; + +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.n4js.ts.types.TypableElement; +import org.eclipse.xtend.lib.annotations.Data; +import org.eclipse.xtext.xbase.lib.Pair; +import org.eclipse.xtext.xbase.lib.util.ToStringBuilder; + +/** + * Destructuring patterns can appear in very different forms within the AST and in different contexts. This helper class + * is used to transform those heterogeneous representations into a single, uniform structure, that can be traversed more + * easily. + *

+ * All fields are optional, i.e. may be 'null'. At most one of 'varRef', 'varDecl' and 'nestedPattern' may be non-null; + * if all three are 'null' the node is a padding node. + * + *

Overview of Destructuring Patterns in the AST

Different forms: + *
    + *
  1. as a {@link BindingPattern} (may contain nested {@code BindingPattern}s). + *
  2. as an {@link ArrayLiteral} (may contain nested patterns in form of {@code ArrayLiteral}s or + * {@code ObjectLiteral}s). + *
  3. as an {@link ObjectLiteral} (may contain nested patterns in form of {@code ArrayLiteral}s or + * {@code ObjectLiteral}s). + *
+ * Different contexts: + *
    + *
  1. within a {@link VariableStatement} (then contained in a {@link VariableBinding}, which is an alternative to a + * {@link VariableDeclaration}). + *
  2. within an {@link AssignmentExpression} (then it appears as the left-hand side expression) + *
  3. within a {@link ForStatement} (only in for..in and for..of, because if used in plain for it is a use case of a + * variable statement or assignment expression inside the for statement). + *
  4. NOT SUPPORTED YET: in the context of lists of formal parameters or function argument lists + *
+ * The above 6 use cases have several special characteristics and constraints, most of which are unified in this class. + * It might be possible to generate more unified patterns in the parser, but the above situation is more in line with + * terminology in the ES6 specification. + *

+ */ +@Data +@SuppressWarnings("javadoc") +public class DestructNode { + final public EObject astElement; + // property name (iff in object destructuring pattern) or 'null' (iff in array destructuring pattern) + final public String propName; + final public IdentifierRef varRef; + final public VariableDeclaration varDecl; + // nested pattern that will be bound/assigned (or 'null' iff 'varName' is non-null) + final public DestructNode[] nestedNodes; + final public Expression defaultExpr; + // can be an Expression or an IdentifiableElement (in case of Getter/Setter/Method) + final public TypableElement assignedElem; + final public boolean rest; + + public DestructNode(EObject astElement, String propName, IdentifierRef varRef, VariableDeclaration varDecl, + DestructNode[] nestedNodes, Expression defaultExpr, TypableElement assignedElem, boolean rest) { + + this.astElement = astElement; + this.propName = propName; + this.varRef = varRef; + this.varDecl = varDecl; + this.nestedNodes = nestedNodes; + this.defaultExpr = defaultExpr; + this.assignedElem = assignedElem; + this.rest = rest; + } + + /** + * Returns true if if receiving node belongs to a positional destructuring pattern (i.e. an array destructuring + * pattern). + */ + public boolean isPositional() { + return propName == null; + } + + /** + * Returns true if if the given nodes belong to a positional destructuring pattern (i.e. an array destructuring + * pattern). + */ + static public boolean arePositional(List nodes) { + return nodes != null && exists(nodes, n -> n.isPositional()); + } + + /** + * Returns true if if this is a padding node. + */ + public boolean isPadding() { + return varRef == null && varDecl == null && nestedNodes == null; + } + + /** + * If this node has a reference to a variable or a variable declaration, returns the variable's name, + * null otherwise. + */ + public String varName() { + if (varRef != null) { + return varRef.getId() == null ? null : varRef.getId().getName(); + } else if (varDecl != null) { + return varDecl.getName(); + } + return null; + } + + /** + * Returns the variable declaration contained in this node's astElement or null. + */ + public VariableDeclaration getVariableDeclaration() { + if (astElement instanceof BindingElement) { + return ((BindingElement) astElement).getVarDecl(); + } + if (astElement instanceof BindingProperty && ((BindingProperty) astElement).getValue() != null) { + return ((BindingProperty) astElement).getValue().getVarDecl(); + } + return null; + } + + /** + * Returns the AST node and EStructuralFeature to be used when showing an error message on the receiving node's + * propName attribute. Intended for issue generation in validations. + */ + public Pair getEObjectAndFeatureForPropName() { + if (propName != null) { + if (astElement instanceof PropertyNameValuePairSingleName) { + PropertyNameValuePairSingleName pnvpsn = (PropertyNameValuePairSingleName) astElement; + if (pnvpsn.getExpression() instanceof AssignmentExpression) { + return Pair.of(pnvpsn.getExpression(), N4JSPackage.eINSTANCE.getAssignmentExpression_Lhs()); + } + } + if (astElement instanceof PropertyNameValuePairSingleName) { + return Pair.of(astElement, N4JSPackage.eINSTANCE.getPropertyNameValuePair_Expression()); + } + if (astElement instanceof BindingProperty) { + BindingProperty bp = (BindingProperty) astElement; + + if (bp.getDeclaredName() != null) { + return Pair.of(bp, N4JSPackage.eINSTANCE.getPropertyNameOwner_DeclaredName()); + } + if (bp.getProperty() != null) { + return Pair.of(bp, N4JSPackage.eINSTANCE.getBindingProperty_Property()); + } + if (bp.getValue() != null && bp.getValue().getVarDecl() != null + && bp.getValue().getVarDecl().getName() != null) { + return Pair.of(bp.getValue().getVarDecl(), N4JSPackage.eINSTANCE.getAbstractVariable_Name()); + } + } + if (astElement instanceof PropertyNameValuePair + && ((PropertyNameValuePair) astElement).getProperty() != null) { + + return Pair.of(astElement, N4JSPackage.eINSTANCE.getPropertyNameValuePair_Property()); + } + if (astElement instanceof PropertyNameOwner) { + return Pair.of(astElement, N4JSPackage.eINSTANCE.getPropertyNameOwner_DeclaredName()); + } + } + return Pair.of(astElement, null);// show error on entire node + } + + /** + * Returns the node with the given astElement. + */ + public DestructNode findNodeForElement(EObject pAstElement) { + return findNodeOrParentForElement(pAstElement, false); + } + + /** + * Returns the node with the given astElement or its parent node. + */ + public DestructNode findNodeOrParentForElement(EObject pAstElement, boolean returnParent) { + EObject reprAstElem = pAstElement; + if (pAstElement instanceof BindingElement && pAstElement.eContainer() instanceof BindingProperty) { + reprAstElem = pAstElement.eContainer(); + } + + if (this.astElement == reprAstElem) { + if (returnParent) { + return null; + } + return this; + } + if (this.nestedNodes == null) { + return null; + } + for (DestructNode nested : this.nestedNodes) { + if (nested.astElement == reprAstElem) { + if (returnParent) { + return this; + } + return nested; + } + DestructNode resNested = nested.findNodeOrParentForElement(reprAstElem, returnParent); + if (resNested != null) { + return resNested; + } + } + return null; + } + + /** + * Returns stream of this node and all its descendants, i.e. directly and indirectly nested nodes. + */ + public Stream stream() { + if (nestedNodes == null) { + return Stream.of(this); + } else { + return Stream.concat(Stream.of(this), Stream.of(nestedNodes).flatMap(dn -> dn.stream())); + } + } + + public static DestructNode unify(EObject eobj) { + if (eobj instanceof VariableBinding) { + return unify((VariableBinding) eobj); + } + if (eobj instanceof AssignmentExpression) { + return unify((AssignmentExpression) eobj); + } + if (eobj instanceof ForStatement) { + return unify((ForStatement) eobj); + } + return null; + } + + /** + * Returns a unified copy of the given destructuring pattern or null if it is invalid. This is helpful + * because these patterns can appear in very different forms and locations within the AST. + */ + public static DestructNode unify(EObject astElem, EObject lhs, Expression rhs) { + return new DestructNode( + astElem, // astElement + null, // propName + null, // varRef + null, // varDecl + toEntries(lhs, rhs), // nestedNodes + rhs, // defaultExpr + rhs, // assignedExpr + false // rest + ); + } + + /** + * Returns a unified copy of the given destructuring pattern or null if it is invalid. This is helpful + * because these patterns can appear in very different forms and locations within the AST. + */ + public static DestructNode unify(VariableBinding binding) { + if (binding != null && binding.getPattern() != null + // note: binding.expression is mandatory in variable statements + // but optional in for..in/of statements + && (binding.getExpression() != null || binding.eContainer() instanceof ForStatement)) { + + return unify(binding, binding.getPattern(), binding.getExpression()); + } + return null; + } + + /** + * Returns a unified copy of the given destructuring pattern or null if it is invalid. This is helpful + * because these patterns can appear in very different forms and locations within the AST. + */ + public static DestructNode unify(AssignmentExpression assignExpr) { + if (assignExpr != null && assignExpr.getLhs() != null && assignExpr.getRhs() != null + && DestructureUtils.isTopOfDestructuringAssignment(assignExpr)) { + + return unify(assignExpr, assignExpr.getLhs(), assignExpr.getRhs()); + } + return null; + } + + /** + * Returns a unified copy of the given destructuring pattern or null if it is invalid. This is helpful + * because these patterns can appear in very different forms and locations within the AST. + */ + public static DestructNode unify(ForStatement forStmnt) { + if (forStmnt != null && DestructureUtils.isTopOfDestructuringForStatement(forStmnt)) { + Expression valueToBeDestructured; + Expression defaultExpression; + + if (forStmnt.isForOf()) { + valueToBeDestructured = firstArrayElement(forStmnt.getExpression()); + defaultExpression = forStmnt.getExpression(); + } else if (forStmnt.isForIn()) { + StringLiteral slit1 = N4JSFactory.eINSTANCE.createStringLiteral(); + slit1.setValue(""); + valueToBeDestructured = slit1; + + StringLiteral slit2 = N4JSFactory.eINSTANCE.createStringLiteral(); + slit2.setValue(""); + defaultExpression = slit2; + } else { + // impossible because #isTopOfDestructuringForStatement() returned true + throw new IllegalStateException(); + } + + if (DestructureUtils.containsDestructuringPattern(forStmnt)) { + // case: for(var [a,b] of arr) {} + VariableBinding binding = head(filter(forStmnt.getVarDeclsOrBindings(), VariableBinding.class)); + Expression rhs = firstArrayElement(forStmnt.getExpression()); + return new DestructNode( + forStmnt, // astElement + null, // propName + null, // varRef + null, // varDecl + toEntries(binding.getPattern(), rhs), // nestedNodes + defaultExpression, // defaultExpr + valueToBeDestructured, // assignedExpr + false // rest + ); + } else if (DestructureUtils.isObjectOrArrayLiteral(forStmnt.getInitExpr())) { + // case: for([a,b] of arr) {} + return new DestructNode( + forStmnt, // astElement + null, // propName + null, // varRef + null, // varDecl + toEntries(forStmnt.getInitExpr(), null), // nestedNodes + defaultExpression, // defaultExpr + defaultExpression, // assignedExpr + false // rest + ); + } + } + return null; + } + + private static Expression firstArrayElement(Expression expr) { + return (expr instanceof ArrayLiteral) ? ((ArrayLiteral) expr).getElements().get(0).getExpression() : expr; + } + + private static DestructNode[] toEntries(EObject pattern, TypableElement rhs) { + Iterator patElemIter = null; + if (pattern instanceof ArrayLiteral) { + patElemIter = ((ArrayLiteral) pattern).getElements().iterator(); + } else if (pattern instanceof ObjectLiteral) { + patElemIter = ((ObjectLiteral) pattern).getPropertyAssignments().iterator(); + } else if (pattern instanceof ArrayBindingPattern) { + patElemIter = ((ArrayBindingPattern) pattern).getElements().iterator(); + } else if (pattern instanceof ObjectBindingPattern) { + patElemIter = ((ObjectBindingPattern) pattern).getProperties().iterator(); + } else { + return null; + } + + Iterator rhsElemIter = null; + if (rhs instanceof ArrayLiteral) { + rhsElemIter = ((ArrayLiteral) rhs).getElements().iterator(); + } + if (rhs instanceof ObjectLiteral) { + rhsElemIter = ((ObjectLiteral) rhs).getPropertyAssignments().iterator(); + } + + BasicEList nestedDNs = new BasicEList<>(); + while (patElemIter.hasNext()) { + EObject patElem = patElemIter.next(); + TypableElement litElem = (rhsElemIter == null) ? rhs : (rhsElemIter.hasNext()) ? rhsElemIter.next() : null; + + DestructNode nestedNode = null; + if (patElem instanceof ArrayElement) { + nestedNode = toEntry((ArrayElement) patElem, litElem); + } + if (patElem instanceof PropertyNameValuePair) { + nestedNode = toEntry((PropertyNameValuePair) patElem, litElem); + } + if (patElem instanceof BindingElement) { + nestedNode = toEntry((BindingElement) patElem, litElem); + } + if (patElem instanceof BindingProperty) { + nestedNode = toEntry((BindingProperty) patElem, litElem); + } + + if (nestedNode != null) { + nestedDNs.add(nestedNode); + } + } + return nestedDNs.toArray(new DestructNode[0]); + } + + private static DestructNode toEntry(ArrayElement elem, TypableElement rhs) { + TypableElement rhsExpr = (rhs instanceof ArrayElement) ? ((ArrayElement) rhs).getExpression() : rhs; + Expression expr = elem.getExpression(); // note: ArrayPadding will return null for getExpression() + if (expr instanceof AssignmentExpression) { + AssignmentExpression ae = (AssignmentExpression) expr; + return toEntry(elem, null, ae.getLhs(), ae.getRhs(), elem.isSpread(), rhsExpr); + } else { + return toEntry(elem, null, expr, null, elem.isSpread(), rhsExpr); + } + } + + private static DestructNode toEntry(PropertyNameValuePair pa, TypableElement rhs) { + TypableElement rhsExpr = (rhs instanceof PropertyNameValuePair) + ? ((PropertyNameValuePair) rhs).getExpression() + : rhs; + Expression expr = pa.getExpression(); + if (expr instanceof AssignmentExpression) { + AssignmentExpression ae = (AssignmentExpression) expr; + return toEntry(pa, pa.getName(), ae.getLhs(), ae.getRhs(), false, rhsExpr); + } else { + return toEntry(pa, pa.getName(), expr, null, false, rhsExpr); + } + } + + private static DestructNode toEntry(BindingElement elem, TypableElement rhs) { + TypableElement expr = (rhs instanceof ArrayElement) ? ((ArrayElement) rhs).getExpression() : rhs; + + if (elem.getVarDecl() != null) { + return toEntry(elem, null, elem.getVarDecl(), elem.getVarDecl().getExpression(), elem.isRest(), expr); + } else if (elem.getNestedPattern() != null) { + return toEntry(elem, null, elem.getNestedPattern(), elem.getExpression(), elem.isRest(), expr); + } else { + return toEntry(elem, null, null, null, false, expr); // return dummy entry to not break indices + } + } + + private static DestructNode toEntry(BindingProperty prop, TypableElement rhs) { + if (prop.getValue() != null && prop.getValue().getVarDecl() != null) { + TypableElement expr = getPropertyAssignmentExpression(rhs); + return toEntry(prop, prop.getName(), prop.getValue().getVarDecl(), + prop.getValue().getVarDecl().getExpression(), false, expr); + + } else if (prop.getValue() != null && prop.getValue().getNestedPattern() != null) { + TypableElement expr = getPropertyAssignmentExpression(rhs); + return toEntry(prop, prop.getName(), prop.getValue().getNestedPattern(), prop.getValue().getExpression(), + false, expr); + + } else { + return toEntry(prop, null, null, null, false, rhs); + } + } + + /** + * @param bindingTarget + * an IdentifierRef/VariableDeclaration or a nested pattern (which may be a BindingPattern, ArrayLiteral, + * or ObjectLiteral) + */ + private static DestructNode toEntry(EObject astElement, String propName, EObject bindingTarget, + Expression defaultExpr, boolean rest, TypableElement rhs) { + + if (bindingTarget == null) { + // no target -> create a padding node + return new DestructNode(astElement, propName, null, null, null, defaultExpr, null, rest); + + } else if (bindingTarget instanceof IdentifierRef) { + return new DestructNode(astElement, propName, (IdentifierRef) bindingTarget, null, null, defaultExpr, rhs, + rest); + + } else if (bindingTarget instanceof VariableDeclaration) { + return new DestructNode(astElement, propName, null, (VariableDeclaration) bindingTarget, null, defaultExpr, + rhs, rest); + + } else if (bindingTarget instanceof ArrayLiteral || bindingTarget instanceof ObjectLiteral || + bindingTarget instanceof BindingPattern) { + return new DestructNode(astElement, propName, null, null, toEntries(bindingTarget, rhs), defaultExpr, rhs, + rest); + + } else { + // invalid binding target (probably a corrupt AST) -> create a padding node + return new DestructNode(astElement, propName, null, null, null, defaultExpr, null, rest); + } + } + + /** @return the expression or function of the given PropertyAssignment */ + private static TypableElement getPropertyAssignmentExpression(TypableElement rhs) { + if (rhs instanceof PropertyGetterDeclaration) { + return ((PropertyGetterDeclaration) rhs).getDefinedFunctionOrAccessor(); + } + if (rhs instanceof PropertySetterDeclaration) { + return ((PropertySetterDeclaration) rhs).getDefinedFunctionOrAccessor(); + } + if (rhs instanceof PropertyMethodDeclaration) { + return ((PropertyMethodDeclaration) rhs).getDefinedFunctionOrAccessor(); + } + if (rhs instanceof PropertyNameValuePair) { + return ((PropertyNameValuePair) rhs).getExpression(); + } + if (rhs instanceof PropertyAssignmentAnnotationList) { + return null; + } + + return rhs; + } + + /** @return all {@link IdentifierRef} of variables that are written in the given assignment */ + public List getAllDeclaredIdRefs() { + List idRefs = new LinkedList<>(); + Iterator allNestedNodes = this.stream().iterator(); + + while (allNestedNodes.hasNext()) { + EObject eobj = allNestedNodes.next().astElement; + if (eobj instanceof ArrayElement) { + Expression expr = ((ArrayElement) eobj).getExpression(); + if (expr instanceof AssignmentExpression) { + idRefs.add((((AssignmentExpression) expr).getLhs())); + } else { + idRefs.add(expr); + } + + } else if (eobj instanceof PropertyNameValuePairSingleName) { + idRefs.add(((PropertyNameValuePairSingleName) eobj).getIdentifierRef()); + + } else if (eobj instanceof PropertyNameValuePair) { + Expression expr = ((PropertyNameValuePair) eobj).getExpression(); + if (expr instanceof AssignmentExpression) { + idRefs.add(((AssignmentExpression) expr).getLhs()); + } else { + idRefs.add(expr); + } + } + } + return idRefs; + } + + /** + * @return a pair where its key is the assigned EObject and its value is the default EObject to the given lhs AST + * element + */ + public static Pair getValueFromDestructuring(EObject nodeElem) { + EObject node = nodeElem; + EObject topNode = null; + EObject dNodeElem = null; + boolean breakSearch = false; + + while (!breakSearch) { + EObject parent = node.eContainer(); + dNodeElem = getDNodeElem(dNodeElem, parent, node); + topNode = getTopElem(topNode, parent); + breakSearch = parent instanceof Statement; + node = parent; + } + + DestructNode dNode = null; + if (topNode instanceof AssignmentExpression) { + dNode = DestructNode.unify(topNode); + } else if (topNode instanceof VariableBinding) { + dNode = DestructNode.unify(topNode); + } else if (topNode instanceof ForStatement) { + dNode = DestructNode.unify(topNode); + } + + if (dNode != null) { + dNode = dNode.findNodeForElement(dNodeElem); + if (dNode != null) { + EObject assgnValue = dNode.assignedElem; + EObject defaultValue = dNode.defaultExpr; + return Pair.of(assgnValue, defaultValue); + } + } + + return null; + } + + private static EObject getDNodeElem(EObject dNodeElem, EObject parent, EObject node) { + if (dNodeElem != null) { + return dNodeElem; + } + if (node instanceof BindingElement && parent instanceof BindingProperty) { + return parent; + } + if (node instanceof BindingElement || node instanceof ArrayElement || node instanceof PropertyAssignment) { + return node; + } + return null; + } + + private static EObject getTopElem(EObject oldTopNode, EObject parent) { + EObject newTopNode = null; + if (parent instanceof ForStatement) { + newTopNode = parent; + } + if (parent instanceof AssignmentExpression) { + newTopNode = parent; + } + if (parent instanceof VariableBinding) { + newTopNode = parent; + } + + if (newTopNode != null) { + return newTopNode; + } else { + return oldTopNode; + } + } + + public static List getAllDeclaredIdRefs(EObject eobj) { + DestructNode dnode = null; + if (eobj instanceof ForStatement) { + dnode = unify(eobj); + } + if (eobj instanceof VariableBinding) { + dnode = unify(eobj); + } + if (eobj instanceof AssignmentExpression) { + dnode = unify(eobj); + } + + if (dnode == null) { + return Collections.emptyList(); + } + return dnode.getAllDeclaredIdRefs(); + } + + @Override + public String toString() { + ToStringBuilder b = new ToStringBuilder(this); + b.add("astElement", this.astElement); + b.add("propName", this.propName); + b.add("varRef", this.varRef); + b.add("varDecl", this.varDecl); + b.add("nestedNodes", this.nestedNodes); + b.add("defaultExpr", this.defaultExpr); + b.add("assignedElem", this.assignedElem); + b.add("rest", this.rest); + return b.toString(); + } + + public List getNestedNodes() { + if (nestedNodes == null) { + return Collections.emptyList(); + } + return Arrays.asList(this.nestedNodes); + } + +} diff --git a/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/DestructNode.xtend b/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/DestructNode.xtend deleted file mode 100644 index 648f3500a9..0000000000 --- a/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/DestructNode.xtend +++ /dev/null @@ -1,547 +0,0 @@ -/** - * 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.n4JS - -import java.util.Iterator -import java.util.LinkedList -import java.util.List -import java.util.stream.Stream -import org.eclipse.emf.common.util.BasicEList -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.EStructuralFeature -import org.eclipse.n4js.ts.types.TypableElement -import org.eclipse.xtend.lib.annotations.Data - -/** - * Destructuring patterns can appear in very different forms within the AST and in different contexts. - * This helper class is used to transform those heterogeneous representations into a single, uniform - * structure, that can be traversed more easily. - *

- * All fields are optional, i.e. may be 'null'. At most one of 'varRef', 'varDecl' and 'nestedPattern' - * may be non-null; if all three are 'null' the node is a padding node. - * - *

Overview of Destructuring Patterns in the AST

- * Different forms: - *
    - *
  1. as a {@link BindingPattern} (may contain nested {@code BindingPattern}s). - *
  2. as an {@link ArrayLiteral} (may contain nested patterns in form of {@code ArrayLiteral}s or {@code ObjectLiteral}s). - *
  3. as an {@link ObjectLiteral} (may contain nested patterns in form of {@code ArrayLiteral}s or {@code ObjectLiteral}s). - *
- * Different contexts: - *
    - *
  1. within a {@link VariableStatement} (then contained in a {@link VariableBinding}, which is an alternative - * to a {@link VariableDeclaration}). - *
  2. within an {@link AssignmentExpression} (then it appears as the left-hand side expression) - *
  3. within a {@link ForStatement} (only in for..in and for..of, because if used in plain for it is a use case - * of a variable statement or assignment expression inside the for statement). - *
  4. NOT SUPPORTED YET: in the context of lists of formal parameters or function argument lists - *
- * The above 6 use cases have several special characteristics and constraints, most of which are unified in this class. - * It might be possible to generate more unified patterns in the parser, but the above situation is more in line with - * terminology in the ES6 specification. - *

- */ -@Data -public class DestructNode { - EObject astElement; - String propName; // property name (iff in object destructuring pattern) or 'null' (iff in array destructuring pattern) - IdentifierRef varRef; - VariableDeclaration varDecl; - DestructNode[] nestedNodes; // nested pattern that will be bound/assigned (or 'null' iff 'varName' is non-null) - Expression defaultExpr; - TypableElement assignedElem; // can be an Expression or an IdentifiableElement (in case of Getter/Setter/Method) - boolean rest; - - /** - * Tells if receiving node belongs to a positional destructuring pattern - * (i.e. an array destructuring pattern). - */ - def boolean isPositional() { - propName === null - } - - /** - * Tells if the given nodes belong to a positional destructuring pattern - * (i.e. an array destructuring pattern). - */ - static def boolean arePositional(DestructNode[] nodes) { - nodes !== null && nodes.exists[positional] - } - - /** - * Tells if this is a padding node. - */ - def boolean isPadding() { - varRef === null && varDecl === null && nestedNodes === null - } - - /** - * If this node has a reference to a variable or a variable declaration, - * returns the variable's name, null otherwise. - */ - def String varName() { - if (varRef !== null) - varRef.id?.name - else if (varDecl !== null) - varDecl.name - } - - /** - * Returns the variable declaration contained in this node's astElement or null. - */ - def VariableDeclaration getVariableDeclaration() { - switch (astElement) { - BindingElement: - astElement.varDecl - BindingProperty case astElement.value !== null: - astElement.value.varDecl - } - } - - /** - * Returns the AST node and EStructuralFeature to be used when showing an error message - * on the receiving node's propName attribute. Intended for issue generation in validations. - */ - def Pair getEObjectAndFeatureForPropName() { - if (propName !== null) { - switch (astElement) { - PropertyNameValuePairSingleName case astElement.expression instanceof AssignmentExpression: - astElement.expression -> N4JSPackage.eINSTANCE.assignmentExpression_Lhs - PropertyNameValuePairSingleName: - astElement -> N4JSPackage.eINSTANCE.propertyNameValuePair_Expression - BindingProperty case astElement.declaredName !== null: - astElement -> N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName - BindingProperty case astElement.property !== null: - astElement -> N4JSPackage.eINSTANCE.bindingProperty_Property - BindingProperty case astElement.value?.varDecl?.name !== null: - astElement.value.varDecl -> N4JSPackage.eINSTANCE.abstractVariable_Name - PropertyNameValuePair case astElement.property !== null: - astElement -> N4JSPackage.eINSTANCE.propertyNameValuePair_Property - PropertyNameOwner: - astElement -> N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName - default: - astElement -> null // show error on entire node - } - } else { - astElement -> null // show error on entire node - } - } - - /** - * Returns the node with the given astElement. - */ - def DestructNode findNodeForElement(EObject astElement) { - return findNodeOrParentForElement(astElement, false); - } - - /** - * Returns the node with the given astElement or its parent node. - */ - def DestructNode findNodeOrParentForElement(EObject astElement, boolean returnParent) { - val reprAstElem = if (astElement instanceof BindingElement && astElement.eContainer instanceof BindingProperty) - astElement.eContainer else astElement; - - if (this.astElement === reprAstElem) { - if (returnParent) { - return null; - } - return this; - } - if (this.nestedNodes === null) { - return null; - } - for (nested : this.nestedNodes) { - if (nested.astElement === reprAstElem) { - if (returnParent) { - return this; - } - return nested; - } - val resNested = nested.findNodeOrParentForElement(reprAstElem, returnParent); - if (resNested !== null) { - return resNested; - } - } - return null; - } - - /** - * Returns stream of this node and all its descendants, i.e. directly and indirectly nested nodes. - */ - def Stream stream() { - if (nestedNodes === null || nestedNodes.empty) { - Stream.of(this) - } else { - Stream.concat(Stream.of(this), Stream.of(nestedNodes).flatMap[stream]); - } - } - - public static def DestructNode unify(EObject eobj) { - return switch (eobj) { - VariableBinding: unify(eobj) - AssignmentExpression: unify(eobj) - ForStatement: unify(eobj) - default: null - } - } - - /** - * Returns a unified copy of the given destructuring pattern or null if it is invalid. - * This is helpful because these patterns can appear in very different forms and locations within the AST. - */ - public static def DestructNode unify(EObject astElem, EObject lhs, Expression rhs) { - new DestructNode( - astElem, // astElement - null, // propName - null, // varRef - null, // varDecl - toEntries(lhs, rhs), // nestedNodes - rhs, // defaultExpr - rhs, // assignedExpr - false // rest - ) - } - - /** - * Returns a unified copy of the given destructuring pattern or null if it is invalid. - * This is helpful because these patterns can appear in very different forms and locations within the AST. - */ - public static def DestructNode unify(VariableBinding binding) { - if (binding !== null && binding.pattern !== null // note: binding.expression is mandatory in variable statements but optional in for..in/of statements - && (binding.expression !== null || binding.eContainer instanceof ForStatement - )) { - unify(binding, binding.pattern, binding.expression); - } - } - - /** - * Returns a unified copy of the given destructuring pattern or null if it is invalid. - * This is helpful because these patterns can appear in very different forms and locations within the AST. - */ - public static def DestructNode unify(AssignmentExpression assignExpr) { - if (assignExpr !== null && assignExpr.lhs !== null && assignExpr.rhs !== null - && DestructureUtils.isTopOfDestructuringAssignment(assignExpr) - ) { - unify(assignExpr, assignExpr.lhs, assignExpr.rhs); - } - } - - /** - * Returns a unified copy of the given destructuring pattern or null if it is invalid. - * This is helpful because these patterns can appear in very different forms and locations within the AST. - */ - public static def DestructNode unify(ForStatement forStmnt) { - if (forStmnt !== null && DestructureUtils.isTopOfDestructuringForStatement(forStmnt)) { - val valueToBeDestructured = if (forStmnt.forOf) { - firstArrayElement(forStmnt.expression) - } else if (forStmnt.forIn) { - N4JSFactory.eINSTANCE.createStringLiteral() => [ - value = "" - ] - } else { - // impossible because #isTopOfDestructuringForStatement() returned true - throw new IllegalStateException - }; - val defaultExpression = if (forStmnt.forOf) { - forStmnt.expression - } else if (forStmnt.forIn) { - N4JSFactory.eINSTANCE.createStringLiteral() => [ - value = "" - ] - } else { - // impossible because #isTopOfDestructuringForStatement() returned true - throw new IllegalStateException - }; - - if (DestructureUtils.containsDestructuringPattern(forStmnt)) { - // case: for(var [a,b] of arr) {} - val binding = forStmnt.varDeclsOrBindings.filter(VariableBinding).head; - val rhs = firstArrayElement(forStmnt.expression); - return new DestructNode( - forStmnt, // astElement - null, // propName - null, // varRef - null, // varDecl - toEntries(binding.pattern, rhs), // nestedNodes - defaultExpression, // defaultExpr - valueToBeDestructured, // assignedExpr - false // rest - ) - } else if (DestructureUtils.isObjectOrArrayLiteral(forStmnt.getInitExpr())) { - // case: for([a,b] of arr) {} - return new DestructNode( - forStmnt, // astElement - null, // propName - null, // varRef - null, // varDecl - toEntries(forStmnt.initExpr, null), // nestedNodes - defaultExpression, // defaultExpr - defaultExpression, // assignedExpr - false // rest - ) - } - } - return null; - } - - private static def Expression firstArrayElement(Expression expr) { - return if (expr instanceof ArrayLiteral) expr.elements.head.expression else expr; - } - - private static def DestructNode[] toEntries(EObject pattern, TypableElement rhs) { - - val Iterator patElemIter = switch (pattern) { - ArrayLiteral: - pattern.elements.iterator - ObjectLiteral: - pattern.propertyAssignments.iterator - ArrayBindingPattern: - pattern.elements.iterator - ObjectBindingPattern: - pattern.properties.iterator - } - - var Iterator rhsElemIter = switch (rhs) { - ArrayLiteral: - rhs.elements.iterator - ObjectLiteral: - rhs.propertyAssignments.iterator - } - - val nestedDNs = new BasicEList(); - while (patElemIter.hasNext) { - val patElem = patElemIter.next; - val litElem = if (rhsElemIter === null) rhs else if (rhsElemIter.hasNext) rhsElemIter.next else null; - - val nestedNode = switch (patElem) { - ArrayElement: - toEntry(patElem, litElem) - PropertyNameValuePair: - toEntry(patElem, litElem) - BindingElement: - toEntry(patElem, litElem) - BindingProperty: - toEntry(patElem, litElem) - } - - if (nestedNode !== null) { - nestedDNs.add(nestedNode); - } - } - return nestedDNs; - } - - private static def DestructNode toEntry(ArrayElement elem, TypableElement rhs) { - val TypableElement rhsExpr = if (rhs instanceof ArrayElement) rhs.expression else rhs; - val expr = elem.expression; // note: ArrayPadding will return null for getExpression() - if (expr instanceof AssignmentExpression) - toEntry(elem, null, expr.lhs, expr.rhs, elem.spread, rhsExpr) - else - toEntry(elem, null, expr, null, elem.spread, rhsExpr) - } - - private static def DestructNode toEntry(PropertyNameValuePair pa, TypableElement rhs) { - val TypableElement rhsExpr = if (rhs instanceof PropertyNameValuePair) rhs.expression else rhs; - val expr = pa.expression; - if (expr instanceof AssignmentExpression) - toEntry(pa, pa.name, expr.lhs, expr.rhs, false, rhsExpr) - else - toEntry(pa, pa.name, expr, null, false, rhsExpr) - } - - private static def DestructNode toEntry(BindingElement elem, TypableElement rhs) { - val TypableElement expr = if (rhs instanceof ArrayElement) rhs.expression else rhs; - - if (elem.varDecl !== null) - toEntry(elem, null, elem.varDecl, elem.varDecl.expression, elem.rest, expr) - else if (elem.nestedPattern !== null) - toEntry(elem, null, elem.nestedPattern, elem.expression, elem.rest, expr) - else - toEntry(elem, null, null, null, false, expr) // return dummy entry to not break indices - } - - private static def DestructNode toEntry(BindingProperty prop, TypableElement rhs) { - if (prop.value?.varDecl !== null) { - val expr = getPropertyAssignmentExpression(rhs); - toEntry(prop, prop.name, prop.value.varDecl, prop.value.varDecl.expression, false, expr) - - } else if (prop.value?.nestedPattern !== null) { - val expr = getPropertyAssignmentExpression(rhs); - toEntry(prop, prop.name, prop.value.nestedPattern, prop.value.expression, false, expr) - - } else { - toEntry(prop, null, null, null, false, rhs) - } - } - - /** - * @param bindingTarget - * an IdentifierRef/VariableDeclaration or a nested pattern (which may be - * a BindingPattern, ArrayLiteral, or ObjectLiteral) - */ - private static def DestructNode toEntry(EObject astElement, String propName, EObject bindingTarget, - Expression defaultExpr, boolean rest, TypableElement rhs) { - - if (bindingTarget === null) { - // no target -> create a padding node - new DestructNode(astElement, propName, null, null, null, defaultExpr, null, rest) - - } else if (bindingTarget instanceof IdentifierRef) { - new DestructNode(astElement, propName, bindingTarget, null, null, defaultExpr, rhs, rest) - - } else if (bindingTarget instanceof VariableDeclaration) { - new DestructNode(astElement, propName, null, bindingTarget, null, defaultExpr, rhs, rest) - - } else if (bindingTarget instanceof ArrayLiteral || bindingTarget instanceof ObjectLiteral || - bindingTarget instanceof BindingPattern) { - new DestructNode(astElement, propName, null, null, toEntries(bindingTarget, rhs), defaultExpr, rhs, rest) - - } else { - // invalid binding target (probably a corrupt AST) -> create a padding node - new DestructNode(astElement, propName, null, null, null, defaultExpr, null, rest) - } - } - - /** @return the expression or function of the given PropertyAssignment */ - private static def TypableElement getPropertyAssignmentExpression(TypableElement rhs) { - switch (rhs) { - PropertyGetterDeclaration: - return rhs.definedFunctionOrAccessor - PropertySetterDeclaration: - return rhs.definedFunctionOrAccessor - PropertyMethodDeclaration: - return rhs.definedFunctionOrAccessor - PropertyNameValuePair: - return rhs.expression - PropertyAssignmentAnnotationList: - return null - default: - return rhs - } - } - - /** @return all {@link IdentifierRef} of variables that are written in the given assignment */ - public def List getAllDeclaredIdRefs() { - val List idRefs = new LinkedList(); - val Iterator allNestedNodes = this.stream().iterator(); - - while (allNestedNodes.hasNext()) { - val EObject eobj = allNestedNodes.next().getAstElement(); - if (eobj instanceof ArrayElement) { - val Expression expr = eobj.getExpression(); - if (expr instanceof AssignmentExpression) { - idRefs.add((expr.getLhs())); - } else { - idRefs.add(expr); - } - - } else if (eobj instanceof PropertyNameValuePairSingleName) { - idRefs.add(eobj.getIdentifierRef()); - - } else if (eobj instanceof PropertyNameValuePair) { - val Expression expr = eobj.getExpression(); - if (expr instanceof AssignmentExpression) { - idRefs.add(expr.getLhs()); - } else { - idRefs.add(expr); - } - } - } - return idRefs; - } - - /** @return a pair where its key is the assigned EObject and its value is the default EObject to the given lhs AST element */ - public static def Pair getValueFromDestructuring(EObject nodeElem) { - var EObject node = nodeElem; - var EObject topNode = null; - var EObject dNodeElem = null; - var boolean breakSearch = false; - - while (!breakSearch) { - var EObject parent = node.eContainer(); - dNodeElem = getDNodeElem(dNodeElem, parent, node); - topNode = getTopElem(topNode, parent); - breakSearch = parent instanceof Statement; - node = parent; - } - - var DestructNode dNode = if (topNode instanceof AssignmentExpression) { - DestructNode.unify(topNode); - } else if (topNode instanceof VariableBinding) { - DestructNode.unify(topNode); - } else if (topNode instanceof ForStatement) { - DestructNode.unify(topNode); - } else { - null; - }; - - if (dNode !== null) { - dNode = dNode.findNodeForElement(dNodeElem); - if (dNode !== null) { - var EObject assgnValue = dNode.getAssignedElem(); - var EObject defaultValue = dNode.getDefaultExpr(); - return assgnValue -> defaultValue; - } - } - - return null; - } - - private static def EObject getDNodeElem(EObject dNodeElem, EObject parent, EObject node) { - if (dNodeElem !== null) { - return dNodeElem; - } - if (node instanceof BindingElement && parent instanceof BindingProperty) { - return parent; - } - if (node instanceof BindingElement || node instanceof ArrayElement || node instanceof PropertyAssignment) { - return node; - } - } - - private static def EObject getTopElem(EObject oldTopNode, EObject parent) { - val EObject newTopNode = switch (parent) { - ForStatement: - parent - AssignmentExpression: - parent - VariableBinding: - parent - default: - null - }; - - if (newTopNode !== null) { - return newTopNode - } else { - oldTopNode; - } - } - - public static def List getAllDeclaredIdRefs(EObject eobj) { - val DestructNode dnode = switch (eobj) { - ForStatement: - unify(eobj) - VariableBinding: - unify(eobj) - AssignmentExpression: - unify(eobj) - default: - null - }; - - if (dnode === null) { - return #[]; - } - - return dnode.allDeclaredIdRefs; - } -} diff --git a/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/DestructureUtils.java b/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/DestructureUtils.java index c1d0340739..777b2887f7 100644 --- a/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/DestructureUtils.java +++ b/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/DestructureUtils.java @@ -275,7 +275,7 @@ public static boolean isInDestructuringPattern(EObject obj) { return isParentPartOfSameDestructuringPattern(obj); } - /** @return true iff the given {@link EObject} can be {@link DestructNode#getAstElement()} */ + /** @return true iff the given {@link EObject} can be {@link DestructNode#astElement} */ public static boolean isRepresentingElement(EObject eobj) { boolean isRepresentingElement = false; isRepresentingElement |= eobj instanceof ArrayElement; diff --git a/plugins/org.eclipse.n4js.model/xtend-gen/.gitignore b/plugins/org.eclipse.n4js.model/xtend-gen/.gitignore deleted file mode 100644 index c96a04f008..0000000000 --- a/plugins/org.eclipse.n4js.model/xtend-gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/plugins/org.eclipse.n4js.regex.ide/.classpath b/plugins/org.eclipse.n4js.regex.ide/.classpath index d28af888cb..fc609eff89 100644 --- a/plugins/org.eclipse.n4js.regex.ide/.classpath +++ b/plugins/org.eclipse.n4js.regex.ide/.classpath @@ -2,7 +2,6 @@ - diff --git a/plugins/org.eclipse.n4js.regex.ide/build.properties b/plugins/org.eclipse.n4js.regex.ide/build.properties index bef28d3d93..ec65859a4c 100644 --- a/plugins/org.eclipse.n4js.regex.ide/build.properties +++ b/plugins/org.eclipse.n4js.regex.ide/build.properties @@ -1,5 +1,4 @@ source.. = src/,\ - src-gen/,\ - xtend-gen/ + src-gen/ bin.includes = META-INF/,\ . diff --git a/plugins/org.eclipse.n4js.regex.ide/pom.xml b/plugins/org.eclipse.n4js.regex.ide/pom.xml index 0fd5ff17d0..6da554c206 100644 --- a/plugins/org.eclipse.n4js.regex.ide/pom.xml +++ b/plugins/org.eclipse.n4js.regex.ide/pom.xml @@ -30,10 +30,6 @@ Contributors: org.apache.maven.plugins maven-clean-plugin - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeModule.xtend b/plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeModule.java similarity index 76% rename from plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeModule.xtend rename to plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeModule.java index 2daca727c9..c67769bc34 100644 --- a/plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeModule.xtend +++ b/plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeModule.java @@ -8,11 +8,11 @@ * Contributors: * NumberFour AG - Initial API and implementation */ -package org.eclipse.n4js.regex.ide - +package org.eclipse.n4js.regex.ide; /** * Use this class to register ide components. */ -class RegularExpressionIdeModule extends AbstractRegularExpressionIdeModule { +public class RegularExpressionIdeModule extends AbstractRegularExpressionIdeModule { + // empty } diff --git a/plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeSetup.java b/plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeSetup.java new file mode 100644 index 0000000000..41d24e8772 --- /dev/null +++ b/plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeSetup.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2017 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.regex.ide; + +import org.eclipse.n4js.regex.RegularExpressionRuntimeModule; +import org.eclipse.n4js.regex.RegularExpressionStandaloneSetup; +import org.eclipse.xtext.util.Modules2; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * Initialization support for running Xtext languages as language servers. + */ +public class RegularExpressionIdeSetup extends RegularExpressionStandaloneSetup { + + @Override + public Injector createInjector() { + return Guice + .createInjector(Modules2.mixin(new RegularExpressionRuntimeModule(), new RegularExpressionIdeModule())); + } + +} diff --git a/plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeSetup.xtend b/plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeSetup.xtend deleted file mode 100644 index 926c575f3c..0000000000 --- a/plugins/org.eclipse.n4js.regex.ide/src/org/eclipse/n4js/regex/ide/RegularExpressionIdeSetup.xtend +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2017 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.regex.ide - -import com.google.inject.Guice -import org.eclipse.n4js.regex.RegularExpressionRuntimeModule -import org.eclipse.n4js.regex.RegularExpressionStandaloneSetup -import org.eclipse.xtext.util.Modules2 - -/** - * Initialization support for running Xtext languages as language servers. - */ -class RegularExpressionIdeSetup extends RegularExpressionStandaloneSetup { - - override createInjector() { - Guice.createInjector(Modules2.mixin(new RegularExpressionRuntimeModule, new RegularExpressionIdeModule)) - } - -} diff --git a/plugins/org.eclipse.n4js.regex.ide/xtend-gen/.gitignore b/plugins/org.eclipse.n4js.regex.ide/xtend-gen/.gitignore deleted file mode 100644 index c96a04f008..0000000000 --- a/plugins/org.eclipse.n4js.regex.ide/xtend-gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/plugins/org.eclipse.n4js.regex/.classpath b/plugins/org.eclipse.n4js.regex/.classpath index 217ca618e4..5153825dfe 100644 --- a/plugins/org.eclipse.n4js.regex/.classpath +++ b/plugins/org.eclipse.n4js.regex/.classpath @@ -12,6 +12,5 @@ - diff --git a/plugins/org.eclipse.n4js.regex/build.properties b/plugins/org.eclipse.n4js.regex/build.properties index 4e5f9fdb5f..ac1f3722dc 100644 --- a/plugins/org.eclipse.n4js.regex/build.properties +++ b/plugins/org.eclipse.n4js.regex/build.properties @@ -1,6 +1,5 @@ source.. = src/,\ - src-gen/,\ - xtend-gen/ + src-gen/ bin.includes = model/,\ META-INF/,\ .,\ diff --git a/plugins/org.eclipse.n4js.regex/pom.xml b/plugins/org.eclipse.n4js.regex/pom.xml index b32fd2695f..613d662dde 100644 --- a/plugins/org.eclipse.n4js.regex/pom.xml +++ b/plugins/org.eclipse.n4js.regex/pom.xml @@ -73,11 +73,6 @@ Contributors: - - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/RegularExpressionRuntimeModule.xtend b/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/RegularExpressionRuntimeModule.java similarity index 65% rename from plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/RegularExpressionRuntimeModule.xtend rename to plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/RegularExpressionRuntimeModule.java index 7e0943ffd4..5cd4418fb9 100644 --- a/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/RegularExpressionRuntimeModule.xtend +++ b/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/RegularExpressionRuntimeModule.java @@ -8,20 +8,20 @@ * Contributors: * NumberFour AG - Initial API and implementation */ -package org.eclipse.n4js.regex +package org.eclipse.n4js.regex; -import org.eclipse.xtext.conversion.impl.INTValueConverter +import org.eclipse.xtext.conversion.impl.INTValueConverter; /** * Use this class to register components to be used at runtime / without the Equinox extension registry. */ -class RegularExpressionRuntimeModule extends AbstractRegularExpressionRuntimeModule { +public class RegularExpressionRuntimeModule extends AbstractRegularExpressionRuntimeModule { /** * INT is a data type rule thus the specialized binding */ - def Class bindINTValueConverter() { - return RegExINTValueConverter; + public Class bindINTValueConverter() { + return RegExINTValueConverter.class; } } diff --git a/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/RegularExpressionStandaloneSetup.xtend b/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/RegularExpressionStandaloneSetup.java similarity index 74% rename from plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/RegularExpressionStandaloneSetup.xtend rename to plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/RegularExpressionStandaloneSetup.java index b69feb848e..6f00167592 100644 --- a/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/RegularExpressionStandaloneSetup.xtend +++ b/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/RegularExpressionStandaloneSetup.java @@ -8,15 +8,15 @@ * Contributors: * NumberFour AG - Initial API and implementation */ -package org.eclipse.n4js.regex - +package org.eclipse.n4js.regex; /** * Initialization support for running Xtext languages without Equinox extension registry. */ -class RegularExpressionStandaloneSetup extends RegularExpressionStandaloneSetupGenerated { +public class RegularExpressionStandaloneSetup extends RegularExpressionStandaloneSetupGenerated { - def static void doSetup() { - new RegularExpressionStandaloneSetup().createInjectorAndDoEMFRegistration() + /***/ + static public void doSetup() { + new RegularExpressionStandaloneSetup().createInjectorAndDoEMFRegistration(); } } diff --git a/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/generator/RegularExpressionGenerator.java b/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/generator/RegularExpressionGenerator.java new file mode 100644 index 0000000000..35eb206c3b --- /dev/null +++ b/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/generator/RegularExpressionGenerator.java @@ -0,0 +1,33 @@ +/** + * 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.regex.generator; + +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.xtext.generator.AbstractGenerator; +import org.eclipse.xtext.generator.IFileSystemAccess2; +import org.eclipse.xtext.generator.IGeneratorContext; + +/** + * Generates code from your model files on save. + * + * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation + */ +public class RegularExpressionGenerator extends AbstractGenerator { + + @Override + public void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) { + // fsa.generateFile('greetings.txt', 'People to greet: ' + + // resource.allContents + // .filter(typeof(Greeting)) + // .map[name] + // .join(', ')) + } +} diff --git a/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/generator/RegularExpressionGenerator.xtend b/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/generator/RegularExpressionGenerator.xtend deleted file mode 100644 index b63de1fecc..0000000000 --- a/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/generator/RegularExpressionGenerator.xtend +++ /dev/null @@ -1,32 +0,0 @@ -/** - * 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.regex.generator - -import org.eclipse.emf.ecore.resource.Resource -import org.eclipse.xtext.generator.AbstractGenerator -import org.eclipse.xtext.generator.IFileSystemAccess2 -import org.eclipse.xtext.generator.IGeneratorContext - -/** - * Generates code from your model files on save. - * - * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation - */ -class RegularExpressionGenerator extends AbstractGenerator { - - override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) { -// fsa.generateFile('greetings.txt', 'People to greet: ' + -// resource.allContents -// .filter(typeof(Greeting)) -// .map[name] -// .join(', ')) - } -} diff --git a/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/scoping/RegularExpressionScopeProvider.xtend b/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/scoping/RegularExpressionScopeProvider.java similarity index 71% rename from plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/scoping/RegularExpressionScopeProvider.xtend rename to plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/scoping/RegularExpressionScopeProvider.java index ed6c9c4794..d974dbbbdf 100644 --- a/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/scoping/RegularExpressionScopeProvider.xtend +++ b/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/scoping/RegularExpressionScopeProvider.java @@ -8,14 +8,13 @@ * Contributors: * NumberFour AG - Initial API and implementation */ -package org.eclipse.n4js.regex.scoping +package org.eclipse.n4js.regex.scoping; /** * This class contains custom scoping description. * - * see : http://www.eclipse.org/Xtext/documentation.html#scoping - * on how and when to use it + * see : http://www.eclipse.org/Xtext/documentation.html#scoping on how and when to use it */ -class RegularExpressionScopeProvider extends org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider { - +public class RegularExpressionScopeProvider extends org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider { + // empty } diff --git a/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/validation/RegularExpressionValidator.xtend b/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/validation/RegularExpressionValidator.java similarity index 54% rename from plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/validation/RegularExpressionValidator.xtend rename to plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/validation/RegularExpressionValidator.java index 141632cdf4..2ecc798cd8 100644 --- a/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/validation/RegularExpressionValidator.xtend +++ b/plugins/org.eclipse.n4js.regex/src/org/eclipse/n4js/regex/validation/RegularExpressionValidator.java @@ -8,7 +8,7 @@ * Contributors: * NumberFour AG - Initial API and implementation */ -package org.eclipse.n4js.regex.validation +package org.eclipse.n4js.regex.validation; //import org.eclipse.xtext.validation.Check /** @@ -16,16 +16,16 @@ * * see http://www.eclipse.org/Xtext/documentation.html#validation */ -class RegularExpressionValidator extends AbstractRegularExpressionValidator { +public class RegularExpressionValidator extends AbstractRegularExpressionValidator { -// public static val INVALID_NAME = 'invalidName' -// -// @Check -// def checkGreetingStartsWithCapital(Greeting greeting) { -// if (!Character.isUpperCase(greeting.name.charAt(0))) { -// warning('Name should start with a capital', -// MyDslPackage.Literals.GREETING__NAME, -// INVALID_NAME) -// } -// } + // public static val INVALID_NAME = 'invalidName' + // + // @Check + // def checkGreetingStartsWithCapital(Greeting greeting) { + // if (!Character.isUpperCase(greeting.name.charAt(0))) { + // warning('Name should start with a capital', + // MyDslPackage.Literals.GREETING__NAME, + // INVALID_NAME) + // } + // } } diff --git a/plugins/org.eclipse.n4js.regex/xtend-gen/.gitignore b/plugins/org.eclipse.n4js.regex/xtend-gen/.gitignore deleted file mode 100644 index c96a04f008..0000000000 --- a/plugins/org.eclipse.n4js.regex/xtend-gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/plugins/org.eclipse.n4js.semver.ide/.classpath b/plugins/org.eclipse.n4js.semver.ide/.classpath index d28af888cb..fc609eff89 100644 --- a/plugins/org.eclipse.n4js.semver.ide/.classpath +++ b/plugins/org.eclipse.n4js.semver.ide/.classpath @@ -2,7 +2,6 @@ - diff --git a/plugins/org.eclipse.n4js.semver.ide/build.properties b/plugins/org.eclipse.n4js.semver.ide/build.properties index bef28d3d93..ec65859a4c 100644 --- a/plugins/org.eclipse.n4js.semver.ide/build.properties +++ b/plugins/org.eclipse.n4js.semver.ide/build.properties @@ -1,5 +1,4 @@ source.. = src/,\ - src-gen/,\ - xtend-gen/ + src-gen/ bin.includes = META-INF/,\ . diff --git a/plugins/org.eclipse.n4js.semver.ide/pom.xml b/plugins/org.eclipse.n4js.semver.ide/pom.xml index 0e1fd68378..78d94531f6 100644 --- a/plugins/org.eclipse.n4js.semver.ide/pom.xml +++ b/plugins/org.eclipse.n4js.semver.ide/pom.xml @@ -30,10 +30,6 @@ Contributors: org.apache.maven.plugins maven-clean-plugin - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/plugins/org.eclipse.n4js.semver.ide/xtend-gen/.gitignore b/plugins/org.eclipse.n4js.semver.ide/xtend-gen/.gitignore deleted file mode 100644 index d6b7ef32c8..0000000000 --- a/plugins/org.eclipse.n4js.semver.ide/xtend-gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/plugins/org.eclipse.n4js.semver.model/pom.xml b/plugins/org.eclipse.n4js.semver.model/pom.xml index 760864b701..7464ebfba8 100644 --- a/plugins/org.eclipse.n4js.semver.model/pom.xml +++ b/plugins/org.eclipse.n4js.semver.model/pom.xml @@ -38,11 +38,6 @@ Contributors: maven-resources-plugin ${maven-resources-plugin.version} - - org.eclipse.xtend - xtend-maven-plugin - - diff --git a/plugins/org.eclipse.n4js.transpiler.es/.classpath b/plugins/org.eclipse.n4js.transpiler.es/.classpath index 14dd6eb29b..e3378d07f0 100644 --- a/plugins/org.eclipse.n4js.transpiler.es/.classpath +++ b/plugins/org.eclipse.n4js.transpiler.es/.classpath @@ -1,7 +1,6 @@ - diff --git a/plugins/org.eclipse.n4js.transpiler.es/build.properties b/plugins/org.eclipse.n4js.transpiler.es/build.properties index aaedd5b241..17daa5b49c 100644 --- a/plugins/org.eclipse.n4js.transpiler.es/build.properties +++ b/plugins/org.eclipse.n4js.transpiler.es/build.properties @@ -1,5 +1,4 @@ -source.. = src/,\ - xtend-gen/ +source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ diff --git a/plugins/org.eclipse.n4js.transpiler.es/pom.xml b/plugins/org.eclipse.n4js.transpiler.es/pom.xml index cda3552311..3856d6b132 100644 --- a/plugins/org.eclipse.n4js.transpiler.es/pom.xml +++ b/plugins/org.eclipse.n4js.transpiler.es/pom.xml @@ -34,11 +34,6 @@ Contributors: maven-resources-plugin ${maven-resources-plugin.version} - - org.eclipse.xtend - xtend-maven-plugin - - diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/BlockAssistant.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/BlockAssistant.java new file mode 100644 index 0000000000..4fd6b166a4 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/BlockAssistant.java @@ -0,0 +1,50 @@ +/** + * 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.transpiler.es.assistants; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.voidType; + +import org.eclipse.n4js.n4JS.ArrowFunction; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.transpiler.TransformationAssistant; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; + +import com.google.inject.Inject; + +/** + */ +public class BlockAssistant extends TransformationAssistant { + + @Inject + private N4JSTypeSystem ts; + + /***/ + public final boolean needsReturnInsertionForBody(ArrowFunction arrowFuncInIM) { + // unfortunately, we need a properly contained AST element below (see preconditions above) + ArrowFunction origAST = getState().tracer.getOriginalASTNodeOfSameType(arrowFuncInIM, false); + if (origAST == null) { + // this arrow function does not come from the N4JS source code but was created by some transformation + // -> we assume it was intended to return a value and hence a return must be inserted + return true; + } + if (!origAST.isSingleExprImplicitReturn()) { + return false; + } + // check if body is typed void, in which case no return will be inserted + Expression singleExpr = origAST.implicitReturnExpr(); + TypeRef implicitReturnTypeRef = ts.type(getState().G, singleExpr); + if (implicitReturnTypeRef != null && implicitReturnTypeRef.getDeclaredType() == voidType(getState().G)) { + return false; + } + return true; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/BlockAssistant.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/BlockAssistant.xtend deleted file mode 100644 index 21eec2cdcc..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/BlockAssistant.xtend +++ /dev/null @@ -1,46 +0,0 @@ -/** - * 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.transpiler.es.assistants - -import com.google.inject.Inject -import org.eclipse.n4js.n4JS.ArrowFunction -import org.eclipse.n4js.transpiler.TransformationAssistant -import org.eclipse.n4js.typesystem.N4JSTypeSystem - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - */ -class BlockAssistant extends TransformationAssistant { - - @Inject - private N4JSTypeSystem ts - - def public final boolean needsReturnInsertionForBody(ArrowFunction arrowFuncInIM) { - // unfortunately, we need a properly contained AST element below (see preconditions above) - val origAST = state.tracer.getOriginalASTNodeOfSameType(arrowFuncInIM, false); - if (origAST === null) { - // this arrow function does not come from the N4JS source code but was created by some transformation - // -> we assume it was intended to return a value and hence a return must be inserted - return true; - } - if (!origAST.isSingleExprImplicitReturn) { - return false; - } - // check if body is typed void, in which case no return will be inserted - val singleExpr = origAST.implicitReturnExpr(); - val implicitReturnTypeRef = ts.type(state.G, singleExpr); - if (implicitReturnTypeRef?.declaredType === state.G.voidType) { - return false; - } - return true; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassConstructorAssistant.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassConstructorAssistant.java new file mode 100644 index 0000000000..7ad80f6149 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassConstructorAssistant.java @@ -0,0 +1,580 @@ +/** + * 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.transpiler.es.assistants; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Argument; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._AssignmentExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ConditionalExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._EqualityExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ExprStmnt; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Fpar; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IfStmnt; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4MethodDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._OR; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ObjLit; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Parenthesis; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyNameValuePair; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._RelationalExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Snippet; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteralForSTE; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._SuperLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._TRUE; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ThisLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableDeclaration; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableStatement; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.errorType; +import static org.eclipse.n4js.utils.N4JSLanguageUtils.builtInOrProvidedByRuntime; +import static org.eclipse.n4js.utils.N4JSLanguageUtils.builtInOrProvidedByRuntimeOrShape; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.head; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.last; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; +import static org.eclipse.xtext.xbase.lib.ListExtensions.map; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.N4JSLanguageConstants; +import org.eclipse.n4js.n4JS.Argument; +import org.eclipse.n4js.n4JS.Block; +import org.eclipse.n4js.n4JS.EqualityOperator; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ExpressionStatement; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.ModifierUtils; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.N4MethodDeclaration; +import org.eclipse.n4js.n4JS.N4Modifier; +import org.eclipse.n4js.n4JS.N4SetterDeclaration; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.n4JS.RelationalOperator; +import org.eclipse.n4js.n4JS.Statement; +import org.eclipse.n4js.n4JS.SuperLiteral; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.VariableStatementKeyword; +import org.eclipse.n4js.transpiler.TransformationAssistant; +import org.eclipse.n4js.transpiler.assistants.TypeAssistant; +import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryInternal; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.MemberAccessModifier; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TInterface; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.xtext.xbase.lib.Pair; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.inject.Inject; + +/** + * Modify or create the constructor of a class declaration. + */ +public class ClassConstructorAssistant extends TransformationAssistant { + + @Inject + private TypeAssistant typeAssistant; + @Inject + private ClassifierAssistant classifierAssistant; + + private static final class SpecInfo { + /** + * The @Spec-fpar in the intermediate model. Never null. + */ + public final FormalParameter fpar; + /** + * Names of properties in the with-clause of the @Spec-fpar's type. For example, as in: + * + *

+		 * constructor(@Spec specObj: ~i~this with { addProp: string }) { ... } .
+		 */
+		public final ImmutableSet additionalProps;
+
+		public SpecInfo(FormalParameter fpar, Iterable additionalProps) {
+			this.fpar = Objects.requireNonNull(fpar);
+			this.additionalProps = ImmutableSet.copyOf(additionalProps);
+		}
+	}
+
+	/**
+	 * Amend the constructor of the given class with implicit functionality (e.g. initialization of instance fields).
+	 * Will create an implicit constructor declaration iff no constructor is defined in the N4JS source code AND an
+	 * implicit constructor is actually required.
+	 */
+	public void amendConstructor(N4ClassDeclaration classDecl, SymbolTableEntry classSTE,
+			SymbolTableEntryOriginal superClassSTE,
+			LinkedHashSet fieldsRequiringExplicitDefinition) {
+
+		N4MethodDeclaration explicitCtorDecl = classDecl.getOwnedCtor(); // the constructor defined in the N4JS source
+																			// code or 'null' if none was defined
+		N4MethodDeclaration ctorDecl = explicitCtorDecl != null ? explicitCtorDecl
+				: _N4MethodDecl(N4JSLanguageConstants.CONSTRUCTOR);
+
+		// amend formal parameters
+		SpecInfo specInfo = amendFormalParametersOfConstructor(classDecl, ctorDecl, explicitCtorDecl);
+
+		// amend body
+		boolean isNonTrivial = amendBodyOfConstructor(classDecl, classSTE, superClassSTE, ctorDecl, explicitCtorDecl,
+				specInfo, fieldsRequiringExplicitDefinition);
+
+		// add constructor to classDecl (if necessary)
+		if (ctorDecl.eContainer() == null && isNonTrivial) {
+			classDecl.getOwnedMembersRaw().add(0, ctorDecl);
+		}
+	}
+
+	private SpecInfo amendFormalParametersOfConstructor(N4ClassDeclaration classDecl, N4MethodDeclaration ctorDecl,
+			N4MethodDeclaration explicitCtorDecl) {
+		FormalParameter specFpar = null;
+		TypeRef specFparTypeRef = null;
+
+		boolean hasExplicitCtor = explicitCtorDecl != null;
+		if (hasExplicitCtor) {
+			// explicitly defined constructor
+			// --> nothing to be changed (use fpars from N4JS source code)
+
+			specFpar = head(filter(ctorDecl.getFpars(), fpar -> AnnotationDefinition.SPEC.hasAnnotation(fpar)));
+			if (specFpar != null) {
+				TypeReferenceNode typeRefNode = specFpar.getDeclaredTypeRefNode();
+				if (typeRefNode != null) {
+					specFparTypeRef = getState().info.getOriginalProcessedTypeRef(typeRefNode);
+				}
+			}
+		} else {
+			// implicit constructor
+			// --> create fpars using fpars of nearest constructor in hierarchy as template
+
+			TMethod templateCtor = getNearestConstructorInHierarchy(classDecl);
+			if (templateCtor != null) {
+				for (TFormalParameter templateFpar : templateCtor.getFpars()) {
+					boolean isSpecFpar = AnnotationDefinition.SPEC.hasAnnotation(templateFpar);
+					FormalParameter newFpar = _Fpar(templateFpar.getName(), templateFpar.isVariadic(), isSpecFpar);
+					ctorDecl.getFpars().add(newFpar);
+
+					if (isSpecFpar && specFpar == null) {
+						specFpar = newFpar;
+						specFparTypeRef = TypeUtils.copy(templateFpar.getTypeRef());
+					}
+				}
+			}
+		}
+
+		if (specFpar != null) {
+			Iterable additionalProps = Collections.emptyList();
+			if (specFparTypeRef != null && specFparTypeRef.getStructuralMembers() != null) {
+				additionalProps = map(specFparTypeRef.getStructuralMembers(), m -> m.getName());
+			}
+			return new SpecInfo(specFpar, additionalProps);
+		}
+		return null;
+	}
+
+	/**
+	 * Returns true iff the constructor is non-trivial, i.e. non-empty and containing more than just the
+	 * default super call.
+	 */
+	private boolean amendBodyOfConstructor(N4ClassDeclaration classDecl, SymbolTableEntry classSTE,
+			SymbolTableEntryOriginal superClassSTE,
+			N4MethodDeclaration ctorDecl, N4MethodDeclaration explicitCtorDecl, SpecInfo specInfo,
+			LinkedHashSet fieldsRequiringExplicitDefinition) {
+
+		boolean hasExplicitCtor = explicitCtorDecl != null;
+		Block body = ctorDecl.getBody();
+
+		boolean isDirectSubclassOfError = superClassSTE == null ? null
+				: superClassSTE.getOriginalTarget() == errorType(getState().G);
+		int superCallIndex = (explicitCtorDecl != null && explicitCtorDecl.getBody() != null)
+				? getSuperCallIndex(explicitCtorDecl)
+				: -1;
+		boolean hasExplicitSuperCall = superCallIndex >= 0;
+		ExpressionStatement defaultSuperCall = null;
+
+		int idx = (hasExplicitSuperCall) ? superCallIndex + 1 : 0;
+
+		// add/replace/modify super call
+		if (hasExplicitSuperCall) {
+			// keep existing, explicit super call unchanged
+		} else {
+			// no explicitCtorDecl OR no body OR no explicit super call (and no direct subclass of Error)
+			// --> add default super call (if required)
+			if (superClassSTE != null) {
+				List fparsOfSuperCtor = (hasExplicitCtor) ?
+				// explicit ctor without an explicit super call: only allowed if the super constructor
+				// does not have any arguments, so we can simply assume empty fpars here, without actually
+				// looking up the super constructor with #getNearestConstructorInHierarchy():
+						Collections.emptyList()
+						:
+						// no explicit ctor: the already created implicit constructor in 'ctorDecl' has the
+						// same fpars as the super constructor, so we can use those as a template:
+						ctorDecl.getFpars();
+				defaultSuperCall = createDefaultSuperCall(fparsOfSuperCtor);
+				idx = insertAt(body.getStatements(), idx, defaultSuperCall);
+			}
+		}
+		if (isDirectSubclassOfError) {
+			// special case: add oddities for sub-classing Error
+			idx = insertAt(body.getStatements(), idx, createSubclassingErrorOddities());
+		}
+
+		// if we are in a spec-constructor: prepare a local variable for the spec-object and
+		// ensure it is never 'undefined' or 'null'
+		SymbolTableEntry specObjSTE = null;
+		if (specInfo != null) {
+			// let $specObj = specFpar || {};
+			SymbolTableEntry specFparSTE = findSymbolTableEntryForElement(specInfo.fpar, true);
+			VariableDeclaration specObjVarDecl = _VariableDeclaration("$specObj",
+					_OR(_IdentRef(specFparSTE), _ObjLit()));
+			idx = insertAt(body.getStatements(), idx,
+					_VariableStatement(VariableStatementKeyword.CONST, specObjVarDecl));
+
+			specObjSTE = findSymbolTableEntryForElement(specObjVarDecl, true);
+		}
+
+		// add explicit definitions of instance fields (only for fields that actually require this)
+		idx = insertAt(body.getStatements(), idx,
+				classifierAssistant.createExplicitFieldDefinitions(classSTE, false, fieldsRequiringExplicitDefinition));
+
+		// add initialization code for instance fields
+		idx = insertAt(body.getStatements(), idx,
+				createInstanceFieldInitCode(classDecl, specInfo, specObjSTE, fieldsRequiringExplicitDefinition));
+
+		// add delegation to field initialization functions of all directly implemented interfaces
+		idx = insertAt(body.getStatements(), idx,
+				createDelegationToFieldInitOfImplementedInterfaces(classDecl, specObjSTE));
+
+		// check if constructor is non-trivial
+		EList ctorDeclStmnts = ctorDecl.getBody().getStatements();
+		boolean bodyContainsOnlyDefaultSuperCall = defaultSuperCall != null
+				&& ctorDeclStmnts.size() == 1
+				&& ctorDeclStmnts.get(0) == defaultSuperCall;
+		boolean isNonTrivialCtor = !ctorDeclStmnts.isEmpty() && !bodyContainsOnlyDefaultSuperCall;
+
+		return isNonTrivialCtor;
+	}
+
+	private List createInstanceFieldInitCode(N4ClassDeclaration classDecl, SpecInfo specInfo,
+			SymbolTableEntry specObjSTE, Set fieldsWithExplicitDefinition) {
+		List allFields = toList(filter(classDecl.getOwnedFields(), f -> !f.isStatic()
+				&& !isConsumedFromInterface(f)
+				&& !builtInOrProvidedByRuntime(getState().info.getOriginalDefinedMember(f))));
+		if (specInfo != null) {
+			// we have a spec-parameter -> we are in a spec-style constructor
+			List result = new ArrayList<>();
+
+			// step #1: initialize all fields either with data from the specFpar OR or their initializer expression
+			List currFields = new ArrayList<>();
+			boolean currFieldsAreSpecced = false;
+			for (N4FieldDeclaration field : allFields) {
+				boolean isSpecced = isPublic(field) || specInfo.additionalProps.contains(field.getName());
+				if (isSpecced == currFieldsAreSpecced) {
+					currFields.add(field);
+				} else {
+					result.addAll(createFieldInitCodeForSeveralFields(currFields, currFieldsAreSpecced, specObjSTE));
+					currFields.clear();
+					currFields.add(field);
+					currFieldsAreSpecced = isSpecced;
+				}
+			}
+			result.addAll(createFieldInitCodeForSeveralFields(currFields, currFieldsAreSpecced, specObjSTE));
+
+			// step #2: invoke setters with data from specFpar
+			// (note: in case of undefined specFpar at runtime, setters should not be invoked, so we wrap in if
+			// statement)
+			Iterable speccedSetters = filter(classDecl.getOwnedSetters(),
+					sd -> !sd.isStatic() && sd.getDeclaredModifiers().contains(N4Modifier.PUBLIC));
+			result.addAll(toList(map(speccedSetters, sd -> createFieldInitCodeForSingleSpeccedSetter(sd, specObjSTE))));
+
+			return result;
+		} else {
+			// simple: just initialize fields with data from their initializer expression
+			return toList(map(filter(allFields,
+					f -> !(f.getExpression() == null && fieldsWithExplicitDefinition.contains(f))),
+					f -> createFieldInitCodeForSingleField(f)));
+		}
+	}
+
+	private List createFieldInitCodeForSeveralFields(List fieldDecls,
+			boolean fieldsAreSpecced, SymbolTableEntry specObjSTE) {
+		if (fieldDecls.isEmpty()) {
+			return Collections.emptyList();
+		}
+		if (!fieldsAreSpecced) {
+			return toList(map(fieldDecls, fd -> createFieldInitCodeForSingleField(fd)));
+		}
+		if (fieldDecls.size() == 1) {
+			return List.of(createFieldInitCodeForSingleSpeccedField(fieldDecls.get(0), specObjSTE));
+		}
+		return List.of(createFieldInitCodeForSeveralSpeccedFields(fieldDecls, specObjSTE));
+	}
+
+	private Statement createFieldInitCodeForSingleField(N4FieldDeclaration fieldDecl) {
+		// here we create:
+		//
+		// this.fieldName = ;
+		// or
+		// this.fieldName = undefined;
+		//
+		// NOTE: we set the field to 'undefined' even in the second case, because ...
+		// 1) it makes a difference when #hasOwnProperty(), etc. is used after the constructor returns,
+		// 2) for consistency with the method #createFieldInitCodeForSeveralSpeccedFields(), because with
+		// destructuring as used by that method, the property will always be assigned (even if the
+		// value is 'undefined' and there is no default).
+		//
+		SymbolTableEntry fieldSTE = findSymbolTableEntryForElement(fieldDecl, true);
+		return _ExprStmnt(_AssignmentExpr(
+				_PropertyAccessExpr(_ThisLiteral(), fieldSTE),
+				(fieldDecl.getExpression() != null) ? fieldDecl.getExpression() // reusing the expression here
+						: undefinedRef()));
+	}
+
+	@SuppressWarnings("unchecked")
+	private Statement createFieldInitCodeForSeveralSpeccedFields(Iterable fieldDecls,
+			SymbolTableEntry specObjSTE) {
+		// here we create:
+		//
+		// ({
+		// fieldName: this.fieldName = ,
+		// ...
+		// } = spec);
+		//
+
+		Iterable> pairs = map(fieldDecls, fieldDecl -> {
+			SymbolTableEntry fieldSTE = findSymbolTableEntryForElement(fieldDecl, true);
+			ParameterizedPropertyAccessExpression_IM thisFieldName = _PropertyAccessExpr(_ThisLiteral(), fieldSTE);
+			Expression expr = hasNonTrivialInitExpression(fieldDecl)
+					? _AssignmentExpr(thisFieldName, fieldDecl.getExpression()) // reusing the expression here
+					: thisFieldName;
+			return Pair.of(fieldDecl.getName(), expr);
+		});
+
+		return _ExprStmnt(
+				_Parenthesis(
+						_AssignmentExpr(
+								_ObjLit(
+										Iterables.toArray(pairs, Pair.class)),
+								_IdentRef(specObjSTE))));
+	}
+
+	private Statement createFieldInitCodeForSingleSpeccedField(N4FieldDeclaration fieldDecl,
+			SymbolTableEntry specObjSTE) {
+		SymbolTableEntry fieldSTE = findSymbolTableEntryForElement(fieldDecl, true);
+		if (hasNonTrivialInitExpression(fieldDecl)) {
+			// here we create:
+			//
+			// this.fieldName = spec.fieldName == undefined ?  : spec.fieldName;
+			//
+			// NOTE: don't use something like "'fieldName' in spec" as the condition above, because that would
+			// not have the same behavior as destructuring in method #createFieldInitCodeForSeveralSpeccedFields()
+			// in case the property is present but has value 'undefined'!
+			//
+			return _ExprStmnt(_AssignmentExpr(
+					_PropertyAccessExpr(_ThisLiteral(), fieldSTE),
+					// ? :
+					_ConditionalExpr(
+							// spec.fieldName == undefined
+							_EqualityExpr(_PropertyAccessExpr(specObjSTE, fieldSTE), EqualityOperator.SAME,
+									undefinedRef()),
+							// 
+							(fieldDecl.getExpression() != null) ? copy(fieldDecl.getExpression()) // need to copy
+																									// expression here,
+																									// because it will
+																									// be used again!
+									: undefinedRef(),
+							// spec.fieldName
+							_PropertyAccessExpr(specObjSTE, fieldSTE))));
+		} else {
+			// we have a trivial init-expression ...
+
+			// here we create:
+			//
+			// this.fieldName = spec.fieldName;
+			//
+			return _ExprStmnt(_AssignmentExpr(
+					_PropertyAccessExpr(_ThisLiteral(), fieldSTE),
+					_PropertyAccessExpr(specObjSTE, fieldSTE)));
+		}
+	}
+
+	private Statement createFieldInitCodeForSingleSpeccedSetter(N4SetterDeclaration setterDecl,
+			SymbolTableEntry specObjSTE) {
+		// here we create:
+		//
+		// if ('fieldName' in spec) {
+		// this.fieldName = spec.fieldName;
+		// }
+		//
+
+		SymbolTableEntry setterSTE = findSymbolTableEntryForElement(setterDecl, true);
+		return _IfStmnt(
+				_RelationalExpr(
+						_StringLiteralForSTE(setterSTE), RelationalOperator.IN, _IdentRef(specObjSTE)),
+				_ExprStmnt(
+						_AssignmentExpr(
+								_PropertyAccessExpr(_ThisLiteral(), setterSTE),
+								_PropertyAccessExpr(specObjSTE, setterSTE))));
+	}
+
+	// NOTE: compare this to the super calls generated from SuperLiterals in SuperLiteralTransformation
+	private ExpressionStatement createDefaultSuperCall(List fpars) {
+
+		boolean variadicCase = !fpars.isEmpty() && last(fpars).isVariadic();
+		List args = map(fpars, fpar -> _Argument(
+				_IdentRef(findSymbolTableEntryForElement(fpar, true))));
+
+		if (variadicCase) {
+			last(args).setSpread(true);
+		}
+
+		ParameterizedCallExpression callExpr = _CallExpr();
+		callExpr.setTarget(_SuperLiteral());
+		callExpr.getArguments().addAll(args);
+		return _ExprStmnt(callExpr);
+	}
+
+	/** To be inserted where the explicit or implicit super call would be located, normally. */
+	private List createSubclassingErrorOddities() {
+		return List.of(_ExprStmnt(_Snippet("""
+					this.name = this.constructor.n4type.name;
+					if (Error.captureStackTrace) {
+					    Error.captureStackTrace(this, this.name);
+					}
+				""")));
+	}
+
+	private List createDelegationToFieldInitOfImplementedInterfaces(N4ClassDeclaration classDecl,
+			SymbolTableEntry /* nullable */ specObjSTE) {
+
+		List implementedIfcSTEs = toList(
+				filter(typeAssistant.getSuperInterfacesSTEs(classDecl), intf ->
+				// regarding the cast to TInterface: see preconditions of ClassDeclarationTransformation
+				// regarding the entire line: generate $fieldInit call only if the interface is neither built-in nor
+				// provided by runtime nor shape
+				!builtInOrProvidedByRuntimeOrShape((TInterface) intf.getOriginalTarget())));
+		if (implementedIfcSTEs.isEmpty()) {
+			return Collections.emptyList();
+		}
+
+		LinkedHashSet ownedInstanceDataFieldsSupressMixin = new LinkedHashSet<>();
+		ownedInstanceDataFieldsSupressMixin.addAll(
+				toList(map(filter(classDecl.getOwnedGetters(), g -> !isConsumedFromInterface(g)), g -> g.getName())));
+		ownedInstanceDataFieldsSupressMixin.addAll(
+				toList(map(filter(classDecl.getOwnedSetters(), s -> !isConsumedFromInterface(s)), s -> s.getName())));
+
+		SymbolTableEntry classSTE = findSymbolTableEntryForElement(classDecl, false);
+		SymbolTableEntryInternal $initFieldsFromInterfacesSTE = steFor_$initFieldsFromInterfaces();
+
+		return List.of(_ExprStmnt(
+				_CallExpr(
+						_IdentRef($initFieldsFromInterfacesSTE),
+						_ThisLiteral(),
+						_IdentRef(classSTE),
+						(specObjSTE != null) ? _IdentRef(specObjSTE)
+								: undefinedRef(),
+						_ObjLit(
+								Iterables.toArray(map(ownedInstanceDataFieldsSupressMixin,
+										str -> _PropertyNameValuePair(str, _TRUE())), PropertyNameValuePair.class)))));
+	}
+
+	// ################################################################################################################
+	// UTILITY STUFF
+
+	private int getSuperCallIndex(N4MethodDeclaration ownedCtor) {
+		if (ownedCtor != null && ownedCtor.getBody() != null && ownedCtor.getBody().getStatements() != null) {
+			EList stmnts = ownedCtor.getBody().getStatements();
+
+			for (int i = 0; i < stmnts.size(); i++) {
+				Statement stmnt = stmnts.get(i);
+				if (stmnt instanceof ExpressionStatement) {
+					Expression expr = ((ExpressionStatement) stmnt).getExpression();
+					if (expr instanceof ParameterizedCallExpression) {
+						if (((ParameterizedCallExpression) expr).getTarget() instanceof SuperLiteral) {
+							return i;
+						}
+					}
+				}
+			}
+		}
+		return -1;
+	}
+
+	private TMethod getNearestConstructorInHierarchy(N4ClassDeclaration classDecl) {
+		TClass tClass = getState().info.getOriginalDefinedType(classDecl);
+		return getNearestConstructorInHierarchy(tClass);
+	}
+
+	private TMethod getNearestConstructorInHierarchy(TClassifier clazz) {
+		TMethod ownedCtor = null;
+		if (clazz instanceof TClass) {
+			ownedCtor = clazz.getOwnedCtor();
+		}
+
+		if (ownedCtor != null) {
+			return ownedCtor;
+		} else {
+			Type superType = null;
+			if (clazz instanceof TClass) {
+				ParameterizedTypeRef superClassRef = ((TClass) clazz).getSuperClassRef();
+				superType = superClassRef == null ? null : superClassRef.getDeclaredType();
+			}
+
+			if (superType instanceof TClassifier) {
+				return getNearestConstructorInHierarchy((TClassifier) superType);
+			}
+		}
+		return null;
+	}
+
+	private boolean isConsumedFromInterface(N4MemberDeclaration memberDecl) {
+		return getState().info.isConsumedFromInterface(memberDecl);
+	}
+
+	// TODO GH-2153 use reusable utility method for computing actual accessibility
+	private boolean isPublic(N4MemberDeclaration memberDecl) {
+		// no need to bother with default accessibility, here, because 'public' is never the default
+		// (not ideal; would be better if the utility method handled default accessibility)
+		MemberAccessModifier accessModifier = ModifierUtils.convertToMemberAccessModifier(
+				memberDecl.getDeclaredModifiers(),
+				memberDecl.getAnnotations());
+		return accessModifier == MemberAccessModifier.PUBLIC;
+	}
+
+	private static  int insertAt(List list, int index, T element) {
+		list.add(index, element);
+		return index + 1;
+	}
+
+	private static  int insertAt(List list, int index, Collection elements) {
+		list.addAll(index, elements);
+		return index + elements.size();
+	}
+}
diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassConstructorAssistant.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassConstructorAssistant.xtend
deleted file mode 100644
index 2a5b95892f..0000000000
--- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassConstructorAssistant.xtend
+++ /dev/null
@@ -1,517 +0,0 @@
-/**
- * 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.transpiler.es.assistants
-
-import com.google.common.collect.ImmutableSet
-import com.google.inject.Inject
-import java.util.ArrayList
-import java.util.Collection
-import java.util.LinkedHashSet
-import java.util.List
-import java.util.Objects
-import java.util.Set
-import org.eclipse.n4js.AnnotationDefinition
-import org.eclipse.n4js.N4JSLanguageConstants
-import org.eclipse.n4js.n4JS.EqualityOperator
-import org.eclipse.n4js.n4JS.ExpressionStatement
-import org.eclipse.n4js.n4JS.FormalParameter
-import org.eclipse.n4js.n4JS.ModifierUtils
-import org.eclipse.n4js.n4JS.N4ClassDeclaration
-import org.eclipse.n4js.n4JS.N4FieldDeclaration
-import org.eclipse.n4js.n4JS.N4MemberDeclaration
-import org.eclipse.n4js.n4JS.N4MethodDeclaration
-import org.eclipse.n4js.n4JS.N4Modifier
-import org.eclipse.n4js.n4JS.N4SetterDeclaration
-import org.eclipse.n4js.n4JS.ParameterizedCallExpression
-import org.eclipse.n4js.n4JS.RelationalOperator
-import org.eclipse.n4js.n4JS.Statement
-import org.eclipse.n4js.n4JS.SuperLiteral
-import org.eclipse.n4js.n4JS.VariableStatementKeyword
-import org.eclipse.n4js.transpiler.TransformationAssistant
-import org.eclipse.n4js.transpiler.assistants.TypeAssistant
-import org.eclipse.n4js.transpiler.im.SymbolTableEntry
-import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal
-import org.eclipse.n4js.ts.typeRefs.TypeRef
-import org.eclipse.n4js.ts.types.MemberAccessModifier
-import org.eclipse.n4js.ts.types.TClass
-import org.eclipse.n4js.ts.types.TClassifier
-import org.eclipse.n4js.ts.types.TInterface
-import org.eclipse.n4js.ts.types.TMethod
-import org.eclipse.n4js.types.utils.TypeUtils
-
-import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.*
-
-import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.*
-import static extension org.eclipse.n4js.utils.N4JSLanguageUtils.*
-
-/**
- * Modify or create the constructor of a class declaration.
- */
-class ClassConstructorAssistant extends TransformationAssistant {
-
-	@Inject private TypeAssistant typeAssistant;
-	@Inject private ClassifierAssistant classifierAssistant;
-
-	private static final class SpecInfo {
-		/**
-		 * The @Spec-fpar in the intermediate model. Never null.
-		 */
-		public final FormalParameter fpar;
-		/**
-		 * Names of properties in the with-clause of the @Spec-fpar's type. For example, as in:
-		 * 
-		 * constructor(@Spec specObj: ~i~this with { addProp: string }) { ... }
-		 * .
-		 */
-		public final ImmutableSet additionalProps;
-
-		new(FormalParameter fpar, Iterable additionalProps) {
-			this.fpar = Objects.requireNonNull(fpar);
-			this.additionalProps = ImmutableSet.copyOf(additionalProps);
-		}
-	}
-
-	/**
-	 * Amend the constructor of the given class with implicit functionality (e.g. initialization of instance fields).
-	 * Will create an implicit constructor declaration iff no constructor is defined in the N4JS source code AND an
-	 * implicit constructor is actually required.
-	 */
-	def public void amendConstructor(N4ClassDeclaration classDecl, SymbolTableEntry classSTE, SymbolTableEntryOriginal superClassSTE,
-		LinkedHashSet fieldsRequiringExplicitDefinition) {
-
-		val explicitCtorDecl = classDecl.ownedCtor; // the constructor defined in the N4JS source code or 'null' if none was defined
-		val ctorDecl = explicitCtorDecl ?: _N4MethodDecl(N4JSLanguageConstants.CONSTRUCTOR);
-
-		// amend formal parameters
-		val specInfo = amendFormalParametersOfConstructor(classDecl, ctorDecl, explicitCtorDecl);
-
-		// amend body
-		val isNonTrivial = amendBodyOfConstructor(classDecl, classSTE, superClassSTE,
-			ctorDecl, explicitCtorDecl, specInfo, fieldsRequiringExplicitDefinition);
-
-		// add constructor to classDecl (if necessary)
-		if (ctorDecl.eContainer === null && isNonTrivial) {
-			classDecl.ownedMembersRaw.add(0, ctorDecl);
-		}
-	}
-
-	def private SpecInfo amendFormalParametersOfConstructor(N4ClassDeclaration classDecl, N4MethodDeclaration ctorDecl, N4MethodDeclaration explicitCtorDecl) {
-		var specFpar = null as FormalParameter;
-		var specFparTypeRef = null as TypeRef;
-		
-		val hasExplicitCtor = explicitCtorDecl !== null;
-		if (hasExplicitCtor) {
-			// explicitly defined constructor
-			// --> nothing to be changed (use fpars from N4JS source code)
-
-			specFpar = ctorDecl.fpars.filter[AnnotationDefinition.SPEC.hasAnnotation(it)].head;
-			if (specFpar !== null) {
-				val typeRefNode = specFpar.declaredTypeRefNode;
-				if (typeRefNode !== null) {
-					specFparTypeRef = state.info.getOriginalProcessedTypeRef(typeRefNode);
-				}
-			}
-		} else {
-			// implicit constructor
-			// --> create fpars using fpars of nearest constructor in hierarchy as template
-
-			val templateCtor = getNearestConstructorInHierarchy(classDecl);
-			if (templateCtor !== null) {
-				for (templateFpar : templateCtor.fpars) {
-					val isSpecFpar = AnnotationDefinition.SPEC.hasAnnotation(templateFpar);
-					val newFpar = _Fpar(templateFpar.name, templateFpar.variadic, isSpecFpar);
-					ctorDecl.fpars += newFpar;
-					
-					if (isSpecFpar && specFpar === null) {
-						specFpar = newFpar;
-						specFparTypeRef = TypeUtils.copy(templateFpar.typeRef);
-					}
-				}
-			}
-		}
-
-		if (specFpar !== null) {
-			return new SpecInfo(specFpar, specFparTypeRef?.structuralMembers?.map[name] ?: #[]);
-		}
-		return null;
-	}
-
-	/**
-	 * Returns true iff the constructor is non-trivial, i.e. non-empty and containing more
-	 * than just the default super call.
-	 */
-	def private boolean amendBodyOfConstructor(N4ClassDeclaration classDecl, SymbolTableEntry classSTE, SymbolTableEntryOriginal superClassSTE,
-		N4MethodDeclaration ctorDecl, N4MethodDeclaration explicitCtorDecl, SpecInfo specInfo,
-		LinkedHashSet fieldsRequiringExplicitDefinition) {
-
-		val hasExplicitCtor = explicitCtorDecl !== null;
-		val body = ctorDecl.body;
-
-		val isDirectSubclassOfError = superClassSTE?.originalTarget===state.G.errorType;
-		val superCallIndex = if(explicitCtorDecl?.body!==null) explicitCtorDecl.superCallIndex else -1;
-		val hasExplicitSuperCall = superCallIndex>=0;
-		val explicitSuperCall = if(hasExplicitSuperCall) explicitCtorDecl.body.statements.get(superCallIndex);
-		var defaultSuperCall = null as ExpressionStatement;
-
-		var idx = if(hasExplicitSuperCall) superCallIndex + 1 else 0;
-
-		// add/replace/modify super call
-		if(hasExplicitSuperCall) {
-			// keep existing, explicit super call unchanged
-		} else {
-			// no explicitCtorDecl OR no body OR no explicit super call (and no direct subclass of Error)
-			// --> add default super call (if required)
-			if(superClassSTE!==null) {
-				val fparsOfSuperCtor = if (hasExplicitCtor) {
-					// explicit ctor without an explicit super call: only allowed if the super constructor
-					// does not have any arguments, so we can simply assume empty fpars here, without actually
-					// looking up the super constructor with #getNearestConstructorInHierarchy():
-					#[]
-				} else {
-					// no explicit ctor: the already created implicit constructor in 'ctorDecl' has the
-					// same fpars as the super constructor, so we can use those as a template:
-					ctorDecl.fpars
-				};
-				defaultSuperCall = createDefaultSuperCall(classDecl, superClassSTE, fparsOfSuperCtor);
-				idx = body.statements.insertAt(idx, defaultSuperCall);
-			}
-		}
-		if(isDirectSubclassOfError) {
-			// special case: add oddities for sub-classing Error
-			idx = body.statements.insertAt(idx,
-				createSubclassingErrorOddities(classDecl, ctorDecl.fpars, explicitSuperCall));
-		}
-
-		// if we are in a spec-constructor: prepare a local variable for the spec-object and
-		// ensure it is never 'undefined' or 'null'
-		var specObjSTE = null as SymbolTableEntry;
-		if (specInfo !== null) {
-			// let $specObj = specFpar || {};
-			val specFparSTE = findSymbolTableEntryForElement(specInfo.fpar, true);
-			val specObjVarDecl = _VariableDeclaration("$specObj", _OR(_IdentRef(specFparSTE), _ObjLit));
-			idx = body.statements.insertAt(idx, _VariableStatement(VariableStatementKeyword.CONST, specObjVarDecl));
-
-			specObjSTE = findSymbolTableEntryForElement(specObjVarDecl, true);
-		}
-
-		// add explicit definitions of instance fields (only for fields that actually require this)
-		idx = body.statements.insertAt(idx, classifierAssistant.createExplicitFieldDefinitions(classSTE, false, fieldsRequiringExplicitDefinition));
-
-		// add initialization code for instance fields
-		idx = body.statements.insertAt(idx, createInstanceFieldInitCode(classDecl, specInfo, specObjSTE, fieldsRequiringExplicitDefinition));
-
-		// add delegation to field initialization functions of all directly implemented interfaces
-		idx = body.statements.insertAt(idx, createDelegationToFieldInitOfImplementedInterfaces(classDecl, specObjSTE));
-
-		// check if constructor is non-trivial
-		val ctorDeclStmnts = ctorDecl.body.statements;
-		val bodyContainsOnlyDefaultSuperCall = defaultSuperCall !== null
-			&& ctorDeclStmnts.size === 1
-			&& ctorDeclStmnts.head === defaultSuperCall;
-		val isNonTrivialCtor = !ctorDeclStmnts.empty && !bodyContainsOnlyDefaultSuperCall;
-
-		return isNonTrivialCtor;
-	}
-
-	def private Statement[] createInstanceFieldInitCode(N4ClassDeclaration classDecl, SpecInfo specInfo, SymbolTableEntry specObjSTE, Set fieldsWithExplicitDefinition) {
-		val allFields = classDecl.ownedFields.filter[
-			!isStatic
-			&& !isConsumedFromInterface
-			&& !builtInOrProvidedByRuntime(state.info.getOriginalDefinedMember(it))
-		].toList;
-		if(specInfo!==null) {
-			// we have a spec-parameter -> we are in a spec-style constructor
-			val result = newArrayList;
-
-			// step #1: initialize all fields either with data from the specFpar OR or their initializer expression
-			val currFields = newArrayList;
-			var currFieldsAreSpecced = false;
-			for(field : allFields) {
-				val isSpecced = isPublic(field) || specInfo.additionalProps.contains(field.name);
-				if (isSpecced === currFieldsAreSpecced) {
-					currFields += field;
-				} else {
-					result += createFieldInitCodeForSeveralFields(currFields, currFieldsAreSpecced, specObjSTE);
-					currFields.clear();
-					currFields += field;
-					currFieldsAreSpecced = isSpecced;
-				}
-			}
-			result += createFieldInitCodeForSeveralFields(currFields, currFieldsAreSpecced, specObjSTE);
-
-			// step #2: invoke setters with data from specFpar
-			// (note: in case of undefined specFpar at runtime, setters should not be invoked, so we wrap in if statement)
-			val speccedSetters = classDecl.ownedSetters.filter[!isStatic && declaredModifiers.contains(N4Modifier.PUBLIC)].toList;
-			result += speccedSetters.map[createFieldInitCodeForSingleSpeccedSetter(specObjSTE)];
-
-			return result;
-		} else {
-			// simple: just initialize fields with data from their initializer expression
-			return allFields
-				.filter[!(expression===null && fieldsWithExplicitDefinition.contains(it))]
-				.map[createFieldInitCodeForSingleField];
-		}
-	}
-
-	def private Statement[] createFieldInitCodeForSeveralFields(Collection fieldDecls, boolean fieldsAreSpecced, SymbolTableEntry specObjSTE) {
-		if (fieldDecls.empty) {
-			return #[];
-		}
-		if (!fieldsAreSpecced) {
-			return fieldDecls.map[createFieldInitCodeForSingleField];
-		}
-		if (fieldDecls.size === 1) {
-			return #[ fieldDecls.head.createFieldInitCodeForSingleSpeccedField(specObjSTE) ];
-		}
-		return #[ fieldDecls.createFieldInitCodeForSeveralSpeccedFields(specObjSTE) ];
-	}
-
-	def private Statement createFieldInitCodeForSingleField(N4FieldDeclaration fieldDecl) {
-		// here we create:
-		//
-		//     this.fieldName = ;
-		// or
-		//     this.fieldName = undefined;
-		//
-		// NOTE: we set the field to 'undefined' even in the second case, because ...
-		// 1) it makes a difference when #hasOwnProperty(), etc. is used after the constructor returns,
-		// 2) for consistency with the method #createFieldInitCodeForSeveralSpeccedFields(), because with
-		//    destructuring as used by that method, the property will always be assigned (even if the
-		//    value is 'undefined' and there is no default).
-		//
-		val fieldSTE = findSymbolTableEntryForElement(fieldDecl, true);
-		return _ExprStmnt(_AssignmentExpr(
-			_PropertyAccessExpr(_ThisLiteral, fieldSTE),
-			if(fieldDecl.expression!==null) {
-				fieldDecl.expression // reusing the expression here
-			} else {
-				undefinedRef()
-			}
-		));
-	}
-
-	def private Statement createFieldInitCodeForSeveralSpeccedFields(Iterable fieldDecls, SymbolTableEntry specObjSTE) {
-		// here we create:
-		//
-		//     ({
-		//         fieldName: this.fieldName = ,
-		//         ...
-		//     } = spec);
-		//
-		return _ExprStmnt(
-			_Parenthesis(
-				_AssignmentExpr(
-					_ObjLit(
-						fieldDecls.map[fieldDecl|
-							val fieldSTE = findSymbolTableEntryForElement(fieldDecl, true);
-							val thisFieldName = _PropertyAccessExpr(_ThisLiteral, fieldSTE);
-							return fieldDecl.name -> if (fieldDecl.hasNonTrivialInitExpression) {
-								_AssignmentExpr(thisFieldName, fieldDecl.expression) // reusing the expression here
-							} else {
-								thisFieldName
-							};
-						]
-					),
-					_IdentRef(specObjSTE)
-				)
-			)
-		);
-	}
-
-	def private Statement createFieldInitCodeForSingleSpeccedField(N4FieldDeclaration fieldDecl, SymbolTableEntry specObjSTE) {
-		val fieldSTE = findSymbolTableEntryForElement(fieldDecl, true);
-		if (fieldDecl.hasNonTrivialInitExpression) {
-			// here we create:
-			//
-			//     this.fieldName = spec.fieldName === undefined ?  : spec.fieldName;
-			//
-			// NOTE: don't use something like "'fieldName' in spec" as the condition above, because that would
-			// not have the same behavior as destructuring in method #createFieldInitCodeForSeveralSpeccedFields()
-			// in case the property is present but has value 'undefined'!
-			//
-			return _ExprStmnt(_AssignmentExpr(
-				_PropertyAccessExpr(_ThisLiteral, fieldSTE),
-				// ? :
-				_ConditionalExpr(
-					// spec.fieldName === undefined
-					_EqualityExpr(_PropertyAccessExpr(specObjSTE, fieldSTE), EqualityOperator.SAME, undefinedRef()),
-					// 
-					if(fieldDecl.expression!==null) {
-						copy(fieldDecl.expression) // need to copy expression here, because it will be used again!
-					} else {
-						undefinedRef()
-					},
-					// spec.fieldName
-					_PropertyAccessExpr(specObjSTE, fieldSTE)
-				)
-			));
-		} else {
-			// we have a trivial init-expression ...
-
-			// here we create:
-			//
-			//     this.fieldName = spec.fieldName;
-			//
-			return _ExprStmnt(_AssignmentExpr(
-				_PropertyAccessExpr(_ThisLiteral, fieldSTE),
-				_PropertyAccessExpr(specObjSTE, fieldSTE)
-			));
-		}
-	}
-
-	def private Statement createFieldInitCodeForSingleSpeccedSetter(N4SetterDeclaration setterDecl, SymbolTableEntry specObjSTE) {
-		// here we create:
-		//
-		// 	if ('fieldName' in spec) {
-		//		this.fieldName = spec.fieldName;
-		// 	}
-		//
-
-		val setterSTE = findSymbolTableEntryForElement(setterDecl, true);
-		return _IfStmnt(
-			_RelationalExpr(
-				_StringLiteralForSTE(setterSTE), RelationalOperator.IN, _IdentRef(specObjSTE)
-			),
-			_ExprStmnt(
-				_AssignmentExpr(
-					_PropertyAccessExpr(_ThisLiteral, setterSTE),
-					_PropertyAccessExpr(specObjSTE, setterSTE)
-		)));
-	}
-
-	// NOTE: compare this to the super calls generated from SuperLiterals in SuperLiteralTransformation
-	def private ExpressionStatement createDefaultSuperCall(N4ClassDeclaration classDecl, SymbolTableEntry superClassSTE, FormalParameter[] fpars) {
-		val variadicCase = !fpars.empty && fpars.last.isVariadic;
-		val argsIter = fpars.map[findSymbolTableEntryForElement(it, true)].map[_Argument(_IdentRef(it))];
-		val args = new ArrayList(argsIter); // WARNING: .toList won't work!
-		if (variadicCase) {
-			args.last.spread = true;
-		}
-		return _ExprStmnt(_CallExpr() => [
-			target = _SuperLiteral();
-			arguments += args;
-		]);
-	}
-
-	/** To be inserted where the explicit or implicit super call would be located, normally. */
-	def private Statement[] createSubclassingErrorOddities(N4ClassDeclaration classDecl, FormalParameter[] fpars, Statement explicitSuperCall) {
-		return #[ _ExprStmnt(_Snippet('''
-			this.name = this.constructor.n4type.name;
-			if (Error.captureStackTrace) {
-			    Error.captureStackTrace(this, this.name);
-			}
-		''')) ];
-	}
-
-	def private Statement[] createDelegationToFieldInitOfImplementedInterfaces(N4ClassDeclaration classDecl, SymbolTableEntry /*nullable*/ specObjSTE ) {
-
-		val implementedIfcSTEs = typeAssistant.getSuperInterfacesSTEs(classDecl).filter [
-			// regarding the cast to TInterface: see preconditions of ClassDeclarationTransformation
-			// regarding the entire line: generate $fieldInit call only if the interface is neither built-in nor provided by runtime nor shape
-			!builtInOrProvidedByRuntimeOrShape(originalTarget as TInterface);
-		];
-		if (implementedIfcSTEs.empty) {
-			return #[];
-		}
-		
-
-		val LinkedHashSet ownedInstanceDataFieldsSupressMixin = newLinkedHashSet
-		ownedInstanceDataFieldsSupressMixin.addAll(classDecl.ownedGetters.filter[!isConsumedFromInterface].map[name])
-		ownedInstanceDataFieldsSupressMixin.addAll(classDecl.ownedSetters.filter[!isConsumedFromInterface].map[name])
-
-		val classSTE = findSymbolTableEntryForElement(classDecl, false);
-		val $initFieldsFromInterfacesSTE = steFor_$initFieldsFromInterfaces;
-
-		return #[ _ExprStmnt(
-			_CallExpr(
-				_IdentRef($initFieldsFromInterfacesSTE),
-				_ThisLiteral,
-				_IdentRef(classSTE),
-				if (specObjSTE !== null) {
-					_IdentRef(specObjSTE)
-				} else {
-					undefinedRef()
-				},
-				_ObjLit(
-					ownedInstanceDataFieldsSupressMixin.map[
-						_PropertyNameValuePair(it, _TRUE)
-					]
-				)
-			)
-		)];
-	}
-
-	// ################################################################################################################
-	// UTILITY STUFF
-
-	def private int getSuperCallIndex(N4MethodDeclaration ownedCtor) {
-		val stmnts = ownedCtor?.body?.statements;
-		if(stmnts!==null && !stmnts.empty) {
-			for(i : 0.. int insertAt(List list, int index, T element) {
-		list.add(index, element);
-		return index + 1;
-	}
-
-	def private static  int insertAt(List list, int index, Collection elements) {
-		list.addAll(index, elements);
-		return index + elements.size();
-	}
-}
diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassifierAssistant.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassifierAssistant.java
new file mode 100644
index 0000000000..9ac9a2eba8
--- /dev/null
+++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassifierAssistant.java
@@ -0,0 +1,163 @@
+/**
+ * Copyright (c) 2020 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.transpiler.es.assistants;
+
+import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._AssignmentExpr;
+import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr;
+import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ExprStmnt;
+import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef;
+import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr;
+import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteral;
+import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ThisLiteral;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.n4js.AnnotationDefinition;
+import org.eclipse.n4js.n4JS.Expression;
+import org.eclipse.n4js.n4JS.ExpressionStatement;
+import org.eclipse.n4js.n4JS.N4ClassDeclaration;
+import org.eclipse.n4js.n4JS.N4ClassifierDeclaration;
+import org.eclipse.n4js.n4JS.N4FieldDeclaration;
+import org.eclipse.n4js.n4JS.N4MemberDeclaration;
+import org.eclipse.n4js.n4JS.Statement;
+import org.eclipse.n4js.n4JS.StringLiteral;
+import org.eclipse.n4js.transpiler.TransformationAssistant;
+import org.eclipse.n4js.transpiler.im.SymbolTableEntry;
+import org.eclipse.n4js.ts.types.TClass;
+import org.eclipse.n4js.ts.types.TField;
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
+import org.eclipse.xtext.xbase.lib.Pair;
+
+import com.google.common.collect.Iterables;
+
+/**
+ * Helper methods for transformations of class and interface declarations.
+ */
+public class ClassifierAssistant extends TransformationAssistant {
+
+	/**
+	 * Returns a set/list of data fields that require an explicit property definition. Actual creation of those explicit
+	 * property definitions is done with method
+	 * {@link #createExplicitFieldDefinitions(SymbolTableEntry, boolean, LinkedHashSet)}.
+	 *
+	 * 

Background

+ * + * Data fields that override an accessor require an explicit property definition along the lines of + * + *
+	 * Object.defineProperty(this, "myField", {writable: true, ...});
+	 * 
+ * + * A simple initialization of the form this.myField = undefined; would throw an exception at runtime + * (in case of overriding only a getter) or would simply invoke the setter (in case of overriding a setter or an + * accessor pair). + *

+ * This applies to both instance and static fields. + */ + public LinkedHashSet findFieldsRequiringExplicitDefinition(N4ClassDeclaration classDecl) { + TClass tClass = getState().info.getOriginalDefinedType(classDecl); + Set> fieldsOverridingAnAccessor = null; + if (tClass != null) { + fieldsOverridingAnAccessor = IterableExtensions.toSet(IterableExtensions.map( + getState().memberCollector.computeOwnedFieldsOverridingAnAccessor(tClass, true), + f -> Pair.of(f.isStatic(), f.getName()))); + } + + LinkedHashSet result = new LinkedHashSet<>(); + for (N4MemberDeclaration member : classDecl.getOwnedMembers()) { + if (member instanceof N4FieldDeclaration + && AnnotationDefinition.OVERRIDE.hasAnnotation(member) + && (fieldsOverridingAnAccessor == null + || fieldsOverridingAnAccessor.contains(Pair.of(member.isStatic(), member.getName())))) { + result.add((N4FieldDeclaration) member); + } + } + + return result; + } + + /** + * Creates explicit property definitions for the fields identified by method + * {@link #findFieldsRequiringExplicitDefinition(N4ClassDeclaration)}. + */ + public List createExplicitFieldDefinitions(SymbolTableEntry steClass, boolean staticCase, + LinkedHashSet fieldsRequiringExplicitDefinition) { + + // Creates either + // $defineFields(D, "staticFieldName1", "staticFieldName2", ...); + // or + // $defineFields(this, "instanceFieldName1", "instanceFieldName2", ...); + List names = new ArrayList<>(); + for (N4FieldDeclaration fd : fieldsRequiringExplicitDefinition) { + if (fd.isStatic() == staticCase) { + names.add(_StringLiteral(fd.getName())); + } + } + + if (names.isEmpty()) { + return Collections.emptyList(); + } + + List args = new ArrayList<>(); + args.add((staticCase) ? __NSSafe_IdentRef(steClass) : _ThisLiteral()); + args.addAll(names); + + ExpressionStatement result = _ExprStmnt( + _CallExpr( + _IdentRef(steFor_$defineFields()), + Iterables.toArray(args, Expression.class))); + return List.of(result); + } + + /** + * Creates a new list of statements to initialize the static fields of the given classifier declaration. + *

+ * Clients of this method may modify the returned list. + */ + public List createStaticFieldInitializations(N4ClassifierDeclaration classifierDecl, + SymbolTableEntry classifierSTE, + Set fieldsWithExplicitDefinition) { + + List result = new ArrayList<>(); + for (N4MemberDeclaration member : classifierDecl.getOwnedMembers()) { + if (member.isStatic() && member instanceof N4FieldDeclaration + && !(((N4FieldDeclaration) member).getExpression() == null + && fieldsWithExplicitDefinition.contains(member))) { + + Statement sic = createStaticInitialiserCode((N4FieldDeclaration) member, classifierSTE); + result.add(sic); + } + } + + return result; + } + + private Statement createStaticInitialiserCode(N4FieldDeclaration fieldDecl, SymbolTableEntry classSTE) { + TField tField = (TField) getState().info.getOriginalDefinedMember(fieldDecl); + SymbolTableEntry fieldSTE = (tField != null) ? getSymbolTableEntryOriginal(tField, true) + : findSymbolTableEntryForElement(fieldDecl, true); + + ExpressionStatement exprStmnt = _ExprStmnt( + _AssignmentExpr( + _PropertyAccessExpr(__NSSafe_IdentRef(classSTE), fieldSTE), + fieldDecl.getExpression() == null ? undefinedRef() : fieldDecl.getExpression()// reuse existing + // expression + // (if present) + )); + getState().tracer.copyTrace(fieldDecl, exprStmnt); + + return exprStmnt; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassifierAssistant.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassifierAssistant.xtend deleted file mode 100644 index c5f58728dd..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ClassifierAssistant.xtend +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Copyright (c) 2020 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.transpiler.es.assistants - -import java.util.LinkedHashSet -import java.util.List -import java.util.Set -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.Statement -import org.eclipse.n4js.transpiler.TransformationAssistant -import org.eclipse.n4js.transpiler.im.SymbolTableEntry -import org.eclipse.n4js.ts.types.TField - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - * Helper methods for transformations of class and interface declarations. - */ -class ClassifierAssistant extends TransformationAssistant { - - /** - * Returns a set/list of data fields that require an explicit property definition. Actual creation of those explicit - * property definitions is done with method {@link #createExplicitFieldDefinitions(SymbolTableEntry, boolean, LinkedHashSet)}. - * - *

Background

- * - * Data fields that override an accessor require an explicit property definition along the lines of - *
-	 * Object.defineProperty(this, "myField", {writable: true, ...});
-	 * 
- * A simple initialization of the form this.myField = undefined; would throw an exception at runtime (in case of - * overriding only a getter) or would simply invoke the setter (in case of overriding a setter or an accessor pair). - *

- * This applies to both instance and static fields. - */ - def public LinkedHashSet findFieldsRequiringExplicitDefinition(N4ClassDeclaration classDecl) { - val tClass = state.info.getOriginalDefinedType(classDecl); - val fieldsOverridingAnAccessor = if (tClass !== null) { - state.memberCollector.computeOwnedFieldsOverridingAnAccessor(tClass, true) - .map[static -> name] - .toSet; - }; - val result = newLinkedHashSet; - result += classDecl.ownedMembers - .filter[AnnotationDefinition.OVERRIDE.hasAnnotation(it)] - .filter(N4FieldDeclaration) - .filter[fieldsOverridingAnAccessor === null || fieldsOverridingAnAccessor.contains(static -> name)]; - return result; - } - - /** - * Creates explicit property definitions for the fields identified by method - * {@link #findFieldsRequiringExplicitDefinition(N4ClassDeclaration)}. - */ - def public List createExplicitFieldDefinitions(SymbolTableEntry steClass, boolean staticCase, - LinkedHashSet fieldsRequiringExplicitDefinition) { - - // Creates either - // $defineFields(D, "staticFieldName1", "staticFieldName2", ...); - // or - // $defineFields(this, "instanceFieldName1", "instanceFieldName2", ...); - val names = fieldsRequiringExplicitDefinition.filter[static === staticCase].map[name].map[_StringLiteral(it)].toList; - if (names.empty) { - return #[]; - } - val result = _ExprStmnt( - _CallExpr( - _IdentRef(steFor_$defineFields), - #[ - if (staticCase) { - __NSSafe_IdentRef(steClass) - } else { - _ThisLiteral - } - ] + names - ) - ); - return #[ result ]; - } - - /** - * Creates a new list of statements to initialize the static fields of the given classifier declaration. - *

- * Clients of this method may modify the returned list. - */ - def public List createStaticFieldInitializations(N4ClassifierDeclaration classifierDecl, SymbolTableEntry classifierSTE, - Set fieldsWithExplicitDefinition) { - - return classifierDecl.ownedMembers - .filter[isStatic] - .filter(N4FieldDeclaration) - .filter[!(expression===null && fieldsWithExplicitDefinition.contains(it))] - .map[createStaticInitialiserCode(classifierSTE)] - .filterNull - .toList; - } - - def private Statement createStaticInitialiserCode(N4FieldDeclaration fieldDecl, SymbolTableEntry classSTE) { - val tField = state.info.getOriginalDefinedMember(fieldDecl) as TField; - val fieldSTE = if (tField !== null) getSymbolTableEntryOriginal(tField, true) else findSymbolTableEntryForElement(fieldDecl, true); - - val exprStmnt = _ExprStmnt( - _AssignmentExpr( - _PropertyAccessExpr(__NSSafe_IdentRef(classSTE), fieldSTE), - fieldDecl.expression ?: undefinedRef // reuse existing expression (if present) - ) - ); - state.tracer.copyTrace(fieldDecl, exprStmnt); - - return exprStmnt; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DelegationAssistant.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DelegationAssistant.java new file mode 100644 index 0000000000..bded2e2cf1 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DelegationAssistant.java @@ -0,0 +1,435 @@ +/** + * 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.transpiler.es.assistants; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Block; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ExprStmnt; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Fpar; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IndexAccessExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._LiteralOrComputedPropertyName; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4GetterDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4MethodDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4SetterDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ReturnStmnt; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteralForSTE; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ThisLiteral; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.functionType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.objectType; + +import org.eclipse.n4js.n4JS.Block; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor; +import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName; +import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4GetterDeclaration; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.N4MethodDeclaration; +import org.eclipse.n4js.n4JS.N4Modifier; +import org.eclipse.n4js.n4JS.N4SetterDeclaration; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.transpiler.TransformationAssistant; +import org.eclipse.n4js.transpiler.assistants.TypeAssistant; +import org.eclipse.n4js.transpiler.im.DelegatingGetterDeclaration; +import org.eclipse.n4js.transpiler.im.DelegatingMember; +import org.eclipse.n4js.transpiler.im.DelegatingMethodDeclaration; +import org.eclipse.n4js.transpiler.im.DelegatingSetterDeclaration; +import org.eclipse.n4js.transpiler.im.ImFactory; +import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.ts.types.ContainerType; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TInterface; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.TSetter; +import org.eclipse.n4js.ts.types.util.SuperInterfacesIterable; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.RecursionGuard; + +import com.google.common.collect.Lists; +import com.google.inject.Inject; + +/** + * This assistant provides helper methods to create members that delegate to some other target member (see + * {@link DelegationAssistant#createDelegatingMember(TClassifier, TMember) createDelegatingMember(TClassifier, + * TMember)}) and to create the Javascript output code to actually implement these delegating members in the transpiler + * output (see {@link DelegationAssistant#createOrdinaryMemberForDelegatingMember(DelegatingMember) }). + *

+ * Usually inherited members in a classifier do not require any special code, because they will be accessed via the + * native prototype chain mechanism of Javascript. However, there are special cases when some special code has to be + * generated for an inherited member in order to properly access that inherited member, because it is not available via + * the ordinary prototype chain. + */ +public class DelegationAssistant extends TransformationAssistant { + + @Inject + private TypeAssistant typeAssistant; + + /** + * Creates a new delegating member intended to be inserted into classifier origin in order to delegate + * from origin to the given member target. The target member is assumed to be an inherited + * or consumed member of classifier origin, i.e. it is assumed to be located in one of the ancestor + * classes of origin or one of its directly or indirectly implemented interfaces (but not in origin + * itself!). + *

+ * Throws exceptions in case of invalid arguments or an invalid internal getState(), see implementation for details. + */ + public DelegatingMember createDelegatingMember(TClassifier origin, TMember target) { + if (target.getContainingType() == origin) { + throw new IllegalArgumentException("no point in delegating to an owned member"); + } + DelegatingMember result = null; + if (target instanceof TGetter) { + result = ImFactory.eINSTANCE.createDelegatingGetterDeclaration(); + ((DelegatingGetterDeclaration) result).setDeclaredName(_LiteralOrComputedPropertyName(target.getName())); + } + if (target instanceof TSetter) { + result = ImFactory.eINSTANCE.createDelegatingSetterDeclaration(); + ((DelegatingSetterDeclaration) result).setDeclaredName(_LiteralOrComputedPropertyName(target.getName())); + } + if (target instanceof TMethod) { + result = ImFactory.eINSTANCE.createDelegatingMethodDeclaration(); + ((DelegatingMethodDeclaration) result).setDeclaredName(_LiteralOrComputedPropertyName(target.getName())); + } + if (target instanceof TField || result == null) { + throw new IllegalArgumentException("delegation to fields not supported yet"); + } + + // set simple properties + result.setDelegationTarget(getSymbolTableEntryOriginal(target, true)); + if (target.isStatic()) { + result.getDeclaredModifiers().add(N4Modifier.STATIC); + } + // set delegationBaseType and delegationSuperClassSteps + if (origin instanceof TInterface) { + // we are in an interface and the target must also be in an interface + if (!(target.eContainer() instanceof TInterface)) { + throw new IllegalArgumentException("cannot delegate from an interface to member of a class"); + } + ContainerType tSuper = getDirectSuperTypeBequestingMember(origin, target); + // we know the STE of tSuper must already exist, because it is a direct super type and must therefore be + // referenced in the declaration of classifier origin + result.setDelegationBaseType(getSymbolTableEntryOriginal(tSuper, true)); + result.setDelegationSuperClassSteps(0); + } else if (origin instanceof TClass) { + // we are in a class and the target may either be in a class or an interface + TClass tAncestor = getAncestorClassBequestingMember((TClass) origin, target); + if (tAncestor != origin) { + // we are inheriting 'target' from one of our ancestor classes -> delegate to that ancestor class + // (note: this includes the case the 'target' is contained in an interface and one of our ancestor + // classes implements that interface) + TClass tSuper = (TClass) ((TClass) origin).getSuperClassRef().getDeclaredType(); + result.setDelegationBaseType(getSymbolTableEntryOriginal(tSuper, true)); + result.setDelegationSuperClassSteps(getDistanceToAncestorClass((TClass) origin, tAncestor) - 1); + } else if (tAncestor != null) { + // we are consuming 'target' from one of our directly implemented interfaces or its extended interfaces + // (similar as case "origin instanceof TInterface" above) + ContainerType tSuper = getDirectSuperTypeBequestingMember(origin, target); + result.setDelegationBaseType(getSymbolTableEntryOriginal(tSuper, true)); + result.setDelegationSuperClassSteps(0); + } else { + throw new IllegalStateException("cannot find target (probably not an inherited member)"); + } + } else { + throw new IllegalArgumentException("unsupported subtype of TClassifier: " + origin.eClass().getName()); + } + // set some properties to let this delegating member behave more like an ordinary member of the same type + result.setDelegationTargetIsAbstract(target.isAbstract()); + if (!target.isAbstract()) { + ((FunctionOrFieldAccessor) result).setBody(_Block()); + } + return result; + } + + /** + * Convenience method for replacing each delegating member in the given declaration by an ordinary member created + * with method {@link #createOrdinaryMemberForDelegatingMember(DelegatingMember)}. Will modify the given classifier + * declaration. + */ + public void replaceDelegatingMembersByOrdinaryMembers(N4ClassifierDeclaration classifierDecl) { + for (N4MemberDeclaration currMember : Lists.newArrayList(classifierDecl.getOwnedMembersRaw())) { + if (currMember instanceof DelegatingMember) { + N4MemberDeclaration resolvedDelegatingMember = createOrdinaryMemberForDelegatingMember( + (DelegatingMember) currMember); + replace(currMember, resolvedDelegatingMember); + } + } + } + + /** Creates a {@link N4MemberDeclaration} for the given delegator */ + public N4MemberDeclaration createOrdinaryMemberForDelegatingMember(DelegatingMember delegator) { + String targetNameStr = delegator.getDelegationTarget().getName(); + LiteralOrComputedPropertyName targetName; + if (targetNameStr != null && targetNameStr.startsWith(N4JSLanguageUtils.SYMBOL_IDENTIFIER_PREFIX)) { + targetName = _LiteralOrComputedPropertyName(typeAssistant.getMemberNameAsSymbol(targetNameStr), + targetNameStr); + } else { + targetName = _LiteralOrComputedPropertyName(targetNameStr); + } + + Block body = createBodyForDelegatingMember(delegator); + if (delegator instanceof DelegatingGetterDeclaration) { + return _N4GetterDecl(targetName, body); + } + if (delegator instanceof DelegatingSetterDeclaration) { + return _N4SetterDecl(targetName, _Fpar("value"), body); + } + if (delegator instanceof DelegatingMethodDeclaration) { + return _N4MethodDecl(targetName, body); + } + return null; + } + + private Block createBodyForDelegatingMember(DelegatingMember delegator) { + SymbolTableEntryOriginal baseSTE = delegator.getDelegationBaseType(); + boolean baseIsInterface = baseSTE == null ? false : baseSTE.getOriginalTarget() instanceof TInterface; + + Expression targetAccess; + if (baseIsInterface) { + boolean targetIsStatic = delegator.isStatic(); + Expression objOfInterfaceOfTargetExpr = createAccessToInterfaceObject(baseSTE, targetIsStatic); + targetAccess = createAccessToMemberFunction(objOfInterfaceOfTargetExpr, !targetIsStatic, delegator); + } else { + Expression ctorOfClassOfTarget = createAccessToClassConstructor(baseSTE, + delegator.getDelegationSuperClassSteps()); + + // based on that constructor expression, now create an expression that evaluates to the member function of + // the target member: + targetAccess = createAccessToMemberFunction(ctorOfClassOfTarget, false, delegator); + } + + ParameterizedCallExpression callExpr = _CallExpr( + _PropertyAccessExpr( + targetAccess, + getSymbolTableEntryForMember(functionType(getState().G), "apply", false, false, true)), + _ThisLiteral(), + _IdentRef(steFor_arguments())); + + if (delegator instanceof DelegatingSetterDeclaration) { + return _Block( + _ExprStmnt(callExpr)); + } else { + return _Block( + _ReturnStmnt(callExpr)); + } + } + + /** + * Creates an expression that will evaluate to the constructor of the class denoted by the given symbol table entry + * or one of its super classes (depending on argument superClassSteps). + *

+ * For example, if classSTE denotes a class "C", then this will produce an expression like + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Cfor superClassSteps == 0
Object.getPrototypeOf(C)for superClassSteps == 1
Object.getPrototypeOf(Object.getPrototypeOf(C))for superClassSteps == 2
+ */ + private Expression createAccessToClassConstructor(SymbolTableEntry classSTE, int superClassSteps) { + TClassifier objectType = objectType(getState().G); + SymbolTableEntryOriginal objectSTE = getSymbolTableEntryOriginal(objectType, true); + Expression result = __NSSafe_IdentRef(classSTE); // this is the "C" in the above examples + // for each super-class-step wrap 'result' into "Object.getPrototypeOf(result)" + if (superClassSteps > 0) { + SymbolTableEntryOriginal getPrototypeOfSTE = getSymbolTableEntryForMember(objectType, "getPrototypeOf", + false, true, true); + for (int n = 0; n < superClassSteps; n++) { + result = _CallExpr( + _PropertyAccessExpr(objectSTE, getPrototypeOfSTE), + result); + } + } + return result; + } + + private Expression createAccessToInterfaceObject(SymbolTableEntry ifcSTE, boolean targetIsStatic) { + Expression result = __NSSafe_IdentRef(ifcSTE); + if (!targetIsStatic) { + result = _PropertyAccessExpr(result, steFor_$defaultMembers()); + } + return result; + } + + /** + * Same as {@link #createAccessToMemberDescriptor(Expression, boolean, N4MemberDeclaration)}, but will add a + * property access to the Javascript function representing the member, which is stored in the member definition (by + * appending ".get", ".set", or ".value" depending on the type of member). + *

+ * Since fields do not have such a function this will throw an exception if given member is a field. + */ + private Expression createAccessToMemberFunction(Expression protoOrCtorExpr, boolean exprIsProto, + N4MemberDeclaration member) { + if (member instanceof N4FieldDeclaration) { + throw new IllegalArgumentException("no member function available for fields"); + } + if (member instanceof N4MethodDeclaration) { + // for methods we can use a simple property access instead of Object.getOwnPropertyDescriptor() + String memberName = member.getName(); + boolean memberIsSymbol = memberName != null + && memberName.startsWith(N4JSLanguageUtils.SYMBOL_IDENTIFIER_PREFIX); + SymbolTableEntry memberSTE = findSymbolTableEntryForElement(member, true); + return (!memberIsSymbol) ? _PropertyAccessExpr(protoOrCtorExpr, memberSTE) + : _IndexAccessExpr(protoOrCtorExpr, typeAssistant.getMemberNameAsSymbol(memberName)); + } + // for other members (i.e. getters and setters) we need to retrieve the property descriptor: + Expression accessToMemberDefinition = createAccessToMemberDescriptor(protoOrCtorExpr, exprIsProto, member); + // append ".get", ".set", or ".value" depending on member type + ParameterizedPropertyAccessExpression_IM result = _PropertyAccessExpr(accessToMemberDefinition, + getPropertyDescriptorValueProperty(member)); + return result; + } + + /** + * Given an expression that will evaluate to a prototype or constructor, this method returns an expression that will + * evaluate to the property descriptor of a particular member. + * + * @param protoOrCtorExpr + * an expression that is expected to evaluate to a prototype or a constructor. + * @param exprIsProto + * tells whether argument protoOrCtorExpr will evaluate to a prototype or a constructor: if + * true, it will evaluate to a prototype, if false it will evaluate to a constructor. + * @param member + * the member. + */ + private Expression createAccessToMemberDescriptor(Expression protoOrCtorExpr, boolean exprIsProto, + N4MemberDeclaration member) { + String memberName = member.getName(); + boolean memberIsSymbol = memberName != null + && memberName.startsWith(N4JSLanguageUtils.SYMBOL_IDENTIFIER_PREFIX); + SymbolTableEntry memberSTE = findSymbolTableEntryForElement(member, true); + TClassifier objectType = objectType(getState().G); + SymbolTableEntryOriginal objectSTE = getSymbolTableEntryOriginal(objectType, true); + SymbolTableEntryOriginal getOwnPropertyDescriptorSTE = getSymbolTableEntryForMember(objectType, + "getOwnPropertyDescriptor", false, true, true); + // compute first argument to the #getOwnPropertyDescriptor() call: + boolean isStatic = member.isStatic(); + var arg0 = protoOrCtorExpr; + if (!exprIsProto && !isStatic) { + // got a constructor, but need a prototype -> append ".prototype" + SymbolTableEntryOriginal prototypeSTE = getSymbolTableEntryForMember(objectType, "prototype", false, true, + true); + arg0 = _PropertyAccessExpr(arg0, prototypeSTE); + } else if (exprIsProto && isStatic) { + // got a prototype, but need a constructor -> append ".constructor" + SymbolTableEntryOriginal constructorSTE = getSymbolTableEntryForMember(objectType, "constructor", false, + false, true); + arg0 = _PropertyAccessExpr(arg0, constructorSTE); + } + + // compute second argument to the #getOwnPropertyDescriptor() call: + Expression arg1 = (!memberIsSymbol) ? _StringLiteralForSTE(memberSTE) + : typeAssistant.getMemberNameAsSymbol(memberName); + // create #getOwnPropertyDescriptor() call + ParameterizedCallExpression result = _CallExpr(_PropertyAccessExpr(objectSTE, getOwnPropertyDescriptorSTE), + arg0, arg1); + return result; + } + + /** + * Returns the direct super type (i.e. immediate super class or directly implemented interface) of the given + * classifier through which the given classifier inherits the given inherited member. Fails fast in case of + * inconsistencies. + */ + private ContainerType getDirectSuperTypeBequestingMember(TClassifier classifier, TMember inheritedMember) { + return getState().memberCollector.directSuperTypeBequestingMember(classifier, inheritedMember); + } + + /** + * Returns the ancestor class (i.e. direct or indirect super class) of the given classifier that either contains the + * given inherited member (if given member is contained in a class) or consumes the given member (if given member is + * contained in an interface). + *

+ * For example: + * + *

+	 * interface I {
+	 * 	m(){}
+	 * }
+	 * class A implements I {
+	 * }
+	 * class B extends A {
+	 * }
+	 * class C extends B {
+	 * }
+	 * 
+ * + * With the above type declarations, for arguments C and m this method would return class + * A. + */ + private TClass getAncestorClassBequestingMember(TClass classifier, TMember inheritedOrConsumedMember) { + ContainerType containingType = inheritedOrConsumedMember.getContainingType(); + if (containingType == classifier) { + return classifier; + } else if (containingType instanceof TInterface) { + return SuperInterfacesIterable.of(classifier).findClassImplementingInterface((TInterface) containingType); + } else if (containingType instanceof TClass) { + return (TClass) containingType;// note: we do not check if containingType is actually an ancestor of + // 'classifier' + } else { + throw new IllegalArgumentException( + "unsupported subtype of TClassifier: " + containingType.eClass().getName()); + } + } + + /** + * Returns distance to given ancestor or 0 if second argument is 'base' or not an ancestor or null. + */ + private static int getDistanceToAncestorClass(TClass base, TClass ancestorClass) { + if (ancestorClass == null || ancestorClass == base) { + return 0; + } + RecursionGuard guard = new RecursionGuard<>(); + int result = 0; + TClass curr = base; + while (curr != null && curr != ancestorClass) { + if (guard.tryNext(curr)) { + result++; + curr = curr.getSuperClassRef() == null ? null : (TClass) curr.getSuperClassRef().getDeclaredType(); + // no need to call guard.done() + } + } + return (curr != null) ? result : 0; + } + + /** + * Returns symbol table entry for the property in a Javascript property descriptor that holds the actual value, i.e. + * the function expression implementing the member. + */ + private SymbolTableEntry getPropertyDescriptorValueProperty(N4MemberDeclaration delegator) { + if (delegator instanceof N4GetterDeclaration) { + return steFor_get(); + } + if (delegator instanceof N4SetterDeclaration) { + return steFor_set(); + } + if (delegator instanceof N4MethodDeclaration) { + return steFor_value(); + } + return null; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DelegationAssistant.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DelegationAssistant.xtend deleted file mode 100644 index 0db5dc519a..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DelegationAssistant.xtend +++ /dev/null @@ -1,376 +0,0 @@ -/** - * 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.transpiler.es.assistants - -import com.google.common.collect.Lists -import com.google.inject.Inject -import org.eclipse.n4js.n4JS.Block -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.N4GetterDeclaration -import org.eclipse.n4js.n4JS.N4MemberDeclaration -import org.eclipse.n4js.n4JS.N4MethodDeclaration -import org.eclipse.n4js.n4JS.N4Modifier -import org.eclipse.n4js.n4JS.N4SetterDeclaration -import org.eclipse.n4js.transpiler.TransformationAssistant -import org.eclipse.n4js.transpiler.assistants.TypeAssistant -import org.eclipse.n4js.transpiler.im.DelegatingGetterDeclaration -import org.eclipse.n4js.transpiler.im.DelegatingMember -import org.eclipse.n4js.transpiler.im.DelegatingMethodDeclaration -import org.eclipse.n4js.transpiler.im.DelegatingSetterDeclaration -import org.eclipse.n4js.transpiler.im.ImFactory -import org.eclipse.n4js.transpiler.im.SymbolTableEntry -import org.eclipse.n4js.ts.types.ContainerType -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TField -import org.eclipse.n4js.ts.types.TGetter -import org.eclipse.n4js.ts.types.TInterface -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.ts.types.TSetter -import org.eclipse.n4js.ts.types.util.SuperInterfacesIterable -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.RecursionGuard - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * This assistant provides helper methods to create members that delegate to some other target member (see - * {@link DelegationAssistant#createDelegatingMember(TClassifier, TMember) createDelegatingMember(TClassifier, TMember)}) - * and to create the Javascript output code to actually implement these delegating members in the transpiler output - * (see {@link DelegationAssistant#createDelegation(DelegatingMember) createDelegation(DelegatingMember)}). - *

- * Usually inherited members in a classifier do not require any special code, because they will be accessed via the - * native prototype chain mechanism of Javascript. However, there are special cases when some special code has to be - * generated for an inherited member in order to properly access that inherited member, because it is not available - * via the ordinary prototype chain. - */ -class DelegationAssistant extends TransformationAssistant { - - @Inject private TypeAssistant typeAssistant; - - - /** - * Creates a new delegating member intended to be inserted into classifier origin in order to delegate - * from origin to the given member target. The target member is assumed to be an inherited - * or consumed member of classifier origin, i.e. it is assumed to be located in one of the ancestor - * classes of origin or one of its directly or indirectly implemented interfaces (but not in origin - * itself!). - *

- * Throws exceptions in case of invalid arguments or an invalid internal state, see implementation for details. - */ - def public DelegatingMember createDelegatingMember(TClassifier origin, TMember target) { - if(target.containingType===origin) { - throw new IllegalArgumentException("no point in delegating to an owned member"); - } - val result = switch(target) { - TField: throw new IllegalArgumentException("delegation to fields not supported yet") - TGetter: ImFactory.eINSTANCE.createDelegatingGetterDeclaration - TSetter: ImFactory.eINSTANCE.createDelegatingSetterDeclaration - TMethod: ImFactory.eINSTANCE.createDelegatingMethodDeclaration - }; - // set simple properties - result.declaredName = _LiteralOrComputedPropertyName(target.name); - result.delegationTarget = getSymbolTableEntryOriginal(target, true); - if(target.static) { - result.declaredModifiers += N4Modifier.STATIC; - } - // set delegationBaseType and delegationSuperClassSteps - if(origin instanceof TInterface) { - // we are in an interface and the target must also be in an interface - if(!(target.eContainer instanceof TInterface)) { - throw new IllegalArgumentException("cannot delegate from an interface to member of a class"); - } - val tSuper = getDirectSuperTypeBequestingMember(origin, target); - // we know the STE of tSuper must already exist, because it is a direct super type and must therefore be - // referenced in the declaration of classifier origin - result.delegationBaseType = getSymbolTableEntryOriginal(tSuper, true); - result.delegationSuperClassSteps = 0; - } else if(origin instanceof TClass) { - // we are in a class and the target may either be in a class or an interface - val tAncestor = getAncestorClassBequestingMember(origin, target); - if(tAncestor!==origin) { - // we are inheriting 'target' from one of our ancestor classes -> delegate to that ancestor class - // (note: this includes the case the 'target' is contained in an interface and one of our ancestor - // classes implements that interface) - val tSuper = origin.superClassRef.declaredType as TClass; - result.delegationBaseType = getSymbolTableEntryOriginal(tSuper, true); - result.delegationSuperClassSteps = origin.getDistanceToAncestorClass(tAncestor) - 1; - } else if(tAncestor!==null) { - // we are consuming 'target' from one of our directly implemented interfaces or its extended interfaces - // (similar as case "origin instanceof TInterface" above) - val tSuper = getDirectSuperTypeBequestingMember(origin, target); - result.delegationBaseType = getSymbolTableEntryOriginal(tSuper, true); - result.delegationSuperClassSteps = 0; - } else { - throw new IllegalStateException("cannot find target (probably not an inherited member)"); - } - } else { - throw new IllegalArgumentException("unsupported subtype of TClassifier: " + origin.eClass.name); - } - // set some properties to let this delegating member behave more like an ordinary member of the same type - result.delegationTargetIsAbstract = target.isAbstract; - if( ! target.isAbstract ) result.body = _Block(); - return result; - } - - /** - * Convenience method for replacing each delegating member in the given declaration by an ordinary member - * created with method {@link #createOrdinaryMemberForDelegatingMember(DelegatingMember)}. Will modify the - * given classifier declaration. - */ - def public void replaceDelegatingMembersByOrdinaryMembers(N4ClassifierDeclaration classifierDecl) { - for (currMember : Lists.newArrayList(classifierDecl.ownedMembersRaw)) { - if (currMember instanceof DelegatingMember) { - val resolvedDelegatingMember = createOrdinaryMemberForDelegatingMember(currMember); - replace(currMember, resolvedDelegatingMember); - } - } - } - - def public N4MemberDeclaration createOrdinaryMemberForDelegatingMember(DelegatingMember delegator) { - val targetNameStr = delegator.delegationTarget.name; - val targetName = if (targetNameStr!==null && targetNameStr.startsWith(N4JSLanguageUtils.SYMBOL_IDENTIFIER_PREFIX)) { - _LiteralOrComputedPropertyName(typeAssistant.getMemberNameAsSymbol(targetNameStr), targetNameStr) - } else { - _LiteralOrComputedPropertyName(targetNameStr) - }; - - val body = createBodyForDelegatingMember(delegator); - - return switch(delegator) { - DelegatingGetterDeclaration: - _N4GetterDecl(targetName, body) - DelegatingSetterDeclaration: - _N4SetterDecl(targetName, _Fpar("value"), body) - DelegatingMethodDeclaration: - _N4MethodDecl(targetName, body) - }; - } - - def private Block createBodyForDelegatingMember(DelegatingMember delegator) { - val baseSTE = delegator.delegationBaseType; - val baseIsInterface = baseSTE?.originalTarget instanceof TInterface; - - val targetAccess = if(baseIsInterface) { - val targetIsStatic = delegator.static; - val objOfInterfaceOfTargetExpr = createAccessToInterfaceObject(baseSTE, targetIsStatic); - createAccessToMemberFunction(objOfInterfaceOfTargetExpr, !targetIsStatic, delegator); - } else { - val ctorOfClassOfTarget = createAccessToClassConstructor(baseSTE, delegator.delegationSuperClassSteps); - - // based on that constructor expression, now create an expression that evaluates to the member function of - // the target member: - createAccessToMemberFunction(ctorOfClassOfTarget, false, delegator) - }; - - val callExpr = _CallExpr( - _PropertyAccessExpr( - targetAccess, - getSymbolTableEntryForMember(state.G.functionType, "apply", false, false, true) - ), - _ThisLiteral, - _IdentRef(steFor_arguments) - ); - - if (delegator instanceof DelegatingSetterDeclaration) { - return _Block( - _ExprStmnt(callExpr) - ); - } else { - return _Block( - _ReturnStmnt(callExpr) - ); - } - } - - /** - * Creates an expression that will evaluate to the constructor of the class denoted by the given symbol table - * entry or one of its super classes (depending on argument superClassSteps). - *

- * For example, if classSTE denotes a class "C", then this will produce an expression like - * - * - * - * - *
Cfor superClassSteps == 0
Object.getPrototypeOf(C)for superClassSteps == 1
Object.getPrototypeOf(Object.getPrototypeOf(C))for superClassSteps == 2
- */ - def private Expression createAccessToClassConstructor(SymbolTableEntry classSTE, int superClassSteps) { - val objectType = state.G.objectType; - val objectSTE = getSymbolTableEntryOriginal(objectType, true); - var Expression result = __NSSafe_IdentRef(classSTE); // this is the "C" in the above examples - // for each super-class-step wrap 'result' into "Object.getPrototypeOf(result)" - if(superClassSteps>0) { - val getPrototypeOfSTE = getSymbolTableEntryForMember(objectType, "getPrototypeOf", false, true, true); - for(n : 0.. - * Since fields do not have such a function this will throw an exception if given member is a field. - */ - def private Expression createAccessToMemberFunction(Expression protoOrCtorExpr, boolean exprIsProto, N4MemberDeclaration member) { - if(member instanceof N4FieldDeclaration) { - throw new IllegalArgumentException("no member function available for fields"); - } - if(member instanceof N4MethodDeclaration) { - // for methods we can use a simple property access instead of Object.getOwnPropertyDescriptor() - val memberName = member.name; - val memberIsSymbol = memberName!==null && memberName.startsWith(N4JSLanguageUtils.SYMBOL_IDENTIFIER_PREFIX); - val memberSTE = findSymbolTableEntryForElement(member, true); - return if(!memberIsSymbol) { - _PropertyAccessExpr(protoOrCtorExpr, memberSTE) - } else { - _IndexAccessExpr(protoOrCtorExpr, typeAssistant.getMemberNameAsSymbol(memberName)) - }; - } - // for other members (i.e. getters and setters) we need to retrieve the property descriptor: - val accessToMemberDefinition = createAccessToMemberDescriptor(protoOrCtorExpr, exprIsProto, member); - // append ".get", ".set", or ".value" depending on member type - val result = _PropertyAccessExpr(accessToMemberDefinition, getPropertyDescriptorValueProperty(member)); - return result; - } - - /** - * Given an expression that will evaluate to a prototype or constructor, this method returns an expression that - * will evaluate to the property descriptor of a particular member. - * - * @param protoOrCtorExpr - * an expression that is expected to evaluate to a prototype or a constructor. - * @param exprIsProto - * tells whether argument protoOrCtorExpr will evaluate to a prototype or a constructor: - * if true, it will evaluate to a prototype, if false it will evaluate to a constructor. - * @param member - * the member. - */ - def private Expression createAccessToMemberDescriptor(Expression protoOrCtorExpr, boolean exprIsProto, N4MemberDeclaration member) { - val memberName = member.name; - val memberIsSymbol = memberName!==null && memberName.startsWith(N4JSLanguageUtils.SYMBOL_IDENTIFIER_PREFIX); - val memberSTE = findSymbolTableEntryForElement(member, true); - val objectType = state.G.objectType; - val objectSTE = getSymbolTableEntryOriginal(objectType, true); - val getOwnPropertyDescriptorSTE = getSymbolTableEntryForMember(objectType, "getOwnPropertyDescriptor", false, true, true); - // compute first argument to the #getOwnPropertyDescriptor() call: - val isStatic = member.static; - var arg0 = protoOrCtorExpr; - if(!exprIsProto && !isStatic) { - // got a constructor, but need a prototype -> append ".prototype" - val prototypeSTE = getSymbolTableEntryForMember(objectType, "prototype", false, true, true); - arg0 = _PropertyAccessExpr(arg0, prototypeSTE); - } else if(exprIsProto && isStatic) { - // got a prototype, but need a constructor -> append ".constructor" - val constructorSTE = getSymbolTableEntryForMember(objectType, "constructor", false, false, true); - arg0 = _PropertyAccessExpr(arg0, constructorSTE); - }; - // compute second argument to the #getOwnPropertyDescriptor() call: - val arg1 = if(!memberIsSymbol) { - _StringLiteralForSTE(memberSTE) - } else { - typeAssistant.getMemberNameAsSymbol(memberName) - }; - // create #getOwnPropertyDescriptor() call - val result = _CallExpr(_PropertyAccessExpr(objectSTE, getOwnPropertyDescriptorSTE), arg0, arg1); - return result; - } - - /** - * Returns the direct super type (i.e. immediate super class or directly implemented interface) of the given - * classifier through which the given classifier inherits the given inherited member. Fails fast in case of - * inconsistencies. - */ - def private ContainerType getDirectSuperTypeBequestingMember(TClassifier classifier, TMember inheritedMember) { - return state.memberCollector.directSuperTypeBequestingMember(classifier, inheritedMember); - } - - /** - * Returns the ancestor class (i.e. direct or indirect super class) of the given classifier that either contains - * the given inherited member (if given member is contained in a class) or consumes the given member (if given - * member is contained in an interface). - *

- * For example: - *

-	 * interface I {
-	 *     m() {}
-	 * }
-	 * class A implements I {}
-	 * class B extends A {}
-	 * class C extends B {}
-	 * 
- * With the above type declarations, for arguments C and m this method would return class - * A. - */ - def private TClass getAncestorClassBequestingMember(TClass classifier, TMember inheritedOrConsumedMember) { - val containingType = inheritedOrConsumedMember.containingType; - if(containingType===classifier) { - return classifier - } else if(containingType instanceof TInterface) { - SuperInterfacesIterable.of(classifier).findClassImplementingInterface(containingType) - } else if(containingType instanceof TClass) { - containingType // note: we do not check if containingType is actually an ancestor of 'classifier' - } else { - throw new IllegalArgumentException("unsupported subtype of TClassifier: " + containingType.eClass.name); - } - } - - /** - * Returns distance to given ancestor or 0 if second argument is 'base' or not an ancestor or null. - */ - def private static int getDistanceToAncestorClass(TClass base, TClass ancestorClass) { - if(ancestorClass===null || ancestorClass===base) { - return 0; - } - val guard = new RecursionGuard(); - var result = 0; - var curr = base; - while(curr!==null && curr!==ancestorClass) { - if(guard.tryNext(curr)) { - result++; - curr = curr.superClassRef?.declaredType as TClass; - // no need to call guard.done() - } - } - return if(curr!==null) result else 0; - } - - /** - * Returns symbol table entry for the property in a Javascript property descriptor that holds the actual value, - * i.e. the function expression implementing the member. - */ - def private SymbolTableEntry getPropertyDescriptorValueProperty(N4MemberDeclaration delegator) { - switch(delegator) { - N4GetterDeclaration: steFor_get - N4SetterDeclaration: steFor_set - N4MethodDeclaration: steFor_value - } - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DestructuringAssistant.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DestructuringAssistant.java new file mode 100644 index 0000000000..ebc5b56d9b --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DestructuringAssistant.java @@ -0,0 +1,112 @@ +/** + * Copyright (c) 2017 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.transpiler.es.assistants; + +import static com.google.common.collect.Iterables.toArray; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrLit; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrayElement; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrayPadding; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._AssignmentExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ObjLit; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyNameValuePair; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; + +import org.eclipse.n4js.n4JS.ArrayBindingPattern; +import org.eclipse.n4js.n4JS.ArrayElement; +import org.eclipse.n4js.n4JS.ArrayLiteral; +import org.eclipse.n4js.n4JS.BindingElement; +import org.eclipse.n4js.n4JS.BindingPattern; +import org.eclipse.n4js.n4JS.BindingProperty; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ObjectBindingPattern; +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.PrimaryExpression; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.VariableDeclarationOrBinding; +import org.eclipse.n4js.transpiler.TransformationAssistant; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; + +/** + * A {@link TransformationAssistant} providing helper functionality for dealing with ES2015 destructuring. + */ +public class DestructuringAssistant extends TransformationAssistant { + + /** + * Converts the given array or object binding pattern into an array or object literal that, if used on the + * right-hand side of an assignment expression, performs the equivalent destructuring operation. + *

+ * Expression for default values are removed from the given binding, so the given binding is incomplete after this + * method returns. It is only guaranteed that (1) the given binding is not removed from its contained and (2) it + * will still include the same variable declarations as before, which can be retrieved via + * {@link VariableDeclarationOrBinding#getAllVariableDeclarations()} on the containing variable binding. + */ + public PrimaryExpression convertBindingPatternToArrayOrObjectLiteral(BindingPattern binding) { + if (binding instanceof ArrayBindingPattern) { + return convertArrayBindingPatternToArrayLiteral((ArrayBindingPattern) binding); + } + if (binding instanceof ObjectBindingPattern) { + return convertObjectBindingPatternToObjectLiteral((ObjectBindingPattern) binding); + } + return null; + } + + /** + * Same as {@link #convertBindingPatternToArrayOrObjectLiteral(BindingPattern)}, but only for array binding + * patterns. + */ + public ArrayLiteral convertArrayBindingPatternToArrayLiteral(ArrayBindingPattern binding) { + ArrayElement[] elems = toArray(map(binding.getElements(), elem -> convertBindingElementToArrayElement(elem)), + ArrayElement.class); + + return _ArrLit(elems); + } + + /** + * Same as {@link #convertBindingPatternToArrayOrObjectLiteral(BindingPattern)}, but only for object binding + * patterns. + */ + public ObjectLiteral convertObjectBindingPatternToObjectLiteral(ObjectBindingPattern binding) { + PropertyNameValuePair[] pairs = toArray( + map(binding.getProperties(), prop -> convertBindingPropertyToPropertyNameValuePair(prop)), + PropertyNameValuePair.class); + return _ObjLit(pairs); + } + + private ArrayElement convertBindingElementToArrayElement(BindingElement element) { + BindingPattern nestedPattern = element.getNestedPattern(); + VariableDeclaration varDecl = element.getVarDecl(); + + Expression lhs; + Expression rhs; + if (nestedPattern != null) { + lhs = convertBindingPatternToArrayOrObjectLiteral(nestedPattern); + rhs = element.getExpression(); // may be null (which is ok, see below) + } else if (varDecl != null) { + SymbolTableEntry ste_varDecl = findSymbolTableEntryForElement(varDecl, true); + lhs = _IdentRef(ste_varDecl); + rhs = varDecl.getExpression(); // may be null (which is ok, see below) + } else { + return _ArrayPadding(); + } + + return _ArrayElement( + element.isRest(), + (rhs != null) ? _AssignmentExpr(lhs, rhs) : lhs); + } + + private PropertyNameValuePair convertBindingPropertyToPropertyNameValuePair(BindingProperty property) { + return _PropertyNameValuePair( + property.getName(), + convertBindingElementToArrayElement(property.getValue()).getExpression()); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DestructuringAssistant.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DestructuringAssistant.xtend deleted file mode 100644 index c0c59d0265..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/DestructuringAssistant.xtend +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Copyright (c) 2017 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.transpiler.es.assistants - -import org.eclipse.n4js.n4JS.ArrayBindingPattern -import org.eclipse.n4js.n4JS.ArrayElement -import org.eclipse.n4js.n4JS.ArrayLiteral -import org.eclipse.n4js.n4JS.BindingElement -import org.eclipse.n4js.n4JS.BindingPattern -import org.eclipse.n4js.n4JS.BindingProperty -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.ObjectBindingPattern -import org.eclipse.n4js.n4JS.ObjectLiteral -import org.eclipse.n4js.n4JS.PrimaryExpression -import org.eclipse.n4js.n4JS.PropertyNameValuePair -import org.eclipse.n4js.n4JS.VariableDeclarationOrBinding -import org.eclipse.n4js.transpiler.TransformationAssistant - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - * A {@link TransformationAssistant} providing helper functionality for dealing with ES2015 destructuring. - */ -class DestructuringAssistant extends TransformationAssistant { - - - /** - * Converts the given array or object binding pattern into an array or object literal that, if used on the - * right-hand side of an assignment expression, performs the equivalent destructuring operation. - *

- * Expression for default values are removed from the given binding, so the given binding is incomplete after this - * method returns. It is only guaranteed that (1) the given binding is not removed from its contained and (2) it - * will still include the same variable declarations as before, which can be retrieved via - * {@link VariableDeclarationOrBinding#getVariableDeclarations()} on the containing variable binding. - */ - public def PrimaryExpression convertBindingPatternToArrayOrObjectLiteral(BindingPattern binding) { - return switch(binding) { - ArrayBindingPattern: convertArrayBindingPatternToArrayLiteral(binding) - ObjectBindingPattern: convertObjectBindingPatternToObjectLiteral(binding) - }; - } - - /** - * Same as {@link #convertBindingPatternToArrayOrObjectLiteral(BindingPattern)}, but only for array binding - * patterns. - */ - public def ArrayLiteral convertArrayBindingPatternToArrayLiteral(ArrayBindingPattern binding) { - return _ArrLit( - binding.elements.map[convertBindingElementToArrayElement] - ); - } - - /** - * Same as {@link #convertBindingPatternToArrayOrObjectLiteral(BindingPattern)}, but only for object binding - * patterns. - */ - public def ObjectLiteral convertObjectBindingPatternToObjectLiteral(ObjectBindingPattern binding) { - return _ObjLit( - binding.properties.map[convertBindingPropertyToPropertyNameValuePair] - ); - } - - private def ArrayElement convertBindingElementToArrayElement(BindingElement element) { - val nestedPattern = element.nestedPattern; - val varDecl = element.varDecl; - - var Expression lhs; - var Expression rhs; - if(nestedPattern!==null) { - lhs = convertBindingPatternToArrayOrObjectLiteral(nestedPattern); - rhs = element.expression; // may be null (which is ok, see below) - } else if(varDecl!==null) { - val ste_varDecl = findSymbolTableEntryForElement(varDecl, true); - lhs = _IdentRef(ste_varDecl); - rhs = varDecl.expression; // may be null (which is ok, see below) - } else { - return _ArrayPadding(); - } - - return _ArrayElement( - element.rest, - if(rhs!==null) { - _AssignmentExpr(lhs, rhs) - } else { - lhs - } - ); - } - - private def PropertyNameValuePair convertBindingPropertyToPropertyNameValuePair(BindingProperty property) { - return _PropertyNameValuePair( - property.name, - convertBindingElementToArrayElement(property.value).expression - ); - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ReflectionAssistant.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ReflectionAssistant.java new file mode 100644 index 0000000000..4e6aae441d --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ReflectionAssistant.java @@ -0,0 +1,110 @@ +/** + * 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.transpiler.es.assistants; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Block; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._LiteralOrComputedPropertyName; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4GetterDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ReturnStmnt; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ThisLiteral; + +import org.eclipse.n4js.N4JSLanguageConstants; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; +import org.eclipse.n4js.n4JS.N4EnumDeclaration; +import org.eclipse.n4js.n4JS.N4GetterDeclaration; +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration; +import org.eclipse.n4js.n4JS.N4Modifier; +import org.eclipse.n4js.n4JS.N4TypeDeclaration; +import org.eclipse.n4js.transpiler.InformationRegistry; +import org.eclipse.n4js.transpiler.TransformationAssistant; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryInternal; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.utils.ResourceNameComputer; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.inject.Inject; + +/** + * Helper methods for creating output code related to reflection for classes, interfaces, and enums in N4JS. + */ +public class ReflectionAssistant extends TransformationAssistant { + @Inject + private ResourceNameComputer resourceNameComputer; + + /** + * Convenience method. Same as {@link #createN4TypeGetter(N4TypeDeclaration)}, but if creation of the 'n4type' + * reflection getter is successful, the getter will be added to the given classifier; otherwise, this method does + * nothing. + */ + public void addN4TypeGetter(N4TypeDeclaration typeDecl, N4ClassifierDeclaration addHere) { + N4GetterDeclaration getter = createN4TypeGetter(typeDecl); + if (getter != null) { + addHere.getOwnedMembersRaw().add(getter); + } + } + + /** + * Returns the 'n4type' getter for obtaining reflection information of the given class, interface, or enum + * declaration or null if it cannot be created. + *

+ * NOTE: Reflection is only supported for declarations that were given in the original source code, i.e. when method + * {@link InformationRegistry#getOriginalDefinedType(N4ClassifierDeclaration)} returns a non-null value. Otherwise, + * this method will return null as well. + * + * @return the 'n4type' getter for the given declaration or null iff the declaration does not have an + * original defined type. + */ + public N4GetterDeclaration createN4TypeGetter(N4TypeDeclaration typeDecl) { + Type originalType = getState().info.getOriginalDefinedType(typeDecl); + if (originalType == null) { + return null; + } + + SymbolTableEntry typeSTE = findSymbolTableEntryForElement(typeDecl, true); + ReflectionBuilder reflectionBuilder = new ReflectionBuilder(this, getState(), resourceNameComputer); + JsonElement reflectInfo = reflectionBuilder.createReflectionInfo(typeDecl, typeSTE); + Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + String origJsonString = gson.toJson(reflectInfo); + String quotedJsonString = "'" + origJsonString.replaceAll("\'", "\\\\\'") + "'"; + + SymbolTableEntryInternal methodName = null; + if (typeDecl instanceof N4ClassDeclaration) { + methodName = steFor_$getReflectionForClass(); + } + if (typeDecl instanceof N4InterfaceDeclaration) { + methodName = steFor_$getReflectionForInterface(); + } + if (typeDecl instanceof N4EnumDeclaration) { + methodName = steFor_$getReflectionForEnum(); + } + + N4GetterDeclaration getterDecl = _N4GetterDecl( + _LiteralOrComputedPropertyName(N4JSLanguageConstants.N4TYPE_NAME), + _Block( + _ReturnStmnt( + _CallExpr( + _IdentRef(methodName), + _ThisLiteral(), + _StringLiteral(quotedJsonString, quotedJsonString))))); + + getterDecl.getDeclaredModifiers().add(N4Modifier.STATIC); + + return getterDecl; + } + +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ReflectionAssistant.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ReflectionAssistant.xtend deleted file mode 100644 index ca9cbb8fc3..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/assistants/ReflectionAssistant.xtend +++ /dev/null @@ -1,93 +0,0 @@ -/** - * 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.transpiler.es.assistants - -import com.google.gson.GsonBuilder -import com.google.inject.Inject -import org.eclipse.n4js.N4JSLanguageConstants -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.n4JS.N4EnumDeclaration -import org.eclipse.n4js.n4JS.N4GetterDeclaration -import org.eclipse.n4js.n4JS.N4InterfaceDeclaration -import org.eclipse.n4js.n4JS.N4Modifier -import org.eclipse.n4js.n4JS.N4TypeDeclaration -import org.eclipse.n4js.transpiler.InformationRegistry -import org.eclipse.n4js.transpiler.TransformationAssistant -import org.eclipse.n4js.utils.ResourceNameComputer - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - * Helper methods for creating output code related to reflection for classes, interfaces, and enums in N4JS. - */ -class ReflectionAssistant extends TransformationAssistant { - @Inject private ResourceNameComputer resourceNameComputer; - - /** - * Convenience method. Same as {@link #createN4TypeGetter(N4TypeDeclaration)}, but if creation of the - * 'n4type' reflection getter is successful, the getter will be added to the given classifier; otherwise, - * this method does nothing. - */ - def public void addN4TypeGetter(N4TypeDeclaration typeDecl, N4ClassifierDeclaration addHere) { - val getter = createN4TypeGetter(typeDecl); - if (getter !== null) { - addHere.ownedMembersRaw += getter; - } - } - - /** - * Returns the 'n4type' getter for obtaining reflection information of the given class, interface, or enum declaration - * or null if it cannot be created. - *

- * NOTE: Reflection is only supported for declarations that were given in the original source code, i.e. when method - * {@link InformationRegistry#getOriginalDefinedType(N4TypeDeclaration) getOriginalDefinedType()} - * returns a non-null value. Otherwise, this method will return null as well. - * - * @return the 'n4type' getter for the given declaration or null iff the declaration does not have - * an original defined type. - */ - def public N4GetterDeclaration createN4TypeGetter(N4TypeDeclaration typeDecl) { - val originalType = state.info.getOriginalDefinedType(typeDecl); - if (originalType === null) { - return null; - } - - val typeSTE = findSymbolTableEntryForElement(typeDecl, true); - val reflectionBuilder = new ReflectionBuilder(this, state, resourceNameComputer); - val reflectInfo = reflectionBuilder.createReflectionInfo(typeDecl, typeSTE); - val gson = new GsonBuilder().disableHtmlEscaping().create(); - val origJsonString = gson.toJson(reflectInfo); - val quotedJsonString = "'" + origJsonString.replaceAll("\'", "\\\\\'") + "'"; - - val methodName = switch (typeDecl) { - N4ClassDeclaration: steFor_$getReflectionForClass() - N4InterfaceDeclaration: steFor_$getReflectionForInterface() - N4EnumDeclaration: steFor_$getReflectionForEnum() - } - - return _N4GetterDecl( - _LiteralOrComputedPropertyName(N4JSLanguageConstants.N4TYPE_NAME), - _Block( - _ReturnStmnt( - _CallExpr( - _IdentRef(methodName), - _ThisLiteral, - _StringLiteral(quotedJsonString, quotedJsonString) - ) - ) - ) - ) => [ - declaredModifiers += N4Modifier.STATIC - ]; - } - -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ApiImplStubGenerationTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ApiImplStubGenerationTransformation.java new file mode 100644 index 0000000000..6adde5476d --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ApiImplStubGenerationTransformation.java @@ -0,0 +1,356 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._AnnotationList; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._EnumDeclaration; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._EnumLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ExportDeclaration; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._FunDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4ClassDeclaration; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4InterfaceDeclaration; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4MemberDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4MethodDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._NewExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ThrowStmnt; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.last; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.n4JS.AnnotableScriptElement; +import org.eclipse.n4js.n4JS.ExportableElement; +import org.eclipse.n4js.n4JS.FunctionDeclaration; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; +import org.eclipse.n4js.n4JS.N4EnumDeclaration; +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.n4JS.ScriptElement; +import org.eclipse.n4js.tooling.compare.ProjectComparisonEntry; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.TransformationDependency.RequiresBefore; +import org.eclipse.n4js.transpiler.assistants.TypeAssistant; +import org.eclipse.n4js.transpiler.es.assistants.DelegationAssistant; +import org.eclipse.n4js.transpiler.im.DelegatingMember; +import org.eclipse.n4js.transpiler.im.Script_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryInternal; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.transpiler.utils.ConcreteMembersOrderedForTranspiler; +import org.eclipse.n4js.transpiler.utils.MissingApiMembersForTranspiler; +import org.eclipse.n4js.transpiler.utils.ScriptApiTracker; +import org.eclipse.n4js.transpiler.utils.ScriptApiTracker.ProjectComparisonAdapter; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TEnum; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TInterface; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.TSetter; +import org.eclipse.n4js.ts.types.TVariable; +import org.eclipse.n4js.ts.types.util.AccessorTuple; +import org.eclipse.n4js.ts.types.util.MemberList; +import org.eclipse.n4js.utils.ContainerTypesHelper; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind; +import org.eclipse.n4js.validation.N4JSElementKeywordProvider; + +import com.google.inject.Inject; + +/** + * Generation of code for missing implementations in projects implementing a specific API. + */ +@RequiresBefore(MemberPatchingTransformation.class) +public class ApiImplStubGenerationTransformation extends Transformation { + + @Inject + private DelegationAssistant delegationAssistant; + @Inject + private TypeAssistant typeAssistant; + @Inject + private ScriptApiTracker scriptApiTracker; + @Inject + private ContainerTypesHelper containerTypesHelper; + @Inject + private N4JSElementKeywordProvider n4jsElementKeywordProvider; + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + // perform API/Impl compare for the resource to compile + scriptApiTracker.initApiCompare(getState().resource.getScript()); + // (reminder: code in #analyze() will be invoked once per resource to compile, so this is what we want) + } + + @Override + public void transform() { + // add stubs for missing members in EXISTING classes and interfaces + for (N4ClassifierDeclaration cd : collectNodes(getState().im, N4ClassifierDeclaration.class, false)) { + addMissingMembers(cd); + } + // add missing types (classes, interfaces, enums) and other top-level elements (declared functions, variables) + addMissingTopLevelElements(); + } + + private void addMissingMembers(N4ClassifierDeclaration classifierDecl) { + TClassifier type = getState().info.getOriginalDefinedType(classifierDecl); + MissingApiMembersForTranspiler mamft = createMAMFT(type); + + // add API/Impl method stubs + for (TMethod m : mamft.missingApiMethods) { + N4MemberDeclaration member = createApiImplStub(classifierDecl, m); + classifierDecl.getOwnedMembersRaw().add(member); + } + // add API/Impl field accessor stubs + for (AccessorTuple accTuple : mamft.missingApiAccessorTuples) { + if (accTuple.getGetter() != null) { + TGetter g = accTuple.getGetter(); + N4MemberDeclaration member = createApiImplStub(classifierDecl, g); + classifierDecl.getOwnedMembersRaw().add(member); + } + if (accTuple.getSetter() != null) { + TSetter s = accTuple.getSetter(); + N4MemberDeclaration member = createApiImplStub(classifierDecl, s); + classifierDecl.getOwnedMembersRaw().add(member); + } + } + + // add delegates to inherited fields/getters/setters shadowed by an owned setter XOR getter + // NOTE: Partial shadowing in general is disallowed by validation. However, in incomplete + // API-impl situation we still support this feature here to propagate generated stubs for + // test reporting-purposes. + for (AccessorTuple accTuple : mamft.missingApiAccessorTuples) { + if (accTuple.getInheritedGetter() != null && accTuple.getGetter() == null && accTuple.getSetter() != null) { + // an owned setter is shadowing an inherited getter -> delegate to the inherited getter + DelegatingMember delegator = delegationAssistant.createDelegatingMember(type, + accTuple.getInheritedGetter()); + classifierDecl.getOwnedMembersRaw().add(delegator); + } + if (accTuple.getInheritedSetter() != null && accTuple.getGetter() != null && accTuple.getSetter() == null) { + // an owned getter is shadowing an inherited setter -> delegate to the inherited setter + DelegatingMember delegator = delegationAssistant.createDelegatingMember(type, + accTuple.getInheritedSetter()); + classifierDecl.getOwnedMembersRaw().add(delegator); + } + } + + } + + private void addMissingTopLevelElements() { + Script script = getState().resource.getScript(); + + scriptApiTracker.initApiCompare(script); + ProjectComparisonAdapter comparison = ScriptApiTracker.firstProjectComparisonAdapter(script.eResource()) + .orElse(null); + if (null == comparison) { + return; + } + + for (ProjectComparisonEntry pce : comparison.getEntryFor(script.getModule()).allChildren().toList()) { + if (null == pce.getElementImpl(0)) {// no implementation + EObject x = pce.getElementAPI(); + if (x instanceof TMethod) { + /* do nothing */ + } + if (x instanceof TFunction) { + missing((TFunction) x); + } + if (x instanceof TClass) { + missing((TClass) x); + } + if (x instanceof TInterface) { + missing((TInterface) x); + } + if (x instanceof TEnum) { + missing((TEnum) x); + } + if (x instanceof TVariable) { + missing((TVariable) x); + } + } + } + } + + private void missing(TInterface tinter) { + N4InterfaceDeclaration stub0 = _N4InterfaceDeclaration(tinter.getName()); + + // annotations + stub0.setAnnotationList(_AnnotationList( + toList(map(tinter.getAnnotations(), a -> AnnotationDefinition.find(a.getName()))))); + + // export + ScriptElement stub = (ScriptElement) wrapExported(tinter.isDirectlyExported(), stub0); + + // members + // (in an interface stub we need member stubs for static AND non-static members) + MemberList members = getState().memberCollector.members(tinter, false, false); + for (TMember m : members) { + if (!(m instanceof TField)) { + stub0.getOwnedMembersRaw().add(createApiImplStub(stub0, m)); + } + } + + appendToScript(stub); + + getState().info.setOriginalDefinedType(stub0, tinter); + + createSymbolTableEntryIMOnly(stub0); + } + + private void missing(TClass tclass) { + N4ClassDeclaration stub0 = _N4ClassDeclaration(tclass.getName()); + + // at least a ctor throwing an exception is required here. + stub0.getOwnedMembersRaw().add(_N4MethodDecl("constructor", + _ThrowStmnt(_NewExpr( + _IdentRef(N4ApiNotImplementedErrorSTE()), + _StringLiteral("Class " + tclass.getName() + " is not implemented yet."))))); + + // annotations + stub0.setAnnotationList(_AnnotationList( + toList(map(tclass.getAnnotations(), a -> AnnotationDefinition.find(a.getName()))))); + + // export + ScriptElement stub = (ScriptElement) wrapExported(tclass.isDirectlyExported(), stub0); + + // members + // (in a class stub we need member stubs ONLY for static members) + MemberList members = getState().memberCollector.members(tclass, false, false); + for (TMember m : members) { + if (!(m instanceof TField) && m.isStatic()) { + stub0.getOwnedMembersRaw().add(createApiImplStub(stub0, m)); + } + } + + appendToScript(stub); + + getState().info.setOriginalDefinedType(stub0, tclass); + + createSymbolTableEntryIMOnly(stub0); + } + + private void missing(TEnum tenum) { + N4EnumDeclaration stub0 = _EnumDeclaration(tenum.getName(), + toList(map(tenum.getLiterals(), l -> _EnumLiteral(l.getName(), l.getName())))); + + // exported + ScriptElement stub = (ScriptElement) wrapExported(tenum.isDirectlyExported(), stub0); + + // number-/string-based + EnumKind enumKind = N4JSLanguageUtils.getEnumKind(tenum); + switch (enumKind) { + case Normal: { + // do nothing + break; + } + case NumberBased: { + ((AnnotableScriptElement) stub) + .setAnnotationList(_AnnotationList(List.of(AnnotationDefinition.NUMBER_BASED))); + break; + } + case StringBased: { + ((AnnotableScriptElement) stub) + .setAnnotationList(_AnnotationList(List.of(AnnotationDefinition.STRING_BASED))); + break; + } + } + + appendToScript(stub); + + getState().info.setOriginalDefinedType(stub0, tenum); + + createSymbolTableEntryIMOnly(stub0); + } + + private void appendToScript(ScriptElement stub) { + Script_IM script = getState().im; + if (script.getScriptElements().isEmpty()) { + script.getScriptElements().add(stub); + } else { + insertAfter(last(script.getScriptElements()), stub); + } + } + + private void missing(TVariable tvar) { + missingFuncOrVar(tvar, tvar.isDirectlyExported(), "variable"); + } + + private void missing(TFunction func) { + missingFuncOrVar(func, func.isDirectlyExported(), "function"); + } + + private SymbolTableEntryInternal N4ApiNotImplementedErrorSTE() { + return steFor_N4ApiNotImplementedError(); + } + + private void missingFuncOrVar(IdentifiableElement func, boolean exported, String description) { + SymbolTableEntryOriginal funcSTE = getSymbolTableEntryOriginal(func, true); // createSymbolTableEntry(fun); + + FunctionDeclaration funcDecl = _FunDecl(funcSTE.getName(), _ThrowStmnt(_NewExpr( + _IdentRef(N4ApiNotImplementedErrorSTE()), + _StringLiteral(description + " " + funcSTE.getName() + " is not implemented yet.")))); + EObject stub = wrapExported(exported, funcDecl); + + insertAfter(last(getState().im.getScriptElements()), stub); + } + + private EObject wrapExported(boolean exported, ExportableElement toExportOrNotToExport) { + return (exported) ? _ExportDeclaration(toExportOrNotToExport) : toExportOrNotToExport; + } + + /** + * Creates a member that servers as the stub for a missing member on implementation side, corresponding to the given + * member apiMember on API side. + */ + private N4MemberDeclaration createApiImplStub(N4ClassifierDeclaration classifierDecl, TMember apiMember) { + // here we create: + // + // public m() { // or a getter or setter + // throw new N4ApiNotImplementedError("API for method C.m not implemented yet."); + // } + // + SymbolTableEntryInternal N4ApiNotImplementedErrorSTE = steFor_N4ApiNotImplementedError(); + String typeName = classifierDecl.getName(); + String memberKeyword = n4jsElementKeywordProvider.keyword(apiMember); + String memberName = apiMember.getName(); + return _N4MemberDecl(apiMember, + _ThrowStmnt( + _NewExpr(_IdentRef(N4ApiNotImplementedErrorSTE), _StringLiteral( + "API for " + memberKeyword + " " + typeName + "." + memberName + + " not implemented yet.")))); + } + + // note: the following uses logic from old transpiler (MissingApiMembersForTranspiler, ScriptApiTracker) + private MissingApiMembersForTranspiler createMAMFT(TClassifier classifier) { + ConcreteMembersOrderedForTranspiler cmoft = typeAssistant.getOrCreateCMOFT(classifier); + return MissingApiMembersForTranspiler.create(containerTypesHelper, scriptApiTracker, + classifier, cmoft, getState().resource.getScript()); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ApiImplStubGenerationTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ApiImplStubGenerationTransformation.xtend deleted file mode 100644 index 52665e3e65..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ApiImplStubGenerationTransformation.xtend +++ /dev/null @@ -1,301 +0,0 @@ -/** - * 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.transpiler.es.transform - -import com.google.inject.Inject -import java.util.stream.Stream -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.AnnotableScriptElement -import org.eclipse.n4js.n4JS.ExportableElement -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.n4JS.N4MemberDeclaration -import org.eclipse.n4js.n4JS.ScriptElement -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.TransformationDependency.RequiresBefore -import org.eclipse.n4js.transpiler.assistants.TypeAssistant -import org.eclipse.n4js.transpiler.es.assistants.DelegationAssistant -import org.eclipse.n4js.transpiler.utils.MissingApiMembersForTranspiler -import org.eclipse.n4js.transpiler.utils.ScriptApiTracker -import org.eclipse.n4js.ts.types.IdentifiableElement -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TEnum -import org.eclipse.n4js.ts.types.TField -import org.eclipse.n4js.ts.types.TFunction -import org.eclipse.n4js.ts.types.TInterface -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.ts.types.TVariable -import org.eclipse.n4js.utils.ContainerTypesHelper -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.validation.N4JSElementKeywordProvider - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.transpiler.utils.ScriptApiTracker.firstProjectComparisonAdapter - -/** - * Generation of code for missing implementations in projects implementing a specific API. - */ -@RequiresBefore(MemberPatchingTransformation) -class ApiImplStubGenerationTransformation extends Transformation { - - @Inject private DelegationAssistant delegationAssistant; - @Inject private TypeAssistant typeAssistant; - @Inject private ScriptApiTracker scriptApiTracker; - @Inject private ContainerTypesHelper containerTypesHelper; - @Inject private N4JSElementKeywordProvider n4jsElementKeywordProvider; - - - override assertPreConditions() { - } - override assertPostConditions() { - } - - override analyze() { - // perform API/Impl compare for the resource to compile - scriptApiTracker.initApiCompare(state.resource.script); - // (reminder: code in #analyze() will be invoked once per resource to compile, so this is what we want) - } - - override transform() { - // add stubs for missing members in EXISTING classes and interfaces - collectNodes(state.im, N4ClassifierDeclaration, false).forEach[addMissingMembers]; - // add missing types (classes, interfaces, enums) and other top-level elements (declared functions, variables) - addMissingTopLevelElements(); - } - - def private void addMissingMembers(N4ClassifierDeclaration classifierDecl) { - val type = state.info.getOriginalDefinedType(classifierDecl); - val mamft = createMAMFT(type); - - // add API/Impl method stubs - for(m : mamft.missingApiMethods) { - val member = createApiImplStub(classifierDecl, m); - classifierDecl.ownedMembersRaw += member; - } - // add API/Impl field accessor stubs - for(accTuple : mamft.missingApiAccessorTuples) { - if(accTuple.getter!==null) { - val g = accTuple.getter; - val member = createApiImplStub(classifierDecl, g); - classifierDecl.ownedMembersRaw += member; - } - if(accTuple.setter!==null) { - val s = accTuple.setter; - val member = createApiImplStub(classifierDecl, s); - classifierDecl.ownedMembersRaw += member; - } - } - - - // add delegates to inherited fields/getters/setters shadowed by an owned setter XOR getter - // NOTE: Partial shadowing in general is disallowed by validation. However, in incomplete - // API-impl situation we still support this feature here to propagate generated stubs for - // test reporting-purposes. - for(accTuple : mamft.missingApiAccessorTuples) { - if(accTuple.inheritedGetter!==null && accTuple.getter===null && accTuple.setter!==null) { - // an owned setter is shadowing an inherited getter -> delegate to the inherited getter - val delegator = delegationAssistant.createDelegatingMember(type, accTuple.inheritedGetter); - classifierDecl.ownedMembersRaw += delegator; - } - if(accTuple.inheritedSetter!==null && accTuple.getter!==null && accTuple.setter===null) { - // an owned getter is shadowing an inherited setter -> delegate to the inherited setter - val delegator = delegationAssistant.createDelegatingMember(type, accTuple.inheritedSetter); - classifierDecl.ownedMembersRaw += delegator; - } - } - - - } - - def private void addMissingTopLevelElements() { - - val script = state.resource.script; - - scriptApiTracker.initApiCompare(script) - val comparison = script.eResource.firstProjectComparisonAdapter.orElse(null); - if (null === comparison) { - return; - } - - comparison.getEntryFor(script.module).allChildren.toIterable - .filter[null === getElementImpl(0)] // no implementation - .forEach[ - switch x:elementAPI{ - TMethod : { /* do nothing */ } - TFunction : missing(x) - TClass : missing(x) - TInterface : missing(x) - TEnum : missing(x) - TVariable : missing(x) - } - ]; - } - - def private dispatch missing(TInterface tinter){ - val stub0 = _N4InterfaceDeclaration( tinter.name ) ; - - // annotations - stub0.annotationList = _AnnotationList( tinter.annotations.map[ AnnotationDefinition.find(it.name) ] ) - - // export - val stub = wrapExported(tinter.isDirectlyExported, stub0) as ScriptElement - - // members - // (in an interface stub we need member stubs for static AND non-static members) - val members = state.memberCollector.members(tinter, false, false); - for(TMember m : members) { - if(!(m instanceof TField)) { - stub0.ownedMembersRaw += createApiImplStub(stub0, m); - } - } - - appendToScript(stub); - - state.info.setOriginalDefinedType(stub0, tinter); - - createSymbolTableEntryIMOnly(stub0) - } - def private dispatch missing(TClass tclass){ - val stub0 = _N4ClassDeclaration( tclass.name ) =>[ - // at least a ctor throwing an exception is required here. - it.ownedMembersRaw += _N4MethodDecl("constructor", - _ThrowStmnt( _NewExpr( - _IdentRef( N4ApiNotImplementedErrorSTE ), - _StringLiteral( '''Class «tclass.name» is not implemented yet.''') - ) ) ) - ]; - - // annotations - stub0.annotationList = _AnnotationList( tclass.annotations.map[ AnnotationDefinition.find(it.name) ] ) - - // export - val stub = wrapExported(tclass.isDirectlyExported, stub0) as ScriptElement - - // members - // (in a class stub we need member stubs ONLY for static members) - val members = state.memberCollector.members(tclass, false, false); - for(TMember m : members) { - if(!(m instanceof TField) && m.static) { - stub0.ownedMembersRaw += createApiImplStub(stub0, m); - } - } - - appendToScript(stub); - - state.info.setOriginalDefinedType(stub0, tclass); - - createSymbolTableEntryIMOnly(stub0) - } - def private dispatch missing(TEnum tenum){ - - val stub0 = _EnumDeclaration(tenum.name, tenum.literals.map[ _EnumLiteral(name, name) ] ); - - // exported - var ScriptElement stub = wrapExported( tenum.isDirectlyExported , - stub0 - ) as ScriptElement; - - // number-/string-based - val enumKind = N4JSLanguageUtils.getEnumKind(tenum); - switch (enumKind) { - case Normal: { - // do nothing - } - case NumberBased: { - (stub as AnnotableScriptElement).annotationList = _AnnotationList(#[AnnotationDefinition.NUMBER_BASED]); - } - case StringBased: { - (stub as AnnotableScriptElement).annotationList = _AnnotationList(#[AnnotationDefinition.STRING_BASED]); - } - }; - - appendToScript( stub ) - - state.info.setOriginalDefinedType(stub0, tenum); - - createSymbolTableEntryIMOnly(stub0) - } - - def private appendToScript(ScriptElement stub) { - val script = state.im; - if ( script.scriptElements.isEmpty ) script.scriptElements+=stub - else insertAfter ( script.scriptElements.last, stub ); - } - - def private dispatch missing(TVariable tvar){ - missingFuncOrVar(tvar, tvar.isDirectlyExported, "variable") - } - def private dispatch missing(TFunction func){ - missingFuncOrVar(func, func.isDirectlyExported, "function") - } - - def private N4ApiNotImplementedErrorSTE() { - steFor_N4ApiNotImplementedError; - } - - def private missingFuncOrVar(IdentifiableElement func, boolean exported, String description) { - val funcSTE = func.getSymbolTableEntryOriginal(true); // createSymbolTableEntry(func); - - val funcDecl = _FunDecl( funcSTE.name, _ThrowStmnt( _NewExpr( - _IdentRef( N4ApiNotImplementedErrorSTE ), - _StringLiteral( '''«description» «funcSTE.name» is not implemented yet.''') - ) ) ) - => [ - // Do some more configuration. - ]; - val stub = wrapExported(exported,funcDecl); - - insertAfter( state.im.scriptElements.last , stub ); - } - - def private wrapExported( boolean exported, ExportableElement toExportOrNotToExport ) - { - if( exported ) _ExportDeclaration( toExportOrNotToExport ) else toExportOrNotToExport - } - - /** - * Creates a member that servers as the stub for a missing member on implementation side, corresponding to the given - * member apiMember on API side. - */ - def private N4MemberDeclaration createApiImplStub(N4ClassifierDeclaration classifierDecl, TMember apiMember) { - // here we create: - // - // public m() { // or a getter or setter - // throw new N4ApiNotImplementedError("API for method C.m not implemented yet."); - // } - // - val N4ApiNotImplementedErrorSTE = steFor_N4ApiNotImplementedError; - val typeName = classifierDecl.name; - val memberKeyword = n4jsElementKeywordProvider.keyword(apiMember); - val memberName = apiMember.name; - return _N4MemberDecl(apiMember, - _ThrowStmnt( - _NewExpr(_IdentRef(N4ApiNotImplementedErrorSTE), _StringLiteral( - '''API for «memberKeyword» «typeName».«memberName» not implemented yet.''' - )) - ) - ); - } - - /** Converts the stream into an iterable. */ - def private Iterable toIterable(Stream stream) { - return [stream.iterator]; - } - - // note: the following uses logic from old transpiler (MissingApiMembersForTranspiler, ScriptApiTracker) - def private MissingApiMembersForTranspiler createMAMFT(TClassifier classifier) { - val cmoft = typeAssistant.getOrCreateCMOFT(classifier); - return MissingApiMembersForTranspiler.create(containerTypesHelper, scriptApiTracker, - classifier, cmoft, state.resource.script); - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part1_Transformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part1_Transformation.java new file mode 100644 index 0000000000..c642e50cad --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part1_Transformation.java @@ -0,0 +1,67 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ReturnStmnt; + +import org.eclipse.n4js.generator.GeneratorOption; +import org.eclipse.n4js.n4JS.ArrowFunction; +import org.eclipse.n4js.n4JS.ExpressionStatement; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.TransformationDependency.Optional; +import org.eclipse.n4js.transpiler.es.assistants.BlockAssistant; + +import com.google.inject.Inject; + +/** + * Transforms ES2015 arrow functions to an ES5 equivalent, using ordinary function expressions. + */ +@Optional(GeneratorOption.ArrowFunctions) +public class ArrowFunction_Part1_Transformation extends Transformation { + + @Inject + BlockAssistant blockAssistant; + + @Override + public void analyze() { + // empty + } + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void transform() { + for (ArrowFunction af : collectNodes(getState().im, ArrowFunction.class, true)) { + transformArrowFunction(af); + } + } + + /** turn implicit returns into explicit ones. */ + private void transformArrowFunction(ArrowFunction arrowFunc) { + + // PART 1 + if (arrowFunc.isSingleExprImplicitReturn()) { + if (blockAssistant.needsReturnInsertionForBody(arrowFunc)) { + // Wrap in return. + ExpressionStatement exprToWrap = (ExpressionStatement) arrowFunc.getBody().getStatements().get(0); + replace(exprToWrap, _ReturnStmnt(exprToWrap.getExpression())); // reuse expression + } + } + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part1_Transformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part1_Transformation.xtend deleted file mode 100644 index 760dbfc949..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part1_Transformation.xtend +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 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.transpiler.es.transform - -import com.google.inject.Inject -import org.eclipse.n4js.n4JS.ArrowFunction -import org.eclipse.n4js.n4JS.ExpressionStatement -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.TransformationDependency.Optional -import org.eclipse.n4js.transpiler.es.assistants.BlockAssistant - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - * Transforms ES2015 arrow functions to an ES5 equivalent, using ordinary function expressions. - */ -@Optional(ArrowFunctions) -class ArrowFunction_Part1_Transformation extends Transformation { - - @Inject BlockAssistant blockAssistant; - - - override analyze() { - - } - - override assertPreConditions() { - } - - override assertPostConditions() { - } - - override transform() { - collectNodes(state.im, ArrowFunction, true).forEach[transformArrowFunction]; - } - - /** turn implicit returns into explicit ones. */ - private def void transformArrowFunction(ArrowFunction arrowFunc ) { - - // PART 1 - if( arrowFunc.isSingleExprImplicitReturn ) { - if( blockAssistant.needsReturnInsertionForBody(arrowFunc)) { - // Wrap in return. - var exprToWrap = arrowFunc.body.statements.get(0) as ExpressionStatement; - replace(exprToWrap, _ReturnStmnt(exprToWrap.expression)); // reuse expression - } - } - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part2_Transformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part2_Transformation.java new file mode 100644 index 0000000000..f7bdccc043 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part2_Transformation.java @@ -0,0 +1,79 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._FunExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Parenthesis; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ThisLiteral; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.functionType; + +import org.eclipse.n4js.generator.GeneratorOption; +import org.eclipse.n4js.n4JS.ArrowFunction; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.transpiler.AbstractTranspiler; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.TransformationDependency.Optional; +import org.eclipse.n4js.transpiler.TransformationDependency.Requires; + +/** + * Part 2 of {@link ArrowFunction_Part1_Transformation}. + */ +@Optional(GeneratorOption.ArrowFunctions) +@Requires(ArrowFunction_Part1_Transformation.class) +public class ArrowFunction_Part2_Transformation extends Transformation { + + @Override + public void analyze() { + // empty + } + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { + assertTrue("No arrow-function left in IM", + collectNodes(getState().im, ArrowFunction.class, true).isEmpty()); + } + } + + @Override + public void transform() { + for (ArrowFunction af : collectNodes(getState().im, ArrowFunction.class, true)) { + transformArrowFunction(af); + } + } + + /** replace arrow-function by function-expression */ + private void transformArrowFunction(ArrowFunction arrowFunc) { + + // PART 2 + FunctionExpression fe = _FunExpr(arrowFunc.isAsync(), arrowFunc.getName(), + arrowFunc.getFpars().toArray(new FormalParameter[0]), arrowFunc.getBody()); + // note: arrow functions cannot be generators, so we do *not* need to do: + // fe.generator = arrowFunc.generator; + + ParameterizedCallExpression thisBinder = _CallExpr( + _PropertyAccessExpr( + _Parenthesis(fe), + getSymbolTableEntryForMember(functionType(getState().G), "bind", false, false, true)), + _ThisLiteral()); // end Call function*() + + replace(arrowFunc, thisBinder, fe); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part2_Transformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part2_Transformation.xtend deleted file mode 100644 index 7aeeae2cb5..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ArrowFunction_Part2_Transformation.xtend +++ /dev/null @@ -1,67 +0,0 @@ -/** - * 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.transpiler.es.transform - -import org.eclipse.n4js.n4JS.ArrowFunction -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.TransformationDependency.Optional -import org.eclipse.n4js.transpiler.TransformationDependency.Requires - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* -import org.eclipse.n4js.transpiler.AbstractTranspiler - -/** - * Part 2 of {@link ArrowFunction_Part1_Transformation}. - */ -@Optional(ArrowFunctions) -@Requires(ArrowFunction_Part1_Transformation) -class ArrowFunction_Part2_Transformation extends Transformation { - - - override analyze() { - - } - - override assertPreConditions() { - - } - - override assertPostConditions() { - if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { - "No arrow-function left in IM".assertTrue( collectNodes(state.im, ArrowFunction, true).isEmpty ); - } - } - - override transform() { - collectNodes(state.im, ArrowFunction, true).toList.forEach[transformArrowFunction]; - } - - /** replace arrow-function by function-expression */ - private def void transformArrowFunction(ArrowFunction arrowFunc ) { - - // PART 2 - val fe = _FunExpr(arrowFunc.async, arrowFunc.name, arrowFunc.fpars, arrowFunc.body); - // note: arrow functions cannot be generators, so we do *not* need to do: - // fe.generator = arrowFunc.generator; - - val thisBinder = _CallExpr( - _PropertyAccessExpr( - _Parenthesis( fe ), - getSymbolTableEntryForMember(state.G.functionType, "bind", false, false, true) - ), - _ThisLiteral - ); // end Call function*() - - replace(arrowFunc, thisBinder, fe); - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/BlockTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/BlockTransformation.java new file mode 100644 index 0000000000..9e32609496 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/BlockTransformation.java @@ -0,0 +1,101 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableDeclaration; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableStatement; + +import org.eclipse.n4js.n4JS.ArrowFunction; +import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor; +import org.eclipse.n4js.n4JS.Statement; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryInternal; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.ts.types.TVariable; + +/** + */ +public class BlockTransformation extends Transformation { + + /** Name for capturing local-arguments-environment in distinct variable on entering a block. */ + public static final String $CAPTURE_ARGS = "$capturedArgs"; + + @Override + public void assertPreConditions() { + // true + } + + @Override + public void assertPostConditions() { + // true + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + for (FunctionOrFieldAccessor fofa : collectNodes(getState().im, FunctionOrFieldAccessor.class, true)) { + transformArguments(fofa); + } + } + + /** capture arguments-variable to be accessible in re-written arrow-functions */ + private void transformArguments(FunctionOrFieldAccessor funcOrAccess) { + FunctionOrFieldAccessor fofa = getState().tracer.getOriginalASTNodeOfSameType(funcOrAccess, false); + if (fofa == null) { + return; + } + TVariable argsVar = fofa.getImplicitArgumentsVariable(); + if (argsVar == null) { + return; + } + + // 1. rename old IdentifierRef_IM pointing to --> arguments with fresh name. + // 2. introduce new IdentifierRef_IM with (new) name 'arguments' + // 3. wire up freshname to new arguments in first line of block. + String newName = $CAPTURE_ARGS; + + SymbolTableEntryOriginal arguments_STE = getSymbolTableEntryOriginal(argsVar, false); + if (arguments_STE == null || arguments_STE.getReferencingElements().isEmpty()) { + // no references to this local arguments variable -> no capturing required + return; + } + + // arguments_STE.referencingElements.empty // + also need to check if we contain a arrow-function accessing + // arguments. + + // 1.) RENAME + rename(arguments_STE, newName); + + // skip ArrowFunctions: (this is the main reason for the capturing here :-) + if (funcOrAccess instanceof ArrowFunction) + return; + // skip empty bodies: + if (funcOrAccess.getBody().getStatements().isEmpty()) + return; + + // 2 + 3.) CAPTURE arguments: + + Statement bodyFirstStatement = funcOrAccess.getBody().getStatements().get(0); + // note, there must be something in the body otherwise the 'arguments' variable could not have been accessed! + + // new SymbolTableEntry for 'real' arguments ( the other was renamed above ) + SymbolTableEntryInternal argumentsSTE = steFor_arguments(); + + insertBefore(bodyFirstStatement, + _VariableStatement(_VariableDeclaration( + newName, _IdentRef(argumentsSTE)))); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/BlockTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/BlockTransformation.xtend deleted file mode 100644 index 6cb1afd6ca..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/BlockTransformation.xtend +++ /dev/null @@ -1,86 +0,0 @@ -/** - * 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.transpiler.es.transform - -import org.eclipse.n4js.n4JS.ArrowFunction -import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor -import org.eclipse.n4js.transpiler.Transformation - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - */ -class BlockTransformation extends Transformation { - - /** Name for capturing local-arguments-environment in distinct variable on entering a block.*/ - public static final String $CAPTURE_ARGS = "$capturedArgs"; - - - override assertPreConditions() { - // true - } - - override assertPostConditions() { - // true - } - - override analyze() { - // ignore - } - - override transform() { - collectNodes(state.im, FunctionOrFieldAccessor, true).toList.forEach[transformArguments]; - } - - /** capture arguments-variable to be accessible in re-written arrow-functions */ - private def void transformArguments(FunctionOrFieldAccessor funcOrAccess ) { - - val argsVar = state.tracer.getOriginalASTNodeOfSameType(funcOrAccess, false)?.implicitArgumentsVariable - if(argsVar === null) { - return; - } - - // 1. rename old IdentifierRef_IM pointing to --> arguments with fresh name. - // 2. introduce new IdentifierRef_IM with (new) name 'arguments' - // 3. wire up freshname to new arguments in first line of block. - val newName = $CAPTURE_ARGS; - - val arguments_STE = getSymbolTableEntryOriginal(argsVar, false); - if(arguments_STE===null || arguments_STE.referencingElements.empty) { - // no references to this local arguments variable -> no capturing required - return; - } - - // arguments_STE.referencingElements.empty // + also need to check if we contain a arrow-function accessing arguments. - - // 1.) RENAME - rename( arguments_STE, newName ); - - // skip ArrowFunctions: (this is the main reason for the capturing here :-) - if( funcOrAccess instanceof ArrowFunction ) return; - // skip empty bodies: - if( funcOrAccess.body.statements.empty ) return; - - // 2 + 3.) CAPTURE arguments: - - val bodyFirstStatement = funcOrAccess.body.statements.get(0); - // note, there must be something in the body otherwise the 'arguments' variable could not have been accessed! - - // new SymbolTableEntry for 'real' arguments ( the other was renamed above ) - val argumentsSTE = steFor_arguments() ; - - insertBefore( bodyFirstStatement, - _VariableStatement( _VariableDeclaration( - newName, _IdentRef( argumentsSTE ) - )) - ); - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ClassDeclarationTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ClassDeclarationTransformation.java new file mode 100644 index 0000000000..d30b5affbc --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ClassDeclarationTransformation.java @@ -0,0 +1,190 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrLit; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Block; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._LiteralOrComputedPropertyName; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4GetterDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ReturnStmnt; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.exists; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; + +import org.eclipse.n4js.n4JS.ArrayLiteral; +import org.eclipse.n4js.n4JS.GenericDeclaration; +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4ClassExpression; +import org.eclipse.n4js.n4JS.N4FieldAccessor; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4GetterDeclaration; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.N4MethodDeclaration; +import org.eclipse.n4js.n4JS.N4Modifier; +import org.eclipse.n4js.n4JS.Statement; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.TransformationDependency.RequiresBefore; +import org.eclipse.n4js.transpiler.assistants.TypeAssistant; +import org.eclipse.n4js.transpiler.es.assistants.ClassConstructorAssistant; +import org.eclipse.n4js.transpiler.es.assistants.ClassifierAssistant; +import org.eclipse.n4js.transpiler.es.assistants.DelegationAssistant; +import org.eclipse.n4js.transpiler.es.assistants.ReflectionAssistant; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.transpiler.utils.TranspilerUtils; + +import com.google.common.collect.Iterables; +import com.google.inject.Inject; + +/** + * Transforms {@link N4ClassDeclaration}s into a constructor function and a $makeClass call. + *

+ * Dependencies: + *

    + *
  • requiresBefore {@link MemberPatchingTransformation}: additional members must be in place before they are + * transformed within this transformation. + *
+ */ +@RequiresBefore(MemberPatchingTransformation.class) +public class ClassDeclarationTransformation extends Transformation { + + @Inject + private ClassConstructorAssistant classConstructorAssistant; + @Inject + private ClassifierAssistant classifierAssistant; + @Inject + private ReflectionAssistant reflectionAssistant; + @Inject + private DelegationAssistant delegationAssistant; + @Inject + private TypeAssistant typeAssistant; + + @Override + public void assertPreConditions() { + typeAssistant.assertClassifierPreConditions(); + assertFalse("class expressions are not supported yet", + exists(getState().im.eAllContents(), el -> el instanceof N4ClassExpression)); + assertFalse("only top-level classes are supported, for now", + exists(collectNodes(getState().im, N4ClassDeclaration.class, false), + cd -> !typeAssistant.isTopLevel(cd))); + } + + @Override + public void assertPostConditions() { + // none + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + for (N4ClassDeclaration cd : collectNodes(getState().im, N4ClassDeclaration.class, false)) { + transformClassDecl(cd); + } + } + + private void transformClassDecl(N4ClassDeclaration classDecl) { + SymbolTableEntry classSTE = findSymbolTableEntryForElement(classDecl, false); + SymbolTableEntryOriginal superClassSTE = typeAssistant.getSuperClassSTE(classDecl); + LinkedHashSet fieldsRequiringExplicitDefinition = classifierAssistant + .findFieldsRequiringExplicitDefinition(classDecl); + + reflectionAssistant.addN4TypeGetter(classDecl, classDecl); + + classConstructorAssistant.amendConstructor(classDecl, classSTE, superClassSTE, + fieldsRequiringExplicitDefinition); + + List belowClassDecl = new ArrayList<>(); + belowClassDecl.addAll( + classifierAssistant.createExplicitFieldDefinitions(classSTE, true, fieldsRequiringExplicitDefinition)); + belowClassDecl.addAll(classifierAssistant.createStaticFieldInitializations(classDecl, classSTE, + fieldsRequiringExplicitDefinition)); + belowClassDecl.addAll(createAdditionalClassDeclarationCode()); + insertAfter(TranspilerUtils.orContainingExportDeclaration(classDecl), belowClassDecl.toArray(new Statement[0])); + + removeFieldsAndAbstractMembers(classDecl); + delegationAssistant.replaceDelegatingMembersByOrdinaryMembers(classDecl); + removeTypeInformation(classDecl); + + ArrayLiteral implementedInterfaces = createDirectlyImplementedInterfaces(classDecl); + String $implements = steFor_$implementsInterfaces().getName(); + if (!implementedInterfaces.getElements().isEmpty()) { + N4GetterDeclaration newGetter = _N4GetterDecl( + _LiteralOrComputedPropertyName($implements), + _Block( + _ReturnStmnt(implementedInterfaces))); + newGetter.getDeclaredModifiers().add(N4Modifier.STATIC); + classDecl.getOwnedMembersRaw().add(newGetter); + } + + // change superClassRef to an equivalent extends-expression + // (this is a minor quirk required because superClassRef is not supported by the PrettyPrinterSwitch; + // for details see PrettyPrinterSwitch#caseN4ClassDeclaration()) + classDecl.setSuperClassRef(null); + classDecl.setSuperClassExpression(__NSSafe_IdentRef(superClassSTE)); + } + + /** Removes fields and abstract members (they do not have a representation in the output code). */ + private void removeFieldsAndAbstractMembers(N4ClassDeclaration classDecl) { + classDecl.getOwnedMembersRaw().removeIf(m -> { + if (m instanceof N4FieldDeclaration) { + return true; + } + if (m instanceof N4FieldAccessor) { + return m.isAbstract(); + } + if (m instanceof N4MethodDeclaration) { + return m.isAbstract(); + } + return false; + }); + } + + private void removeTypeInformation(N4ClassDeclaration classDecl) { + for (N4MemberDeclaration currMember : classDecl.getOwnedMembersRaw()) { + if (currMember instanceof GenericDeclaration) { + ((GenericDeclaration) currMember).getTypeVars().clear(); + } + if (currMember instanceof N4GetterDeclaration) { + ((N4GetterDeclaration) currMember).setDeclaredTypeRefNode(null); + } + if (currMember instanceof N4MethodDeclaration) { + ((N4MethodDeclaration) currMember).setDeclaredReturnTypeRefNode(null); + } + } + } + + /** Override to add additional output code directly after the default class declaration output code. */ + private List createAdditionalClassDeclarationCode() { + return Collections.emptyList(); // no additional statements by default + } + + private ArrayLiteral createDirectlyImplementedInterfaces(N4ClassDeclaration classDecl) { + List interfaces = typeAssistant.getSuperInterfacesSTEs(classDecl); + + // the return value of this method is intended for default method patching; for this purpose, we have to + // filter out some of the directly implemented interfaces: + Iterable directlyImplementedInterfacesFiltered = TranspilerUtils + .filterNominalInterfaces(interfaces); + return _ArrLit(Iterables.toArray(map(directlyImplementedInterfacesFiltered, ste -> _IdentRef(ste)), + IdentifierRef.class)); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ClassDeclarationTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ClassDeclarationTransformation.xtend deleted file mode 100644 index 309077e2b7..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ClassDeclarationTransformation.xtend +++ /dev/null @@ -1,155 +0,0 @@ -/** - * 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.transpiler.es.transform - -import com.google.inject.Inject -import java.util.List -import org.eclipse.n4js.n4JS.ArrayLiteral -import org.eclipse.n4js.n4JS.GenericDeclaration -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.n4JS.N4ClassExpression -import org.eclipse.n4js.n4JS.N4FieldAccessor -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.N4GetterDeclaration -import org.eclipse.n4js.n4JS.N4MethodDeclaration -import org.eclipse.n4js.n4JS.N4Modifier -import org.eclipse.n4js.n4JS.Statement -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.TransformationDependency.RequiresBefore -import org.eclipse.n4js.transpiler.assistants.TypeAssistant -import org.eclipse.n4js.transpiler.es.assistants.ClassConstructorAssistant -import org.eclipse.n4js.transpiler.es.assistants.ClassifierAssistant -import org.eclipse.n4js.transpiler.es.assistants.DelegationAssistant -import org.eclipse.n4js.transpiler.es.assistants.ReflectionAssistant -import org.eclipse.n4js.transpiler.im.SymbolTableEntry -import org.eclipse.n4js.transpiler.utils.TranspilerUtils - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.transpiler.utils.TranspilerUtils.* - -/** - * Transforms {@link N4ClassDeclaration}s into a constructor function and a $makeClass call. - *

- * Dependencies: - *

    - *
  • requiresBefore {@link MemberPatchingTransformation}: - * additional members must be in place before they are transformed within this transformation. - *
- */ -@RequiresBefore(MemberPatchingTransformation) -class ClassDeclarationTransformation extends Transformation { - - @Inject private ClassConstructorAssistant classConstructorAssistant; - @Inject private ClassifierAssistant classifierAssistant; - @Inject private ReflectionAssistant reflectionAssistant; - @Inject private DelegationAssistant delegationAssistant; - @Inject private TypeAssistant typeAssistant; - - override assertPreConditions() { - typeAssistant.assertClassifierPreConditions(); - assertFalse("class expressions are not supported yet", - state.im.eAllContents.exists[it instanceof N4ClassExpression]); - assertFalse("only top-level classes are supported, for now", - collectNodes(state.im, N4ClassDeclaration, false).exists[!typeAssistant.isTopLevel(it)]); - } - - override assertPostConditions() { - // none - } - - override analyze() { - // ignore - } - - override transform() { - collectNodes(state.im, N4ClassDeclaration, false).forEach[transformClassDecl]; - } - - def private void transformClassDecl(N4ClassDeclaration classDecl) { - val classSTE = findSymbolTableEntryForElement(classDecl, false); - val superClassSTE = typeAssistant.getSuperClassSTE(classDecl); - val fieldsRequiringExplicitDefinition = classifierAssistant.findFieldsRequiringExplicitDefinition(classDecl); - - reflectionAssistant.addN4TypeGetter(classDecl, classDecl); - - classConstructorAssistant.amendConstructor(classDecl, classSTE, superClassSTE, fieldsRequiringExplicitDefinition); - - val belowClassDecl = newArrayList; - belowClassDecl += classifierAssistant.createExplicitFieldDefinitions(classSTE, true, fieldsRequiringExplicitDefinition); - belowClassDecl += classifierAssistant.createStaticFieldInitializations(classDecl, classSTE, fieldsRequiringExplicitDefinition); - belowClassDecl += createAdditionalClassDeclarationCode(classDecl, classSTE); - insertAfter(classDecl.orContainingExportDeclaration, belowClassDecl); - - removeFieldsAndAbstractMembers(classDecl); - delegationAssistant.replaceDelegatingMembersByOrdinaryMembers(classDecl); - removeTypeInformation(classDecl); - - val implementedInterfaces = createDirectlyImplementedInterfaces(classDecl); - val $implements = steFor_$implementsInterfaces.name; - if (!implementedInterfaces.elements.empty) { - classDecl.ownedMembersRaw += _N4GetterDecl( - _LiteralOrComputedPropertyName($implements), - _Block( - _ReturnStmnt(implementedInterfaces) - ) - ) => [ - declaredModifiers += N4Modifier.STATIC; - ]; - } - - // change superClassRef to an equivalent extends-expression - // (this is a minor quirk required because superClassRef is not supported by the PrettyPrinterSwitch; - // for details see PrettyPrinterSwitch#caseN4ClassDeclaration()) - classDecl.superClassRef = null; - classDecl.superClassExpression = __NSSafe_IdentRef(superClassSTE); - } - - /** Removes fields and abstract members (they do not have a representation in the output code). */ - def private void removeFieldsAndAbstractMembers(N4ClassDeclaration classDecl) { - classDecl.ownedMembersRaw.removeIf[m| - switch (m) { - N4FieldDeclaration: true - N4FieldAccessor: m.isAbstract() - N4MethodDeclaration: m.isAbstract() - default: false - } - ]; - } - - def private void removeTypeInformation(N4ClassDeclaration classDecl) { - for (currMember : classDecl.ownedMembersRaw) { - if (currMember instanceof GenericDeclaration) { - currMember.typeVars.clear(); - } - switch (currMember) { - N4GetterDeclaration: - currMember.declaredTypeRefNode = null - N4MethodDeclaration: - currMember.declaredReturnTypeRefNode = null - } - } - } - - /** Override to add additional output code directly after the default class declaration output code. */ - def protected List createAdditionalClassDeclarationCode(N4ClassDeclaration classDecl, SymbolTableEntry classSTE) { - return #[]; // no additional statements by default - } - - def public ArrayLiteral createDirectlyImplementedInterfaces(N4ClassDeclaration classDecl) { - val interfaces = typeAssistant.getSuperInterfacesSTEs(classDecl); - - // the return value of this method is intended for default method patching; for this purpose, we have to - // filter out some of the directly implemented interfaces: - val directlyImplementedInterfacesFiltered = TranspilerUtils.filterNominalInterfaces(interfaces); - return _ArrLit( directlyImplementedInterfacesFiltered.map[ _IdentRef(it) ] ); - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/CommonJsImportsTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/CommonJsImportsTransformation.java new file mode 100644 index 0000000000..57b9c7168e --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/CommonJsImportsTransformation.java @@ -0,0 +1,291 @@ +/** + * Copyright (c) 2021 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ConditionalExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._LiteralOrComputedPropertyName; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Parenthesis; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableBinding; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableDeclaration; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableStatement; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.drop; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.last; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.n4js.N4JSGlobals; +import org.eclipse.n4js.n4JS.BindingElement; +import org.eclipse.n4js.n4JS.BindingProperty; +import org.eclipse.n4js.n4JS.DefaultImportSpecifier; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.ModuleSpecifierForm; +import org.eclipse.n4js.n4JS.N4JSFactory; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.VariableStatement; +import org.eclipse.n4js.n4JS.VariableStatementKeyword; +import org.eclipse.n4js.packagejson.PackageJsonProperties; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.TransformationDependency.ExcludesAfter; +import org.eclipse.n4js.transpiler.TransformationDependency.ExcludesBefore; +import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryInternal; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.utils.N4JSLanguageHelper; +import org.eclipse.n4js.utils.ProjectDescriptionUtils; +import org.eclipse.n4js.utils.Strings; +import org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot; +import org.eclipse.n4js.workspace.WorkspaceAccess; + +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableListMultimap; +import com.google.inject.Inject; + +/** + * Since switching to node's native support for ES6 modules, we have to re-write all import declarations that import + * from an old CommonJS module. Note that this behavior can be turned on/off in the package.json file, see + * {@link PackageJsonProperties#GENERATOR_REWRITE_CJS_IMPORTS}. + */ +@ExcludesAfter(SanitizeImportsTransformation.class) // CommonJsImportsTransformation must not run before + // SanitizeImportsTransformation +@ExcludesBefore(ModuleWrappingTransformation.class) // CommonJsImportsTransformation must not run after + // ModuleWrappingTransformation +public class CommonJsImportsTransformation extends Transformation { + + @Inject + private N4JSLanguageHelper n4jsLanguageHelper; + + @Inject + private WorkspaceAccess workspaceAccess; + + @Override + public void assertPreConditions() { + // true + } + + @Override + public void assertPostConditions() { + // true + } + + @Override + public void analyze() { + // nothing to be done + } + + @Override + public void transform() { + if (!getState().project.getProjectDescription().isGeneratorEnabledRewriteCjsImports()) { + // rewriting of CJS imports is not enabled for the containing project + return; + } + + ImmutableListMultimap importDeclsPerImportedModule = FluentIterable + .from(getState().im.getScriptElements()) + .filter(ImportDeclaration.class) + .filter(id -> !id.isBare()) // ignore bare imports + .index(importDecl -> getState().info.getImportedModule(importDecl)); + + List varStmnts = new ArrayList<>(); + for (TModule targetModule : importDeclsPerImportedModule.keySet()) { + varStmnts.addAll(transformImportDecl(targetModule, importDeclsPerImportedModule.get(targetModule))); + } + + ImportDeclaration lastImportDecl = last(filter(getState().im.getScriptElements(), ImportDeclaration.class)); + insertAfter(lastImportDecl, varStmnts.toArray(new VariableStatement[0])); + } + + /** + * For those of the given imports that actually require rewriting, this method will change them in place *and* + * return one or more variable statements that have to be inserted (by the client code) after all imports. + *

+ * For example: this method will rewrite the following imports + * + *

+	 * import defaultImport+ from "plainJsModule"
+	 * import {namedImport1+} from "plainJsModule"
+	 * import {namedImport2+} from "plainJsModule"
+	 * import * as NamespaceImport+ from "plainJsModule"
+	 * 
+ * + * to this import: + * + *
+	 * import $tempVar from './plainJsModule.cjs'
+	 * 
+ * + * and will return these variable statements: + * + *
+	 * const defaultImport = ($tempVar?.__esModule ? $tempVar.default : $tempVar);
+	 * const NamespaceImport = $tempVar;
+	 * const {
+	 *     namedImport1,
+	 *     namedImport2
+	 * } = $tempVar;
+	 * 
+ */ + private List transformImportDecl(TModule targetModule, + List allImportDeclsForThisModule) { + if (allImportDeclsForThisModule.isEmpty()) { + return Collections.emptyList(); + } + if (!requiresRewrite(targetModule)) { + return Collections.emptyList(); + } + + List importDeclsToRewrite = new ArrayList<>(allImportDeclsForThisModule); + if (exists(importDeclsToRewrite, id -> id.getModuleSpecifierForm() == ModuleSpecifierForm.PROJECT)) { + N4JSProjectConfigSnapshot targetProject = n4jsLanguageHelper.replaceDefinitionProjectByDefinedProject( + getState().resource, workspaceAccess.findProjectContaining(targetModule), true); + if (targetProject != null && targetProject.getProjectDescription().hasModuleProperty()) { + // don't rewrite project imports in case the target project has a top-level property "module" in its + // package.json, + // because in that case project imports will be redirected to an esm-ready file: + importDeclsToRewrite.removeIf(id -> id.getModuleSpecifierForm() == ModuleSpecifierForm.PROJECT); + } + } + if (importDeclsToRewrite.isEmpty()) { + return Collections.emptyList(); + } + + // special case with a simpler approach: + if (importDeclsToRewrite.size() == 1 && importDeclsToRewrite.get(0).getImportSpecifiers().size() == 1) { + ImportSpecifier importSpec = importDeclsToRewrite.get(0).getImportSpecifiers().get(0); + if (importSpec instanceof NamespaceImportSpecifier) { + // in this case we can simply replace the namespace import by a default import + String namespaceName = ((NamespaceImportSpecifier) importSpec).getAlias(); + DefaultImportSpecifier newImportSpec = N4JSFactory.eINSTANCE.createDefaultImportSpecifier(); + newImportSpec.setImportedElementAsText(namespaceName); + newImportSpec.setFlaggedUsedInCode(true); + newImportSpec.setRetainedAtRuntime(true); + // NOTE: don't copy the following lines to other places! Use methods #replace() instead! + getState().tracer.copyTrace(importSpec, newImportSpec); + insertAfter(importSpec, newImportSpec); + remove(importSpec); + return Collections.emptyList(); + } + } + + String tempVarName = computeNameForIntermediateDefaultImport(targetModule); + SymbolTableEntryInternal tempVarSTE = getSymbolTableEntryInternal(tempVarName, true); + + List varDecls = new ArrayList<>(); + List bindingProps = new ArrayList<>(); + + createVarDeclsOrBindings(importDeclsToRewrite, tempVarSTE, varDecls, bindingProps); + + List result = new ArrayList<>(); + for (VariableDeclaration varDecl : varDecls) { + result.add(_VariableStatement(VariableStatementKeyword.CONST, varDecl)); + } + if (!bindingProps.isEmpty()) { + result.add(_VariableStatement(VariableStatementKeyword.CONST, + _VariableBinding(bindingProps, _IdentRef(tempVarSTE)))); + } + + ImportDeclaration firstImportDecl = importDeclsToRewrite.get(0); + removeAll(firstImportDecl.getImportSpecifiers()); + DefaultImportSpecifier dsi = N4JSFactory.eINSTANCE.createDefaultImportSpecifier(); + firstImportDecl.getImportSpecifiers().add(dsi); + dsi.setImportedElementAsText(tempVarSTE.getName()); + dsi.setFlaggedUsedInCode(true); + dsi.setRetainedAtRuntime(true); + removeAll(drop(importDeclsToRewrite, 1)); + + return result; + } + + private void createVarDeclsOrBindings(List importDecls, SymbolTableEntry steTempVar, + List varDecls, List bindingProps) { + + SymbolTableEntry steEsModule = null; + SymbolTableEntry steDefault = null; + for (ImportDeclaration importDecl : importDecls) { + for (ImportSpecifier importSpec : importDecl.getImportSpecifiers()) { + if (importSpec instanceof NamedImportSpecifier) { + NamedImportSpecifier nis = (NamedImportSpecifier) importSpec; + String importedName = nis.getImportedElementAsText(); + String localName = nis.getAlias() != null ? nis.getAlias() : importedName; + boolean isDefaultImport = nis.isDefaultImport() || importedName == "default"; + if (isDefaultImport) { + if (steEsModule == null) { + steEsModule = steFor_interopProperty_esModule(); + } + if (steDefault == null) { + steDefault = getSymbolTableEntryInternal("default", true); + } + ParameterizedPropertyAccessExpression_IM pae = _PropertyAccessExpr(steTempVar, + steFor_interopProperty_esModule()); + pae.setOptionalChaining(true); + varDecls.add(_VariableDeclaration(localName, _Parenthesis(_ConditionalExpr( + pae, + _PropertyAccessExpr(steTempVar, steDefault), + _IdentRef(steTempVar))))); + } else { + BindingProperty bp = N4JSFactory.eINSTANCE.createBindingProperty(); + bindingProps.add(bp); + if (localName != importedName) { + bp.setDeclaredName(_LiteralOrComputedPropertyName(importedName)); + } + BindingElement be = N4JSFactory.eINSTANCE.createBindingElement(); + bp.setValue(be); + be.setVarDecl(_VariableDeclaration(localName)); + } + } else if (importSpec instanceof NamespaceImportSpecifier) { + NamespaceImportSpecifier nis = (NamespaceImportSpecifier) importSpec; + String namespaceName = nis.getAlias(); + varDecls.add(_VariableDeclaration(namespaceName, _IdentRef(steTempVar))); + } else { + throw new IllegalStateException( + "unsupported subclass of ImportSpecifier: " + importSpec.eClass().getName()); + } + } + } + } + + private boolean requiresRewrite(TModule targetModule) { + return !n4jsLanguageHelper.isES6Module(getState().index, targetModule); + } + + private String computeNameForIntermediateDefaultImport(TModule targetModule) { + String packageNameRaw = targetModule.getPackageName(); + if (packageNameRaw != null) { + String n4jsdScopeWithSep = N4JSGlobals.N4JSD_SCOPE + ProjectDescriptionUtils.NPM_SCOPE_SEPARATOR; + if (packageNameRaw.startsWith(n4jsdScopeWithSep)) { + packageNameRaw = packageNameRaw.substring(n4jsdScopeWithSep.length()); + } + } + + String packageName = Strings.toIdentifier(packageNameRaw, '_'); + String moduleName = Strings.toIdentifier(targetModule.getQualifiedName(), '_'); + String baseName = "$cjsImport__" + packageName + "__" + moduleName; + + int idx = 0; + String candidate = baseName; + // TODO: we won't find name conflicts with SymbolTableEntryOriginals (requires refactoring in + // TranspilerState.STECache) + while (getSymbolTableEntryInternal(candidate, false) != null) { + idx++; + candidate = baseName + idx; + } + return candidate; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/CommonJsImportsTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/CommonJsImportsTransformation.xtend deleted file mode 100644 index a7de33852e..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/CommonJsImportsTransformation.xtend +++ /dev/null @@ -1,254 +0,0 @@ -/** - * Copyright (c) 2021 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.transpiler.es.transform - -import com.google.common.collect.FluentIterable -import com.google.inject.Inject -import java.util.ArrayList -import java.util.List -import org.eclipse.n4js.N4JSGlobals -import org.eclipse.n4js.n4JS.BindingProperty -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.ModuleSpecifierForm -import org.eclipse.n4js.n4JS.N4JSFactory -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.n4JS.VariableStatement -import org.eclipse.n4js.n4JS.VariableStatementKeyword -import org.eclipse.n4js.packagejson.PackageJsonProperties -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.TransformationDependency.ExcludesAfter -import org.eclipse.n4js.transpiler.TransformationDependency.ExcludesBefore -import org.eclipse.n4js.transpiler.im.SymbolTableEntry -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.utils.N4JSLanguageHelper -import org.eclipse.n4js.utils.ProjectDescriptionUtils -import org.eclipse.n4js.utils.Strings -import org.eclipse.n4js.workspace.WorkspaceAccess - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - * Since switching to node's native support for ES6 modules, we have to re-write all import declarations - * that import from an old CommonJS module. Note that this behavior can be turned on/off in the package.json - * file, see {@link PackageJsonProperties#GENERATOR_CJS_DEFAULT_IMPORTS}. - */ -@ExcludesAfter(SanitizeImportsTransformation) // CommonJsImportsTransformation must not run before SanitizeImportsTransformation -@ExcludesBefore(ModuleWrappingTransformation) // CommonJsImportsTransformation must not run after ModuleWrappingTransformation -class CommonJsImportsTransformation extends Transformation { - - @Inject - private N4JSLanguageHelper n4jsLanguageHelper; - - @Inject - private WorkspaceAccess workspaceAccess; - - override void assertPreConditions() { - // true - } - - override void assertPostConditions() { - // true - } - - override void analyze() { - // nothing to be done - } - - override void transform() { - if (!state.project.projectDescription.generatorEnabledRewriteCjsImports) { - // rewriting of CJS imports is not enabled for the containing project - return; - } - - val importDeclsPerImportedModule = FluentIterable.from(state.im.scriptElements) - .filter(ImportDeclaration) - .filter[!bare] // ignore bare imports - .index[importDecl | state.info.getImportedModule(importDecl)]; - - val varStmnts = newArrayList; - for (targetModule : importDeclsPerImportedModule.keySet) { - varStmnts += transformImportDecl(targetModule, importDeclsPerImportedModule.get(targetModule)); - } - - val lastImportDecl = state.im.scriptElements.filter(ImportDeclaration).last(); - insertAfter(lastImportDecl, varStmnts); - } - - /** - * For those of the given imports that actually require rewriting, this method will change them in place *and* return one or more - * variable statements that have to be inserted (by the client code) after all imports. - *

- * For example: this method will rewrite the following imports - *

-	 * import defaultImport+ from "plainJsModule"
-	 * import {namedImport1+} from "plainJsModule"
-	 * import {namedImport2+} from "plainJsModule"
-	 * import * as NamespaceImport+ from "plainJsModule"
-	 * 
- * to this import: - *
-	 * import $tempVar from './plainJsModule.cjs'
-	 * 
- * and will return these variable statements: - *
-	 * const defaultImport = ($tempVar?.__esModule ? $tempVar.default : $tempVar);
-	 * const NamespaceImport = $tempVar;
-	 * const {
-	 *     namedImport1,
-	 *     namedImport2
-	 * } = $tempVar;
-	 * 
- */ - def private List transformImportDecl(TModule targetModule, List allImportDeclsForThisModule) { - if (allImportDeclsForThisModule.empty) { - return #[]; - } - if (!requiresRewrite(targetModule)) { - return #[]; - } - - val importDeclsToRewrite = new ArrayList(allImportDeclsForThisModule); - if (importDeclsToRewrite.exists[moduleSpecifierForm === ModuleSpecifierForm.PROJECT]) { - val targetProject = n4jsLanguageHelper.replaceDefinitionProjectByDefinedProject(state.resource, - workspaceAccess.findProjectContaining(targetModule), true); - if (targetProject !== null && targetProject.projectDescription.hasModuleProperty) { - // don't rewrite project imports in case the target project has a top-level property "module" in its package.json, - // because in that case project imports will be redirected to an esm-ready file: - importDeclsToRewrite.removeIf[moduleSpecifierForm === ModuleSpecifierForm.PROJECT]; - } - } - if (importDeclsToRewrite.empty) { - return #[]; - } - - // special case with a simpler approach: - if (importDeclsToRewrite.size === 1 && importDeclsToRewrite.head.importSpecifiers.size === 1) { - val importSpec = importDeclsToRewrite.head.importSpecifiers.head; - if (importSpec instanceof NamespaceImportSpecifier) { - // in this case we can simply replace the namespace import by a default import - val namespaceName = importSpec.alias; - val newImportSpec = N4JSFactory.eINSTANCE.createDefaultImportSpecifier() => [ - importedElementAsText = namespaceName; - flaggedUsedInCode = true; - retainedAtRuntime = true; - ]; - // NOTE: don't copy the following lines to other places! Use methods #replace() instead! - state.tracer.copyTrace(importSpec, newImportSpec); - insertAfter(importSpec, newImportSpec); - remove(importSpec); - return #[] - } - } - - val tempVarName = computeNameForIntermediateDefaultImport(targetModule); - val tempVarSTE = getSymbolTableEntryInternal(tempVarName, true); - - val varDecls = newArrayList; - val bindingProps = newArrayList; - - createVarDeclsOrBindings(importDeclsToRewrite, tempVarSTE, varDecls, bindingProps); - - val result = newArrayList; - for (varDecl : varDecls) { - result += _VariableStatement(VariableStatementKeyword.CONST, varDecl); - } - if (!bindingProps.empty) { - result += _VariableStatement(VariableStatementKeyword.CONST, _VariableBinding(bindingProps, _IdentRef(tempVarSTE))); - } - - val firstImportDecl = importDeclsToRewrite.head; - removeAll(firstImportDecl.importSpecifiers); - firstImportDecl.importSpecifiers += N4JSFactory.eINSTANCE.createDefaultImportSpecifier() => [ - importedElementAsText = tempVarSTE.name; - flaggedUsedInCode = true; - retainedAtRuntime = true; - ]; - removeAll(importDeclsToRewrite.drop(1)); - - return result; - } - - def private void createVarDeclsOrBindings(List importDecls, SymbolTableEntry steTempVar, - List varDecls, List bindingProps) { - - var steEsModule = null as SymbolTableEntry; - var steDefault = null as SymbolTableEntry; - for (importDecl : importDecls) { - for (importSpec : importDecl.importSpecifiers) { - switch (importSpec) { - NamedImportSpecifier: { // including DefaultImportSpecifier - val importedName = importSpec.importedElementAsText; - val localName = importSpec.alias ?: importedName; - val isDefaultImport = importSpec.isDefaultImport || importedName == "default"; - if (isDefaultImport) { - if (steEsModule === null) { - steEsModule = steFor_interopProperty_esModule(); - } - if (steDefault === null) { - steDefault = getSymbolTableEntryInternal("default", true); - } - varDecls += _VariableDeclaration(localName, _Parenthesis(_ConditionalExpr( - _PropertyAccessExpr(steTempVar, steFor_interopProperty_esModule) => [ optionalChaining = true ], - _PropertyAccessExpr(steTempVar, steDefault), - _IdentRef(steTempVar) - ))); - } else { - bindingProps += N4JSFactory.eINSTANCE.createBindingProperty => [ newBindingProp | - if (localName != importedName) { - newBindingProp.declaredName = _LiteralOrComputedPropertyName(importedName); - } - newBindingProp.value = N4JSFactory.eINSTANCE.createBindingElement => [ newBindingElem | - newBindingElem.varDecl = _VariableDeclaration(localName); - ] - ]; - } - } - NamespaceImportSpecifier: { - val namespaceName = importSpec.alias; - varDecls += _VariableDeclaration(namespaceName, _IdentRef(steTempVar)); - } - default: { - throw new IllegalStateException("unsupported subclass of ImportSpecifier: " + importSpec.eClass.name); - } - } - } - } - } - - def private boolean requiresRewrite(TModule targetModule) { - return !n4jsLanguageHelper.isES6Module(state.index, targetModule); - } - - def private String computeNameForIntermediateDefaultImport(TModule targetModule) { - var packageNameRaw = targetModule.packageName; - if (packageNameRaw !== null) { - val n4jsdScopeWithSep = N4JSGlobals.N4JSD_SCOPE + ProjectDescriptionUtils.NPM_SCOPE_SEPARATOR; - if (packageNameRaw.startsWith(n4jsdScopeWithSep)) { - packageNameRaw = packageNameRaw.substring(n4jsdScopeWithSep.length); - } - } - - val packageName = Strings.toIdentifier(packageNameRaw, '_'); - val moduleName = Strings.toIdentifier(targetModule.qualifiedName, '_'); - val baseName = "$cjsImport__" + packageName + "__" + moduleName; - - var idx = 0; - var candidate = baseName; - // TODO: we won't find name conflicts with SymbolTableEntryOriginals (requires refactoring in TranspilerState.STECache) - while (getSymbolTableEntryInternal(candidate, false) !== null) { - idx++; - candidate = baseName + idx; - } - return candidate; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DependencyInjectionTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DependencyInjectionTransformation.java new file mode 100644 index 0000000000..77cf19b81a --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DependencyInjectionTransformation.java @@ -0,0 +1,296 @@ +/** + * 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.transpiler.es.transform; + +import static com.google.common.collect.Iterables.toArray; +import static org.eclipse.n4js.tooling.organizeImports.DIUtility.findParentDIC; +import static org.eclipse.n4js.tooling.organizeImports.DIUtility.hasParentInjector; +import static org.eclipse.n4js.tooling.organizeImports.DIUtility.isBinder; +import static org.eclipse.n4js.tooling.organizeImports.DIUtility.isDIComponent; +import static org.eclipse.n4js.tooling.organizeImports.DIUtility.isInjectedClass; +import static org.eclipse.n4js.tooling.organizeImports.DIUtility.isSingleton; +import static org.eclipse.n4js.tooling.organizeImports.DIUtility.resolveBinders; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrLit; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrayElement; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ExprStmnt; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ObjLit; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyGetterDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyNameValuePair; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ReturnStmnt; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteralForSTE; +import static org.eclipse.n4js.transpiler.utils.TranspilerUtils.orContainingExportDeclaration; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.objectType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.symbolObjectType; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.head; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.last; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.N4JSLanguageConstants; +import org.eclipse.n4js.n4JS.ArrayLiteral; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.PropertyAssignment; +import org.eclipse.n4js.n4JS.Statement; +import org.eclipse.n4js.tooling.organizeImports.DIUtility; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.TAnnotationTypeRefArgument; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.TN4Classifier; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.utils.DeclMergingHelper; +import org.eclipse.xtext.xbase.lib.Pair; + +import com.google.inject.Inject; + +/** + * Generates DI meta information for the injector. Information is attached to the compiled type in the + * {@link N4JSLanguageConstants#DI_SYMBOL_KEY DI_SYMBOL_KEY} property. + * + * TODO the DI code below makes heavy use of TModule (probably) without true need; refactor this + */ +public class DependencyInjectionTransformation extends Transformation { + + @Inject + private DeclMergingHelper declMergingHelper; + + @Override + public void assertPreConditions() { + // true + } + + @Override + public void assertPostConditions() { + // true + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + for (N4ClassDeclaration classDecl : collectNodes(getState().im, N4ClassDeclaration.class, false)) { + TClass tClass = getState().info.getOriginalDefinedType(classDecl); + if (tClass != null) { + Statement codeForDI = generateCodeForDI(tClass, classDecl); + if (codeForDI != null) { + insertAfter(orContainingExportDeclaration(classDecl), codeForDI); + } + } + } + } + + /** + * Generates hooks for DI mechanisms. Mainly N4Injector (part of n4js libraries) depends on those hooks. Note that + * those in many cases require proper types to be imported, which makes those hooks indirectly depended on behavior + * of the script transpiler policy that decides to remove "unused" imported symbols. That one has to leave imported + * symbols that are refereed to in code generated here. + * + * Also, note second parameter passed is name or alias of the super type. passing it from caller, even if we don't + * use it, is a shortcut to avoid computing it again here. + */ + @SuppressWarnings("unchecked") + private Statement generateCodeForDI(TClass tClass, N4ClassDeclaration classDecl) { + List> propertiesForDI = createPropertiesForDI(tClass); + if (propertiesForDI.isEmpty()) { + return null; + } + // Object.defineProperty(C, Symbol.for(''), {value: { ... }} + SymbolTableEntry classSTE = findSymbolTableEntryForElement(classDecl, true); + SymbolTableEntryOriginal objectSTE = getSymbolTableEntryOriginal(objectType(getState().G), true); + SymbolTableEntryOriginal definePropertySTE = getSymbolTableEntryForMember(objectType(getState().G), + "defineProperty", false, true, true); + SymbolTableEntryOriginal symbolObjectSTE = getSymbolTableEntryOriginal(symbolObjectType(getState().G), true); + SymbolTableEntryOriginal forSTE = getSymbolTableEntryForMember(symbolObjectType(getState().G), "for", false, + true, true); + return _ExprStmnt(_CallExpr( + _PropertyAccessExpr(objectSTE, definePropertySTE), + _IdentRef(classSTE), + _CallExpr(_PropertyAccessExpr(symbolObjectSTE, forSTE), + _StringLiteral(N4JSLanguageConstants.DI_SYMBOL_KEY)), + _ObjLit(Pair.of("value", _ObjLit(propertiesForDI.toArray(new Pair[0])))))); + } + + private List> createPropertiesForDI(TClass tClass) { + List> result = new ArrayList<>(); + if (isBinder(tClass)) { + result.add(Pair.of("bindings", (Expression) generateBindingPairs(tClass))); + result.add(Pair.of("methodBindings", (Expression) generateMethodBindings(tClass))); + result.addAll(injectionPointsMetaInfo(tClass)); + } else if (isDIComponent(tClass)) { + if (hasParentInjector(tClass)) { + SymbolTableEntryOriginal parentDIC_STE = getSymbolTableEntryOriginal(findParentDIC(tClass), true); + result.add(Pair.of("parent", (Expression) __NSSafe_IdentRef(parentDIC_STE))); + } + result.add(Pair.of("binders", (Expression) generateBinders(tClass))); + result.addAll(injectionPointsMetaInfo(tClass)); + } else if (isInjectedClass(tClass, declMergingHelper)) { + result.addAll(injectionPointsMetaInfo(tClass)); + } + return result; + } + + /** + * Generate DI hooks for scopes, super type, injected ctor, injected fields + */ + private List> injectionPointsMetaInfo(TClass tClass) { + ArrayLiteral fieldInjectionValue = fieldInjection(tClass); + List> result = new ArrayList<>(); + if (isSingleton(tClass)) { + result.add(Pair.of("scope", _StringLiteral("Singleton"))); + } + TMethod ownedCtor = tClass.getOwnedCtor(); + if (ownedCtor != null && AnnotationDefinition.INJECT.hasAnnotation(ownedCtor)) { + result.add(Pair.of("injectCtorParams", methodInjectedParams(ownedCtor))); + } + if (!fieldInjectionValue.getElements().isEmpty()) { + result.add(Pair.of("fieldsInjectedTypes", fieldInjection(tClass))); + } + return result; + } + + /** + * Generate injection info for method annotated with {@link AnnotationDefinition#INJECT}. If method has no method + * parameters returned value is empty string, otherwise description of parameters is returned. + */ + private ArrayLiteral methodInjectedParams(TMethod tMethod) { + ArrayLiteral result = _ArrLit(); + for (TFormalParameter fpar : tMethod.getFpars()) { + SymbolTableEntryOriginal fparSTE = getSymbolTableEntryOriginal(fpar, true); + List pAs = new ArrayList<>(); + pAs.add(_PropertyNameValuePair("name", _StringLiteralForSTE(fparSTE))); + pAs.addAll(generateTypeInfo(fpar.getTypeRef())); + result.getElements().add(_ArrayElement(_ObjLit(pAs.toArray(new PropertyAssignment[0])))); + } + return result; + } + + /** + * Generate injection info for fields annotated with {@link AnnotationDefinition#INJECT}. + */ + private ArrayLiteral fieldInjection(TClass tClass) { + ArrayLiteral result = _ArrLit(); + for (TField field : getOwnedInejctedFields(tClass)) { + SymbolTableEntryOriginal fieldSTE = getSymbolTableEntryOriginal(field, true); + List pAs = new ArrayList<>(); + pAs.add(_PropertyNameValuePair("name", _StringLiteralForSTE(fieldSTE))); + pAs.addAll(generateTypeInfo(field.getTypeRef())); + result.getElements().add(_ArrayElement(_ObjLit(pAs.toArray(new PropertyAssignment[0])))); + } + return result; + } + + /** + * Generate injection info from {@link AnnotationDefinition#BIND} annotations on the provided class. + */ + @SuppressWarnings("unchecked") + private ArrayLiteral generateBindingPairs(TClass tClass) { + ArrayLiteral result = _ArrLit(); + for (Pair binding : getBindingPairs(tClass)) { + SymbolTableEntryOriginal keySTE = getSymbolTableEntryOriginal(binding.getKey(), true); + SymbolTableEntryOriginal valueSTE = getSymbolTableEntryOriginal(binding.getValue(), true); + result.getElements().add(_ArrayElement(_ObjLit( + Pair.of("from", __NSSafe_IdentRef(keySTE)), + Pair.of("to", __NSSafe_IdentRef(valueSTE))))); + } + return result; + } + + /** + * Generate injection info for methods annotated with {@link AnnotationDefinition#PROVIDES}. Returned information + * contains returned type, name and formal parameters of the method. + */ + private ArrayLiteral generateMethodBindings(TClass tClass) { + ArrayLiteral result = _ArrLit(); + for (TMethod method : getOwnedProviderMethods(tClass)) { + result.getElements().add(_ArrayElement(_ObjLit( + generateTypeInfo(method.getReturnTypeRef(), "to").get(0), + _PropertyNameValuePair("name", _StringLiteral(method.getName())), + _PropertyNameValuePair("args", methodInjectedParams(method))))); + } + return result; + } + + private ArrayLiteral generateBinders(TClass tClass) { + ArrayLiteral result = _ArrLit(); + for (Type binderType : resolveBinders(tClass)) { + SymbolTableEntryOriginal binderTypeSTE = getSymbolTableEntryOriginal(binderType, true); + result.getElements().add(_ArrayElement( + __NSSafe_IdentRef(binderTypeSTE))); + } + return result; + } + + /** + * Generate type information for DI. Mainly FQN of the {@link TypeRef}, or composed information if given type is + * generic. + */ + private List generateTypeInfo(TypeRef typeRef) { + return generateTypeInfo(typeRef, "type"); + } + + private List generateTypeInfo(TypeRef typeRef, String propertyName) { + if (!DIUtility.isProviderType(typeRef)) { + SymbolTableEntryOriginal declaredTypeSTE = getSymbolTableEntryOriginal(typeRef.getDeclaredType(), true); + return List.of( + _PropertyGetterDecl(propertyName, _ReturnStmnt(__NSSafe_IdentRef(declaredTypeSTE)))); + } else if (typeRef instanceof ParameterizedTypeRef) { + // typeRef should be N4Provider, fqn needs to be obtained at runtime + SymbolTableEntryOriginal declaredTypeSTE = getSymbolTableEntryOriginal(typeRef.getDeclaredType(), true); + return List.of( + _PropertyGetterDecl(propertyName, _ReturnStmnt(__NSSafe_IdentRef(declaredTypeSTE))), + _PropertyNameValuePair("typeVar", _ObjLit( + toArray(generateTypeInfo(head(filter(typeRef.getDeclaredTypeArgs(), TypeRef.class))), + PropertyAssignment.class)))); + } else { + String msg = typeRef == null ? "" + : (typeRef.getDeclaredType() == null ? "" : typeRef.getDeclaredType().getName()); + throw new IllegalStateException("cannot generate type info for " + msg); + // note: at this point, the old transpiler did only log the error and returned something like: + // return #[]; + } + } + + /** + * Get list of {@link Pair}s of first and second argument of the {@link AnnotationDefinition#BIND} annotation. + */ + private Iterable> getBindingPairs(TClass clazz) { + return map(AnnotationDefinition.BIND.getAllAnnotations(clazz), a -> Pair.of( + (TN4Classifier) (((TAnnotationTypeRefArgument) a.getArgs().get(0)).getTypeRef().getDeclaredType()), + (TN4Classifier) ((TAnnotationTypeRefArgument) last(a.getArgs())).getTypeRef().getDeclaredType())); + } + + private Iterable getOwnedProviderMethods(TClass clazz) { + return filter(filter(clazz.getOwnedMembers(), TMethod.class), + m -> AnnotationDefinition.PROVIDES.hasAnnotation(m)); + } + + private Iterable getOwnedInejctedFields(TN4Classifier clazz) { + return filter(filter(clazz.getOwnedMembers(), TField.class), f -> AnnotationDefinition.INJECT.hasAnnotation(f)); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DependencyInjectionTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DependencyInjectionTransformation.xtend deleted file mode 100644 index 249acf26c1..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DependencyInjectionTransformation.xtend +++ /dev/null @@ -1,268 +0,0 @@ -/** - * 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.transpiler.es.transform - -import com.google.inject.Inject -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.N4JSLanguageConstants -import org.eclipse.n4js.n4JS.ArrayLiteral -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.n4JS.PropertyAssignment -import org.eclipse.n4js.n4JS.Statement -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.TAnnotationTypeRefArgument -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.TField -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.ts.types.TN4Classifier -import org.eclipse.n4js.utils.DeclMergingHelper - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.tooling.organizeImports.DIUtility.* -import static extension org.eclipse.n4js.transpiler.utils.TranspilerUtils.* -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * Generates DI meta information for the injector. - * Information is attached to the compiled type in the {@link N4JSLanguageConstants#DI_SYMBOL_KEY DI_SYMBOL_KEY} - * property. - * - * TODO the DI code below makes heavy use of TModule (probably) without true need; refactor this - */ -class DependencyInjectionTransformation extends Transformation { - - @Inject private DeclMergingHelper declMergingHelper; - - override assertPreConditions() { - // true - } - - override assertPostConditions() { - // true - } - - override analyze() { - // ignore - } - - override transform() { - collectNodes(state.im, N4ClassDeclaration, false).forEach[classDecl| - val tClass = state.info.getOriginalDefinedType(classDecl); - if( tClass !== null ) { - val codeForDI = generateCodeForDI(tClass, classDecl); - if(codeForDI!==null) { - insertAfter(classDecl.orContainingExportDeclaration, codeForDI); - } - } - ]; - } - - /** - * Generates hooks for DI mechanisms. Mainly N4Injector (part of n4js libraries) - * depends on those hooks. - * Note that those in many cases require proper types to be imported, which makes those - * hooks indirectly depended on behavior of the script transpiler policy that decides to - * remove "unused" imported symbols. That one has to leave imported symbols that are refereed to - * in code generated here. - * - * Also, note second parameter passed is name or alias of the super type. - * passing it from caller, even if we don't use it, is a shortcut to avoid computing it again here. - */ - def private Statement generateCodeForDI(TClass tClass, N4ClassDeclaration classDecl) { - val propertiesForDI = createPropertiesForDI(tClass, classDecl); - if(propertiesForDI.empty) { - return null; - } - // Object.defineProperty(C, Symbol.for(''), {value: { ... }} - val classSTE = findSymbolTableEntryForElement(classDecl, true); - val objectSTE = getSymbolTableEntryOriginal(state.G.objectType, true); - val definePropertySTE = getSymbolTableEntryForMember(state.G.objectType, "defineProperty", false, true, true); - val symbolObjectSTE = getSymbolTableEntryOriginal(state.G.symbolObjectType, true); - val forSTE = getSymbolTableEntryForMember(state.G.symbolObjectType, "for", false, true, true); - return _ExprStmnt(_CallExpr( - _PropertyAccessExpr(objectSTE, definePropertySTE), - _IdentRef(classSTE), - _CallExpr(_PropertyAccessExpr(symbolObjectSTE, forSTE), _StringLiteral(N4JSLanguageConstants.DI_SYMBOL_KEY)), - _ObjLit( - "value" -> _ObjLit( - propertiesForDI - ) - ) - )); - } - - def private Pair[] createPropertiesForDI(TClass tClass, N4ClassDeclaration classDecl) { - val result = >newArrayList; - if(isBinder(tClass)) { - result += "bindings" -> generateBindingPairs(tClass) as Expression; - result += "methodBindings" -> generateMethodBindings(tClass) as Expression; - result += injectionPointsMetaInfo(tClass); - } else if(isDIComponent(tClass)) { - if(hasParentInjector(tClass)) { - val parentDIC_STE = getSymbolTableEntryOriginal(findParentDIC(tClass), true); - result += "parent" -> __NSSafe_IdentRef(parentDIC_STE) as Expression; - } - result += "binders" -> generateBinders(tClass) as Expression; - result += injectionPointsMetaInfo(tClass); - } else if(isInjectedClass(tClass, declMergingHelper)) { - result += injectionPointsMetaInfo(tClass); - } - return result; - } - - /** - * Generate DI hooks for scopes, super type, injected ctor, injected fields - */ - def private Pair[] injectionPointsMetaInfo(TClass tClass) { - val fieldInjectionValue = fieldInjection(tClass); - val result = >newArrayList; - if(isSingleton(tClass)) { - result += "scope" -> _StringLiteral("Singleton") as Expression; - } - val ownedCtor = tClass.ownedCtor; - if(ownedCtor!==null && AnnotationDefinition.INJECT.hasAnnotation(ownedCtor)) { - result += "injectCtorParams" -> ownedCtor.methodInjectedParams as Expression; - } - if(!fieldInjectionValue.elements.empty) { - result += "fieldsInjectedTypes" -> fieldInjection(tClass) as Expression; - } - return result; - } - - /** - * Generate injection info for method annotated with {@link AnnotationDefinition#INJECT}. - * If method has no method parameters returned value is empty string, - * otherwise description of parameters is returned. - */ - def private ArrayLiteral methodInjectedParams(TMethod tMethod) { - val result = _ArrLit(); - for(fpar : tMethod.fpars) { - val fparSTE = getSymbolTableEntryOriginal(fpar, true); - result.elements += _ArrayElement(_ObjLit( - #[ _PropertyNameValuePair("name", _StringLiteralForSTE(fparSTE)) ] - + fpar.typeRef.generateTypeInfo - )); - } - return result; - } - - /** - * Generate injection info for fields annotated with {@link AnnotationDefinition#INJECT}. - */ - def private ArrayLiteral fieldInjection(TClass tClass) { - val result = _ArrLit(); - for(field : getOwnedInejctedFields(tClass)) { - val fieldSTE = getSymbolTableEntryOriginal(field, true); - result.elements += _ArrayElement(_ObjLit( - #[ _PropertyNameValuePair("name", _StringLiteralForSTE(fieldSTE)) ] - + field.typeRef.generateTypeInfo - )); - } - return result; - } - - /** - * Generate injection info from {@link AnnotationDefinition#BIND} annotations on the provided class. - */ - private def ArrayLiteral generateBindingPairs(TClass tClass) { - val result = _ArrLit(); - for(binding : getBindingPairs(tClass)) { - val keySTE = getSymbolTableEntryOriginal(binding.key, true); - val valueSTE = getSymbolTableEntryOriginal(binding.value, true); - result.elements += _ArrayElement(_ObjLit( - "from" -> __NSSafe_IdentRef(keySTE), - "to" -> __NSSafe_IdentRef(valueSTE) - )); - } - return result; - } - - /** - * Generate injection info for methods annotated with {@link AnnotationDefinition#PROVIDES}. - * Returned information contains returned type, name and formal parameters of the method. - */ - def private ArrayLiteral generateMethodBindings(TClass tClass) { - val result = _ArrLit(); - for(method : getOwnedProviderMethods(tClass)) { - result.elements += _ArrayElement(_ObjLit( - method.returnTypeRef.generateTypeInfo("to").head, - _PropertyNameValuePair("name", _StringLiteral(method.name)), - _PropertyNameValuePair("args", method.methodInjectedParams) - )); - } - return result; - } - - def private ArrayLiteral generateBinders(TClass tClass) { - val result = _ArrLit(); - for(binderType : resolveBinders(tClass)) { - val binderTypeSTE = getSymbolTableEntryOriginal(binderType, true); - result.elements += _ArrayElement( - __NSSafe_IdentRef(binderTypeSTE) - ); - } - return result; - } - - /** - * Generate type information for DI. Mainly FQN of the {@link TypeRef}, or composed information - * if given type is generic. - */ - def private PropertyAssignment[] generateTypeInfo(TypeRef typeRef) { - typeRef.generateTypeInfo("type") - } - def private PropertyAssignment[] generateTypeInfo(TypeRef typeRef, String propertyName) { - if (!typeRef.providerType) { - val declaredTypeSTE = getSymbolTableEntryOriginal(typeRef.declaredType, true); - return #[ - _PropertyGetterDecl(propertyName, _ReturnStmnt(__NSSafe_IdentRef(declaredTypeSTE))) - ]; - } else if (typeRef instanceof ParameterizedTypeRef) { - // typeRef should be N4Provider, fqn needs to be obtained at runtime - val declaredTypeSTE = getSymbolTableEntryOriginal(typeRef.declaredType, true); - return #[ - _PropertyGetterDecl(propertyName, _ReturnStmnt(__NSSafe_IdentRef(declaredTypeSTE))), - _PropertyNameValuePair("typeVar", _ObjLit( - typeRef.declaredTypeArgs.filter(TypeRef).head.generateTypeInfo - )) - ]; - } else { - throw new IllegalStateException("cannot generate type info for " + typeRef?.declaredType?.name); -// note: at this point, the old transpiler did only log the error and returned something like: -// return #[]; - } - } - - - - - /** - * Get list of {@link Pair}s of first and second argument of the {@link AnnotationDefinition#BIND} annotation. - */ - def private getBindingPairs(TClass clazz) { - AnnotationDefinition.BIND.getAllAnnotations(clazz).map [ - ((args.head as TAnnotationTypeRefArgument).getTypeRef.declaredType) as TN4Classifier - -> ((args.last as TAnnotationTypeRefArgument).getTypeRef.declaredType) as TN4Classifier - ] - } - - def private getOwnedProviderMethods(TClass clazz) { - clazz.ownedMembers.filter(TMethod).filter[AnnotationDefinition.PROVIDES.hasAnnotation(it)]; - } - - def private getOwnedInejctedFields(TN4Classifier clazz) { - clazz.ownedMembers.filter(TField).filter[AnnotationDefinition.INJECT.hasAnnotation(it)] - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DestructuringTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DestructuringTransformation.java new file mode 100644 index 0000000000..f004873997 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DestructuringTransformation.java @@ -0,0 +1,478 @@ +/** + * 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.transpiler.es.transform; + +import static com.google.common.collect.Iterables.toArray; +import static org.eclipse.n4js.n4JS.DestructureUtils.containsDestructuringPattern; +import static org.eclipse.n4js.n4JS.DestructureUtils.isRoot; +import static org.eclipse.n4js.n4JS.DestructureUtils.isTopOfDestructuringAssignment; +import static org.eclipse.n4js.n4JS.DestructureUtils.isTopOfDestructuringForStatement; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._AssignmentExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Block; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ConditionalExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._EqualityExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ExprStmnt; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._FormalParameter; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._FunExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IndexAccessExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._NumericLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Parenthesis; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ReturnStmnt; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Snippet; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableDeclaration; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableStatement; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.arrayType; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.head; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.generator.GeneratorOption; +import org.eclipse.n4js.n4JS.ArrayLiteral; +import org.eclipse.n4js.n4JS.AssignmentExpression; +import org.eclipse.n4js.n4JS.Block; +import org.eclipse.n4js.n4JS.CatchBlock; +import org.eclipse.n4js.n4JS.DestructNode; +import org.eclipse.n4js.n4JS.EqualityOperator; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ForStatement; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor; +import org.eclipse.n4js.n4JS.N4JSASTUtils; +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.n4JS.PropertyAssignment; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.n4JS.Statement; +import org.eclipse.n4js.n4JS.VariableBinding; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.VariableDeclarationOrBinding; +import org.eclipse.n4js.n4JS.VariableEnvironmentElement; +import org.eclipse.n4js.n4JS.VariableStatement; +import org.eclipse.n4js.n4JS.VariableStatementKeyword; +import org.eclipse.n4js.n4JS.WithStatement; +import org.eclipse.n4js.transpiler.AbstractTranspiler; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.TransformationDependency.ExcludesAfter; +import org.eclipse.n4js.transpiler.TransformationDependency.Optional; +import org.eclipse.n4js.transpiler.im.IdentifierRef_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryIMOnly; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryInternal; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.ts.types.TypableElement; +import org.eclipse.xtext.EcoreUtil2; +import org.eclipse.xtext.xbase.lib.IterableExtensions; +import org.eclipse.xtext.xbase.lib.Pair; + +import com.google.common.base.Strings; + +/** + * Transforms ES6 destructuring patterns into equivalent ES5 code. If the target engine supports ES6 destructuring + * patterns, this transformation can simply be deactivated. + *

+ * For details on destructuring patterns, see documentation of class {@link DestructNode}. + */ +@Optional(GeneratorOption.Destructuring) +@ExcludesAfter(StaticPolyfillTransformation.class) // otherwise destructuring patterns from filling module won't be + // processed! +public class DestructuringTransformation extends Transformation { + + /** Counts destructuring patterns per variable environment. Used to avoid name clashes of helper variables. */ + private final Map destructsPerScope = new HashMap<>(); + + @Override + public void assertPreConditions() { + // true + // (however, this transformation should run as early as possible) + } + + @Override + public void assertPostConditions() { + // true + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + + // compute nodes we have to transform before changing anything + List destructBindings = toList(filter( + collectNodes(getState().im, VariableStatement.class, true), vs -> containsDestructuringPattern(vs))); + List destructAssignments = toList(filter( + collectNodes(getState().im, AssignmentExpression.class, true), + ae -> isTopOfDestructuringAssignment(ae) && isRoot(ae))); + List destructForStmnts = toList(filter(collectNodes(getState().im, ForStatement.class, true), + fs -> containsDestructuringPattern(fs) || isTopOfDestructuringForStatement(fs))); + + // now perform the changes + for (VariableStatement vs : destructBindings) { + transformDestructuringBindings(vs); + } + for (AssignmentExpression ae : destructAssignments) { + transformDestructuringAssignment(ae); + } + for (ForStatement fs : destructForStmnts) { + transformForStatementWithDestructuring(fs); + } + } + + /** + * Transforms not a single destructuring binding but all destructuring bindings in the given variable statement. + */ + private void transformDestructuringBindings(VariableStatement stmnt) { + List newVarDecls = computeVariableDeclarations(stmnt.getVarDeclsOrBindings()); + stmnt.getVarDeclsOrBindings().clear(); + stmnt.getVarDeclsOrBindings().addAll(newVarDecls); + } + + /** + * Transforms (a single) destructuring assignment. + */ + public void transformDestructuringAssignment(AssignmentExpression expr) { + // We pass the value of the expression to the function call. GHOLD-407 + String fparName; + FunctionExpression helperFun; + + fparName = "$destruct" + "Param0"; + FormalParameter fpar = _FormalParameter(fparName); + helperFun = _FunExpr(false, null, fpar); + + EList helperFunContents = helperFun.getBody().getStatements(); + DestructNode rootNode = DestructNode.unify(expr); + List helperVars = new ArrayList<>(); + List> simpleAssignments = new ArrayList<>(); + traverse(helperVars, simpleAssignments, rootNode, expr.getRhs(), fparName); + + helperFunContents.addAll(toList(map(helperVars, vd -> _VariableStatement(vd)))); + helperFunContents.addAll(toList(map(simpleAssignments, sa -> _ExprStmnt(_AssignmentExpr( + __NSSafe_IdentRef(sa.getKey()), sa.getValue()))))); + + // the following return statement is required to make sure entire expression evaluates to the rhs of + // the assignment expression 'expr' (without evaluating rhs again!) + SymbolTableEntry firstHelperVarSTE = findSymbolTableEntryForElement(helperVars.get(0), false); + helperFunContents.add(_ReturnStmnt(_IdentRef(firstHelperVarSTE))); + + // parentheses required because the expression might appear as a statement (to disambiguate from function + // declaration) replace(expr, callExpr); + ParameterizedCallExpression callExpr = _CallExpr(_Parenthesis(helperFun), expr.getRhs()); + replace(expr, callExpr); + } + + private void transformForStatementWithDestructuring(ForStatement stmnt) { + + if (stmnt.isForPlain()) { + + if (!stmnt.getVarDeclsOrBindings().isEmpty()) { + // something like: for( var [a,b]=[1,2] ;;) {} + + // note: pretty much the same case as method #transformDestructuringBindings() above + List newVarDecls = computeVariableDeclarations(stmnt.getVarDeclsOrBindings()); + stmnt.getVarDeclsOrBindings().clear(); + stmnt.getVarDeclsOrBindings().addAll(newVarDecls); + + } else { + // something like: for( [a,b]=[1,2] ;;) {} + + // here, stmnt.initExpr is an ordinary destructuring assignment that was already handled by method + // #transformDestructuringAssignment(AssignmentExpression) above -> nothing to do here! + } + + } else { + // now: for..in OR for..of + + int depth = getNestingDepth(stmnt); + + VariableDeclaration iterVar = _VariableDeclaration("$destructStep$" + depth); + SymbolTableEntryIMOnly iterVarSTE = createSymbolTableEntryIMOnly(iterVar); + + boolean needDeclarations = false; + VariableStatementKeyword varStmtKeyword = VariableStatementKeyword.VAR; + List helperVars = new ArrayList<>(); + List> simpleAssignments = new ArrayList<>(); + if (!stmnt.getVarDeclsOrBindings().isEmpty()) { + // something like: for( var [a,b] of [ [1,2], [3,4] ] ) {} + + if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { + assertTrue("there should be exactly one VariableBinding in stmnt.varDeclsOrBindings", + stmnt.getVarDeclsOrBindings().size() == 1 + && stmnt.getVarDeclsOrBindings().get(0) instanceof VariableBinding); + } + + DestructNode rootNode = DestructNode.unify((VariableBinding) stmnt.getVarDeclsOrBindings().get(0)); + // fparname = null since we do not generate any function. + traverse(helperVars, simpleAssignments, rootNode, _IdentRef(iterVarSTE), null); + needDeclarations = true; + varStmtKeyword = stmnt.getVarStmtKeyword(); + + } else if (stmnt.getInitExpr() instanceof ArrayLiteral || stmnt.getInitExpr() instanceof ObjectLiteral) { + // something like: for( [a,b] of [ [1,2], [3,4] ] ) {} + + DestructNode rootNode = DestructNode.unify(stmnt); + // fparname = null since we do not generate any function. + traverse(helperVars, simpleAssignments, rootNode, _IdentRef(iterVarSTE), null); + needDeclarations = false; + + } else { + throw new IllegalArgumentException(); + } + + if (!(stmnt.getStatement() instanceof Block)) { + stmnt.setStatement(_Block(stmnt.getStatement())); + } + Block body = (Block) stmnt.getStatement(); + + List toBeInserted = new ArrayList<>(); + if (needDeclarations) { + toBeInserted.add(_VariableStatement(varStmtKeyword, toArray(map(simpleAssignments, sa -> { + VariableDeclaration varDecl = getVariableDeclarationFromSTE(sa.getKey()); + varDecl.setExpression(sa.getValue()); + return varDecl; + }), VariableDeclarationOrBinding.class))); + } else { + toBeInserted.add(_VariableStatement(toArray(helperVars, VariableDeclaration.class))); + toBeInserted.addAll(toList(map(simpleAssignments, sa -> _ExprStmnt(_AssignmentExpr( + __NSSafe_IdentRef(sa.getKey()), sa.getValue()))))); + } + + body.getStatements().addAll(0, toBeInserted); + + // initExpr has been move to beginning of body (if any) + stmnt.setInitExpr(null); + // variable declarations have been moved to beginning of body (if any) + stmnt.getVarDeclsOrBindings().clear(); + // only declared variable in the for statement is the iteration variable + stmnt.getVarDeclsOrBindings().add(iterVar); + } + } + + /** + * Breaks down all VariableBindings in the given list into simple variable declarations and returns a list + * containing the variable declarations that were contained in the given list from the beginning plus those created + * when breaking down the variable bindings. The order of the elements in the given list is preserved! + */ + private List computeVariableDeclarations( + List varDeclsOrBindings) { + List result = new ArrayList<>(); + for (VariableDeclarationOrBinding vdeclOrBinding : varDeclsOrBindings) { + if (vdeclOrBinding instanceof VariableDeclaration) { + result.add((VariableDeclaration) vdeclOrBinding); + } else if (vdeclOrBinding instanceof VariableBinding) { + DestructNode rootNode = DestructNode.unify(vdeclOrBinding); + List helperVars = new ArrayList<>(); + List> simpleAssignments = new ArrayList<>(); + // fparname = null since we do not generate any function. + traverse(helperVars, simpleAssignments, rootNode, vdeclOrBinding.getExpression(), null); + result.addAll(toList(map(simpleAssignments, sa -> { + VariableDeclaration varDecl = getVariableDeclarationFromSTE(sa.getKey()); + varDecl.setExpression(sa.getValue()); + return varDecl; + }))); + } + } + return result; + } + + private void traverse(List helperVars, + List> simpleAssignments, + DestructNode rootNode, Expression value, String fparName) { + + VariableEnvironmentElement scope = N4JSASTUtils.getScope(rootNode.astElement, false); + if (scope == null) { + scope = getState().im; + } + int n = destructsPerScope.merge(scope, 1, (i, j) -> i + j) - 1; + traverse(helperVars, simpleAssignments, rootNode.getNestedNodes(), value, fparName, Integer.toString(n)); + } + + /** + * Breaks down the destructuring pattern, represented by the given {@link DestructNode}s, into a number of simple + * assignments (without destructuring) that will be added to argument 'simpleAssignments'. The order of those simple + * assignments matters. Nested patterns as returned by {@link DestructNode#getNestedNodes()} are also broken down. + * fparName, if not null, is the parameter name of the enclosing function. + */ + private void traverse(List helperVars, + List> simpleAssignments, + List nodes, Expression value, String fparName, String helperVarSuffix) { + + int len = nodes.size(); + boolean isPositionalPattern = IterableExtensions.exists(nodes, n -> n.isPositional()); + boolean isRest = isPositionalPattern && len > 0 && nodes.get(len - 1).rest; + + // STEP 1: create code to prepare the value to be destructured and to assign it to a helper variable + + // creating a new helper variable + String currHelperVarName = "$destruct" + helperVarSuffix; + VariableDeclaration currHelperVarDecl = _VariableDeclaration(currHelperVarName); + helperVars.add(currHelperVarDecl); + SymbolTableEntry currHelperVarSTE = findSymbolTableEntryForElement(currHelperVarDecl, true); + if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { + assertTrue("", getVariableDeclarationFromSTE(currHelperVarSTE) == currHelperVarDecl); + assertTrue("", currHelperVarSTE.getElementsOfThisName().contains(currHelperVarDecl)); + } + var $sliceToArrayForDestructSTE = steFor_$sliceToArrayForDestruct(); + + if (isRest) { + // result.add(currHelperVar+" = function(arr){return Array.isArray(arr) ? arr : + // Array.from(arr);}("+value+")"); + simpleAssignments.add(Pair.of(currHelperVarSTE, _CallExpr( + _Snippet("function(arr){return Array.isArray(arr) ? arr : Array.from(arr);}"), + value))); + } else { + Expression passValue; + if (Strings.isNullOrEmpty(fparName)) { + passValue = value; + } else { + // If the fparName is not empty, the generated function for destructuring has a parameter and we should + // use that parameter instead. GHOLD-407 + SymbolTableEntryInternal fparSTE = getSymbolTableEntryInternal(fparName, true); + passValue = _IdentRef(fparSTE); + } + if (isPositionalPattern) { + // result.add(currHelperVar+" = $sliceToArrayForDestruct(("+value+"), "+len+")"); + simpleAssignments.add(Pair.of(currHelperVarSTE, _CallExpr( + _IdentRef($sliceToArrayForDestructSTE), + _Parenthesis(passValue), + _NumericLiteral(len)))); + } else { + // result.add(currHelperVar+" = ("+value+")"); + simpleAssignments.add(Pair.of(currHelperVarSTE, _Parenthesis( + passValue))); + } + } + + // STEP 2: create code to perform the actual destructuring + + SymbolTableEntryOriginal sliceSTE = getSymbolTableEntryForMember(arrayType(getState().G), "slice", false, false, + true); + + var nestedPatternsCounter = 0; + for (var i = 0; i < len; i++) { + DestructNode currNode = nodes.get(i); + + // get the current element or property out of 'value' (i.e. the one that corresponds to 'currNode') + Expression currValueRaw; + if (isRest && i == len - 1) { + // currHelperVar.slice(i) + currValueRaw = _CallExpr(_PropertyAccessExpr(currHelperVarSTE, sliceSTE), _NumericLiteral(i)); + } else if (isPositionalPattern) { + // currHelperVar[i] + currValueRaw = _IndexAccessExpr(currHelperVarSTE, _NumericLiteral(i)); + } else { + // currHelperVar['propName'] + currValueRaw = _IndexAccessExpr(currHelperVarSTE, _StringLiteral(currNode.propName)); + } + + Expression currValue; + if (currNode.defaultExpr != null) { + // currValueRaw+" == undefined ? ("+transformAST.doTransform(currNode.defaultExpr)+") : "+currValueRaw + currValue = _ConditionalExpr( + _EqualityExpr( + copy(currValueRaw), // must copy because used twice in this conditional expression! + EqualityOperator.SAME, + undefinedRef()), + _Parenthesis( + currNode.defaultExpr), + currValueRaw); + } else { + currValue = currValueRaw; + } + + if (currNode.varRef != null || currNode.varDecl != null) { + // actual destructuring + // (assigning an element or property from 'value', i.e. the 'currValue', to the variable with name + // currNode.varName) + TypableElement varSource = currNode.varRef != null ? currNode.varRef : currNode.varDecl; + SymbolTableEntry varSTE = null; + + if (varSource instanceof IdentifierRef_IM) { + varSTE = ((IdentifierRef_IM) varSource).getId_IM(); + } else if (varSource instanceof VariableDeclaration) { + varSTE = findSymbolTableEntryForElement((VariableDeclaration) varSource, true); + } + simpleAssignments.add(Pair.of(varSTE, currValue)); + } else if (currNode.getNestedNodes() != null && currNode.getNestedNodes().size() != 0) { + // nested destructuring + // (assigning the current value in 'currValue' to the nested destructuring pattern) + nestedPatternsCounter++; + // fparname = null since we do not generate any function + traverse(helperVars, simpleAssignments, currNode.getNestedNodes(), currValue, null, + helperVarSuffix + "$" + nestedPatternsCounter); + } else { + // padding entry (from elision) + // -> do nothing (but consume the current index 'i') + } + } + } + + private static final int getNestingDepth(ForStatement stmnt) { + int d = 0; + EObject obj = stmnt; + while ((obj = obj.eContainer()) != null) { + if (obj instanceof ForStatement) { + d++; + } + } + return d; + } + + /** + * Returns a list of statements that are the root statements of the next outer variable environment directly + * containing the given AST node. + */ + static EList getContainingVariableEnvironmentContent(EObject astNode) { + VariableEnvironmentElement vee = EcoreUtil2.getContainerOfType(astNode.eContainer(), + VariableEnvironmentElement.class); + if (vee == null) { + throw new IllegalArgumentException("given AST node does not have an outer variable environment"); + } + if (vee instanceof Script) { + return ((Script) vee).getScriptElements(); + } + if (vee instanceof FunctionOrFieldAccessor) { + return ((FunctionOrFieldAccessor) vee).getBody().getStatements(); + } + if (vee instanceof CatchBlock) { + return ((CatchBlock) vee).getBlock().getStatements(); + } + if (vee instanceof PropertyAssignment) { + return getContainingVariableEnvironmentContent(vee); + } + if (vee instanceof WithStatement) { + WithStatement ws = (WithStatement) vee; + if (!(ws.getStatement() instanceof Block)) { + ws.setStatement(_Block(ws.getStatement())); + } + return ((Block) ws.getStatement()).getStatements(); + } + throw new IllegalArgumentException("given AST node does not have an outer variable environment"); + } + + private static VariableDeclaration getVariableDeclarationFromSTE(SymbolTableEntry ste) { + return head(filter(ste.getElementsOfThisName(), VariableDeclaration.class)); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DestructuringTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DestructuringTransformation.xtend deleted file mode 100644 index 20edd7c310..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/DestructuringTransformation.xtend +++ /dev/null @@ -1,406 +0,0 @@ -/** - * 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.transpiler.es.transform - -import java.util.ArrayList -import java.util.List -import java.util.Map -import org.eclipse.emf.common.util.EList -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.DestructNode -import org.eclipse.n4js.n4JS.ArrayLiteral -import org.eclipse.n4js.n4JS.AssignmentExpression -import org.eclipse.n4js.n4JS.Block -import org.eclipse.n4js.n4JS.CatchBlock -import org.eclipse.n4js.n4JS.EqualityOperator -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.ForStatement -import org.eclipse.n4js.n4JS.FunctionExpression -import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor -import org.eclipse.n4js.n4JS.N4JSASTUtils -import org.eclipse.n4js.n4JS.ObjectLiteral -import org.eclipse.n4js.n4JS.PropertyAssignment -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.n4JS.Statement -import org.eclipse.n4js.n4JS.VariableBinding -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.n4JS.VariableDeclarationOrBinding -import org.eclipse.n4js.n4JS.VariableEnvironmentElement -import org.eclipse.n4js.n4JS.VariableStatement -import org.eclipse.n4js.n4JS.VariableStatementKeyword -import org.eclipse.n4js.n4JS.WithStatement -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.TransformationDependency.ExcludesAfter -import org.eclipse.n4js.transpiler.TransformationDependency.Optional -import org.eclipse.n4js.transpiler.im.IdentifierRef_IM -import org.eclipse.n4js.transpiler.im.SymbolTableEntry -import org.eclipse.xtext.EcoreUtil2 - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.n4JS.DestructureUtils.* -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* -import org.eclipse.n4js.transpiler.AbstractTranspiler - -/** - * Transforms ES6 destructuring patterns into equivalent ES5 code. If the target engine supports ES6 destructuring - * patterns, this transformation can simply be deactivated. - *

- * For details on destructuring patterns, see documentation of class {@link DestructNode}. - */ -@Optional(Destructuring) -@ExcludesAfter(StaticPolyfillTransformation) // otherwise destructuring patterns from filling module won't be processed! -class DestructuringTransformation extends Transformation { - - /** Counts destructuring patterns per variable environment. Used to avoid name clashes of helper variables. */ - private final Map destructsPerScope = newHashMap; - - - override assertPreConditions() { - // true - // (however, this transformation should run as early as possible) - } - override assertPostConditions() { - // true - } - - override analyze() { - // ignore - } - - override transform() { - - // compute nodes we have to transform before changing anything - val destructBindings = collectNodes(state.im, VariableStatement, true) - .filter[containsDestructuringPattern].toList; - val destructAssignments = collectNodes(state.im, AssignmentExpression, true) - .filter[isTopOfDestructuringAssignment].filter[isRoot].toList; - val destructForStmnts = collectNodes(state.im, ForStatement, true) - .filter[containsDestructuringPattern || isTopOfDestructuringForStatement].toList; - - // now perform the changes - destructBindings.forEach[transformDestructuringBindings]; - destructAssignments.forEach[transformDestructuringAssignment]; - destructForStmnts.forEach[transformForStatementWithDestructuring]; - } - - /** - * Transforms not a single destructuring binding but all destructuring bindings in the given variable statement. - */ - def private void transformDestructuringBindings(VariableStatement stmnt) { - val newVarDecls = computeVariableDeclarations(stmnt.varDeclsOrBindings); - stmnt.varDeclsOrBindings.clear(); - stmnt.varDeclsOrBindings += newVarDecls; - } - - /** - * Transforms (a single) destructuring assignment. - */ - def public void transformDestructuringAssignment(AssignmentExpression expr) { - // We pass the value of the expression to the function call. GHOLD-407 - var String fparName; - var FunctionExpression helperFun; - - fparName = "$destruct" + "Param0"; - val fpar = _FormalParameter(fparName); - helperFun = _FunExpr(false, null, fpar); - - val helperFunContents = helperFun.body.statements; - val rootNode = DestructNode.unify(expr); - val helperVars = newArrayList; - val simpleAssignments = >newArrayList; - traverse(helperVars, simpleAssignments, rootNode, expr.rhs, fparName); - - helperFunContents += helperVars.map[_VariableStatement(it)]; - helperFunContents += simpleAssignments.map[ - _ExprStmnt(_AssignmentExpr( - __NSSafe_IdentRef(it.key), - it.value - )) - ]; - - // the following return statement is required to make sure entire expression evaluates to the rhs of - // the assignment expression 'expr' (without evaluating rhs again!) - val firstHelperVarSTE = findSymbolTableEntryForElement(helperVars.get(0), false); - helperFunContents += _ReturnStmnt(_IdentRef(firstHelperVarSTE)); - - val callExpr = _CallExpr(_Parenthesis(helperFun), expr.rhs) // parentheses required because the expression might appear as a statement (to disambiguate from function declaration) - replace(expr, callExpr); - } - - def private void transformForStatementWithDestructuring(ForStatement stmnt) { - - if(stmnt.forPlain) { - - if(!stmnt.varDeclsOrBindings.empty) { - // something like: for( var [a,b]=[1,2] ;;) {} - - // note: pretty much the same case as method #transformDestructuringBindings() above - val newVarDecls = computeVariableDeclarations(stmnt.varDeclsOrBindings); - stmnt.varDeclsOrBindings.clear(); - stmnt.varDeclsOrBindings += newVarDecls; - - } else { - // something like: for( [a,b]=[1,2] ;;) {} - - // here, stmnt.initExpr is an ordinary destructuring assignment that was already handled by method - // #transformDestructuringAssignment(AssignmentExpression) above -> nothing to do here! - } - - } else { - // now: for..in OR for..of - - val depth = stmnt.nestingDepth; - - val iterVar = _VariableDeclaration("$destructStep$"+depth); - val iterVarSTE = createSymbolTableEntryIMOnly(iterVar); - - var needDeclarations = false; - var varStmtKeyword = VariableStatementKeyword.VAR; - val helperVars = newArrayList; - val simpleAssignments = >newArrayList; - if(!stmnt.varDeclsOrBindings.empty) { - // something like: for( var [a,b] of [ [1,2], [3,4] ] ) {} - - if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { - assertTrue("there should be exactly one VariableBinding in stmnt.varDeclsOrBindings", - stmnt.varDeclsOrBindings.size===1 && stmnt.varDeclsOrBindings.get(0) instanceof VariableBinding); - } - - val rootNode = DestructNode.unify(stmnt.varDeclsOrBindings.head as VariableBinding); - traverse(helperVars, simpleAssignments, rootNode, _IdentRef(iterVarSTE), null); // fparname = null since we do not generate any function. - needDeclarations = true; - varStmtKeyword = stmnt.varStmtKeyword; - - } else if(stmnt.initExpr instanceof ArrayLiteral || stmnt.initExpr instanceof ObjectLiteral) { - // something like: for( [a,b] of [ [1,2], [3,4] ] ) {} - - val rootNode = DestructNode.unify(stmnt); - traverse(helperVars, simpleAssignments, rootNode, _IdentRef(iterVarSTE), null); // fparname = null since we do not generate any function. - needDeclarations = false; - - } else { - throw new IllegalArgumentException(); - } - - if(!(stmnt.statement instanceof Block)) { - stmnt.statement = _Block(stmnt.statement); - } - val body = stmnt.statement as Block; - - val toBeInserted = newArrayList; - if(needDeclarations) { - toBeInserted += _VariableStatement(varStmtKeyword, simpleAssignments.map[ - val varDecl = key.getVariableDeclarationFromSTE; - varDecl.expression = value; - return varDecl; - ]); - } else { - toBeInserted += _VariableStatement(helperVars); - toBeInserted += simpleAssignments.map[ - _ExprStmnt(_AssignmentExpr( - __NSSafe_IdentRef(it.key), - it.value - )) - ]; - } - - body.statements.addAll(0, toBeInserted); - - stmnt.initExpr = null; // initExpr has been move to beginning of body (if any) - stmnt.varDeclsOrBindings.clear(); // variable declarations have been moved to beginning of body (if any) - stmnt.varDeclsOrBindings += iterVar; // only declared variable in the for statement is the iteration variable - } - } - - /** - * Breaks down all VariableBindings in the given list into simple variable declarations and returns a list containing - * the variable declarations that were contained in the given list from the beginning plus those created when - * breaking down the variable bindings. The order of the elements in the given list is preserved! - */ - def private List computeVariableDeclarations(List varDeclsOrBindings) { - val result = newArrayList; - for(VariableDeclarationOrBinding vdeclOrBinding : new ArrayList(varDeclsOrBindings)) { - if(vdeclOrBinding instanceof VariableDeclaration) { - result += vdeclOrBinding; - } else if(vdeclOrBinding instanceof VariableBinding) { - val rootNode = DestructNode.unify(vdeclOrBinding); - val helperVars = newArrayList; - val simpleAssignments = >newArrayList; - traverse(helperVars, simpleAssignments, rootNode, vdeclOrBinding.expression, null); // fparname = null since we do not generate any function. - result += simpleAssignments.map[ - var varDecl = key.getVariableDeclarationFromSTE; - varDecl.expression = value; - return varDecl; - ]; - } - } - return result; - } - def private void traverse(List helperVars, List> simpleAssignments, - DestructNode rootNode, Expression value, String fparName) { - val scope = N4JSASTUtils.getScope(rootNode.astElement, false) ?: state.im; - val n = destructsPerScope.merge(scope, 1, [i,j|i+j]) - 1; - traverse(helperVars, simpleAssignments, rootNode.nestedNodes, value, fparName, Integer.toString(n)); - } - /** - * Breaks down the destructuring pattern, represented by the given {@link DestructNode}s, into a number of simple - * assignments (without destructuring) that will be added to argument 'simpleAssignments'. The order of those simple - * assignments matters. Nested patterns as returned by {@link DestructNode#getNestedNodes()} are also broken down. - * fparName, if not null, is the parameter name of the enclosing function. - */ - def private void traverse(List helperVars, List> simpleAssignments, - DestructNode[] nodes, Expression value, String fparName, String helperVarSuffix) { - val len = nodes.length; - val isPositionalPattern = nodes.exists[positional]; - val isRest = isPositionalPattern && !nodes.empty && nodes.last.rest; - - // STEP 1: create code to prepare the value to be destructured and to assign it to a helper variable - - // creating a new helper variable - val currHelperVarName = "$destruct"+helperVarSuffix; - val currHelperVarDecl = _VariableDeclaration(currHelperVarName); - helperVars += currHelperVarDecl; - val SymbolTableEntry currHelperVarSTE = findSymbolTableEntryForElement(currHelperVarDecl, true); - if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { - assertTrue("", currHelperVarSTE.getVariableDeclarationFromSTE === currHelperVarDecl); - assertTrue("", currHelperVarSTE.elementsOfThisName.contains(currHelperVarDecl)); - } - var $sliceToArrayForDestructSTE = steFor_$sliceToArrayForDestruct; - - if(isRest) { - //result.add(currHelperVar+" = function(arr){return Array.isArray(arr) ? arr : Array.from(arr);}("+value+")"); - simpleAssignments += currHelperVarSTE -> _CallExpr( - _Snippet("function(arr){return Array.isArray(arr) ? arr : Array.from(arr);}"), - value - ); - } else { - val passValue = if (fparName.isNullOrEmpty) { - value - } else { - // If the fparName is not empty, the generated function for destructuring has a parameter and we should use that parameter instead. GHOLD-407 - val fparSTE = getSymbolTableEntryInternal(fparName, true); - _IdentRef(fparSTE) - } - if(isPositionalPattern) { - //result.add(currHelperVar+" = $sliceToArrayForDestruct(("+value+"), "+len+")"); - simpleAssignments += currHelperVarSTE -> _CallExpr( - _IdentRef($sliceToArrayForDestructSTE), - _Parenthesis(passValue), - _NumericLiteral(len) - ); - } else { - //result.add(currHelperVar+" = ("+value+")"); - simpleAssignments += currHelperVarSTE -> _Parenthesis( - passValue - ); - } - } - - // STEP 2: create code to perform the actual destructuring - - val sliceSTE = getSymbolTableEntryForMember(state.G.arrayType, "slice", false, false, true); - - var nestedPatternsCounter = 0; - for(var i=0;i currValue; - } - else if(currNode.nestedNodes!==null && !currNode.nestedNodes.empty) { - // nested destructuring - // (assigning the current value in 'currValue' to the nested destructuring pattern) - nestedPatternsCounter++; - // fparname = null since we do not generate any function - traverse(helperVars, simpleAssignments, currNode.nestedNodes, currValue, null, helperVarSuffix+"$"+nestedPatternsCounter); - } - else { - // padding entry (from elision) - // -> do nothing (but consume the current index 'i') - } - } - } - - def private static final int getNestingDepth(ForStatement stmnt) { - var d = 0; - var EObject obj = stmnt; - while((obj = obj.eContainer)!==null) { - if(obj instanceof ForStatement) - d++; - } - return d; - } - - /** - * Returns a list of statements that are the root statements of the next outer variable environment directly - * containing the given AST node. - */ - def static EList getContainingVariableEnvironmentContent(EObject astNode) { - val vee = EcoreUtil2.getContainerOfType(astNode.eContainer, VariableEnvironmentElement); - if(vee===null) { - throw new IllegalArgumentException("given AST node does not have an outer variable environment"); - } - return switch(vee) { - Script: vee.scriptElements - FunctionOrFieldAccessor: vee.body.statements - CatchBlock: vee.block.statements - PropertyAssignment: getContainingVariableEnvironmentContent(vee) - WithStatement: { - if(!(vee.statement instanceof Block)) { - vee.statement = _Block(vee.statement); - } - (vee.statement as Block).statements - } - }; - } - - def private static VariableDeclaration getVariableDeclarationFromSTE(SymbolTableEntry ste) { - return ste.elementsOfThisName.filter(VariableDeclaration).head; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumAccessTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumAccessTransformation.java new file mode 100644 index 0000000000..814f6d0e24 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumAccessTransformation.java @@ -0,0 +1,221 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrLit; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableDeclaration; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableStatement; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.n4NumberBasedEnumType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.n4StringBasedEnumType; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.last; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toSet; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.Literal; +import org.eclipse.n4js.n4JS.ParenExpression; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.VariableStatement; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.im.IdentifierRef_IM; +import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.transpiler.utils.TranspilerUtils; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.TEnum; +import org.eclipse.n4js.ts.types.TEnumLiteral; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind; + +/** + * Transforms references to literals of @StringBased enums by replacing them with a plain string literal. + * References to ordinary enums (i.e. not string-based) are not touched by this transformation. + */ +public class EnumAccessTransformation extends Transformation { + + private final Map literalsConstants = new HashMap<>(); // need not be linked + private TMember member_NumberBasedEnum_literals; + private TMember member_StringBasedEnum_literals; + + @Override + public void assertPreConditions() { + assertNotNull("member of built-in type not found: NumberBasedEnum#literals", member_NumberBasedEnum_literals); + assertNotNull("member of built-in type not found: StringBasedEnum#literals", member_StringBasedEnum_literals); + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + member_NumberBasedEnum_literals = n4NumberBasedEnumType(getState().G).findOwnedMember("literals", false, true); + member_StringBasedEnum_literals = n4StringBasedEnumType(getState().G).findOwnedMember("literals", false, true); + } + + @Override + public void transform() { + for (ParameterizedPropertyAccessExpression_IM ppae : collectNodes(getState().im, + ParameterizedPropertyAccessExpression_IM.class, true)) { + transformEnumAccess(ppae); + } + } + + private void transformEnumAccess(ParameterizedPropertyAccessExpression_IM expr) { + SymbolTableEntry propSTE = expr.getProperty_IM(); + if (propSTE instanceof SymbolTableEntryOriginal) { + IdentifiableElement prop = ((SymbolTableEntryOriginal) propSTE).getOriginalTarget(); + if (prop instanceof TEnumLiteral) { + transformEnumLiteralAccess(resolveOriginalNumberOrStringBasedEnum(expr), expr, (TEnumLiteral) prop); + } + if (prop == member_StringBasedEnum_literals || prop == member_NumberBasedEnum_literals) + transformEnumLiteralsConstantAccess(resolveOriginalNumberOrStringBasedEnum(expr), expr); + } + + } + + /** + * Assumes {@code originalEnum} was resolved to string based enum, e,g, + * @StringBased enum Color {RED : "red", SOME}, transforms access to Color.RED to + * "red" and Color.SOME to "SOME".It is low level transformation, assumes + * caller did all necessary checks and did provide proper data. Replacement is applied only if none of the provided + * parameters is {@code null}. + * + * @param originalEnum + * string based enum from AST for which literal access is generated. + * @param expr + * expression which will have value generated. + * @param prop + * enum literal from which value is generated. + */ + private void transformEnumLiteralAccess(TEnum originalEnum, ParameterizedPropertyAccessExpression_IM expr, + TEnumLiteral prop) { + if (originalEnum != null && expr != null && prop != null) { + replace(expr, TranspilerUtils.enumLiteralToNumericOrStringLiteral(prop)); + } + } + + /** + * Assumes {@code originalEnum} was resolved to string based enum, e,g, + * @StringBased enum Color {RED : "red", SOME}, transforms access to Color.literals to + * ["red", "SOME". It is low level transformation, assumes caller did all necessary checks and did + * provide proper data. Replacement is applied only if none of the provided parameters is {@code null}. + * + * @param originalEnum + * string based enum from AST for which literals access is generated. + * @param expr + * expression which will have values generated. + */ + private void transformEnumLiteralsConstantAccess(TEnum originalEnum, + ParameterizedPropertyAccessExpression_IM expr) { + if (originalEnum != null && expr != null) { + replace(expr, getReferenceToLiteralsConstant(originalEnum)); + } + } + + /** + * Resolves left hand side of the {@code ParameterizedPropertyAccessExpression_IM} to the original + * {@link AnnotationDefinition#STRING_BASED} enum. + * + * @return resolved original string based enum or null. + */ + private TEnum resolveOriginalNumberOrStringBasedEnum(ParameterizedPropertyAccessExpression_IM pex) { + SymbolTableEntry targetEnumSTE = resolveOriginalExpressionTarget(pex.getTarget()); + if (targetEnumSTE instanceof SymbolTableEntryOriginal) { + IdentifiableElement original = ((SymbolTableEntryOriginal) targetEnumSTE).getOriginalTarget(); + if (original instanceof TEnum) { + if (N4JSLanguageUtils.getEnumKind((TEnum) original) != EnumKind.Normal) { + return (TEnum) original; + } + } + } + return null; + } + + /** + * Resolve target of the {@code ParameterizedPropertyAccessExpression_IM} when left hand side is an simple access or + * nested expression, e.g. for + *

    + *
  • Enum.EnumLiteral
  • + *
  • Enum.literals
  • + *
  • (((((Enum)))).EnumLiteral
  • + *
  • (((((Enum)))).literals
  • + *
+ * resolves to {@code SymbolTableEntry} of the Enum. + */ + private SymbolTableEntry resolveOriginalExpressionTarget(Expression ex) { + if (ex instanceof IdentifierRef_IM) { + return ((IdentifierRef_IM) ex).getRewiredTarget(); + } + if (ex instanceof ParameterizedPropertyAccessExpression_IM) { + return ((ParameterizedPropertyAccessExpression_IM) ex).getProperty_IM(); + } + if (ex instanceof ParenExpression) { + return resolveOriginalExpressionTarget(((ParenExpression) ex).getExpression()); + } + return null; + } + + private IdentifierRef_IM getReferenceToLiteralsConstant(TEnum tEnum) { + var vdecl = literalsConstants.get(tEnum); + if (vdecl == null) { + vdecl = createLiteralsConstant(tEnum); + literalsConstants.put(tEnum, vdecl); + } + // note: always have to create a new reference + return _IdentRef(findSymbolTableEntryForElement(vdecl, false)); + } + + private VariableDeclaration createLiteralsConstant(TEnum tEnum) { + String name = findUniqueNameForLiteralsConstant(tEnum); + + List literals = toList(map( + tEnum.getLiterals(), l -> TranspilerUtils.enumLiteralToNumericOrStringLiteral(l))); + VariableDeclaration vdecl = _VariableDeclaration(name, _ArrLit(literals.toArray(new Literal[0]))); + VariableStatement vstmnt = _VariableStatement(vdecl); + ImportDeclaration lastImport = last(filter(getState().im.getScriptElements(), ImportDeclaration.class)); + if (lastImport != null) { + insertAfter(lastImport, vstmnt); + } else if (!getState().im.getScriptElements().isEmpty()) { + insertBefore(getState().im.getScriptElements().get(0), vstmnt); + } else { + getState().im.getScriptElements().add(vstmnt); + } + createSymbolTableEntryIMOnly(vdecl); + return vdecl; + } + + private String findUniqueNameForLiteralsConstant(TEnum tEnum) { + Set names = toSet(map(literalsConstants.values(), lc -> lc.getName())); + var newName = "$enumLiteralsOf" + (tEnum != null && tEnum.getName() != null ? tEnum.getName() : "Unnamed"); + if (names.contains(newName)) { + int cnt = 1; + while (names.contains(newName + cnt)) { + cnt++; + } + newName = newName + cnt; + } + return newName; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumAccessTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumAccessTransformation.xtend deleted file mode 100644 index 8d62712e14..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumAccessTransformation.xtend +++ /dev/null @@ -1,178 +0,0 @@ -/** - * 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.transpiler.es.transform - -import java.util.Map -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.ParenExpression -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.im.IdentifierRef_IM -import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM -import org.eclipse.n4js.transpiler.im.SymbolTableEntry -import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal -import org.eclipse.n4js.transpiler.utils.TranspilerUtils -import org.eclipse.n4js.ts.types.TEnum -import org.eclipse.n4js.ts.types.TEnumLiteral -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * Transforms references to literals of @StringBased enums by replacing them with a plain string literal. - * References to ordinary enums (i.e. not string-based) are not touched by this transformation. - */ -class EnumAccessTransformation extends Transformation { - - private final Map literalsConstants = newHashMap; // need not be linked - private TMember member_NumberBasedEnum_literals; - private TMember member_StringBasedEnum_literals; - - - override assertPreConditions() { - assertNotNull("member of built-in type not found: NumberBasedEnum#literals", member_NumberBasedEnum_literals); - assertNotNull("member of built-in type not found: StringBasedEnum#literals", member_StringBasedEnum_literals); - } - - override assertPostConditions() { - } - - override analyze() { - member_NumberBasedEnum_literals = state.G.n4NumberBasedEnumType.findOwnedMember("literals", false, true); - member_StringBasedEnum_literals = state.G.n4StringBasedEnumType.findOwnedMember("literals", false, true); - } - - override transform() { - collectNodes(state.im, ParameterizedPropertyAccessExpression_IM, true).forEach[transformEnumAccess]; - } - - def private void transformEnumAccess(ParameterizedPropertyAccessExpression_IM expr) { - val propSTE = expr.property_IM; - val prop = if (propSTE instanceof SymbolTableEntryOriginal) propSTE.originalTarget; - switch prop { - TEnumLiteral: - resolveOriginalNumberOrStringBasedEnum(expr).transformEnumLiteralAccess(expr, prop) - case prop === member_StringBasedEnum_literals || prop === member_NumberBasedEnum_literals: - resolveOriginalNumberOrStringBasedEnum(expr).transformEnumLiteralsConstantAccess(expr) - } - } - - /** - * Assumes {@code originalEnum} was resolved to string based enum, e,g, @StringBased enum Color {RED : "red", SOME}, - * transforms access to Color.RED to "red" and Color.SOME to "SOME".It is low level transformation, assumes - * caller did all necessary checks and did provide proper data. Replacement is applied only if none of the provided parameters is {@code null}. - * - * @param originalEnum string based enum from AST for which literal access is generated. - * @param expr expression which will have value generated. - * @param prop enum literal from which value is generated. - */ - private def transformEnumLiteralAccess(TEnum originalEnum, ParameterizedPropertyAccessExpression_IM expr, TEnumLiteral prop) { - if (originalEnum !== null && expr !== null && prop !== null) { - replace(expr, TranspilerUtils.enumLiteralToNumericOrStringLiteral(prop)); - } - } - - /** - * Assumes {@code originalEnum} was resolved to string based enum, e,g, @StringBased enum Color {RED : "red", SOME}, - * transforms access to Color.literals to ["red", "SOME". It is low level transformation, assumes - * caller did all necessary checks and did provide proper data. Replacement is applied only if none of the provided parameters is {@code null}. - * - * @param originalEnum string based enum from AST for which literals access is generated. - * @param expr expression which will have values generated. - */ - private def transformEnumLiteralsConstantAccess(TEnum originalEnum, ParameterizedPropertyAccessExpression_IM expr) { - if (originalEnum !== null && expr !== null) { - replace(expr, getReferenceToLiteralsConstant(originalEnum)); - } - } - - /** - * Resolves left hand side of the {@code ParameterizedPropertyAccessExpression_IM} to the original {@link AnnotationDefinition#STRING_BASED} enum. - * - * @return resolved original string based enum or null. - */ - def private TEnum resolveOriginalNumberOrStringBasedEnum(ParameterizedPropertyAccessExpression_IM pex) { - val targetEnumSTE = resolveOriginalExpressionTarget(pex.target) - if (targetEnumSTE instanceof SymbolTableEntryOriginal) { - val original = targetEnumSTE.originalTarget; - if (original instanceof TEnum) { - if (N4JSLanguageUtils.getEnumKind(original) !== EnumKind.Normal) { - return original; - } - } - } - return null; - } - - /** - * Resolve target of the {@code ParameterizedPropertyAccessExpression_IM} when left hand side is an simple access or nested expression, e.g. for - *
    - *
  • Enum.EnumLiteral
  • - *
  • Enum.literals
  • - *
  • (((((Enum)))).EnumLiteral
  • - *
  • (((((Enum)))).literals
  • - *
- * resolves to {@code SymbolTableEntry} of the Enum. - */ - def private SymbolTableEntry resolveOriginalExpressionTarget(Expression ex){ - switch ex { - IdentifierRef_IM : ex.rewiredTarget - ParameterizedPropertyAccessExpression_IM : ex.property_IM - ParenExpression : resolveOriginalExpressionTarget(ex.expression) - default : null - } - } - - def private getReferenceToLiteralsConstant(TEnum tEnum) { - var vdecl = literalsConstants.get(tEnum); - if (vdecl === null) { - vdecl = createLiteralsConstant(tEnum); - literalsConstants.put(tEnum, vdecl); - } - // note: always have to create a new reference - return _IdentRef(findSymbolTableEntryForElement(vdecl, false)); - } - - def private VariableDeclaration createLiteralsConstant(TEnum tEnum) { - val name = findUniqueNameForLiteralsConstant(tEnum); - val vdecl = _VariableDeclaration(name, _ArrLit(tEnum.literals.map[TranspilerUtils.enumLiteralToNumericOrStringLiteral(it)])); - val vstmnt = _VariableStatement(vdecl); - val lastImport = state.im.scriptElements.filter(ImportDeclaration).last; - if (lastImport !== null) { - insertAfter(lastImport, vstmnt); - } else if (!state.im.scriptElements.empty) { - insertBefore(state.im.scriptElements.head, vstmnt); - } else { - state.im.scriptElements.add(vstmnt); - } - createSymbolTableEntryIMOnly(vdecl); - return vdecl; - } - - def private String findUniqueNameForLiteralsConstant(TEnum tEnum) { - val names = literalsConstants.values.map[name].toSet; - var newName = "$enumLiteralsOf" + (tEnum?.name ?: "Unnamed"); - if (names.contains(newName)) { - var cnt = 1; - while (names.contains(newName + cnt)) { - cnt++; - } - newName = newName + cnt; - } - return newName; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumDeclarationTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumDeclarationTransformation.java new file mode 100644 index 0000000000..2622ab216a --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumDeclarationTransformation.java @@ -0,0 +1,157 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrLit; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ExprStmnt; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Fpar; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4FieldDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4MethodDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._NewExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._SuperLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._TypeReferenceNode; +import static org.eclipse.n4js.transpiler.utils.TranspilerUtils.orContainingExportDeclaration; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.n4EnumTypeRef; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.filter; + +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.N4JSLanguageConstants; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4EnumDeclaration; +import org.eclipse.n4js.n4JS.N4EnumLiteral; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4JSFactory; +import org.eclipse.n4js.n4JS.N4MethodDeclaration; +import org.eclipse.n4js.n4JS.Statement; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.TransformationDependency.RequiresAfter; +import org.eclipse.n4js.transpiler.assistants.TypeAssistant; +import org.eclipse.n4js.transpiler.es.assistants.ReflectionAssistant; +import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryIMOnly; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind; + +import com.google.inject.Inject; + +/** + * Transforms {@link N4EnumDeclaration}s into a corresponding class declaration (for ordinary enums) or removes them + * entirely (for @StringBased enums). + */ +@RequiresAfter(ClassDeclarationTransformation.class) +public class EnumDeclarationTransformation extends Transformation { + + @Inject + private ReflectionAssistant reflectionAssistant; + @Inject + private TypeAssistant typeAssistant; + + @Override + public void assertPreConditions() { + assertFalse("only top-level enums are supported, for now", + exists(filter(getState().im.eAllContents(), N4EnumDeclaration.class), + ed -> !typeAssistant.isTopLevel(ed))); + } + + @Override + public void assertPostConditions() { + assertFalse("there should not be any N4EnumDeclarations in the intermediate model", + exists(getState().im.eAllContents(), elem -> elem instanceof N4EnumDeclaration)); + } + + @Override + public void analyze() { + // nothing to do + } + + @Override + public void transform() { + for (N4EnumDeclaration ed : collectNodes(getState().im, N4EnumDeclaration.class, false)) { + transformEnumDecl(ed); + } + } + + private void transformEnumDecl(N4EnumDeclaration enumDecl) { + EnumKind enumKind = N4JSLanguageUtils.getEnumKind(enumDecl); + if (enumKind != EnumKind.Normal) { + // declarations of number/string-based enums are simply removed + // (they do not have a representation in the output code) + EObject root = orContainingExportDeclaration(enumDecl); + remove(root); + return; + } + + N4ClassDeclaration classDecl = N4JSFactory.eINSTANCE.createN4ClassDeclaration(); + classDecl.setName(enumDecl.getName()); // need to set name before creating a symbol table entry + SymbolTableEntryIMOnly classSTE = createSymbolTableEntryIMOnly(classDecl); + + List fieldsForLiterals = toList( + map(enumDecl.getLiterals(), l -> convertLiteralToField(l, classSTE))); + + classDecl.getDeclaredModifiers().addAll(enumDecl.getDeclaredModifiers()); // reuse existing modifiers + classDecl.setSuperClassRef(_TypeReferenceNode(getState(), n4EnumTypeRef(getState().G))); + + classDecl.getOwnedMembersRaw().add(createEnumConstructor()); + classDecl.getOwnedMembersRaw().addAll(fieldsForLiterals); + classDecl.getOwnedMembersRaw().add(_N4FieldDecl( + true, + "literals", + _ArrLit(toList(map(fieldsForLiterals, + fd -> _PropertyAccessExpr(classSTE, findSymbolTableEntryForElement(fd, true)))) + .toArray(new ParameterizedPropertyAccessExpression_IM[0])))); + + // add 'n4type' getter for reflection + reflectionAssistant.addN4TypeGetter(enumDecl, classDecl); + + getState().tracer.copyTrace(enumDecl, classDecl); + + replace(enumDecl, classDecl); + } + + private N4MethodDeclaration createEnumConstructor() { + // constructor(name, value) { + // super(name, value); + // } + FormalParameter nameFpar = _Fpar("name"); + FormalParameter valueFpar = _Fpar("value"); + SymbolTableEntryIMOnly nameSTE = createSymbolTableEntryIMOnly(nameFpar); + SymbolTableEntryIMOnly valueSTE = createSymbolTableEntryIMOnly(valueFpar); + return _N4MethodDecl( + N4JSLanguageConstants.CONSTRUCTOR, + new FormalParameter[] { nameFpar, valueFpar }, + new Statement[] { + _ExprStmnt( + _CallExpr(_SuperLiteral(), _IdentRef(nameSTE), _IdentRef(valueSTE))) + }); + } + + private N4FieldDeclaration convertLiteralToField(N4EnumLiteral literal, SymbolTableEntry classSTE) { + Object value = N4JSLanguageUtils.getEnumLiteralValue(literal); + return _N4FieldDecl( + true, + literal.getName(), + _NewExpr( + _IdentRef(classSTE), + _StringLiteral(literal.getName()), + (value instanceof String) ? _StringLiteral((String) value) : null)); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumDeclarationTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumDeclarationTransformation.xtend deleted file mode 100644 index 095a53fd62..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/EnumDeclarationTransformation.xtend +++ /dev/null @@ -1,130 +0,0 @@ -/** - * 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.transpiler.es.transform - -import com.google.inject.Inject -import org.eclipse.n4js.N4JSLanguageConstants -import org.eclipse.n4js.n4JS.N4EnumDeclaration -import org.eclipse.n4js.n4JS.N4EnumLiteral -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.N4JSFactory -import org.eclipse.n4js.n4JS.N4MethodDeclaration -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.TransformationDependency.RequiresAfter -import org.eclipse.n4js.transpiler.assistants.TypeAssistant -import org.eclipse.n4js.transpiler.es.assistants.ReflectionAssistant -import org.eclipse.n4js.transpiler.im.SymbolTableEntry -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.transpiler.utils.TranspilerUtils.* -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * Transforms {@link N4EnumDeclaration}s into a corresponding class declaration (for ordinary enums) or - * removes them entirely (for @StringBased enums). - */ -@RequiresAfter(ClassDeclarationTransformation) -class EnumDeclarationTransformation extends Transformation { - - @Inject private ReflectionAssistant reflectionAssistant; - @Inject private TypeAssistant typeAssistant; - - - override assertPreConditions() { - assertFalse("only top-level enums are supported, for now", - state.im.eAllContents.filter(N4EnumDeclaration).exists[!typeAssistant.isTopLevel(it)]); - } - - override assertPostConditions() { - assertFalse("there should not be any N4EnumDeclarations in the intermediate model", - state.im.eAllContents.exists[it instanceof N4EnumDeclaration]); - } - - override analyze() { - // nothing to do - } - - override transform() { - collectNodes(state.im, N4EnumDeclaration, false).forEach[transformEnumDecl]; - } - - def private void transformEnumDecl(N4EnumDeclaration enumDecl) { - val enumKind = N4JSLanguageUtils.getEnumKind(enumDecl); - if(enumKind !== EnumKind.Normal) { - // declarations of number/string-based enums are simply removed - // (they do not have a representation in the output code) - val root = enumDecl.orContainingExportDeclaration; - remove(root); - return; - } - - val classDecl = N4JSFactory.eINSTANCE.createN4ClassDeclaration; - classDecl.name = enumDecl.name; // need to set name before creating a symbol table entry - val classSTE = createSymbolTableEntryIMOnly(classDecl); - - val fieldsForLiterals = enumDecl.literals.map[convertLiteralToField(it, classSTE)]; - - classDecl.declaredModifiers += enumDecl.declaredModifiers; // reuse existing modifiers - classDecl.superClassRef = _TypeReferenceNode(state, state.G.n4EnumTypeRef); - - classDecl.ownedMembersRaw += createEnumConstructor(); - classDecl.ownedMembersRaw += fieldsForLiterals; - classDecl.ownedMembersRaw += _N4FieldDecl( - true, - "literals", - _ArrLit(fieldsForLiterals.map[ - _PropertyAccessExpr(classSTE, findSymbolTableEntryForElement(it, true)) - ]) - ); - - // add 'n4type' getter for reflection - reflectionAssistant.addN4TypeGetter(enumDecl, classDecl); - - state.tracer.copyTrace(enumDecl, classDecl); - - replace(enumDecl, classDecl); - } - - def private N4MethodDeclaration createEnumConstructor() { - // constructor(name, value) { - // super(name, value); - // } - val nameFpar = _Fpar("name"); - val valueFpar = _Fpar("value"); - val nameSTE = createSymbolTableEntryIMOnly(nameFpar); - val valueSTE = createSymbolTableEntryIMOnly(valueFpar); - return _N4MethodDecl( - N4JSLanguageConstants.CONSTRUCTOR, - #[ nameFpar, valueFpar ], - #[ - _ExprStmnt( - _CallExpr(_SuperLiteral, _IdentRef(nameSTE), _IdentRef(valueSTE)) - ) - ] - ); - } - - def private N4FieldDeclaration convertLiteralToField(N4EnumLiteral literal, SymbolTableEntry classSTE) { - val value = N4JSLanguageUtils.getEnumLiteralValue(literal); - return _N4FieldDecl( - true, - literal.name, - _NewExpr( - _IdentRef(classSTE), - _StringLiteral(literal.name), - if (value instanceof String) _StringLiteral(value) - ) - ); - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ExpressionTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ExpressionTransformation.java new file mode 100644 index 0000000000..74bdee6966 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ExpressionTransformation.java @@ -0,0 +1,314 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrLit; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrayElement; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._BooleanLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteralForSTE; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.isIterableN; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.n4ElementType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.n4NamedElementType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.n4ObjectType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.n4TypeType; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; +import static org.eclipse.xtext.xbase.lib.ListExtensions.reverse; + +import java.util.List; + +import org.eclipse.n4js.N4JSLanguageConstants; +import org.eclipse.n4js.n4JS.ArrayElement; +import org.eclipse.n4js.n4JS.AwaitExpression; +import org.eclipse.n4js.n4JS.CastExpression; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ExpressionWithTarget; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.n4JS.PromisifyExpression; +import org.eclipse.n4js.scoping.builtin.N4Scheme; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.im.IdentifierRef_IM; +import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeArgument; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.utils.PromisifyHelper; +import org.eclipse.n4js.utils.ResourceNameComputer; + +import com.google.inject.Inject; + +/** + * Some expressions need special handling, this is done in this transformation. + */ +public class ExpressionTransformation extends Transformation { + + @Inject + private ResourceNameComputer resourceNameComputer; + @Inject + private PromisifyHelper promisifyHelper; + + private TGetter n4Object_n4type; + private TGetter n4NamedElement_name; + private TGetter n4Element_origin; + private TGetter n4Type_fqn; + + @Override + public void assertPreConditions() { + // true + } + + @Override + public void assertPostConditions() { + // true + } + + @Override + public void analyze() { + n4Object_n4type = (TGetter) n4ObjectType(getState().G).findOwnedMember(N4JSLanguageConstants.N4TYPE_NAME, false, + true); + n4NamedElement_name = (TGetter) n4NamedElementType(getState().G).findOwnedMember("name", false, false); + n4Element_origin = (TGetter) n4ElementType(getState().G).findOwnedMember("origin", false, false); + n4Type_fqn = (TGetter) n4TypeType(getState().G).findOwnedMember("fqn", false, false); + + if (n4Object_n4type == null + || n4NamedElement_name == null + || n4Element_origin == null + || n4Type_fqn == null) { + throw new IllegalStateException("could not find required members of built-in types"); + } + } + + @Override + public void transform() { + for (Expression expr : reverse(collectNodes(getState().im, Expression.class, true))) { + // transforming expressions in bottom-up order (it's more natural and simplifies some nesting cases) + if (expr instanceof CastExpression) { + transformExpression((CastExpression) expr); + } else if (expr instanceof ExpressionWithTarget) { + transformExpression((ExpressionWithTarget) expr); + } else if (expr instanceof AwaitExpression) { + transformExpression((AwaitExpression) expr); + } else if (expr instanceof PromisifyExpression) { + transformExpression((PromisifyExpression) expr); + } + } + } + + private void transformExpression(CastExpression castExpr) { + replace(castExpr, castExpr.getExpression()); // simply remove the cast + } + + private void transformExpression(ExpressionWithTarget exprWithTarget) { + if (exprWithTarget instanceof ParameterizedPropertyAccessExpression_IM) { + if (transformTrivialUsageOfReflection((ParameterizedPropertyAccessExpression_IM) exprWithTarget)) { + return; + } + } + } + + /** + * IMPORTANT: here we only do some special handling for the auto-promisify case within an AwaitExpression; + * the main handling of the AwaitExpression itself is done in a later transformation + * {@code BlockTransformation.transformBlockAsync(Block)}!!! + *

+ * Changes + * + *

+	 * await cls.meth(a, b)
+	 * 
+ * + * to + * + *
+	 * await $n4promisifyMethod(cls, 'meth', [a, b])
+	 * 
+ * + * OR + * + *
+	 * await fun(a, b)
+	 * 
+ * + * to + * + *
+	 * await $n4promisifyFunction(fun, [a, b])
+	 * 
+ * + * assuming that method 'meth' and function 'fun' are annotated with @Promisifiable. + */ + private void transformExpression(AwaitExpression awaitExpr) { + AwaitExpression awaitExprOrig = getState().tracer.getOriginalASTNodeOfSameType(awaitExpr, false); + if (promisifyHelper.isAutoPromisify(awaitExprOrig)) { + // cast is safe because isPromisifiableExpression() returned true + ParameterizedCallExpression callExpr = (ParameterizedCallExpression) awaitExpr.getExpression(); + ParameterizedCallExpression replacement = promisify(callExpr); + // note: leaving awaitExpr in the IM; only replacing its contained expression!! + replace(callExpr, replacement); + } + } + + /** + * Changes + * + *
+	 * @Promisify cls.meth(a, b)
+	 * 
+ * + * to + * + *
+	 * $n4promisifyMethod(cls, 'meth', [a, b])
+	 * 
+ * + * OR + * + *
+	 * @Promisify fun(a, b)
+	 * 
+ * + * to + * + *
+	 * $n4promisifyFunction(fun, [a, b])
+	 * 
+ */ + private void transformExpression(PromisifyExpression promiExpr) { + // cast is safe because of validations + ParameterizedCallExpression callExpr = (ParameterizedCallExpression) promiExpr.getExpression(); + ParameterizedCallExpression replacement = promisify(callExpr); + replace(promiExpr, replacement); + } + + private ParameterizedCallExpression promisify(ParameterizedCallExpression callExpr) { + Expression target = callExpr.getTarget(); + SymbolTableEntry targetSTE = null; + if (target instanceof ParameterizedPropertyAccessExpression_IM) { + targetSTE = ((ParameterizedPropertyAccessExpression_IM) target).getProperty_IM(); + } + if (target instanceof IdentifierRef_IM) { + targetSTE = ((IdentifierRef_IM) target).getId_IM(); + } + if (targetSTE instanceof SymbolTableEntryOriginal) { + SymbolTableEntryOriginal steo = (SymbolTableEntryOriginal) targetSTE; + IdentifiableElement originalTarget = steo.getOriginalTarget(); + if (originalTarget instanceof TFunction) { // could be a method + FunctionTypeRef originalTargetTypeRef = (FunctionTypeRef) TypeUtils + .createTypeRef((TFunction) originalTarget); + var returnTypeRef = promisifyHelper.extractPromisifiedReturnType(getState().G, originalTargetTypeRef); + if (returnTypeRef != null) { + List returnTypeRefTypeArgs = returnTypeRef.getTypeArgsWithDefaults(); + // isUndefined() is null-safe + boolean hasErrorValue = !TypeUtils.isUndefined(returnTypeRefTypeArgs.get(1)); + // isIterableN() is null-safe + boolean hasMoreThan1SuccessValue = isIterableN(getState().G, returnTypeRefTypeArgs.get(0)); + + ArrayElement[] arrayElements = toList(map(callExpr.getArguments(), + arg -> _ArrayElement(arg.isSpread(), arg.getExpression()))).toArray(new ArrayElement[0]); + + if (target instanceof ParameterizedPropertyAccessExpression_IM + && steo.getOriginalTarget() instanceof TMethod) { + // we have a method invocation, so we need to preserve the 'this' argument: + + // @Promisify cls.meth(a, b) + // --> + // $n4promisifyMethod(cls, 'meth', [a, b]) + return _CallExpr( + _IdentRef(steFor_$n4promisifyMethod()), + // here we take the "cls" part of "cls.meth" as first argument + ((ParameterizedPropertyAccessExpression_IM) target).getTarget(), + _StringLiteralForSTE(targetSTE), + _ArrLit(arrayElements), // reuse arguments while preserving spread + _BooleanLiteral(hasMoreThan1SuccessValue), + _BooleanLiteral(!hasErrorValue)); + } else { + // in all other cases, we do not preserve the 'this' argument: + + // @Promisify fun(a, b) + // --> + // $n4promisifyFunction(fun, [a, b]) + return _CallExpr( + _IdentRef(steFor_$n4promisifyFunction()), + callExpr.getTarget(), // reuse target as first argument + _ArrLit(arrayElements), // reuse arguments while preserving spread + _BooleanLiteral(hasMoreThan1SuccessValue), + _BooleanLiteral(!hasErrorValue)); + } + } + } + } + // if anything goes awry, we just return callExpr as replacement, which means we simply remove the @Promisify + return callExpr; + } + + /** + * Replaces the following trivial uses of the reflection APIs by the resulting value (i.e. a string literal): + * + *
+	 * MyClass.n4type.name
+	 * MyClass.n4type.origin
+	 * MyClass.n4type.fqn
+	 * 
+ * + * Thus, reflection will not actually be used in the output code in the above cases. + */ + private boolean transformTrivialUsageOfReflection(ParameterizedPropertyAccessExpression_IM propAccessExpr) { + IdentifiableElement property = propAccessExpr.getOriginalTargetOfRewiredTarget(); + if (property == n4NamedElement_name + || property == n4Element_origin + || property == n4Type_fqn) { + + Expression target = propAccessExpr.getTarget(); + if (target instanceof ParameterizedPropertyAccessExpression_IM) { + ParameterizedPropertyAccessExpression_IM ppae = (ParameterizedPropertyAccessExpression_IM) target; + IdentifiableElement propertyOfTarget = ppae.getOriginalTargetOfRewiredTarget(); + if (propertyOfTarget == n4Object_n4type) { + Expression targetOfTarget = ppae.getTarget(); + if (targetOfTarget instanceof IdentifierRef_IM) { + IdentifiableElement id = ((IdentifierRef_IM) targetOfTarget).getOriginalTargetOfRewiredTarget(); + if (id instanceof TClass) { + String value = null; + if (property == n4NamedElement_name) { + value = id.getName(); + } else if (property == n4Element_origin) { + value = resourceNameComputer.generateProjectDescriptor(id.eResource()); + } else if (property == n4Type_fqn) { + // avoid optimizing this case for built-in types + // (we cannot know for sure the value of the 'fqn' property set in the .js files) + if (!N4Scheme.isFromResourceWithN4Scheme(id)) { + value = resourceNameComputer.getFullyQualifiedTypeName((TClass) id); + } + } else { + throw new IllegalStateException(); // should not happen (see above) + } + if (value != null) { + replace(propAccessExpr, _StringLiteral(value)); + return true; + } + } + } + } + } + } + return false; + } + +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ExpressionTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ExpressionTransformation.xtend deleted file mode 100644 index e5e6ed2454..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ExpressionTransformation.xtend +++ /dev/null @@ -1,233 +0,0 @@ -/** - * 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.transpiler.es.transform - -import com.google.inject.Inject -import org.eclipse.n4js.N4JSLanguageConstants -import org.eclipse.n4js.n4JS.AwaitExpression -import org.eclipse.n4js.n4JS.CastExpression -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.ExpressionWithTarget -import org.eclipse.n4js.n4JS.ParameterizedCallExpression -import org.eclipse.n4js.n4JS.PromisifyExpression -import org.eclipse.n4js.scoping.builtin.N4Scheme -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.im.IdentifierRef_IM -import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM -import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal -import org.eclipse.n4js.ts.typeRefs.FunctionTypeRef -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.TFunction -import org.eclipse.n4js.ts.types.TGetter -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.utils.PromisifyHelper -import org.eclipse.n4js.utils.ResourceNameComputer - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * Some expressions need special handling, this is done in this transformation. - */ -class ExpressionTransformation extends Transformation { - - @Inject private ResourceNameComputer resourceNameComputer; - @Inject private PromisifyHelper promisifyHelper; - - private TGetter n4Object_n4type; - private TGetter n4NamedElement_name; - private TGetter n4Element_origin; - private TGetter n4Type_fqn; - - override assertPreConditions() { - // true - } - - override assertPostConditions() { - // true - } - - override analyze() { - n4Object_n4type = state.G.n4ObjectType.findOwnedMember(N4JSLanguageConstants.N4TYPE_NAME, false, true) as TGetter; - n4NamedElement_name = state.G.n4NamedElementType.findOwnedMember("name", false, false) as TGetter; - n4Element_origin = state.G.n4ElementType.findOwnedMember("origin", false, false) as TGetter; - n4Type_fqn = state.G.n4TypeType.findOwnedMember("fqn", false, false) as TGetter; - if (n4Object_n4type === null - || n4NamedElement_name === null - || n4Element_origin === null - || n4Type_fqn === null) { - throw new IllegalStateException("could not find required members of built-in types"); - } - } - - override transform() { - collectNodes(state.im, Expression, true) - .reverse // transforming expressions in bottom-up order (it's more natural and simplifies some nesting cases) - .forEach[transformExpression]; - } - - def private dispatch void transformExpression(Expression expr) { - // default case -> do nothing - } - - def private dispatch void transformExpression(CastExpression castExpr) { - replace(castExpr, castExpr.expression); // simply remove the cast - } - - def private dispatch void transformExpression(ExpressionWithTarget exprWithTarget) { - if (exprWithTarget instanceof ParameterizedPropertyAccessExpression_IM) { - if (transformTrivialUsageOfReflection(exprWithTarget)) { - return; - } - } - } - - /** - * IMPORTANT: - * here we only do some special handling for the auto-promisify case within an AwaitExpression; the main - * handling of the AwaitExpression itself is done in a later transformation {@code BlockTransformation.transformBlockAsync(Block)}!!! - *

- * Changes - *

await cls.meth(a, b)
- * to - *
await $n4promisifyMethod(cls, 'meth', [a, b])
- * OR - *
await fun(a, b)
- * to - *
await $n4promisifyFunction(fun, [a, b])
- * assuming that method 'meth' and function 'fun' are annotated with @Promisifiable. - */ - def private dispatch void transformExpression(AwaitExpression awaitExpr) { - val awaitExprOrig = state.tracer.getOriginalASTNodeOfSameType(awaitExpr, false); - if(promisifyHelper.isAutoPromisify(awaitExprOrig)) { - val callExpr = awaitExpr.expression as ParameterizedCallExpression; // cast is safe because isPromisifiableExpression() returned true - val replacement = promisify(callExpr); - replace(callExpr, replacement); // note: leaving awaitExpr in the IM; only replacing its contained expression!! - } - } - - /** - * Changes - *
@Promisify cls.meth(a, b)
- * to - *
$n4promisifyMethod(cls, 'meth', [a, b])
- * OR - *
@Promisify fun(a, b)
- * to - *
$n4promisifyFunction(fun, [a, b])
- */ - def private dispatch void transformExpression(PromisifyExpression promiExpr) { - val callExpr = promiExpr.expression as ParameterizedCallExpression; // cast is safe because of validations - val replacement = promisify(callExpr); - replace(promiExpr, replacement); - } - - def private ParameterizedCallExpression promisify(ParameterizedCallExpression callExpr) { - val target = callExpr.target; - val targetSTE = switch(target) { - ParameterizedPropertyAccessExpression_IM: target.property_IM - IdentifierRef_IM: target.id_IM - }; - if(targetSTE instanceof SymbolTableEntryOriginal) { - val originalTarget = targetSTE.originalTarget; - if(originalTarget instanceof TFunction) { // could be a method - val originalTargetTypeRef = TypeUtils.createTypeRef(originalTarget) as FunctionTypeRef; - var returnTypeRef = promisifyHelper.extractPromisifiedReturnType(state.G, originalTargetTypeRef); - if (returnTypeRef !== null) { - val returnTypeRefTypeArgs = returnTypeRef.typeArgsWithDefaults; - val hasErrorValue = !TypeUtils.isUndefined(returnTypeRefTypeArgs.drop(1).head); // isUndefined() is null-safe - val hasMoreThan1SuccessValue = state.G.isIterableN(returnTypeRefTypeArgs.head); // isIterableN() is null-safe - if(target instanceof ParameterizedPropertyAccessExpression_IM && targetSTE.originalTarget instanceof TMethod) { - // we have a method invocation, so we need to preserve the 'this' argument: - - // @Promisify cls.meth(a, b) - // --> - // $n4promisifyMethod(cls, 'meth', [a, b]) - return _CallExpr( - _IdentRef(steFor_$n4promisifyMethod()), - (target as ParameterizedPropertyAccessExpression_IM).target, // here we take the "cls" part of "cls.meth" as first argument - _StringLiteralForSTE(targetSTE), - _ArrLit(callExpr.arguments.map[_ArrayElement(spread, expression)]), // reuse arguments while preserving spread - _BooleanLiteral(hasMoreThan1SuccessValue), - _BooleanLiteral(!hasErrorValue) - ); - } else { - // in all other cases, we do not preserve the 'this' argument: - - // @Promisify fun(a, b) - // --> - // $n4promisifyFunction(fun, [a, b]) - return _CallExpr( - _IdentRef(steFor_$n4promisifyFunction()), - callExpr.target, // reuse target as first argument - _ArrLit(callExpr.arguments.map[_ArrayElement(spread,expression)]), // reuse arguments while preserving spread - _BooleanLiteral(hasMoreThan1SuccessValue), - _BooleanLiteral(!hasErrorValue) - ); - } - } - } - } - // if anything goes awry, we just return callExpr as replacement, which means we simply remove the @Promisify - return callExpr; - } - - /** - * Replaces the following trivial uses of the reflection APIs by the resulting value (i.e. a string literal): - *
-	 * MyClass.n4type.name
-	 * MyClass.n4type.origin
-	 * MyClass.n4type.fqn
-	 * 
- * Thus, reflection will not actually be used in the output code in the above cases. - */ - def private boolean transformTrivialUsageOfReflection(ParameterizedPropertyAccessExpression_IM propAccessExpr) { - val property = propAccessExpr.originalTargetOfRewiredTarget; - if (property === n4NamedElement_name - || property === n4Element_origin - || property === n4Type_fqn) { - val target = propAccessExpr.target; - if (target instanceof ParameterizedPropertyAccessExpression_IM) { - val propertyOfTarget = target.originalTargetOfRewiredTarget; - if (propertyOfTarget === n4Object_n4type) { - val targetOfTarget = target.target; - if (targetOfTarget instanceof IdentifierRef_IM) { - val id = targetOfTarget.originalTargetOfRewiredTarget; - if (id instanceof TClass) { - val value = switch(property) { - case n4NamedElement_name: - id.name - case n4Element_origin: - resourceNameComputer.generateProjectDescriptor(id.eResource) - case n4Type_fqn: - // avoid optimizing this case for built-in types - // (we cannot know for sure the value of the 'fqn' property set in the .js files) - if (!N4Scheme.isFromResourceWithN4Scheme(id)) { - resourceNameComputer.getFullyQualifiedTypeName(id) - } - default: - throw new IllegalStateException() // should not happen (see above) - } - if (value !== null) { - replace(propAccessExpr, _StringLiteral(value)); - return true; - } - } - } - } - } - } - return false; - } - -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/InterfaceDeclarationTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/InterfaceDeclarationTransformation.java new file mode 100644 index 0000000000..2b61c314d5 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/InterfaceDeclarationTransformation.java @@ -0,0 +1,443 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrLit; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrowFunc; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Block; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Fpar; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._LiteralOrComputedPropertyName; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4MethodDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ObjLit; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Parenthesis; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAssignmentAnnotationList; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyGetterDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyNameValuePair; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ReturnStmnt; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Snippet; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableDeclaration; +import static org.eclipse.n4js.transpiler.utils.TranspilerUtils.orContainingExportDeclaration; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.getGlobalObjectScope; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.symbolObjectType; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.AdditiveExpression; +import org.eclipse.n4js.n4JS.AnnotablePropertyAssignment; +import org.eclipse.n4js.n4JS.Annotation; +import org.eclipse.n4js.n4JS.ArrayLiteral; +import org.eclipse.n4js.n4JS.AwaitExpression; +import org.eclipse.n4js.n4JS.BinaryBitwiseExpression; +import org.eclipse.n4js.n4JS.BinaryLogicalExpression; +import org.eclipse.n4js.n4JS.BooleanLiteral; +import org.eclipse.n4js.n4JS.CastExpression; +import org.eclipse.n4js.n4JS.CommaExpression; +import org.eclipse.n4js.n4JS.ExportDeclaration; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.GetterDeclaration; +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName; +import org.eclipse.n4js.n4JS.MultiplicativeExpression; +import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration; +import org.eclipse.n4js.n4JS.N4JSFactory; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.N4MethodDeclaration; +import org.eclipse.n4js.n4JS.NullLiteral; +import org.eclipse.n4js.n4JS.NumericLiteral; +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.ParenExpression; +import org.eclipse.n4js.n4JS.PromisifyExpression; +import org.eclipse.n4js.n4JS.PropertyAssignment; +import org.eclipse.n4js.n4JS.PropertyGetterDeclaration; +import org.eclipse.n4js.n4JS.PropertyMethodDeclaration; +import org.eclipse.n4js.n4JS.PropertyNameOwner; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.n4JS.PropertySetterDeclaration; +import org.eclipse.n4js.n4JS.SetterDeclaration; +import org.eclipse.n4js.n4JS.Statement; +import org.eclipse.n4js.n4JS.StringLiteral; +import org.eclipse.n4js.n4JS.UnaryExpression; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.YieldExpression; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.assistants.TypeAssistant; +import org.eclipse.n4js.transpiler.es.assistants.ClassifierAssistant; +import org.eclipse.n4js.transpiler.es.assistants.DelegationAssistant; +import org.eclipse.n4js.transpiler.es.assistants.ReflectionAssistant; +import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.transpiler.utils.TranspilerUtils; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TInterface; +import org.eclipse.n4js.ts.types.TypingStrategy; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.ResourceNameComputer; +import org.eclipse.xtext.xbase.lib.Pair; + +import com.google.inject.Inject; + +/** + */ +public class InterfaceDeclarationTransformation extends Transformation { + + @Inject + private ClassifierAssistant classifierAssistant; + @Inject + private ReflectionAssistant reflectionAssistant; + @Inject + private DelegationAssistant delegationAssistant; + @Inject + private TypeAssistant typeAssistant; + @Inject + private ResourceNameComputer resourceNameComputer; + + @Override + public void assertPreConditions() { + typeAssistant.assertClassifierPreConditions(); + } + + @Override + public void assertPostConditions() { + // none + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + for (N4InterfaceDeclaration id : collectNodes(getState().im, N4InterfaceDeclaration.class, false)) { + transformInterfaceDecl(id); + } + } + + private void transformInterfaceDecl(N4InterfaceDeclaration ifcDecl) { + if (ifcDecl.getTypingStrategy() == TypingStrategy.STRUCTURAL) { + // structural interfaces are shapes, i.e. do only exist at compile time + EObject ifcOrParent = ifcDecl.eContainer() instanceof ExportDeclaration ? ifcDecl.eContainer() : ifcDecl; + remove(ifcOrParent); + return; + } + SymbolTableEntry ifcSTE = findSymbolTableEntryForElement(ifcDecl, true); + + // add 'Symbol.hasInstance' function for supporting the 'instanceof' operator + ifcDecl.getOwnedMembersRaw().add(createHasInstanceMethod(ifcDecl)); + + reflectionAssistant.addN4TypeGetter(ifcDecl, ifcDecl); + + List belowIfcDecl = new ArrayList<>(); + belowIfcDecl.addAll(createStaticFieldInitializations(ifcDecl, ifcSTE)); + insertAfter(orContainingExportDeclaration(ifcDecl), belowIfcDecl.toArray(new Statement[0])); + + ifcDecl.getOwnedMembersRaw().removeIf(m -> m.isStatic() && m instanceof N4FieldDeclaration); + delegationAssistant.replaceDelegatingMembersByOrdinaryMembers(ifcDecl); + + ObjectLiteral ifcObjLit = createInterfaceObject(ifcDecl); + VariableDeclaration varDecl = _VariableDeclaration(ifcDecl.getName(), ifcObjLit); + getState().tracer.copyTrace(ifcDecl, varDecl); + + replace(ifcDecl, varDecl); + } + + /** Creates an object literal for the object representing the interface of the given ifcDecl. */ + private ObjectLiteral createInterfaceObject(N4InterfaceDeclaration ifcDecl) { + List props = new ArrayList<>(); + ArrayLiteral extendedInterfaces = createDirectlyImplementedOrExtendedInterfacesArgument(ifcDecl); + if (!extendedInterfaces.getElements().isEmpty()) { + String $extends = steFor_$extendsInterfaces().getName(); + props.add(_PropertyGetterDecl( + $extends, + _ReturnStmnt(extendedInterfaces))); + } + props.addAll(createInstanceFieldDefaultsProperty(ifcDecl)); + props.addAll(createInstanceMemberPropertiesExceptFields(ifcDecl)); + props.addAll(createStaticMemberPropertiesExceptFields(ifcDecl)); + + return _ObjLit(props.toArray(new PropertyAssignment[0])); + } + + private ArrayLiteral createDirectlyImplementedOrExtendedInterfacesArgument(N4ClassifierDeclaration typeDecl) { + List interfaces = typeAssistant.getSuperInterfacesSTEs(typeDecl); + + // the return value of this method is intended for default method patching; for this purpose, we have to + // filter out some of the directly implemented interfaces: + Iterable directlyImplementedInterfacesFiltered = TranspilerUtils + .filterNominalInterfaces(interfaces); + return _ArrLit( + toList(map(directlyImplementedInterfacesFiltered, i -> _IdentRef(i))).toArray(new IdentifierRef[0])); + } + + @SuppressWarnings("unchecked") + private List createInstanceFieldDefaultsProperty(N4InterfaceDeclaration ifcDecl) { + // $fieldInits: { + // fieldName1: undefined, + // fieldName2: 42, + // fieldName3: () => , + // ... + // } + List instanceFields = toList( + filter(ifcDecl.getOwnedFields(), f -> !f.isStatic() && f.getName() != null)); + if (instanceFields.isEmpty()) { + return Collections.emptyList(); + } + List> nameValuePairs = new ArrayList<>(); + for (N4FieldDeclaration fd : instanceFields) { + nameValuePairs.add(Pair.of(fd.getName(), + hasNonTrivialInitExpression(fd) + ? (canSkipFunctionWrapping(fd.getExpression()) ? fd.getExpression() + : _ArrowFunc(false, new FormalParameter[0], + wrapInParenthesesIfNeeded(fd.getExpression()))) + : undefinedRef())); + } + + return List.of( + _PropertyNameValuePair( + steFor_$fieldInits().getName(), + _ObjLit(nameValuePairs.toArray(new Pair[0])))); + } + + private List createInstanceMemberPropertiesExceptFields(N4InterfaceDeclaration ifcDecl) { + // $defaultMembers: { + // get getter() { + // }, + // set setter(value) { + // }, + // method() { + // }, + // ... + // } + + List instanceMembersExceptFields = toList(filter(ifcDecl.getOwnedMembers(), + m -> !m.isStatic() && !m.isAbstract() && m.getName() != null && !(m instanceof N4FieldDeclaration))); + + if (instanceMembersExceptFields.isEmpty()) { + return Collections.emptyList(); + } + return List.of( + _PropertyNameValuePair( + steFor_$defaultMembers().getName(), + _ObjLit( + toList(map(instanceMembersExceptFields, m -> convertMemberToProperty(m))) + .toArray(new PropertyAssignment[0])))); + } + + private List createStaticMemberPropertiesExceptFields(N4InterfaceDeclaration ifcDecl) { + // get staticGetter() { + // }, + // set staticSetter(value) { + // }, + // staticMethod() { + // }, + // ... + + List staticMembersExceptFields = toList(filter(ifcDecl.getOwnedMembers(), + m -> m.isStatic() && !m.isAbstract() && m.getName() != null && !(m instanceof N4FieldDeclaration))); + + if (staticMembersExceptFields.isEmpty()) { + return Collections.emptyList(); + } + return toList(map(staticMembersExceptFields, m -> convertMemberToProperty(m))); + } + + /** + * Converts getter, setter, and method declarations to the corresponding declarations in object literals. Does not + * support conversion of field declarations! + */ + private PropertyAssignment convertMemberToProperty(N4MemberDeclaration memberDecl) { + // fields: + if (memberDecl instanceof N4FieldDeclaration) { + N4FieldDeclaration fieldDecl = (N4FieldDeclaration) memberDecl; + return _PropertyNameValuePair( + // reuse existing name + fieldDecl.getDeclaredName(), + // reuse existing initializer expression (if any) + fieldDecl.getExpression() != null ? fieldDecl.getExpression() : undefinedRef()); + } + // getters, setters, and methods: + AnnotablePropertyAssignment result = null; + if (memberDecl instanceof GetterDeclaration) { + PropertyGetterDeclaration gd = N4JSFactory.eINSTANCE.createPropertyGetterDeclaration(); + gd.setBody(((GetterDeclaration) memberDecl).getBody()); // reuse existing body + result = gd; + } else if (memberDecl instanceof SetterDeclaration) { + PropertySetterDeclaration sd = N4JSFactory.eINSTANCE.createPropertySetterDeclaration(); + sd.setFpar(((SetterDeclaration) memberDecl).getFpar()); // reuse existing fpar + sd.setBody(((SetterDeclaration) memberDecl).getBody()); // reuse existing body + result = sd; + } else if (memberDecl instanceof FunctionDefinition) { + FunctionDefinition fd = (FunctionDefinition) memberDecl; + PropertyMethodDeclaration pmd = N4JSFactory.eINSTANCE.createPropertyMethodDeclaration(); + pmd.getFpars().addAll(fd.getFpars()); // reuse existing fpar + pmd.setBody(fd.getBody()); // reuse existing body + pmd.setGenerator(fd.isGenerator()); + pmd.setDeclaredAsync(fd.isAsync()); + result = pmd; + } else { + throw new IllegalArgumentException("not a getter, setter, or method declaration"); + } + + result.setDeclaredName(((PropertyNameOwner) memberDecl).getDeclaredName()); // reuse existing name + if (!memberDecl.getAnnotations().isEmpty()) { + // reuse existing annotations + result.setAnnotationList( + _PropertyAssignmentAnnotationList(memberDecl.getAnnotations().toArray(new Annotation[0]))); + } + return result; + } + + private Expression wrapInParenthesesIfNeeded(Expression expr) { + if (expr instanceof CommaExpression + || expr instanceof ObjectLiteral + || expr instanceof AwaitExpression + || expr instanceof YieldExpression + || expr instanceof PromisifyExpression) { + return _Parenthesis(expr); + } + return expr; + } + + private boolean canSkipFunctionWrapping(Expression initExpression) { + if (initExpression instanceof BooleanLiteral + || initExpression instanceof NullLiteral + || initExpression instanceof NumericLiteral + || initExpression instanceof StringLiteral) { + return true; + } + if (initExpression instanceof UnaryExpression) { + UnaryExpression unaryExpr = (UnaryExpression) initExpression; + // WARNING: some unary operators have a side effect, so they have to be wrapped in a function! + if (canSkipFunctionWrapping(unaryExpr.getExpression())) { + switch (unaryExpr.getOp()) { + case INC: + case DEC: + case DELETE: + return false; + case POS: + case NEG: + case INV: + case NOT: + case TYPEOF: + case VOID: + return true; + } + } + } + if (initExpression instanceof AdditiveExpression) { + AdditiveExpression addExpr = (AdditiveExpression) initExpression; + if (canSkipFunctionWrapping(addExpr.getLhs()) + && canSkipFunctionWrapping(addExpr.getRhs())) { + + switch (addExpr.getOp()) { + case ADD: + case SUB: + return true; + } + } + } + if (initExpression instanceof MultiplicativeExpression) { + MultiplicativeExpression mulExpr = (MultiplicativeExpression) initExpression; + if (canSkipFunctionWrapping(mulExpr.getLhs()) + && canSkipFunctionWrapping(mulExpr.getRhs())) { + + switch (mulExpr.getOp()) { + case TIMES: + case DIV: + case MOD: + return true; + } + } + } + if (initExpression instanceof BinaryBitwiseExpression) { + BinaryBitwiseExpression bbExpr = (BinaryBitwiseExpression) initExpression; + if (canSkipFunctionWrapping(bbExpr.getLhs()) + && canSkipFunctionWrapping(bbExpr.getRhs())) { + + switch (bbExpr.getOp()) { + case OR: + case XOR: + case AND: + return true; + } + } + } + if (initExpression instanceof BinaryLogicalExpression) { + BinaryLogicalExpression blExpr = (BinaryLogicalExpression) initExpression; + if (canSkipFunctionWrapping(blExpr.getLhs()) + && canSkipFunctionWrapping(blExpr.getRhs())) { + + switch (blExpr.getOp()) { + case OR: + case AND: + return true; + } + } + } + if (initExpression instanceof CastExpression) { + return canSkipFunctionWrapping(((CastExpression) initExpression).getExpression()); + } + if (initExpression instanceof ParenExpression) { + return canSkipFunctionWrapping(((ParenExpression) initExpression).getExpression()); + } + if (initExpression instanceof IdentifierRef) { + IdentifierRef idRef = (IdentifierRef) initExpression; + return idRef.getId() == getGlobalObjectScope(getState().G).getFieldUndefined(); + } + + return false; + } + + private List createStaticFieldInitializations(N4InterfaceDeclaration ifcDecl, + SymbolTableEntry ifcSTE) { + return classifierAssistant.createStaticFieldInitializations(ifcDecl, ifcSTE, Collections.emptySet()); + } + + private N4MethodDeclaration createHasInstanceMethod(N4InterfaceDeclaration ifcDecl) { + TClass symbolObjectType = symbolObjectType(getState().G); + SymbolTableEntryOriginal symbolSTE = getSymbolTableEntryOriginal(symbolObjectType, true); + SymbolTableEntryOriginal hasInstanceSTE = getSymbolTableEntryForMember(symbolObjectType, "hasInstance", false, + true, true); + ParameterizedPropertyAccessExpression_IM hasInstanceExpr = _PropertyAccessExpr(symbolSTE, hasInstanceSTE); + LiteralOrComputedPropertyName declaredName = _LiteralOrComputedPropertyName(hasInstanceExpr, + N4JSLanguageUtils.SYMBOL_IDENTIFIER_PREFIX + "hasInstance"); + + TInterface ifcType = getState().info.getOriginalDefinedType(ifcDecl); + String fqn = resourceNameComputer.getFullyQualifiedTypeName(ifcType); + + N4MethodDeclaration result = _N4MethodDecl(true, declaredName, new FormalParameter[] { _Fpar("instance") }, + _Block( + _ReturnStmnt( + _Snippet("instance && instance.constructor && instance.constructor.n4type " + // required because we cannot be sure "instance.constructor.n4type" is of type + // N4Classifier + + "&& instance.constructor.n4type.allImplementedInterfaces " + + "&& instance.constructor.n4type.allImplementedInterfaces.indexOf('" + fqn + + "') !== -1")))); + + getState().info.markAsHiddenFromReflection(result); + + return result; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/InterfaceDeclarationTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/InterfaceDeclarationTransformation.xtend deleted file mode 100644 index d1321ca496..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/InterfaceDeclarationTransformation.xtend +++ /dev/null @@ -1,368 +0,0 @@ -/** - * 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.transpiler.es.transform - -import com.google.inject.Inject -import java.util.Collections -import java.util.List -import org.eclipse.n4js.n4JS.AdditiveExpression -import org.eclipse.n4js.n4JS.ArrayLiteral -import org.eclipse.n4js.n4JS.AwaitExpression -import org.eclipse.n4js.n4JS.BinaryBitwiseExpression -import org.eclipse.n4js.n4JS.BinaryLogicalExpression -import org.eclipse.n4js.n4JS.BooleanLiteral -import org.eclipse.n4js.n4JS.CastExpression -import org.eclipse.n4js.n4JS.CommaExpression -import org.eclipse.n4js.n4JS.ExportDeclaration -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor -import org.eclipse.n4js.n4JS.GetterDeclaration -import org.eclipse.n4js.n4JS.IdentifierRef -import org.eclipse.n4js.n4JS.MultiplicativeExpression -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.N4InterfaceDeclaration -import org.eclipse.n4js.n4JS.N4JSFactory -import org.eclipse.n4js.n4JS.N4MemberDeclaration -import org.eclipse.n4js.n4JS.N4MethodDeclaration -import org.eclipse.n4js.n4JS.NullLiteral -import org.eclipse.n4js.n4JS.NumericLiteral -import org.eclipse.n4js.n4JS.ObjectLiteral -import org.eclipse.n4js.n4JS.ParenExpression -import org.eclipse.n4js.n4JS.PromisifyExpression -import org.eclipse.n4js.n4JS.PropertyAssignment -import org.eclipse.n4js.n4JS.PropertyNameOwner -import org.eclipse.n4js.n4JS.PropertyNameValuePair -import org.eclipse.n4js.n4JS.SetterDeclaration -import org.eclipse.n4js.n4JS.Statement -import org.eclipse.n4js.n4JS.StringLiteral -import org.eclipse.n4js.n4JS.UnaryExpression -import org.eclipse.n4js.n4JS.YieldExpression -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.assistants.TypeAssistant -import org.eclipse.n4js.transpiler.es.assistants.ClassifierAssistant -import org.eclipse.n4js.transpiler.es.assistants.DelegationAssistant -import org.eclipse.n4js.transpiler.es.assistants.ReflectionAssistant -import org.eclipse.n4js.transpiler.im.SymbolTableEntry -import org.eclipse.n4js.transpiler.utils.TranspilerUtils -import org.eclipse.n4js.ts.types.TypingStrategy -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.ResourceNameComputer - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.transpiler.utils.TranspilerUtils.* -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - */ -class InterfaceDeclarationTransformation extends Transformation { - - @Inject private ClassifierAssistant classifierAssistant; - @Inject private ReflectionAssistant reflectionAssistant; - @Inject private DelegationAssistant delegationAssistant; - @Inject private TypeAssistant typeAssistant; - @Inject private ResourceNameComputer resourceNameComputer; - - - override assertPreConditions() { - typeAssistant.assertClassifierPreConditions(); - } - - override assertPostConditions() { - // none - } - - override analyze() { - // ignore - } - - override transform() { - collectNodes(state.im, N4InterfaceDeclaration, false).forEach[transformInterfaceDecl]; - } - - def private void transformInterfaceDecl(N4InterfaceDeclaration ifcDecl) { - if (ifcDecl.typingStrategy === TypingStrategy.STRUCTURAL) { - // structural interfaces are shapes, i.e. do only exist at compile time - val ifcOrParent = ifcDecl.eContainer instanceof ExportDeclaration ? ifcDecl.eContainer : ifcDecl; - remove(ifcOrParent); - return; - } - val ifcSTE = findSymbolTableEntryForElement(ifcDecl, true); - - // add 'Symbol.hasInstance' function for supporting the 'instanceof' operator - ifcDecl.ownedMembersRaw += createHasInstanceMethod(ifcDecl, ifcSTE); - - reflectionAssistant.addN4TypeGetter(ifcDecl, ifcDecl); - - val belowIfcDecl = newArrayList; - belowIfcDecl += createStaticFieldInitializations(ifcDecl, ifcSTE); - insertAfter(ifcDecl.orContainingExportDeclaration, belowIfcDecl); - - ifcDecl.ownedMembersRaw.removeIf[static && it instanceof N4FieldDeclaration]; - delegationAssistant.replaceDelegatingMembersByOrdinaryMembers(ifcDecl); - - val ifcObjLit = createInterfaceObject(ifcDecl, ifcSTE); - val varDecl = _VariableDeclaration(ifcDecl.name, ifcObjLit); - state.tracer.copyTrace(ifcDecl, varDecl); - - replace(ifcDecl, varDecl); - } - - /** Creates an object literal for the object representing the interface of the given ifcDecl. */ - def private ObjectLiteral createInterfaceObject(N4InterfaceDeclaration ifcDecl, SymbolTableEntry ifcSTE) { - val props = newArrayList; - val extendedInterfaces = createDirectlyImplementedOrExtendedInterfacesArgument(ifcDecl); - if (!extendedInterfaces.elements.empty) { - val $extends = steFor_$extendsInterfaces.name; - props += _PropertyGetterDecl( - $extends, - _ReturnStmnt(extendedInterfaces) - ); - } - props += createInstanceFieldDefaultsProperty(ifcDecl, ifcSTE); - props += createInstanceMemberPropertiesExceptFields(ifcDecl, ifcSTE); - props += createStaticMemberPropertiesExceptFields(ifcDecl, ifcSTE); - - return _ObjLit(props); - } - - def private ArrayLiteral createDirectlyImplementedOrExtendedInterfacesArgument(N4ClassifierDeclaration typeDecl) { - val interfaces = typeAssistant.getSuperInterfacesSTEs(typeDecl); - - // the return value of this method is intended for default method patching; for this purpose, we have to - // filter out some of the directly implemented interfaces: - val directlyImplementedInterfacesFiltered = TranspilerUtils.filterNominalInterfaces(interfaces); - return _ArrLit( directlyImplementedInterfacesFiltered.map[ _IdentRef(it) ] ); - } - - def private PropertyNameValuePair[] createInstanceFieldDefaultsProperty(N4InterfaceDeclaration ifcDecl, SymbolTableEntry ifcSTE) { - // $fieldInits: { - // fieldName1: undefined, - // fieldName2: 42, - // fieldName3: () => , - // ... - // } - val instanceFields = ifcDecl.ownedFields - .filter[!static && name!==null] - .toList; - if (instanceFields.empty) { - return #[]; - } - return #[ - _PropertyNameValuePair( - steFor_$fieldInits.name, - _ObjLit( - instanceFields.map[field| - field.name -> if (field.hasNonTrivialInitExpression) { - if (canSkipFunctionWrapping(field.expression)) { - field.expression - } else { - _ArrowFunc(false, #[], field.expression.wrapInParenthesesIfNeeded) - } - } else { - undefinedRef() - } - ] - ) - ) - ]; - } - - def private PropertyNameValuePair[] createInstanceMemberPropertiesExceptFields(N4InterfaceDeclaration ifcDecl, SymbolTableEntry ifcSTE) { - // $defaultMembers: { - // get getter() { - // }, - // set setter(value) { - // }, - // method() { - // }, - // ... - // } - - val instanceMembersExceptFields = ifcDecl.ownedMembers - .filter[!static && !abstract && name!==null] - .filter[!(it instanceof N4FieldDeclaration)] - .toList; - if (instanceMembersExceptFields.empty) { - return #[]; - } - return #[ - _PropertyNameValuePair( - steFor_$defaultMembers.name, - _ObjLit( - instanceMembersExceptFields.map[convertMemberToProperty] - ) - ) - ]; - } - - def private PropertyAssignment[] createStaticMemberPropertiesExceptFields(N4InterfaceDeclaration ifcDecl, SymbolTableEntry ifcSTE) { - // get staticGetter() { - // }, - // set staticSetter(value) { - // }, - // staticMethod() { - // }, - // ... - - val staticMembersExceptFields = ifcDecl.ownedMembers - .filter[static && !abstract && name!==null] - .filter[!(it instanceof N4FieldDeclaration)] - .toList; - if (staticMembersExceptFields.empty) { - return #[]; - } - return staticMembersExceptFields.map[convertMemberToProperty]; - } - - /** - * Converts getter, setter, and method declarations to the corresponding declarations in object literals. - * Does not support conversion of field declarations! - */ - def private PropertyAssignment convertMemberToProperty(N4MemberDeclaration memberDecl) { - // fields: - if (memberDecl instanceof N4FieldDeclaration) { - return _PropertyNameValuePair( - memberDecl.declaredName, // reuse existing name - memberDecl.expression ?: undefinedRef); // reuse existing initializer expression (if any) - } - // getters, setters, and methods: - val result = switch(memberDecl) { - GetterDeclaration: N4JSFactory.eINSTANCE.createPropertyGetterDeclaration - SetterDeclaration: N4JSFactory.eINSTANCE.createPropertySetterDeclaration => [ - it.fpar = memberDecl.fpar; // reuse existing fpar - ] - FunctionDefinition: N4JSFactory.eINSTANCE.createPropertyMethodDeclaration => [ - it.fpars += memberDecl.fpars; // reuse existing fpars - it.generator = memberDecl.generator; - it.declaredAsync = memberDecl.async; - ] - default: - throw new IllegalArgumentException("not a getter, setter, or method declaration") - }; - result.declaredName = (memberDecl as PropertyNameOwner).declaredName; // reuse existing name - result.body = (memberDecl as FunctionOrFieldAccessor).body; // reuse existing body - if (!memberDecl.annotations.isEmpty) { - result.annotationList = _PropertyAssignmentAnnotationList( memberDecl.annotations ) // reuse existing annotations - } - return result; - } - - def private Expression wrapInParenthesesIfNeeded(Expression expr) { - if (expr instanceof CommaExpression - || expr instanceof ObjectLiteral - || expr instanceof AwaitExpression - || expr instanceof YieldExpression - || expr instanceof PromisifyExpression) { - return _Parenthesis(expr); - } - return expr; - } - - def private boolean canSkipFunctionWrapping(Expression initExpression) { - return switch(initExpression) { - BooleanLiteral: true - NullLiteral: true - NumericLiteral: true - StringLiteral: true - UnaryExpression: { - // WARNING: some unary operators have a side effect, so they have to be wrapped in a function! - val isFreeOfSideEffect = switch(initExpression.op) { - case INC: false - case DEC: false - case DELETE: false - case POS: true - case NEG: true - case INV: true - case NOT: true - case TYPEOF: true - case VOID: true - } - return isFreeOfSideEffect - && canSkipFunctionWrapping(initExpression.expression); - } - AdditiveExpression: { - val isFreeOfSideEffect = switch(initExpression.op) { - case ADD: true - case SUB: true - } - return isFreeOfSideEffect - && canSkipFunctionWrapping(initExpression.lhs) - && canSkipFunctionWrapping(initExpression.rhs); - } - MultiplicativeExpression: { - val isFreeOfSideEffect = switch(initExpression.op) { - case TIMES: true - case DIV: true - case MOD: true - } - return isFreeOfSideEffect - && canSkipFunctionWrapping(initExpression.lhs) - && canSkipFunctionWrapping(initExpression.rhs); - } - BinaryBitwiseExpression: { - val isFreeOfSideEffect = switch(initExpression.op) { - case OR: true - case XOR: true - case AND: true - } - return isFreeOfSideEffect - && canSkipFunctionWrapping(initExpression.lhs) - && canSkipFunctionWrapping(initExpression.rhs); - } - BinaryLogicalExpression: { - val isFreeOfSideEffect = switch(initExpression.op) { - case OR: true - case AND: true - } - return isFreeOfSideEffect - && canSkipFunctionWrapping(initExpression.lhs) - && canSkipFunctionWrapping(initExpression.rhs); - } - CastExpression: canSkipFunctionWrapping(initExpression.expression) - ParenExpression: canSkipFunctionWrapping(initExpression.expression) - IdentifierRef: { - return initExpression.id === state.G.globalObjectScope.fieldUndefined; - } - default: false - }; - } - - def protected List createStaticFieldInitializations(N4InterfaceDeclaration ifcDecl, SymbolTableEntry ifcSTE) { - return classifierAssistant.createStaticFieldInitializations(ifcDecl, ifcSTE, Collections.emptySet); - } - - def private N4MethodDeclaration createHasInstanceMethod(N4InterfaceDeclaration ifcDecl, SymbolTableEntry ifcSTE) { - val symbolObjectType = state.G.symbolObjectType; - val symbolSTE = getSymbolTableEntryOriginal(symbolObjectType, true); - val hasInstanceSTE = getSymbolTableEntryForMember(symbolObjectType, "hasInstance", false, true, true); - val hasInstanceExpr = _PropertyAccessExpr(symbolSTE, hasInstanceSTE); - val declaredName = _LiteralOrComputedPropertyName(hasInstanceExpr, N4JSLanguageUtils.SYMBOL_IDENTIFIER_PREFIX + "hasInstance"); - - val ifcType = state.info.getOriginalDefinedType(ifcDecl); - val fqn = resourceNameComputer.getFullyQualifiedTypeName(ifcType); - - val result = _N4MethodDecl(true, declaredName, #[ _Fpar("instance") ], _Block( - _ReturnStmnt( - _Snippet("instance && instance.constructor && instance.constructor.n4type " - + "&& instance.constructor.n4type.allImplementedInterfaces " // required because we cannot be sure "instance.constructor.n4type" is of type N4Classifier - + "&& instance.constructor.n4type.allImplementedInterfaces.indexOf('" + fqn + "') !== -1" - ) - ) - )); - - state.info.markAsHiddenFromReflection(result); - - return result; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.java new file mode 100644 index 0000000000..7ef14e5728 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.java @@ -0,0 +1,314 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._NULL; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ObjLit; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyNameValuePair; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._TRUE; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.JSXAbstractElement; +import org.eclipse.n4js.n4JS.JSXAttribute; +import org.eclipse.n4js.n4JS.JSXChild; +import org.eclipse.n4js.n4JS.JSXElement; +import org.eclipse.n4js.n4JS.JSXExpression; +import org.eclipse.n4js.n4JS.JSXFragment; +import org.eclipse.n4js.n4JS.JSXPropertyAttribute; +import org.eclipse.n4js.n4JS.JSXSpreadAttribute; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.n4JS.PropertyAssignment; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.tooling.react.ReactHelper; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.im.IdentifierRef_IM; +import org.eclipse.n4js.transpiler.im.Script_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.utils.ResourceType; +import org.eclipse.xtext.EcoreUtil2; + +import com.google.inject.Inject; + +/** + * Transforms JSX tags to output code according to JSX/React conventions. + *

+ * For example: + * + *

+ * <div attr="value"></div>
+ * 
+ * + * will be transformed to + * + *
+ * React.createElement('div', Object.assign({attr: "value"}));
+ * 
+ */ +public class JSXTransformation extends Transformation { + + private SymbolTableEntryOriginal steForJsxBackendNamespace; + private SymbolTableEntryOriginal steForJsxBackendElementFactoryFunction; + private SymbolTableEntryOriginal steForJsxBackendFragmentComponent; + + @Inject + private ReactHelper reactHelper; + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + // ignore + } + + /** + * IMPORTANT: our strategy for handling nested JSXElements is as follows: 1) direct child JSXElements will be + * handled together with their parent JSXElement 2) indirect children that are contained in nested expressions will + * be handled via a separate invocation to method #transformJSXElement(JSXElement) + * + * Example for case 1: + * + *
+	 * let elem1 = <div><a></a></div>; // <a> is a direct child
+	 * 
+ * + * Example for case 2: + * + *
+	 * let elem2 = <div>{function() {return <a></a>;}}</div>; // <a> is the child of a nested expression!
+	 * 
+ * + * More examples for case 2: + * + *
+	 * let elem3 = <div>{<a></a>}</div>;
+	 * let elem4 = <div prop={<a></a>}></div>;
+	 * 
+ */ + @Override + public void transform() { + ResourceType resourceType = ResourceType.getResourceType(getState().resource); + boolean inJSX = resourceType == ResourceType.JSX || resourceType == ResourceType.N4JSX; + if (!inJSX) { + return; // this transformation is not applicable + } + + // Transform JSXFragments and JSXElements + List jsxAbstractElements = collectNodes(getState().im, JSXAbstractElement.class, true); + if (jsxAbstractElements.isEmpty()) { + // Nothing to transform + return; + } + + steForJsxBackendNamespace = prepareImportOfJsxBackend(); + steForJsxBackendElementFactoryFunction = prepareElementFactoryFunction(); + steForJsxBackendFragmentComponent = prepareFragmentComponent(); + + // note: we are passing 'true' to #collectNodes(), i.e. we are searching for nested elements + for (JSXAbstractElement jsxElem : jsxAbstractElements) { + transformJSXAbstractElement(jsxElem); + } + } + + private SymbolTableEntryOriginal prepareImportOfJsxBackend() { + TModule jsxBackendModule = reactHelper.getJsxBackendModule(getState().resource); + if (jsxBackendModule == null) { + throw new RuntimeException("cannot locate JSX backend for N4JSX resource " + getState().resource.getURI()); + } + NamespaceImportSpecifier existingNamespaceImportOfReactIM = null; + for (ImportDeclaration id : filter(getState().im.getScriptElements(), ImportDeclaration.class)) { + if (getState().info.getImportedModule(id) == jsxBackendModule) { + List niss = toList( + filter(id.getImportSpecifiers(), NamespaceImportSpecifier.class)); + if (!niss.isEmpty()) { + existingNamespaceImportOfReactIM = niss.get(0); + break; + } + } + } + + if (existingNamespaceImportOfReactIM != null) { + // we already have a namespace import of the JSX backend, no need to create a new one: + existingNamespaceImportOfReactIM.setFlaggedUsedInCode(true); + return findSymbolTableEntryForNamespaceImport(existingNamespaceImportOfReactIM); + } + // create namespace import for the JSX backend + // (note: we do not have to care for name clashes regarding name of the namespace, because validations ensure + // that "React" is never used as a name in N4JSX files, except as the namespace name of a react import) + return addNamespaceImport(jsxBackendModule, reactHelper.getJsxBackendNamespaceName()); + } + + private SymbolTableEntryOriginal prepareElementFactoryFunction() { + TFunction elementFactoryFunction = reactHelper.getJsxBackendElementFactoryFunction(getState().resource); + if (elementFactoryFunction == null) { + throw new RuntimeException("cannot locate element factory function of JSX backend for N4JSX resource " + + getState().resource.getURI()); + } + return getSymbolTableEntryOriginal(elementFactoryFunction, true); + } + + private SymbolTableEntryOriginal prepareFragmentComponent() { + IdentifiableElement fragmentComponent = reactHelper.getJsxBackendFragmentComponent(getState().resource); + if (fragmentComponent == null) { + throw new RuntimeException("cannot locate fragment component of JSX backend for N4JSX resource " + + getState().resource.getURI()); + } + return getSymbolTableEntryOriginal(fragmentComponent, true); + } + + private void transformJSXAbstractElement(JSXAbstractElement elem) { + // IMPORTANT: 'elem' might be a direct or indirect child, but if it is a direct child, it was already + // transformed when this method was invoked with its ancestor JSXElement as argument + if (EcoreUtil2.getContainerOfType(elem, Script_IM.class) == null) { + // 'elem' was already processed -> simply ignore it + return; + } + replace(elem, convertJSXAbstractElement(elem)); + } + + private ParameterizedCallExpression convertJSXAbstractElement(JSXAbstractElement elem) { + List args = new ArrayList<>(); + if (elem instanceof JSXElement) { + JSXElement jsxElem = (JSXElement) elem; + args.add(getTagNameFromElement(jsxElem)); + args.add(convertJSXAttributes(jsxElem.getJsxAttributes())); + } else { + args.add(_PropertyAccessExpr(steForJsxBackendNamespace, steForJsxBackendFragmentComponent)); + args.add(_NULL()); + } + args.addAll(toList(map(elem.getJsxChildren(), child -> convertJSXChild(child)))); + + return _CallExpr( + _PropertyAccessExpr(steForJsxBackendNamespace, steForJsxBackendElementFactoryFunction), + args.toArray(new Expression[0])); + } + + private Expression convertJSXChild(JSXChild child) { + if (child instanceof JSXElement) { + return convertJSXAbstractElement((JSXElement) child); + } + if (child instanceof JSXFragment) { + return convertJSXAbstractElement((JSXFragment) child); + } + if (child instanceof JSXExpression) { + return ((JSXExpression) child).getExpression(); + } + return null; + } + + // Generate Object.assign({}, {foo, bar: "Hi"}, spr) + private Expression convertJSXAttributes(List attrs) { + if (attrs.isEmpty()) { + return _NULL(); + } else if (attrs.size() == 1 && attrs.get(0) instanceof JSXSpreadAttribute) { + // Special case: if only a single spread operator is passed, we pass it directly, e.g. spr instead of + // cloning with Object.assign. + return ((JSXSpreadAttribute) attrs.get(0)).getExpression(); + } else { + + List spreadIndices = new ArrayList<>(); + for (int idx = 0; idx < attrs.size(); idx++) { + if (attrs.get(idx) instanceof JSXSpreadAttribute) { + spreadIndices.add(idx); + } + } + // GHOLD-413: We have to make sure that the only properties locating next to each other are combined. + // Moreover, the order of properties as well as spread operators must be preserved! + List props = new ArrayList<>(); + if (attrs.get(0) instanceof JSXSpreadAttribute) { + // The first attribute is a spread object, the target must be {}. + } else { + // Otherwise, the target is of the form {foo: true, bar: "Hi"} + int firstSpreadIndex = (!spreadIndices.isEmpty()) ? spreadIndices.get(0) : attrs.size(); + for (int i = 0; i < firstSpreadIndex; i++) { + props.add(convertJSXAttribute((JSXPropertyAttribute) attrs.get(i))); + } + } + ObjectLiteral target = _ObjLit(props.toArray(new PropertyNameValuePair[0])); + + List parameters = new ArrayList<>(); + parameters.add(target); + + for (int i = 0; i < spreadIndices.size(); i++) { + int curSpreadIdx = spreadIndices.get(i); + // Spread expression passed is used directly + parameters.add(((JSXSpreadAttribute) attrs.get(curSpreadIdx)).getExpression()); + // Combine properties between spread intervals + int nextSpreadIdx = (i < spreadIndices.size() - 1) ? spreadIndices.get(i + 1) + : attrs.size(); + List propsBetweenTwoSpreads = attrs.subList(curSpreadIdx + 1, nextSpreadIdx); + if (!propsBetweenTwoSpreads.isEmpty()) { + List props2 = new ArrayList<>(); + for (JSXAttribute attr : propsBetweenTwoSpreads) { + props2.add(convertJSXAttribute((JSXPropertyAttribute) attr)); + } + parameters.add(_ObjLit(props2.toArray(new PropertyAssignment[0]))); + } + } + + return _CallExpr(_PropertyAccessExpr(steFor_Object(), steFor_Object_assign()), + parameters.toArray(new Expression[0])); + } + } + + private PropertyNameValuePair convertJSXAttribute(JSXPropertyAttribute attr) { + return _PropertyNameValuePair( + getNameFromPropertyAttribute(attr), + getValueExpressionFromPropertyAttribute(attr)); + } + + private Expression getTagNameFromElement(JSXElement elem) { + Expression nameExpr = elem.getJsxElementName().getExpression(); + if (nameExpr instanceof IdentifierRef_IM) { + IdentifierRef_IM idRef = (IdentifierRef_IM) nameExpr; + SymbolTableEntry id = idRef.getId_IM(); + if (id == null) { + return _StringLiteral(idRef.getIdAsText()); + } + } + return nameExpr; + } + + private String getNameFromPropertyAttribute(JSXPropertyAttribute attr) { + IdentifiableElement prop = attr.getProperty(); + if (prop != null && !prop.eIsProxy()) { + return prop.getName(); + } + return attr.getPropertyAsText(); + } + + private Expression getValueExpressionFromPropertyAttribute(JSXPropertyAttribute attr) { + return attr.getJsxAttributeValue() != null ? attr.getJsxAttributeValue() : _TRUE(); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.xtend deleted file mode 100644 index b5b758832f..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.xtend +++ /dev/null @@ -1,268 +0,0 @@ -/** - * 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.transpiler.es.transform - -import com.google.inject.Inject -import java.util.ArrayList -import java.util.List -import java.util.stream.IntStream -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.JSXAbstractElement -import org.eclipse.n4js.n4JS.JSXAttribute -import org.eclipse.n4js.n4JS.JSXChild -import org.eclipse.n4js.n4JS.JSXElement -import org.eclipse.n4js.n4JS.JSXExpression -import org.eclipse.n4js.n4JS.JSXFragment -import org.eclipse.n4js.n4JS.JSXPropertyAttribute -import org.eclipse.n4js.n4JS.JSXSpreadAttribute -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.n4JS.ParameterizedCallExpression -import org.eclipse.n4js.n4JS.PropertyNameValuePair -import org.eclipse.n4js.tooling.react.ReactHelper -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.im.IdentifierRef_IM -import org.eclipse.n4js.transpiler.im.Script_IM -import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal -import org.eclipse.n4js.utils.ResourceType -import org.eclipse.xtext.EcoreUtil2 - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - * Transforms JSX tags to output code according to JSX/React conventions. - *

- * For example: - *

- * <div attr="value"></div>
- * 
- * will be transformed to - *
- * React.createElement('div', Object.assign({attr: "value"}));
- * 
- */ -class JSXTransformation extends Transformation { - - private SymbolTableEntryOriginal steForJsxBackendNamespace; - private SymbolTableEntryOriginal steForJsxBackendElementFactoryFunction; - private SymbolTableEntryOriginal steForJsxBackendFragmentComponent; - - @Inject - private ReactHelper reactHelper; - - override assertPreConditions() { - } - - override assertPostConditions() { - } - - override analyze() { - // ignore - } - - /** - * IMPORTANT: our strategy for handling nested JSXElements is as follows: - * 1) direct child JSXElements will be handled together with their parent JSXElement - * 2) indirect children that are contained in nested expressions will be handled via a separate invocation to - * method #transformJSXElement(JSXElement) - * - * Example for case 1: - *
-	 * let elem1 = <div><a></a></div>; // <a> is a direct child
-	 * 
- * Example for case 2: - *
-	 * let elem2 = <div>{function() {return <a></a>;}}</div>; // <a> is the child of a nested expression!
-	 * 
- * More examples for case 2: - *
-	 * let elem3 = <div>{<a></a>}</div>;
-	 * let elem4 = <div prop={<a></a>}></div>;
-	 * 
- */ - override void transform() { - val resourceType = ResourceType.getResourceType(state.resource); - val inJSX = resourceType === ResourceType.JSX || resourceType === ResourceType.N4JSX; - if(!inJSX) { - return; // this transformation is not applicable - } - - // Transform JSXFragments and JSXElements - val jsxAbstractElements = collectNodes(state.im, JSXAbstractElement, true); - if (jsxAbstractElements.isEmpty) { - // Nothing to transform - return; - } - - steForJsxBackendNamespace = prepareImportOfJsxBackend(); - steForJsxBackendElementFactoryFunction = prepareElementFactoryFunction(); - steForJsxBackendFragmentComponent = prepareFragmentComponent(); - - // note: we are passing 'true' to #collectNodes(), i.e. we are searching for nested elements - jsxAbstractElements.forEach[transformJSXAbstractElement]; - } - - def private SymbolTableEntryOriginal prepareImportOfJsxBackend() { - val jsxBackendModule = reactHelper.getJsxBackendModule(state.resource); - if(jsxBackendModule===null) { - throw new RuntimeException("cannot locate JSX backend for N4JSX resource " + state.resource.URI); - } - val existingNamespaceImportOfReactIM = state.im.scriptElements.filter(ImportDeclaration) - .filter[impDeclIM | state.info.getImportedModule(impDeclIM)===jsxBackendModule] - .map[importSpecifiers].flatten - .filter(NamespaceImportSpecifier) - .head; - if(existingNamespaceImportOfReactIM!==null) { - // we already have a namespace import of the JSX backend, no need to create a new one: - existingNamespaceImportOfReactIM.flaggedUsedInCode = true; - return findSymbolTableEntryForNamespaceImport(existingNamespaceImportOfReactIM); - } - // create namespace import for the JSX backend - // (note: we do not have to care for name clashes regarding name of the namespace, because validations ensure - // that "React" is never used as a name in N4JSX files, except as the namespace name of a react import) - return addNamespaceImport(jsxBackendModule, reactHelper.getJsxBackendNamespaceName()); - } - - def private SymbolTableEntryOriginal prepareElementFactoryFunction() { - val elementFactoryFunction = reactHelper.getJsxBackendElementFactoryFunction(state.resource); - if(elementFactoryFunction===null) { - throw new RuntimeException("cannot locate element factory function of JSX backend for N4JSX resource " + state.resource.URI); - } - return getSymbolTableEntryOriginal(elementFactoryFunction, true); - } - - def private SymbolTableEntryOriginal prepareFragmentComponent() { - val fragmentComponent = reactHelper.getJsxBackendFragmentComponent(state.resource); - if(fragmentComponent===null) { - throw new RuntimeException("cannot locate fragment component of JSX backend for N4JSX resource " + state.resource.URI); - } - return getSymbolTableEntryOriginal(fragmentComponent, true); - } - - def private void transformJSXAbstractElement(JSXAbstractElement elem) { - // IMPORTANT: 'elem' might be a direct or indirect child, but if it is a direct child, it was already - // transformed when this method was invoked with its ancestor JSXElement as argument - if(EcoreUtil2.getContainerOfType(elem, Script_IM)===null) { - // 'elem' was already processed -> simply ignore it - return; - } - replace(elem, convertJSXAbstractElement(elem)); - } - - def private ParameterizedCallExpression convertJSXAbstractElement(JSXAbstractElement elem) { - val firstParams = if (elem instanceof JSXElement) { - #[ - elem.tagNameFromElement, - convertJSXAttributes(elem.jsxAttributes) - ] - } else { - #[ - _PropertyAccessExpr(steForJsxBackendNamespace, steForJsxBackendFragmentComponent), - _NULL - ] - }; - return _CallExpr( - _PropertyAccessExpr(steForJsxBackendNamespace, steForJsxBackendElementFactoryFunction), - ( - firstParams - + elem.jsxChildren.map[convertJSXChild] - ) - ); - } - - def private Expression convertJSXChild(JSXChild child) { - switch(child) { - JSXElement: - convertJSXAbstractElement(child) - JSXFragment: - convertJSXAbstractElement(child) - JSXExpression: - child.expression - } - } - - // Generate Object.assign({}, {foo, bar: "Hi"}, spr) - def private Expression convertJSXAttributes(List attrs) { - if(attrs.isEmpty) { - return _NULL; - } else if (attrs.size == 1 && attrs.get(0) instanceof JSXSpreadAttribute) { - // Special case: if only a single spread operator is passed, we pass it directly, e.g. spr instead of cloning with Object.assign. - return (attrs.get(0) as JSXSpreadAttribute).expression; - } else { - val spreadIndices = IntStream.range(0, attrs.size) - .filter[i | attrs.get(i) instanceof JSXSpreadAttribute].toArray; - // GHOLD-413: We have to make sure that the only properties locating next to each other are combined. - // Moreover, the order of properties as well as spread operators must be preserved! - val target = if (attrs.get(0) instanceof JSXSpreadAttribute) { - // The first attribute is a spread object, the target must be {}. - _ObjLit - } else { - // Otherwise, the target is of the form {foo: true, bar: "Hi"} - val firstSpreadIndex = if (!spreadIndices.empty) { - spreadIndices.get(0) - } else { - attrs.size - } - var firstProps = attrs.subList(0, firstSpreadIndex).map[it as JSXPropertyAttribute]; - _ObjLit(firstProps.map[convertJSXAttribute]) - } - - var parameters = new ArrayList(); - parameters.add(target); - - for (var i = 0; i < spreadIndices.length; i++) { - val curSpreadIdx = spreadIndices.get(i) - // Spread expression passed is used directly - parameters.add((attrs.get(curSpreadIdx) as JSXSpreadAttribute).expression); - // Combine properties between spread intervals - val nextSpreadIdx = if (i < spreadIndices.length-1) { - spreadIndices.get(i + 1); - } else { - attrs.length - } - val propsBetweenTwoSpreads = attrs.subList(curSpreadIdx + 1, nextSpreadIdx) - if (!propsBetweenTwoSpreads.empty) { - parameters.add(_ObjLit(propsBetweenTwoSpreads.map[(it as JSXPropertyAttribute).convertJSXAttribute])); - } - } - - return _CallExpr(_PropertyAccessExpr(steFor_Object, steFor_Object_assign), parameters); - } - } - - def private PropertyNameValuePair convertJSXAttribute(JSXPropertyAttribute attr) { - _PropertyNameValuePair( - attr.nameFromPropertyAttribute, - attr.valueExpressionFromPropertyAttribute) - } - - def private Expression getTagNameFromElement(JSXElement elem) { - val nameExpr = elem.jsxElementName.expression; - if(nameExpr instanceof IdentifierRef_IM) { - val id = nameExpr.id_IM; - if(id===null) { - return _StringLiteral(nameExpr.idAsText); - } - } - return nameExpr; - } - - def private String getNameFromPropertyAttribute(JSXPropertyAttribute attr) { - val prop = attr.property; - if(prop!==null && !prop.eIsProxy) { - return prop.name; - } - return attr.propertyAsText; - } - def private Expression getValueExpressionFromPropertyAttribute(JSXPropertyAttribute attr) { - return attr.jsxAttributeValue ?: _TRUE; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/MemberPatchingTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/MemberPatchingTransformation.java new file mode 100644 index 0000000000..bf5bc141b0 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/MemberPatchingTransformation.java @@ -0,0 +1,194 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._N4MemberDecl; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.List; + +import org.apache.log4j.Logger; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.assistants.TypeAssistant; +import org.eclipse.n4js.transpiler.es.assistants.DelegationAssistant; +import org.eclipse.n4js.transpiler.im.DelegatingMember; +import org.eclipse.n4js.transpiler.utils.ConcreteMembersOrderedForTranspiler; +import org.eclipse.n4js.ts.types.ContainerType; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TInterface; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.TSetter; +import org.eclipse.n4js.ts.types.TypingStrategy; +import org.eclipse.n4js.ts.types.util.AccessorTuple; + +import com.google.inject.Inject; + +/** + * Handles some special cases where code has to be emitted for non-owned members, e.g. for members consumed by an + * interface, EXCEPT for {@link StaticPolyfillTransformation static polyfills} and + * {@link ApiImplStubGenerationTransformation API/Impl stubs} (those cases are handled in other transformations). + *

+ * This transformation will add new "full" members or {@link DelegatingMember}s to the ownedMembersRaw + * property of {@link ContainerType}s in the intermediate model. + */ +public class MemberPatchingTransformation extends Transformation { + private final static Logger LOGGER = Logger.getLogger(MemberPatchingTransformation.class); + + @Inject + private DelegationAssistant delegationAssistant; + @Inject + private TypeAssistant typeAssistant; + + @Override + public void assertPreConditions() { + typeAssistant.assertClassifierPreConditions(); + } + + @Override + public void assertPostConditions() { + // true + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + for (N4ClassifierDeclaration cd : collectNodes(getState().im, N4ClassifierDeclaration.class, false)) { + if (cd instanceof N4InterfaceDeclaration) { + transformClassifierDecl((N4InterfaceDeclaration) cd); + + } else if (cd instanceof N4ClassDeclaration) { + transformClassifierDecl((N4ClassDeclaration) cd); + } + } + } + + private void transformClassifierDecl(N4InterfaceDeclaration ifcDecl) { + TInterface tIfc = getState().info.getOriginalDefinedType(ifcDecl); + ConcreteMembersOrderedForTranspiler cmoft = typeAssistant.getOrCreateCMOFT(tIfc); + + // for interfaces we ALWAYS add delegates to ALL inherited members (except fields) + for (TMember m : cmoft.ownedAndMixedInConcreteMembers) { + if (!(m instanceof TField)) { + boolean isInherited = m.getContainingType() != tIfc; + if (isInherited) { + DelegatingMember delegator = delegationAssistant.createDelegatingMember(tIfc, m); + getState().info.markAsConsumedFromInterface(delegator); + ifcDecl.getOwnedMembersRaw().add(delegator); + } + } else { + // note: it is slightly inconsistent that we ignore fields here (also compare with method for classes); + // but not required, because this is handled by the field initializer function created here: + // InterfaceDeclarationTransformation#createInstanceFieldInitializationFunction(N4InterfaceDeclaration, + // SymbolTableEntry) + } + } + + for (TField field : cmoft.fieldsPurelyMixedInNotOverridingAccessor) { + if (cmoft.inlinedMembersFromShapes.contains(field)) { + N4MemberDeclaration member = _N4MemberDecl(field); + ifcDecl.getOwnedMembersRaw().add(member); + getState().info.setOriginalDefinedMember(member, field); + } + } + } + + private void transformClassifierDecl(N4ClassDeclaration classDecl) { + TClass tClass = getState().info.getOriginalDefinedType(classDecl); + ConcreteMembersOrderedForTranspiler cmoft = typeAssistant.getOrCreateCMOFT(tClass); + + // add delegates to methods consumed from a nominal interface + List consumedMethods = toList( + filter(filter(cmoft.ownedAndMixedInConcreteMembers, TMethod.class), m -> m.eContainer() != tClass)); + for (TMethod m : consumedMethods) { + DelegatingMember member = delegationAssistant.createDelegatingMember(tClass, m); + if (!isInStructuralInterface(m)) { + getState().info.markAsConsumedFromInterface(member); + } + classDecl.getOwnedMembersRaw().add(member); + } + + // add delegates to getters/setters consumed from a nominal interface + for (AccessorTuple accTuple : cmoft.concreteAccessorTuples) { + if (accTuple.getGetter() != null && accTuple.getGetter().getContainingType() != tClass + && accTuple.getInheritedGetter() == null) { + TGetter g = accTuple.getGetter(); + DelegatingMember member = delegationAssistant.createDelegatingMember(tClass, g); + if (!isInStructuralInterface(accTuple.getGetter())) { + getState().info.markAsConsumedFromInterface(member); + } + classDecl.getOwnedMembersRaw().add(member); + } + if (accTuple.getSetter() != null && accTuple.getSetter().getContainingType() != tClass + && accTuple.getInheritedSetter() == null) { + TSetter s = accTuple.getSetter(); + DelegatingMember member = delegationAssistant.createDelegatingMember(tClass, s); + if (!isInStructuralInterface(accTuple.getSetter())) { + getState().info.markAsConsumedFromInterface(member); + } + classDecl.getOwnedMembersRaw().add(member); + } + } + + // add fields consumed from a nominal interface + for (TField field : cmoft.fieldsPurelyMixedInNotOverridingAccessor) { + N4MemberDeclaration member = _N4MemberDecl(field); + classDecl.getOwnedMembersRaw().add(member); + getState().info.setOriginalDefinedMember(member, field); + if (!cmoft.inlinedMembersFromShapes.contains(field)) { + getState().info.markAsConsumedFromInterface(member); + } + } + + // add delegates to inherited fields/getters/setters shadowed by an owned setter XOR getter + // NOTE: Partial shadowing in general is disallowed by validation. However, in incomplete + // API-impl situation we still support this feature here to propagate generated stubs for + // test reporting-purposes. + // MOVED: the actual implementation moved to the {@link + // org.eclipse.n4js.transpiler.es.transform.ApiImplStubGenerationTransformation} class + // the following code will issue errors if such a 'forbidden' case is still encountered: + for (AccessorTuple accTuple : cmoft.concreteAccessorTuples) { + if (accTuple.getInheritedGetter() != null && accTuple.getGetter() == null && accTuple.getSetter() != null) { + // an owned setter is shadowing an inherited getter -> delegate to the inherited getter + LOGGER.error("Encountered an invalid getter shadowing. Setter " + accTuple.getSetter().getName() + + " of classifier " + accTuple.getSetter().getContainingType() + "", + new IllegalStateException( + "Invalid shadowing of inherited getter. Getter should be implemented explicitly.")); + } + if (accTuple.getInheritedSetter() != null && accTuple.getGetter() != null && accTuple.getSetter() == null) { + // an owned getter is shadowing an inherited setter -> delegate to the inherited setter + LOGGER.error( + "Encountered an invalid inherited setter shadowing. Getter " + accTuple.getGetter().getName() + + " of classifier " + accTuple.getGetter().getContainingType() + "", + new IllegalStateException( + "Invalid shadowing of inherited setter. Setter should be implemented explicitly.")); + } + } + } + + // Note: Structural interfaces do not appear in the output code. Hence they must be consumed by the + // classes/interfaces that implement them. + private boolean isInStructuralInterface(TMember member) { + return member.eContainer() instanceof TInterface + && ((TInterface) member.eContainer()).getTypingStrategy() == TypingStrategy.STRUCTURAL; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/MemberPatchingTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/MemberPatchingTransformation.xtend deleted file mode 100644 index a410918932..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/MemberPatchingTransformation.xtend +++ /dev/null @@ -1,159 +0,0 @@ -/** - * 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.transpiler.es.transform - -import com.google.inject.Inject -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.n4JS.N4InterfaceDeclaration -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.assistants.TypeAssistant -import org.eclipse.n4js.transpiler.es.assistants.DelegationAssistant -import org.eclipse.n4js.transpiler.im.DelegatingMember -import org.eclipse.n4js.ts.types.ContainerType -import org.eclipse.n4js.ts.types.TField -import org.eclipse.n4js.ts.types.TInterface -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.ts.types.TypingStrategy -import org.eclipse.n4js.utils.Log - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - * Handles some special cases where code has to be emitted for non-owned members, e.g. for members consumed by an - * interface, EXCEPT for {@link StaticPolyfillTransformation static polyfills} and - * {@link ApiImplStubGenerationTransformation API/Impl stubs} (those cases are handled in other transformations). - *

- * This transformation will add new "full" members or {@link DelegatingMember}s to the ownedMembersRaw - * property of {@link ContainerType}s in the intermediate model. - */ -@Log -class MemberPatchingTransformation extends Transformation { - @Inject private DelegationAssistant delegationAssistant; - @Inject private TypeAssistant typeAssistant; - - - override assertPreConditions() { - typeAssistant.assertClassifierPreConditions(); - } - override assertPostConditions() { - // true - } - - override analyze() { - // ignore - } - - override transform() { - collectNodes(state.im, N4ClassifierDeclaration, false).forEach[transformClassifierDecl]; - } - - def private dispatch void transformClassifierDecl(N4InterfaceDeclaration ifcDecl) { - val tIfc = state.info.getOriginalDefinedType(ifcDecl); - val cmoft = typeAssistant.getOrCreateCMOFT(tIfc); - - // for interfaces we ALWAYS add delegates to ALL inherited members (except fields) - for(TMember m : cmoft.ownedAndMixedInConcreteMembers) { - if(!(m instanceof TField)) { - val isInherited = m.containingType!==tIfc; - if(isInherited){ - val delegator = delegationAssistant.createDelegatingMember(tIfc, m); - state.info.markAsConsumedFromInterface(delegator); - ifcDecl.ownedMembersRaw += delegator; - } - } else { - // note: it is slightly inconsistent that we ignore fields here (also compare with method for classes); - // but not required, because this is handled by the field initializer function created here: - // InterfaceDeclarationTransformation#createInstanceFieldInitializationFunction(N4InterfaceDeclaration, SymbolTableEntry) - } - } - - for(field : cmoft.fieldsPurelyMixedInNotOverridingAccessor) { - if (cmoft.inlinedMembersFromShapes.contains(field)) { - val member = _N4MemberDecl(field); - ifcDecl.ownedMembersRaw += member; - state.info.setOriginalDefinedMember(member, field); - } - } - } - - def private dispatch void transformClassifierDecl(N4ClassDeclaration classDecl) { - val tClass = state.info.getOriginalDefinedType(classDecl); - val cmoft = typeAssistant.getOrCreateCMOFT(tClass); - - // add delegates to methods consumed from a nominal interface - val consumedMethods = cmoft.ownedAndMixedInConcreteMembers.filter(TMethod).filter[m|m.eContainer!==tClass].toList; - for(m : consumedMethods) { - val member = delegationAssistant.createDelegatingMember(tClass, m); - if (!isInStructuralInterface(m)) { - state.info.markAsConsumedFromInterface(member); - } - classDecl.ownedMembersRaw += member; - } - - // add delegates to getters/setters consumed from a nominal interface - for(accTuple : cmoft.concreteAccessorTuples) { - if(accTuple.getter!==null && accTuple.getter.containingType!==tClass && accTuple.inheritedGetter===null) { - val g = accTuple.getter; - val member = delegationAssistant.createDelegatingMember(tClass, g); - if (!isInStructuralInterface(accTuple.getter)) { - state.info.markAsConsumedFromInterface(member); - } - classDecl.ownedMembersRaw += member; - } - if(accTuple.setter!==null && accTuple.setter.containingType!==tClass && accTuple.inheritedSetter===null) { - val s = accTuple.setter; - val member = delegationAssistant.createDelegatingMember(tClass, s); - if (!isInStructuralInterface(accTuple.setter)) { - state.info.markAsConsumedFromInterface(member); - } - classDecl.ownedMembersRaw += member; - } - } - - // add fields consumed from a nominal interface - for(field : cmoft.fieldsPurelyMixedInNotOverridingAccessor) { - val member = _N4MemberDecl(field); - classDecl.ownedMembersRaw += member; - state.info.setOriginalDefinedMember(member, field); - if (!cmoft.inlinedMembersFromShapes.contains(field)) { - state.info.markAsConsumedFromInterface(member); - } - } - - - // add delegates to inherited fields/getters/setters shadowed by an owned setter XOR getter - // NOTE: Partial shadowing in general is disallowed by validation. However, in incomplete - // API-impl situation we still support this feature here to propagate generated stubs for - // test reporting-purposes. - // MOVED: the actual implementation moved to the {@link org.eclipse.n4js.transpiler.es.transform.ApiImplStubGenerationTransformation} class - // the following code will issue errors if such a 'forbidden' case is still encountered: - for(accTuple : cmoft.concreteAccessorTuples) { - if(accTuple.inheritedGetter!==null && accTuple.getter===null && accTuple.setter!==null) { - // an owned setter is shadowing an inherited getter -> delegate to the inherited getter - logger.error("Encountered an invalid getter shadowing. Setter "+accTuple.setter.name+ - " of classifier "+accTuple.setter.containingType+"", new IllegalStateException("Invalid shadowing of inherited getter. Getter should be implemented explicitly.")) - } - if(accTuple.inheritedSetter!==null && accTuple.getter!==null && accTuple.setter===null) { - // an owned getter is shadowing an inherited setter -> delegate to the inherited setter - logger.error("Encountered an invalid inherited setter shadowing. Getter "+accTuple.getter.name+ - " of classifier "+accTuple.getter.containingType+"", new IllegalStateException("Invalid shadowing of inherited setter. Setter should be implemented explicitly.")) - } - } - } - - // Note: Structural interfaces do not appear in the output code. Hence they must be consumed by the classes/interfaces that implement them. - def private boolean isInStructuralInterface(TMember member) { - return member.eContainer instanceof TInterface - && (member.eContainer as TInterface).typingStrategy === TypingStrategy.STRUCTURAL - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleSpecifierTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleSpecifierTransformation.java new file mode 100644 index 0000000000..ca8ee2a596 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleSpecifierTransformation.java @@ -0,0 +1,243 @@ +/** + * Copyright (c) 2021 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.transpiler.es.transform; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.ModuleSpecifierForm; +import org.eclipse.n4js.packagejson.projectDescription.ProjectType; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.utils.DeclMergingUtils; +import org.eclipse.n4js.utils.N4JSLanguageHelper; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.ResourceNameComputer; +import org.eclipse.n4js.utils.URIUtils; +import org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot; +import org.eclipse.n4js.workspace.WorkspaceAccess; +import org.eclipse.n4js.workspace.utils.N4JSPackageName; + +import com.google.common.base.Strings; +import com.google.inject.Inject; + +/** + * Converts the module specifiers of import statements from N4JS to ES6. + *

+ * For details, see {@link #computeModuleSpecifierForOutputCode(ImportDeclaration)}. + */ +public class ModuleSpecifierTransformation extends Transformation { + + @Inject + private WorkspaceAccess workspaceAccess; + + @Inject + private ResourceNameComputer resourceNameComputer; + + @Inject + private N4JSLanguageHelper n4jsLanguageHelper; + + private String[] localModulePath = null; // will be set in #analyze() + private Map definedModuleSpecifierRewrites = null; // will be set in #analyze() + + @Override + public void assertPreConditions() { + // true + } + + @Override + public void assertPostConditions() { + // true + } + + @Override + public void analyze() { + TModule localModule = getState().resource.getModule(); + String localModuleSpecifier = resourceNameComputer.getCompleteModuleSpecifier(localModule); + String[] localModuleSpecifierSegments = localModuleSpecifier.split("/", -1); + localModulePath = Arrays.copyOf(localModuleSpecifierSegments, localModuleSpecifierSegments.length - 1); + definedModuleSpecifierRewrites = getState().project.getProjectDescription() + .getGeneratorRewriteModuleSpecifiers(); + } + + @Override + public void transform() { + // adjust module specifiers in imports + for (ImportDeclaration id : collectNodes(getState().im, ImportDeclaration.class, false)) { + transformImportDecl(id); + } + + } + + /** Returns file extension of output module */ + protected String getActualFileExtension(TModule targetModule) { + return n4jsLanguageHelper.getOutputFileExtension(getState().index, targetModule); + } + + private void transformImportDecl(ImportDeclaration importDeclIM) { + String definedRewrite = definedModuleSpecifierRewrites.get(importDeclIM.getModuleSpecifierAsText()); + if (definedRewrite != null) { + // special case: a rewrite for this module specifier was defined in the package.json + importDeclIM.setModuleSpecifierAsText(definedRewrite); + return; + } + + String moduleSpecifier = computeModuleSpecifierForOutputCode(importDeclIM); + String moduleSpecifierNormalized = moduleSpecifier.replace("/./", "/"); + importDeclIM.setModuleSpecifierAsText(moduleSpecifierNormalized); + } + + /** + * For the following reasons, we cannot simply reuse the module specifier from the N4JS source code in the generated + * output code: + *

    + *
  1. in N4JS, module specifiers are always absolute whereas in plain Javascript module specifiers must be relative + * (i.e. start with a segment '.' or '..') when importing from a module within the same npm package. N4JS does not + * even support relative module specifiers. + *
  2. in N4JS, the project name as the first segment of an absolute module specifier is optional (see + * {@link ModuleSpecifierForm#PLAIN} vs. {@link ModuleSpecifierForm#COMPLETE}); this is not supported by plain + * Javascript. + *
  3. in N4JS, module specifiers do not contain the path to the output folder, whereas in plain Javascript absolute + * module specifiers must always contain the full path from a project's root folder to the module. + *
  4. in N4JS, module specifiers do not include file extensions; in Javascript executed with node's native support + * for ES6 modules, file extensions are mandatory (note: this was not the case when using "esm" for handling ES6 + * modules). + *
+ * Importing from a runtime library is an exception to the above: in this case we must never include the runtime + * library's project name nor its path to the output folder in the module specifier. + */ + private String computeModuleSpecifierForOutputCode(ImportDeclaration importDeclIM) { + TModule targetModule = getState().info.getImportedModule(importDeclIM); + + if (URIUtils.isVirtualResourceURI(targetModule.eResource().getURI()) + && !DeclMergingUtils.isModuleAugmentation(targetModule)) { + // SPECIAL CASE #1a + // pointing to a module explicitly declared in a .d.ts file, such as a node built-in library: + // import * as path_lib from "path" + // --> always use plain module specifier + return targetModule.getModuleSpecifier(); // no file extension to add! + } + + N4JSProjectConfigSnapshot targetProject = workspaceAccess.findProjectContaining(targetModule); + if (targetProject.getType() == ProjectType.RUNTIME_LIBRARY) { + // SPECIAL CASE #1b + // pointing to a module in a runtime library, such as importing a node built-in library: + // import * as path_lib from "path" + // --> always use plain module specifier + return targetModule.getModuleSpecifier(); // no file extension to add! + } + + boolean importingFromModuleInSameProject = Objects.equals(targetProject.getPathAsFileURI(), getState().project + .getPathAsFileURI()); + if (importingFromModuleInSameProject) { + // SPECIAL CASE #2 + // module specifiers are always absolute in N4JS, but Javascript requires relative module + // specifiers when importing from a module within the same npm package + // --> need to create a relative module specifier here: + return createRelativeModuleSpecifier(targetModule); + } + + ModuleSpecifierForm moduleSpecifierForm = importDeclIM.getModuleSpecifierForm(); + if (moduleSpecifierForm == ModuleSpecifierForm.PROJECT + || moduleSpecifierForm == ModuleSpecifierForm.PROJECT_NO_MAIN) { + // SPECIAL CASE #3 + // in case of project imports (a.k.a. bare imports) we simply use + // the target project's name as module specifier: + return getActualProjectName(targetProject).getRawName(); // no file extension to add! + } else if (moduleSpecifierForm == ModuleSpecifierForm.PROJECT_EXPORTS) { + // SPECIAL CASE #4 + // in case of project exports imports (defined by package.json property 'exports') we simply use + // the original module specifier: + return importDeclIM.getModuleSpecifierAsText(); + } + + return createAbsoluteModuleSpecifier(targetProject, targetModule); + } + + private String createRelativeModuleSpecifier(TModule targetModule) { + String targetModuleSpecifier = resourceNameComputer.getCompleteModuleSpecifier(targetModule); + String[] targetModuleSpecifierSegments = targetModuleSpecifier.split("/", -1); + String targetModuleName = targetModuleSpecifierSegments[targetModuleSpecifierSegments.length - 1]; + String[] targetModulePath = Arrays.copyOf(targetModuleSpecifierSegments, + targetModuleSpecifierSegments.length - 1); + int l = Math.min(targetModulePath.length, localModulePath.length); + int i = 0; + while (i < l && Objects.equals(targetModulePath[i], localModulePath[i])) { + i++; + } + String[] differingSegments = Arrays.copyOfRange(targetModulePath, i, targetModulePath.length); + List allSegm = new ArrayList<>(Arrays.asList(differingSegments)); + allSegm.add(targetModuleName); + int goUpCount = localModulePath.length - i; + String ext = getActualFileExtension(targetModule); + String result = ((goUpCount > 0) ? "../".repeat(goUpCount) : "./") + + org.eclipse.n4js.utils.Strings.join("/", allSegm) + + ((ext != null && !ext.isEmpty()) ? "." + ext : ""); + return result; + } + + private String createAbsoluteModuleSpecifier(N4JSProjectConfigSnapshot targetProject, TModule targetModule) { + if (N4JSLanguageUtils.isMainModule(targetProject, targetModule)) { + // 'targetModule' is the main module of 'targetProject', so we can use a project import: + return getActualProjectName(targetProject).toString(); + } + + StringBuilder sb = new StringBuilder(); + + // first segment is the project name + N4JSPackageName targetProjectName = getActualProjectName(targetProject); + if (targetProjectName != null) { + sb.append(targetProjectName); + } + + // followed by the path to the output folder + String outputPath = targetProject.getOutputPath(); + if (!Strings.isNullOrEmpty(outputPath)) { + if (!outputPath.startsWith("/")) { + sb.append("/"); + } + sb.append(outputPath); + if (!outputPath.endsWith("/")) { + sb.append("/"); + } + } else { + if (sb.length() > 0) { + sb.append("/"); + } + } + + // and finally the target module's FQN (i.e. the path-to-module) + String targetModuleSpecifier = resourceNameComputer.getCompleteModuleSpecifier(targetModule); + sb.append(targetModuleSpecifier); + + String ext = getActualFileExtension(targetModule); + if (ext != null && !ext.isEmpty()) { + sb.append('.'); + sb.append(ext); + } + + return sb.toString(); + } + + private N4JSPackageName getActualProjectName(N4JSProjectConfigSnapshot project) { + if (project.getType() == ProjectType.DEFINITION) { + N4JSPackageName definedProjectName = project.getDefinesPackage(); + if (definedProjectName != null && !definedProjectName.isEmpty()) { + return definedProjectName; + } + } + return new N4JSPackageName(project.getPackageName()); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleSpecifierTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleSpecifierTransformation.xtend deleted file mode 100644 index 345282c496..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleSpecifierTransformation.xtend +++ /dev/null @@ -1,226 +0,0 @@ -/** - * Copyright (c) 2021 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.transpiler.es.transform - -import com.google.common.base.Joiner -import com.google.inject.Inject -import java.util.Arrays -import java.util.Map -import java.util.Objects -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.ModuleSpecifierForm -import org.eclipse.n4js.packagejson.projectDescription.ProjectType -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.utils.DeclMergingUtils -import org.eclipse.n4js.utils.N4JSLanguageHelper -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.ResourceNameComputer -import org.eclipse.n4js.utils.URIUtils -import org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot -import org.eclipse.n4js.workspace.WorkspaceAccess -import org.eclipse.n4js.workspace.utils.N4JSPackageName - -/** - * Converts the module specifiers of import statements from N4JS to ES6. - *

- * For details, see {@link #computeModuleSpecifierForOutputCode(ImportDeclaration)}. - */ -class ModuleSpecifierTransformation extends Transformation { - - @Inject - private WorkspaceAccess workspaceAccess; - - @Inject - private ResourceNameComputer resourceNameComputer; - - @Inject - private N4JSLanguageHelper n4jsLanguageHelper; - - private String[] localModulePath = null; // will be set in #analyze() - private Map definedModuleSpecifierRewrites = null; // will be set in #analyze() - - override assertPreConditions() { - // true - } - - override assertPostConditions() { - // true - } - - override analyze() { - val localModule = state.resource.module; - val localModuleSpecifier = resourceNameComputer.getCompleteModuleSpecifier(localModule); - val localModuleSpecifierSegments = localModuleSpecifier.split("/", -1); - localModulePath = Arrays.copyOf(localModuleSpecifierSegments, localModuleSpecifierSegments.length - 1); - definedModuleSpecifierRewrites = state.project.projectDescription.generatorRewriteModuleSpecifiers; - } - - override transform() { - // adjust module specifiers in imports - collectNodes(state.im, ImportDeclaration, false).forEach[transformImportDecl]; - } - - def private void transformImportDecl(ImportDeclaration importDeclIM) { - val definedRewrite = definedModuleSpecifierRewrites.get(importDeclIM.moduleSpecifierAsText); - if (definedRewrite !== null) { - // special case: a rewrite for this module specifier was defined in the package.json - importDeclIM.moduleSpecifierAsText = definedRewrite; - return; - } - - val moduleSpecifier = computeModuleSpecifierForOutputCode(importDeclIM); - val moduleSpecifierNormalized = moduleSpecifier.replace("/./", "/"); - importDeclIM.moduleSpecifierAsText = moduleSpecifierNormalized; - } - - /** - * For the following reasons, we cannot simply reuse the module specifier from the N4JS source code - * in the generated output code: - *

    - *
  1. in N4JS, module specifiers are always absolute whereas in plain Javascript module specifiers - * must be relative (i.e. start with a segment '.' or '..') when importing from a module within the - * same npm package. N4JS does not even support relative module specifiers. - *
  2. in N4JS, the project name as the first segment of an absolute module specifier is optional - * (see {@link ModuleSpecifierForm#PLAIN} vs. {@link ModuleSpecifierForm#COMPLETE}); this is not - * supported by plain Javascript. - *
  3. in N4JS, module specifiers do not contain the path to the output folder, whereas in plain - * Javascript absolute module specifiers must always contain the full path from a project's root - * folder to the module. - *
  4. in N4JS, module specifiers do not include file extensions; in Javascript executed with node's - * native support for ES6 modules, file extensions are mandatory (note: this was not the case when - * using "esm" for handling ES6 modules). - *
- * Importing from a runtime library is an exception to the above: in this case we must never include - * the runtime library's project name nor its path to the output folder in the module specifier. - */ - def private String computeModuleSpecifierForOutputCode(ImportDeclaration importDeclIM) { - val targetModule = state.info.getImportedModule(importDeclIM); - - if (URIUtils.isVirtualResourceURI(targetModule.eResource.URI) && !DeclMergingUtils.isModuleAugmentation(targetModule)) { - // SPECIAL CASE #1a - // pointing to a module explicitly declared in a .d.ts file, such as a node built-in library: - // import * as path_lib from "path" - // --> always use plain module specifier - return targetModule.moduleSpecifier; // no file extension to add! - } - - val targetProject = workspaceAccess.findProjectContaining(targetModule); - if (targetProject.type === ProjectType.RUNTIME_LIBRARY) { - // SPECIAL CASE #1b - // pointing to a module in a runtime library, such as importing a node built-in library: - // import * as path_lib from "path" - // --> always use plain module specifier - return targetModule.moduleSpecifier; // no file extension to add! - } - - val importingFromModuleInSameProject = targetProject.pathAsFileURI == state.project.pathAsFileURI; - if (importingFromModuleInSameProject) { - // SPECIAL CASE #2 - // module specifiers are always absolute in N4JS, but Javascript requires relative module - // specifiers when importing from a module within the same npm package - // --> need to create a relative module specifier here: - return createRelativeModuleSpecifier(targetModule); - } - - val moduleSpecifierForm = importDeclIM.moduleSpecifierForm; - if (moduleSpecifierForm === ModuleSpecifierForm.PROJECT - || moduleSpecifierForm === ModuleSpecifierForm.PROJECT_NO_MAIN) { - // SPECIAL CASE #3 - // in case of project imports (a.k.a. bare imports) we simply use - // the target project's name as module specifier: - return getActualProjectName(targetProject).rawName; // no file extension to add! - } else if (moduleSpecifierForm === ModuleSpecifierForm.PROJECT_EXPORTS) { - // SPECIAL CASE #4 - // in case of project exports imports (defined by package.json property 'exports') we simply use - // the original module specifier: - return importDeclIM.moduleSpecifierAsText - } - - return createAbsoluteModuleSpecifier(targetProject, targetModule); - } - - def private String createRelativeModuleSpecifier(TModule targetModule) { - val targetModuleSpecifier = resourceNameComputer.getCompleteModuleSpecifier(targetModule); - val targetModuleSpecifierSegments = targetModuleSpecifier.split("/", -1); - val targetModuleName = targetModuleSpecifierSegments.last(); - val targetModulePath = Arrays.copyOf(targetModuleSpecifierSegments, targetModuleSpecifierSegments.length - 1); - val l = Math.min(targetModulePath.length, localModulePath.length); - var i = 0; - while (i < l && Objects.equals(targetModulePath.get(i), localModulePath.get(i))) { - i++; - } - val differingSegments = Arrays.copyOfRange(targetModulePath, i, targetModulePath.length); - val goUpCount = localModulePath.length - i; - val ext = getActualFileExtension(targetModule); - val result = (if (goUpCount > 0) "../".repeat(goUpCount) else "./") - + Joiner.on("/").join(differingSegments + #[targetModuleName]) - + (if (ext !== null && !ext.empty) "." + ext else ""); - return result; - } - - def protected String createAbsoluteModuleSpecifier(N4JSProjectConfigSnapshot targetProject, TModule targetModule) { - if (N4JSLanguageUtils.isMainModule(targetProject, targetModule)) { - // 'targetModule' is the main module of 'targetProject', so we can use a project import: - return getActualProjectName(targetProject).toString(); - } - - val sb = new StringBuilder(); - - // first segment is the project name - val targetProjectName = getActualProjectName(targetProject); - if (targetProjectName !== null) { - sb.append(targetProjectName); - } - - // followed by the path to the output folder - var outputPath = targetProject.outputPath; - if (!outputPath.isNullOrEmpty) { - if (!outputPath.startsWith('/')) { - sb.append('/'); - } - sb.append(outputPath); - if (!outputPath.endsWith('/')) { - sb.append('/'); - } - } else { - if (sb.length > 0) { - sb.append('/'); - } - } - - // and finally the target module's FQN (i.e. the path-to-module) - val targetModuleSpecifier = resourceNameComputer.getCompleteModuleSpecifier(targetModule); - sb.append(targetModuleSpecifier); - - val ext = getActualFileExtension(targetModule); - if (ext !== null && !ext.empty) { - sb.append('.'); - sb.append(ext); - } - - return sb.toString(); - } - - def protected String getActualFileExtension(TModule targetModule) { - return n4jsLanguageHelper.getOutputFileExtension(state.index, targetModule); - } - - def protected N4JSPackageName getActualProjectName(N4JSProjectConfigSnapshot project) { - if (project.type === ProjectType.DEFINITION) { - val definedProjectName = project.definesPackage; - if (definedProjectName !== null && !definedProjectName.isEmpty) { - return definedProjectName; - } - } - return new N4JSPackageName(project.packageName); - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleWrappingTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleWrappingTransformation.java new file mode 100644 index 0000000000..34766b2042 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleWrappingTransformation.java @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2019 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.isEmpty; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; + +import org.eclipse.n4js.N4JSGlobals; +import org.eclipse.n4js.n4JS.ExportDeclaration; +import org.eclipse.n4js.n4JS.ExportableElement; +import org.eclipse.n4js.n4JS.ModifiableElement; +import org.eclipse.n4js.n4JS.VariableBinding; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.VariableStatement; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; + +/** + * This transformation will prepare the output code for module loading. Since dropping support for commonjs and SystemJS + * and instead using ECMAScript 2015 imports/exports in the output code, this transformation is no longer doing much. + */ +public class ModuleWrappingTransformation extends Transformation { + + @Override + public void assertPreConditions() { + // true + } + + @Override + public void assertPostConditions() { + // true + } + + @Override + public void analyze() { + // nothing + } + + @Override + public void transform() { + // strip modifiers off all exported elements + // (e.g. remove "public" from something like "export public let a = 'hello';") + + for (ModifiableElement me : filter(map(collectNodes(getState().im, ExportDeclaration.class, false), + ed -> ed.getExportedElement()), ModifiableElement.class)) { + + me.getDeclaredModifiers().clear(); + } + + // the following is only required because earlier transformations are producing + // invalid "export default var|let|const ..." + // TODO instead of the next line, change the earlier transformations to not produce these invalid constructs + for (ExportDeclaration ed : collectNodes(getState().im, ExportDeclaration.class, false)) { + splitDefaultExportFromVarDecl(ed); + } + + // add implicit import of "n4js-runtime" + addEmptyImport(N4JSGlobals.N4JS_RUNTIME.getRawName()); + } + + /** + * Turns + * + *
+	 * export default var|let|const C = ...
+	 * 
+ * + * into + * + *
+	 * var|let|const C = ...
+	 * export default C;
+	 * 
+ */ + private void splitDefaultExportFromVarDecl(ExportDeclaration exportDecl) { + if (exportDecl.isDefaultExport()) { + ExportableElement exportedElement = exportDecl.getExportedElement(); + if (exportedElement instanceof VariableStatement) { + VariableStatement variableStatement = (VariableStatement) exportedElement; + if (!isEmpty(filter(variableStatement.getVarDeclsOrBindings(), VariableBinding.class))) { + throw new UnsupportedOperationException("unsupported: default-exported variable binding"); + } + if (variableStatement.getVarDeclsOrBindings().size() > 1) { + throw new UnsupportedOperationException( + "unsupported: several default-exported variable declarations in a single export declaration"); + } + VariableDeclaration varDecl = (VariableDeclaration) variableStatement.getVarDeclsOrBindings().get(0); + SymbolTableEntry varDeclSTE = findSymbolTableEntryForElement(varDecl, true); + insertBefore(exportDecl, variableStatement); // will remove exportedElement from exportDecl + exportDecl.setDefaultExportedExpression(_IdentRef(varDeclSTE)); + } + } + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleWrappingTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleWrappingTransformation.xtend deleted file mode 100644 index 817db39397..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleWrappingTransformation.xtend +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright (c) 2019 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.transpiler.es.transform - -import org.eclipse.n4js.N4JSGlobals -import org.eclipse.n4js.n4JS.ExportDeclaration -import org.eclipse.n4js.n4JS.ModifiableElement -import org.eclipse.n4js.n4JS.VariableBinding -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.n4JS.VariableStatement -import org.eclipse.n4js.transpiler.Transformation - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - * This transformation will prepare the output code for module loading. Since dropping support for commonjs and SystemJS - * and instead using ECMAScript 2015 imports/exports in the output code, this transformation is no longer doing much. - */ -class ModuleWrappingTransformation extends Transformation { - - override assertPreConditions() { - // true - } - - override assertPostConditions() { - // true - } - - override analyze() { - // nothing - } - - override transform() { - // strip modifiers off all exported elements - // (e.g. remove "public" from something like "export public let a = 'hello';") - collectNodes(state.im, ExportDeclaration, false).map[exportedElement].filter(ModifiableElement).forEach [ - it.declaredModifiers.clear - ]; - - // the following is only required because earlier transformations are producing - // invalid "export default var|let|const ..." - // TODO instead of the next line, change the earlier transformations to not produce these invalid constructs - collectNodes(state.im, ExportDeclaration, false).forEach[splitDefaultExportFromVarDecl]; - - // add implicit import of "n4js-runtime" - addEmptyImport(N4JSGlobals.N4JS_RUNTIME.rawName); - } - - /** - * Turns - *
-	 * export default var|let|const C = ...
-	 * 
- * into - *
-	 * var|let|const C = ...
-	 * export default C;
-	 * 
- */ - def private void splitDefaultExportFromVarDecl(ExportDeclaration exportDecl) { - if (exportDecl.isDefaultExport) { - val exportedElement = exportDecl.exportedElement; - if (exportedElement instanceof VariableStatement) { - if (!exportedElement.varDeclsOrBindings.filter(VariableBinding).isEmpty) { - throw new UnsupportedOperationException("unsupported: default-exported variable binding"); - } - if (exportedElement.varDeclsOrBindings.size > 1) { - throw new UnsupportedOperationException( - "unsupported: several default-exported variable declarations in a single export declaration"); - } - val varDecl = exportedElement.varDeclsOrBindings.head as VariableDeclaration; - val varDeclSTE = findSymbolTableEntryForElement(varDecl, true); - insertBefore(exportDecl, exportedElement); // will remove exportedElement from exportDecl - exportDecl.defaultExportedExpression = _IdentRef(varDeclSTE); - } - } - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/RestParameterTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/RestParameterTransformation.java new file mode 100644 index 0000000000..1845b87180 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/RestParameterTransformation.java @@ -0,0 +1,111 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Block; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IdentRef; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._IntLiteral; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableDeclaration; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableStatement; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.List; + +import org.eclipse.n4js.generator.GeneratorOption; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.VariableStatement; +import org.eclipse.n4js.transpiler.AbstractTranspiler; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.TransformationDependency.Optional; +import org.eclipse.n4js.transpiler.TransformationDependency.RequiresBefore; +import org.eclipse.xtext.EcoreUtil2; + +/** + * Transforms ES2015 rest parameters to an ES5 equivalent. + * + * Dependencies: + *
    + *
  • requiresBefore {@link ArrowFunction_Part1_Transformation}:
    + * the transpiled output code for varargs requires the implicit local arguments variable, which is not available in + * arrow functions; therefore, this transformation relies on arrow functions already having been transformed into + * ordinary function expressions. + *
  • requiresBefore {@link BlockTransformation}:
    + * the block transformation sometimes wraps the entire body into a newly created function (for async functions); the + * handling of varargs added below must NOT be wrapped in such an inner function; the easiest way to ensure this is to + * execute BlockTransformation before this transformation. + *
+ */ +@Optional(GeneratorOption.RestParameters) +@RequiresBefore({ ArrowFunction_Part1_Transformation.class, BlockTransformation.class }) +public class RestParameterTransformation extends Transformation { + + @Override + public void assertPreConditions() { + // + } + + @Override + public void assertPostConditions() { + if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { + // as a result of this transformation no rest parameter should be found in the entire model. + List allFormalParameter = EcoreUtil2.eAllOfType(getState().im, FormalParameter.class); + List stillVariadic = toList(filter(allFormalParameter, fp -> fp.isVariadic())); + assertTrue("no rest parameter should be in the model.", stillVariadic.size() == 0); + } + } + + @Override + public void analyze() { + // + } + + @Override + public void transform() { + for (FunctionDefinition fd : collectNodes(getState().im, FunctionDefinition.class, true)) { + transform(fd); + } + } + + private void transform(FunctionDefinition fdef) { + if (fdef.getFpars().isEmpty()) { + return; + } + + int lastFparIdx = fdef.getFpars().size() - 1; + FormalParameter lastFpar = fdef.getFpars().get(lastFparIdx); + + if (!lastFpar.isVariadic()) { + return; // nothing to be done + } + + // rewrite fpar-list. + VariableStatement stmt = _VariableStatement(); + VariableDeclaration varDecl = _VariableDeclaration(lastFpar.getName()); + ParameterizedCallExpression callExpr = _CallExpr( + // Array.prototype.slice.call(arguments, 2); + _PropertyAccessExpr(steFor_Array(), steFor_prototype(), steFor_Array_slice(), steFor_Function_call()), + _IdentRef(steFor_arguments()), + _IntLiteral(lastFparIdx)); + varDecl.setExpression(callExpr); + stmt.getVarDeclsOrBindings().add(varDecl); + + if (fdef.getBody() == null) { + fdef.setBody(_Block()); + } + replaceAndRelocate(lastFpar, stmt, stmt.getVarDecl().get(0), fdef.getBody()); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/RestParameterTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/RestParameterTransformation.xtend deleted file mode 100644 index b105997066..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/RestParameterTransformation.xtend +++ /dev/null @@ -1,94 +0,0 @@ -/** - * 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.transpiler.es.transform - -import org.eclipse.n4js.n4JS.FormalParameter -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.transpiler.AbstractTranspiler -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.TransformationDependency.Optional -import org.eclipse.n4js.transpiler.TransformationDependency.RequiresBefore -import org.eclipse.xtext.EcoreUtil2 - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - * Transforms ES2015 rest parameters to an ES5 equivalent. - * - * Dependencies: - *
    - *
  • requiresBefore {@link ArrowFunction_Part1_Transformation}:
    - * the transpiled output code for varargs requires the implicit local arguments variable, which is not available in - * arrow functions; therefore, this transformation relies on arrow functions already having been transformed into - * ordinary function expressions. - *
  • requiresBefore {@link BlockTransformation}:
    - * the block transformation sometimes wraps the entire body into a newly created function (for async functions); - * the handling of varargs added below must NOT be wrapped in such an inner function; the easiest way to ensure this - * is to execute BlockTransformation before this transformation. - *
- */ -@Optional(RestParameters) -@RequiresBefore(ArrowFunction_Part1_Transformation, BlockTransformation) -class RestParameterTransformation extends Transformation { - - - override assertPreConditions() { - // - } - - override assertPostConditions() { - if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { - // as a result of this transformation no rest parameter should be found in the entire model. - val allFormalParameter = EcoreUtil2.eAllOfType(state.im, FormalParameter); - val stillVariadic = allFormalParameter.filter[it.isVariadic].toList; - assertTrue("no rest parameter should be in the model.", stillVariadic.size === 0); - } - } - - - override analyze() { - // - } - - override transform() { - collectNodes(state.im, FunctionDefinition, true).forEach[it.transform]; - } - - def private void transform(FunctionDefinition fdef) { - if (fdef.fpars.isEmpty) { - return; - } - - val lastFparIdx = fdef.fpars.size - 1; - val lastFpar = fdef.fpars.get(lastFparIdx); - - if (!lastFpar.isVariadic) { - return; // nothing to be done - } - - // rewrite fpar-list. - val stmt = _VariableStatement() => [ - varDeclsOrBindings += _VariableDeclaration(lastFpar.name) => [ - it.expression = _CallExpr( - // Array.prototype.slice.call(arguments, 2); - _PropertyAccessExpr(steFor_Array, steFor_prototype, steFor_Array_slice, steFor_Function_call), - _IdentRef(steFor_arguments), - _IntLiteral(lastFparIdx) - ); - ]; - ]; - - if (fdef.body === null) { - fdef.body = _Block(); - } - replaceAndRelocate(lastFpar, stmt, stmt.varDecl.get(0), fdef.body) - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.java new file mode 100644 index 0000000000..eebfe197e2 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.java @@ -0,0 +1,193 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.map; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.toSet; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.tooling.organizeImports.ScriptDependencyResolver; +import org.eclipse.n4js.transpiler.AbstractTranspiler; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.im.IdentifierRef_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.transpiler.utils.TranspilerUtils; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.Strings; +import org.eclipse.xtext.EcoreUtil2; + +/** + * Transformation to clean up imports: + *
    + *
  • add missing imports, + *
  • remove unused import statements. + *
+ */ +public class SanitizeImportsTransformation extends Transformation { + + @Override + public void analyze() { + // empty + } + + @Override + public void assertPreConditions() { + if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { + assertTrue("requires a fully resolved script", getState().im.isFlaggedUsageMarkingFinished()); + } + } + + @Override + public void assertPostConditions() { + if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { + // no import with flag used in code = false contained. + Iterable unusedImports = filter( + EcoreUtil2.getAllContentsOfType(getState().im, ImportSpecifier.class), is -> !isUsed(is)); + assertTrue("There should not be any unused import." + + " Unused=" + Strings.join(",", unusedImports), !unusedImports.iterator().hasNext()); + } + } + + @Override + public void transform() { + addMissingImplicitImports(); + removeUnusedImports(); + } + + /** + * Compute imports for globally defined elements in other resources on the projects dependencies and add them iff + * missing. + */ + private void addMissingImplicitImports() { + + // Current use-case is use of Variable in global-scope. + // The variable needs the defining module to be executed, hence a + + // collect all elements that are referenced from within the current module + Set referencedSTEs = toSet(filter(map(filter( + getState().im.eAllContents(), IdentifierRef_IM.class), idRef -> idRef.getId_IM()), + SymbolTableEntryOriginal.class)); + + // explanation for filters in previous lines: + // (1) reason why it is legal to filter out all ReferencingElement_IMs that aren't IdentifierRef_IM: + // * ParameterizedTypeRef_IM => type references won't show up in target code anyway -> no import required + // * ParameterizedPropertyAccessExpression_IM => here, the referenced element is a member -> members need not be + // imported + // (2) reason why it is legal to filter out all STEs that aren't SymbolTableEntryOriginal: + // * SymbolTableEntryInternal => low-level stuff, no imports required (at least not imports that work like N4JS + // imports) + // * SymbolTableEntryIMOnly => stuff programmatically created in IM -> need not be imported (defined locally) + + // filter out those that do not require an import (e.g. built-in, provided by runtime, etc.) + TModule baseModule = getState().resource.getModule(); + Iterable requiresImport = filter(referencedSTEs, + ste -> ScriptDependencyResolver.shouldBeImported(baseModule, ste.getOriginalTarget())); + + // look for already given imports: + Iterable thingsToImportSTE = requiresImport; + { + // The Question is, if the variable was already imported, then + // a) do we still see it here and b) if so, was the import flagged by usedInCode ? + + // It turns out, that current scoping as of Dec'2015 doesn't bind to imports to globally available + // definitions. + // Assuming a) no + b) irrelevant for a==no + for (SymbolTableEntryOriginal ste : thingsToImportSTE) { + if (ste.getImportSpecifier() == null) { + IdentifiableElement orig = ste.getOriginalTarget(); + // for an element to be globally available, there are two preconditions: + // (1) containing module must be annotated with @@Global (2) element must be directly exported + if (N4JSLanguageUtils.isDirectlyExported(orig)) { + TModule module = orig.getContainingModule(); + if (AnnotationDefinition.GLOBAL.hasAnnotation(module)) { + addNamedImport(ste, null); + } + } + } + } + } + } + + private void removeUnusedImports() { + List unusedImports = toList( + filter(EcoreUtil2.getAllContentsOfType(getState().im, ImportSpecifier.class), is -> !isUsed(is))); + + for (Iterator iter = unusedImports.iterator(); iter.hasNext();) { + ImportSpecifier is = iter.next(); + + ImportDeclaration container = (ImportDeclaration) is.eContainer(); + EObject toBeRemoved = (container.getImportSpecifiers().size() == 1 + && container.getImportSpecifiers().contains(is)) + ? + // remove container if import-specifier is last child. + container + : + // remove import-specifier + is; + + remove(toBeRemoved); + } + } + + private boolean isUsed(ImportSpecifier importSpec) { + if (importSpec.isFlaggedUsedInCode() == false) { + // was already unused in original N4JS code (and we expect transformations to update this flag if they + // add new usages of an existing import) + // -> therefore simply return false (i.e. unused) + return false; + } else { + // for performance reasons, we do not require the flaggedUsedInCode to be set to false if usages are removed + // -> therefore have to check for references now + SymbolTableEntryOriginal ste = null; + + if (importSpec instanceof NamedImportSpecifier) { + ste = findSymbolTableEntryForNamedImport((NamedImportSpecifier) importSpec); + } else if (importSpec instanceof NamespaceImportSpecifier) { + ste = findSymbolTableEntryForNamespaceImport((NamespaceImportSpecifier) importSpec); + } + + if (ste == null) { + // this may happen in case of several NamedImportSpecifiers importing the same IdentifiableElement + // (which is a validation error in most cases, but the validation misses some corner cases) + return false; + } + + // note: here it is not enough to return !ste.referencingElements.empty, because for performance reasons + // transformations are not required to remove obsolete entries from that list + boolean hasReference = exists(ste.getReferencingElements(), + refElem -> TranspilerUtils.isIntermediateModelElement(refElem)); + if (hasReference) { + // we have an actual reference to the imported element + // -> whether the import is deemed "used" depends on whether that original target actually requires + // an import (will be false in case of elements globally provided by runtime, etc.) + IdentifiableElement target = ste.getOriginalTarget(); + return target != null + && ScriptDependencyResolver.shouldBeImported(getState().resource.getModule(), target); + } + return false; + } + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.xtend deleted file mode 100644 index cf3f21df18..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.xtend +++ /dev/null @@ -1,171 +0,0 @@ -/** - * 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.transpiler.es.transform - -import com.google.common.base.Joiner -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.ImportSpecifier -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.tooling.organizeImports.ScriptDependencyResolver -import org.eclipse.n4js.transpiler.AbstractTranspiler -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.im.IdentifierRef_IM -import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal -import org.eclipse.n4js.transpiler.utils.TranspilerUtils -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.xtext.EcoreUtil2 - -/** - * Transformation to clean up imports: - *
    - *
  • add missing imports, - *
  • remove unused import statements. - *
- */ -class SanitizeImportsTransformation extends Transformation { - - override analyze() { - } - - override assertPreConditions() { - if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { - assertTrue("requires a fully resolved script", state.im.flaggedUsageMarkingFinished); - } - } - - override assertPostConditions() { - if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { - // no import with flag used in code = false contained. - val unusedImports = EcoreUtil2.getAllContentsOfType( state.im, ImportSpecifier ).filter[!isUsed].toList; - assertTrue( "There should not be any unused import." - +" Unused="+ Joiner.on(",").join(unusedImports) - , unusedImports.size === 0 - ); - } - } - - override transform() { - addMissingImplicitImports(); - removeUnusedImports(); - } - - /** - * Compute imports for globally defined elements in other resources on the projects dependencies and - * add them iff missing. - */ - private def addMissingImplicitImports(){ - - // Current use-case is use of Variable in global-scope. - // The variable needs the defining module to be executed, hence a - - // collect all elements that are referenced from within the current module - val referencedSTEs = state.im.eAllContents.filter(IdentifierRef_IM) - .map[id_IM] - .filter(SymbolTableEntryOriginal) - .toSet; - // explanation for filters in previous lines: - // (1) reason why it is legal to filter out all ReferencingElement_IMs that aren't IdentifierRef_IM: - // * ParameterizedTypeRef_IM => type references won't show up in target code anyway -> no import required - // * ParameterizedPropertyAccessExpression_IM => here, the referenced element is a member -> members need not be imported - // (2) reason why it is legal to filter out all STEs that aren't SymbolTableEntryOriginal: - // * SymbolTableEntryInternal => low-level stuff, no imports required (at least not imports that work like N4JS imports) - // * SymbolTableEntryIMOnly => stuff programmatically created in IM -> need not be imported (defined locally) - - // filter out those that do not require an import (e.g. built-in, provided by runtime, etc.) - val baseModule = state.resource.module; - val requiresImport = referencedSTEs.filter[ScriptDependencyResolver.shouldBeImported(baseModule, originalTarget)]; - - - // look for already given imports: - val thingsToImportSTE = requiresImport; - { - // The Question is, if the variable was already imported, then - // a) do we still see it here and b) if so, was the import flagged by usedInCode ? - - // It turns out, that current scoping as of Dec'2015 doesn't bind to imports to globally available definitions. - // Assuming a) no + b) irrelevant for a==no - for (ste : thingsToImportSTE) { - if( ste.importSpecifier === null ) { - val orig = ste.originalTarget; - // for an element to be globally available, there are two preconditions: - // (1) containing module must be annotated with @@Global (2) element must be directly exported - if(N4JSLanguageUtils.isDirectlyExported(orig)) { - val module = orig.containingModule; - if(AnnotationDefinition.GLOBAL.hasAnnotation(module)) { - addNamedImport(ste,null); - } - } - } - } - } - } - - - private def removeUnusedImports(){ - - val unusedImports = EcoreUtil2.getAllContentsOfType( state.im, ImportSpecifier ).filter[!isUsed].toList - - for( val iter = unusedImports.iterator; iter.hasNext; ){ - val is = iter.next; - - val ImportDeclaration container = is.eContainer as ImportDeclaration - val toBeRemoved = if( container.importSpecifiers.size === 1 && container.importSpecifiers.contains( is )) { - // remove container if import-specifier is last child. - container - } else { - // remove import-specifier - is - }; - - remove( toBeRemoved ) - - } - - } - - - def private boolean isUsed(ImportSpecifier importSpec) { - if(importSpec.flaggedUsedInCode===false) { - // was already unused in original N4JS code (and we expect transformations to update this flag if they - // add new usages of an existing import) - // -> therefore simply return false (i.e. unused) - return false; - } else { - // for performance reasons, we do not require the flaggedUsedInCode to be set to false if usages are removed - // -> therefore have to check for references now - val ste = if(importSpec instanceof NamedImportSpecifier) { - findSymbolTableEntryForNamedImport(importSpec) - } else if(importSpec instanceof NamespaceImportSpecifier) { - findSymbolTableEntryForNamespaceImport(importSpec) - }; - - if (ste === null) { - // this may happen in case of several NamedImportSpecifiers importing the same IdentifiableElement - // (which is a validation error in most cases, but the validation misses some corner cases) - return false; - } - - // note: here it is not enough to return !ste.referencingElements.empty, because for performance reasons - // transformations are not required to remove obsolete entries from that list - val hasReference = ste.referencingElements.exists[TranspilerUtils.isIntermediateModelElement(it)]; - if(hasReference) { - // we have an actual reference to the imported element - // -> whether the import is deemed "used" depends on whether that original target actually requires - // an import (will be false in case of elements globally provided by runtime, etc.) - val target = ste.originalTarget; - return target!==null && ScriptDependencyResolver.shouldBeImported(state.resource.module, target); - } - return false; - } - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SimplifyTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SimplifyTransformation.java new file mode 100644 index 0000000000..45c02af56c --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SimplifyTransformation.java @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2020 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteral; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.stringTypeRef; + +import java.util.List; + +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName; +import org.eclipse.n4js.n4JS.PropertyNameKind; +import org.eclipse.n4js.n4JS.StringLiteral; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.UnknownTypeRef; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.utils.N4JSLanguageUtils; + +import com.google.inject.Inject; + +/** + * Performs various simplifications of the output code. This should run rather late to have those simplifications be + * applied to the results of, i.e. code generated by, the main transformations. + */ +public class SimplifyTransformation extends Transformation { + + @Inject + private N4JSTypeSystem ts; + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + List nodes = collectNodes(getState().im, LiteralOrComputedPropertyName.class, + false); + for (LiteralOrComputedPropertyName locpn : nodes) { + simplify(locpn); + } + } + + private void simplify(LiteralOrComputedPropertyName name) { + // simplify { ["name"+1]: ... } to { ["name1"]: ... } + if (name.getKind() == PropertyNameKind.COMPUTED + && isOfTypeStringInAST(name.getExpression())) { + + replace(name.getExpression(), _StringLiteral(name.getComputedName())); + } + + // simplify { ["name"]: ... } to { "name": ... } + if (name.getKind() == PropertyNameKind.COMPUTED && name.getExpression() instanceof StringLiteral) { + + name.setKind(PropertyNameKind.STRING); + name.setLiteralName(name.getComputedName()); + name.setComputedName(null); + remove(name.getExpression()); + } + + // simplify { "name": ... } to { name: ... } (iff 'name' is a valid identifier) + if (name.getKind() == PropertyNameKind.STRING + && name.getLiteralName() != null + && N4JSLanguageUtils.isValidIdentifier(name.getLiteralName())) { + + name.setKind(PropertyNameKind.IDENTIFIER); + } + } + + /** + * Returns true iff the given expression has a corresponding expression in the original AST and that expression in + * the AST is of type 'string'. Returns false in all error cases. + *

+ * Does not support expressions created by earlier transformations (i.e. without original AST node); returns false + * in those cases. + */ + private boolean isOfTypeStringInAST(Expression expressionInIM) { + Expression expressionInAST = getState().tracer.getOriginalASTNodeOfSameType(expressionInIM, false); + if (expressionInAST != null) { + TypeRef typeRef = ts.type(getState().G, expressionInAST); + if (!(typeRef instanceof UnknownTypeRef)) { + return ts.subtypeSucceeded(getState().G, typeRef, stringTypeRef(getState().G)); + } + } + return false; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SimplifyTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SimplifyTransformation.xtend deleted file mode 100644 index bcc8744f88..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SimplifyTransformation.xtend +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright (c) 2020 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.transpiler.es.transform - -import com.google.inject.Inject -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName -import org.eclipse.n4js.n4JS.PropertyNameKind -import org.eclipse.n4js.n4JS.StringLiteral -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.ts.typeRefs.UnknownTypeRef -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.utils.N4JSLanguageUtils - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * Performs various simplifications of the output code. This should run rather late to have - * those simplifications be applied to the results of, i.e. code generated by, the main transformations. - */ -class SimplifyTransformation extends Transformation { - - @Inject - private N4JSTypeSystem ts; - - override assertPreConditions() { - } - - override assertPostConditions() { - } - - override analyze() { - // ignore - } - - override transform() { - collectNodes(state.im, LiteralOrComputedPropertyName, false).forEach[simplify(it)]; - } - - def private void simplify(LiteralOrComputedPropertyName name) { - // simplify { ["name"+1]: ... } to { ["name1"]: ... } - if (name.kind === PropertyNameKind.COMPUTED - && isOfTypeStringInAST(name.expression)) { - - replace(name.expression, _StringLiteral(name.computedName)); - } - - // simplify { ["name"]: ... } to { "name": ... } - if (name.kind === PropertyNameKind.COMPUTED - && name.expression instanceof StringLiteral) { - - name.kind = PropertyNameKind.STRING; - name.literalName = name.computedName; - name.computedName = null; - remove(name.expression); - } - - // simplify { "name": ... } to { name: ... } (iff 'name' is a valid identifier) - if (name.kind === PropertyNameKind.STRING - && name.literalName !== null - && N4JSLanguageUtils.isValidIdentifier(name.literalName)) { - - name.kind = PropertyNameKind.IDENTIFIER; - } - } - - /** - * Returns true iff the given expression has a corresponding expression in the original AST and - * that expression in the AST is of type 'string'. Returns false in all error cases. - *

- * Does not support expressions created by earlier transformations (i.e. without original AST node); - * returns false in those cases. - */ - def private boolean isOfTypeStringInAST(Expression expressionInIM) { - val expressionInAST = state.tracer.getOriginalASTNodeOfSameType(expressionInIM, false); - if (expressionInAST !== null) { - val typeRef = ts.type(state.G, expressionInAST); - if (!(typeRef instanceof UnknownTypeRef)) { - return ts.subtypeSucceeded(state.G, typeRef, state.G.stringTypeRef); - } - } - return false; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/StaticPolyfillTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/StaticPolyfillTransformation.java new file mode 100644 index 0000000000..0b7aad908a --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/StaticPolyfillTransformation.java @@ -0,0 +1,278 @@ +/** + * 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._DefaultImportSpecifier; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ImportDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._NamedImportSpecifier; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._NamespaceImportSpecifier; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._TypeReferenceNode; +import static org.eclipse.n4js.utils.N4JSLanguageUtils.isContainedInStaticPolyfillAware; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.flatten; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.N4JSGlobals; +import org.eclipse.n4js.n4JS.DefaultImportSpecifier; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4ClassDefinition; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.resource.N4JSResource; +import org.eclipse.n4js.tooling.organizeImports.ScriptDependencyResolver; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.assistants.TypeAssistant; +import org.eclipse.n4js.transpiler.im.ReferencingElement_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TEnumLiteral; +import org.eclipse.n4js.ts.types.TInterface; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.utils.StaticPolyfillHelper; +import org.eclipse.n4js.utils.URIUtils; +import org.eclipse.xtext.EcoreUtil2; + +import com.google.inject.Inject; + +/** + */ +public class StaticPolyfillTransformation extends Transformation { + + @Inject + private StaticPolyfillHelper staticPolyfillHelper; + @Inject + private TypeAssistant typeAssistant; + + /** + * While inserting members into classes, we add here the elements referenced in the initializer expressions, fpar + * default expressions and bodies. + */ + private final Set referencedElements = new HashSet<>(); + /** + * Each referenced element for which we add an import gets its own alias. This set is used to keep track of those + * aliases (mainly when creating a new, unique alias). + */ + private final Set referencedElementsAliases = new HashSet<>(); + + @Override + public void assertPreConditions() { + // none + } + + @Override + public void assertPostConditions() { + // none + } + + @Override + public void analyze() { + // nothing + } + + @Override + public void transform() { + boolean isAware = isContainedInStaticPolyfillAware(getState().resource.getScript()); + if (isAware) { + N4JSResource fillingResource = staticPolyfillHelper.getStaticPolyfillResource(getState().resource); + if (fillingResource != null) { + referencedElements.clear(); + for (N4ClassDeclaration cd : collectNodes(getState().im, N4ClassDeclaration.class, false)) { + doStaticPolyfilling(cd); + } + for (SymbolTableEntryOriginal steo : referencedElements) { + addImportIfRequired(steo, fillingResource); + } + } + } + } + + private void doStaticPolyfilling(N4ClassDeclaration classDecl) { + TClass defCls = getState().info.getOriginalDefinedType(classDecl); + N4ClassDeclaration filler = staticPolyfillHelper.getStaticPolyfill(defCls); + if (filler != null) { + doStaticPolyfilling(classDecl, filler); + } + } + + private void doStaticPolyfilling(N4ClassDeclaration classFilled, N4ClassDeclaration classFiller) { + // fill additionally implemented interfaces + Set currentIfcs = new HashSet<>(); + for (TypeReferenceNode trn : classFilled.getImplementedInterfaceRefs()) { + TypeRef origTRef = getState().info.getOriginalProcessedTypeRef(trn); + if (origTRef != null && origTRef.getDeclaredType() instanceof TInterface) { + currentIfcs.add((TInterface) origTRef.getDeclaredType()); + } + } + for (TypeReferenceNode trn : classFiller.getImplementedInterfaceRefs()) { + Type origType = typeAssistant.getOriginalDeclaredType(trn); + if (origType instanceof TInterface) { + insertImplementedInterface(classFilled, (TInterface) origType, currentIfcs); + } + } + // fill members + for (N4MemberDeclaration member : classFiller.getOwnedMembers()) { + insertMember(classFilled, member); + } + } + + private void insertImplementedInterface(N4ClassDefinition classFilled, TInterface ifcToBeInserted, + Set currentIfcs) { + if (!currentIfcs.contains(ifcToBeInserted)) { // avoid duplicates! + classFilled.getImplementedInterfaceRefs() + .add(_TypeReferenceNode(getState(), TypeUtils.createTypeRef(ifcToBeInserted))); + } + } + + /** + * Create and insert a copy of memberToBeInserted into classFilled. + * + * @param classFilled + * the class declaration to be filled, must be contained in the intermediate model. + * @param memberToBeInserted + * this member is expected to be contained in the AST of the filling resource, so this is neither + * contained in the original AST (of the resource to compile) nor the intermediate model! + */ + private void insertMember(N4ClassDefinition classFilled, N4MemberDeclaration memberToBeInserted) { + N4MemberDeclaration existing = findFirst(classFilled.getOwnedMembers(), + member -> member.eClass() == memberToBeInserted.eClass() + && Objects.equals(member.getName(), memberToBeInserted.getName())); + + N4MemberDeclaration copy = copyAlienElement(memberToBeInserted); + // store elements that are referenced from within this member + // (e.g. from within the body, from initializer expressions of fields, from default expressions of fpars, etc.) + for (ReferencingElement_IM refElem : EcoreUtil2.eAllOfType(copy, ReferencingElement_IM.class)) { + if (refElem.getRewiredTarget() instanceof SymbolTableEntryOriginal) { + referencedElements.add((SymbolTableEntryOriginal) refElem.getRewiredTarget()); + } + } + + if (existing != null) { + replace(existing, copy); + } else { + classFilled.getOwnedMembersRaw().add(copy); + } + getState().info.setOriginalDefinedMember(copy, memberToBeInserted.getDefinedTypeElement()); + } + + private void addImportIfRequired(SymbolTableEntryOriginal ste, N4JSResource fillingResource) { + if (ste.getImportSpecifier() == null) { + IdentifiableElement originalTarget = ste.getOriginalTarget(); + boolean isNested = originalTarget instanceof TMember || originalTarget instanceof TEnumLiteral; + if (!isNested + || N4JSGlobals.DTS_FILE_EXTENSION + .equals(URIUtils.fileExtension(originalTarget.eResource().getURI()))) { + boolean isLocal = originalTarget.eResource() == getState().resource; + if (!isLocal + && ScriptDependencyResolver.shouldBeImported(fillingResource.getModule(), originalTarget)) { + addImport(ste, fillingResource); + } + } + } + } + + /** + * Add an import for the element represented by the given SymbolTableEntry in the intermediate model. + */ + private void addImport(SymbolTableEntryOriginal ste, N4JSResource fillingResource) { + IdentifiableElement importedElement = ste.getOriginalTarget(); + boolean isNamespace = importedElement instanceof ModuleNamespaceVirtualType; + + // search original import specification (in original AST of fillingResource) + Iterable impSpecs = flatten(map(filter( + fillingResource.getScript().getScriptElements(), ImportDeclaration.class), + id -> id.getImportSpecifiers())); + ImportSpecifier impSpec_original = (isNamespace) + ? findFirst(filter(impSpecs, NamespaceImportSpecifier.class), + nis -> nis.getDefinedType() == importedElement) + : findFirst(filter(impSpecs, NamedImportSpecifier.class), + nis -> nis.getImportedElement() == importedElement); + EObject impDecl_original = impSpec_original == null ? null : impSpec_original.eContainer(); + + // if all this was successful, go ahead and add the import ... + if (impDecl_original instanceof ImportDeclaration) { + ImportDeclaration impDeclCasted = (ImportDeclaration) impDecl_original; + String aliasName = getAlias(impSpec_original) != null + ? getAlias(impSpec_original) + : ste.getExportedName() != null + ? ste.getExportedName() + : "unnamed"; + String alias = chooseNewUniqueAlias(aliasName); + ImportSpecifier impSpec; + if (isNamespace) { + impSpec = _NamespaceImportSpecifier(alias, true); + } else if (impSpec_original instanceof DefaultImportSpecifier) { + impSpec = _DefaultImportSpecifier(alias, true); + } else { + impSpec = _NamedImportSpecifier(ste.getExportedName(), alias, true); + } + + // obtain module from which we import importedElement + TModule remoteModule = (isNamespace) ? + // warning: in case of namespaces, importedElement resides in the TModule of the fillingResource! + // -> so we cannot just get the containing TModule in this case + ((ModuleNamespaceVirtualType) importedElement).getModule() + : + // standard case: just find the containing TModule of importedElement + impDeclCasted.getModule(); + + ImportDeclaration impDecl = _ImportDecl(impSpec); + impDecl.setModuleSpecifierForm(impDeclCasted.getModuleSpecifierForm()); + getState().im.getScriptElements().add(0, impDecl); + ste.setName(alias); + ste.setImportSpecifier(impSpec); + getState().tracer.setOriginalASTNode(impDecl, impDeclCasted); + getState().tracer.setOriginalASTNode(impSpec, impSpec_original); + // store the imported module in information registry + // (required my ModuleWrappingTransformation) + getState().info.setImportedModule(impDecl, remoteModule); + } + } + + private String chooseNewUniqueAlias(String baseName) { + String alias; + int cnt = 0; + do { + String cntStr = (cnt == 0) ? "" : Integer.toString(cnt); + alias = baseName + cntStr + "$polyfilled"; + cnt++; + } while (referencedElementsAliases.contains(alias)); + referencedElementsAliases.add(alias); + return alias; + } + + private static final String getAlias(ImportSpecifier impSpec) { + if (impSpec instanceof NamedImportSpecifier) { + return ((NamedImportSpecifier) impSpec).getAlias(); + } + + if (impSpec instanceof NamespaceImportSpecifier) { + return ((NamespaceImportSpecifier) impSpec).getAlias(); + } + return null; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/StaticPolyfillTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/StaticPolyfillTransformation.xtend deleted file mode 100644 index 09e6fe1aee..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/StaticPolyfillTransformation.xtend +++ /dev/null @@ -1,217 +0,0 @@ -/** - * 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.transpiler.es.transform - -import com.google.inject.Inject -import java.util.Set -import org.eclipse.n4js.N4JSGlobals -import org.eclipse.n4js.n4JS.DefaultImportSpecifier -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.ImportSpecifier -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.n4JS.N4ClassDefinition -import org.eclipse.n4js.n4JS.N4MemberDeclaration -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.resource.N4JSResource -import org.eclipse.n4js.tooling.organizeImports.ScriptDependencyResolver -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.assistants.TypeAssistant -import org.eclipse.n4js.transpiler.im.ReferencingElement_IM -import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType -import org.eclipse.n4js.ts.types.TEnumLiteral -import org.eclipse.n4js.ts.types.TInterface -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.utils.StaticPolyfillHelper -import org.eclipse.n4js.utils.URIUtils - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.utils.N4JSLanguageUtils.* - -/** - */ -class StaticPolyfillTransformation extends Transformation { - - @Inject private StaticPolyfillHelper staticPolyfillHelper; - @Inject private TypeAssistant typeAssistant; - - /** - * While inserting members into classes, we add here the elements referenced in the initializer expressions, fpar - * default expressions and bodies. - */ - private Set referencedElements = newHashSet; - /** - * Each referenced element for which we add an import gets its own alias. This set is used to keep track of those - * aliases (mainly when creating a new, unique alias). - */ - private Set referencedElementsAliases = newHashSet; - - - override assertPreConditions() { - // none - } - - override assertPostConditions() { - // none - } - - override analyze() { - // nothing - } - - override transform() { - val isAware = state.resource.script.isContainedInStaticPolyfillAware; - if(isAware) { - val fillingResource = staticPolyfillHelper.getStaticPolyfillResource(state.resource); - if(fillingResource!==null) { - referencedElements.clear(); - collectNodes(state.im, N4ClassDeclaration, false).forEach[doStaticPolyfilling]; - referencedElements.forEach[addImportIfRequired(fillingResource)]; - } - } - } - - def private void doStaticPolyfilling(N4ClassDeclaration classDecl) { - val defCls = state.info.getOriginalDefinedType(classDecl); - val filler = staticPolyfillHelper.getStaticPolyfill(defCls); - if(filler!==null) { - doStaticPolyfilling(classDecl, filler); - } - } - - def private void doStaticPolyfilling(N4ClassDeclaration classFilled, N4ClassDeclaration classFiller) { - // fill additionally implemented interfaces - val currentIfcs = classFilled.implementedInterfaceRefs.map[state.info.getOriginalProcessedTypeRef(it)?.declaredType].filterNull.filter(TInterface).toSet; - classFiller.implementedInterfaceRefs - .map[typeAssistant.getOriginalDeclaredType(it)] - .filter(TInterface) - .forEach[classFilled.insertImplementedInterface(it, currentIfcs)]; - // fill members - classFiller.ownedMembers.forEach[classFilled.insertMember(it)]; - } - - def private void insertImplementedInterface(N4ClassDefinition classFilled, TInterface ifcToBeInserted, - Set currentIfcs) { - if(!currentIfcs.contains(ifcToBeInserted)) { // avoid duplicates! - classFilled.implementedInterfaceRefs += _TypeReferenceNode(state, TypeUtils.createTypeRef(ifcToBeInserted)); - } - } - - /** - * Create and insert a copy of memberToBeInserted into classFilled. - * - * @param classFilled the class declaration to be filled, must be contained in the intermediate model. - * @param memberToBeInserted this member is expected to be contained in the AST of the filling resource, so this is - * neither contained in the original AST (of the resource to compile) nor the intermediate model! - */ - def private void insertMember(N4ClassDefinition classFilled, N4MemberDeclaration memberToBeInserted) { - val existing = classFilled.ownedMembers.findFirst[ - eClass===memberToBeInserted.eClass && name==memberToBeInserted.name - ]; - val copy = copyAlienElement(memberToBeInserted); - // store elements that are referenced from within this member - // (e.g. from within the body, from initializer expressions of fields, from default expressions of fpars, etc.) - referencedElements += copy.eAllContents.filter(ReferencingElement_IM).map[rewiredTarget].filter(SymbolTableEntryOriginal).toList; - if(existing!==null) { - replace(existing, copy); - } else { - classFilled.ownedMembersRaw += copy; - } - state.info.setOriginalDefinedMember(copy, memberToBeInserted.definedTypeElement); - } - - def private void addImportIfRequired(SymbolTableEntryOriginal ste, N4JSResource fillingResource) { - if(ste.importSpecifier===null) { - val originalTarget = ste.originalTarget; - val isNested = originalTarget instanceof TMember || originalTarget instanceof TEnumLiteral; - if(!isNested || N4JSGlobals.DTS_FILE_EXTENSION == URIUtils.fileExtension(originalTarget.eResource.URI)) { - val isLocal = originalTarget.eResource === state.resource; - if(!isLocal && ScriptDependencyResolver.shouldBeImported(fillingResource.module, originalTarget)) { - addImport(ste, fillingResource); - } - } - } - } - - /** - * Add an import for the element represented by the given SymbolTableEntry in the intermediate model. - */ - def private void addImport(SymbolTableEntryOriginal ste, N4JSResource fillingResource) { - val importedElement = ste.originalTarget; - val isNamespace = importedElement instanceof ModuleNamespaceVirtualType; - - // search original import specification (in original AST of fillingResource) - val impSpecs = fillingResource.script.scriptElements.filter(ImportDeclaration).map[importSpecifiers].flatten; - val impSpec_original = if(isNamespace) { - impSpecs.filter(NamespaceImportSpecifier).findFirst[definedType===importedElement] - } else { - impSpecs.filter(NamedImportSpecifier).findFirst[it.importedElement===importedElement] - }; - val impDecl_original = impSpec_original?.eContainer; - - - // if all this was successful, go ahead and add the import ... - if(impDecl_original instanceof ImportDeclaration) { - val alias = chooseNewUniqueAlias(impSpec_original.alias ?: ste.exportedName ?: "unnamed"); - val impSpec = if(isNamespace) { - _NamespaceImportSpecifier(alias, true) - } else if (impSpec_original instanceof DefaultImportSpecifier) { - _DefaultImportSpecifier(alias, true) - } else { - _NamedImportSpecifier(ste.exportedName, alias, true) - }; - - // obtain module from which we import importedElement - val remoteModule = if(isNamespace) { - // warning: in case of namespaces, importedElement resides in the TModule of the fillingResource! - // -> so we cannot just get the containing TModule in this case - (importedElement as ModuleNamespaceVirtualType).module - } else { - // standard case: just find the containing TModule of importedElement - impDecl_original.module - }; - - val impDecl = _ImportDecl(impSpec); - impDecl.moduleSpecifierForm = impDecl_original.moduleSpecifierForm; - state.im.scriptElements.add(0, impDecl); - ste.name = alias; - ste.importSpecifier = impSpec; - state.tracer.setOriginalASTNode(impDecl, impDecl_original); - state.tracer.setOriginalASTNode(impSpec, impSpec_original); - // store the imported module in information registry - // (required my ModuleWrappingTransformation) - state.info.setImportedModule(impDecl, remoteModule); - } - } - - def private String chooseNewUniqueAlias(String baseName) { - var String alias; - var cnt = 0; - do { - val cntStr = if(cnt===0) "" else Integer.toString(cnt); - alias = baseName + cntStr + "$polyfilled"; - cnt++; - } while(referencedElementsAliases.contains(alias)); - referencedElementsAliases.add(alias); - return alias; - } - - def private static final String getAlias(ImportSpecifier impSpec) { - return switch(impSpec) { - NamedImportSpecifier: impSpec.alias - NamespaceImportSpecifier: impSpec.alias - }; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TemplateStringTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TemplateStringTransformation.java new file mode 100644 index 0000000000..a1ed513985 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TemplateStringTransformation.java @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2017 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.transpiler.es.transform; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._AdditiveExpression; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrLit; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Parenthesis; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteral; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.generator.GeneratorOption; +import org.eclipse.n4js.n4JS.AdditiveOperator; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ParameterizedAccess; +import org.eclipse.n4js.n4JS.PrimaryExpression; +import org.eclipse.n4js.n4JS.StringLiteral; +import org.eclipse.n4js.n4JS.TaggedTemplateString; +import org.eclipse.n4js.n4JS.TemplateLiteral; +import org.eclipse.n4js.n4JS.TemplateSegment; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.TransformationDependency.Optional; +import org.eclipse.n4js.utils.parser.conversion.ValueConverterUtils; + +import com.google.common.collect.Lists; + +/** + * Transforms ES2015 template literals to a corresponding ES5 equivalent. + */ +@Optional(GeneratorOption.TemplateStringLiterals) +public class TemplateStringTransformation extends Transformation { + + @Override + public void assertPreConditions() { + // true + } + + @Override + public void assertPostConditions() { + // true + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + for (TemplateLiteral tl : collectNodes(getState().im, TemplateLiteral.class, true)) { + transformTemplateLiteral(tl); + } + } + + private void transformTemplateLiteral(TemplateLiteral template) { + EObject parent = template.eContainer(); + if (parent instanceof TaggedTemplateString) { + transformTaggedTemplateLiteral((TaggedTemplateString) parent, template); + } else { + transformPlainTemplateLiteral(template); + } + } + + private void transformTaggedTemplateLiteral(TaggedTemplateString taggedTemplate, TemplateLiteral template) { + // (1) collect string segments and expression segments + List stringSegments = new ArrayList<>(); + List expressionSegments = new ArrayList<>(); + for (Expression segment : Lists.newArrayList(template.getSegments())) { // avoid concurrent modification + if (segment instanceof TemplateSegment) { + TemplateSegment tSegm = (TemplateSegment) segment; + stringSegments.add(_StringLiteral(tSegm.getValueAsString(), wrapAndQuote(tSegm.getValueAsString()))); + } else { + expressionSegments.add(segment); + } + } + // (2) transform the tagged template literal (invoke the tag function with the segments as arguments) + Expression[] wrappedExprs = wrapIfRequired(expressionSegments); + Expression[] args = new Expression[1 + expressionSegments.size()]; + args[0] = _ArrLit(stringSegments.toArray(new Expression[0])); + for (int i = 0; i < wrappedExprs.length; i++) { + args[i + 1] = wrappedExprs[i]; + } + Expression replacement = _CallExpr( + taggedTemplate.getTarget(), + taggedTemplate.isOptionalChaining(), + args); + replace(taggedTemplate, replacement); + } + + private void transformPlainTemplateLiteral(TemplateLiteral template) { + // (1) transform contained template segments to string literals + for (Expression segment : Lists.newArrayList(template.getSegments())) { // avoid concurrent modification + if (segment instanceof TemplateSegment) { + TemplateSegment tSegm = (TemplateSegment) segment; + replace(segment, _StringLiteral(tSegm.getValueAsString(), wrapAndQuote(tSegm.getValueAsString()))); + } else { + // the segment is an ordinary expression -> leave without change + } + } + // (2) transform template literal itself + Expression replacement; + switch (template.getSegments().size()) { + case 0: + replacement = _StringLiteral(""); + break; + case 1: + replacement = template.getSegments().get(0); + break; + default: + replacement = _Parenthesis( + _AdditiveExpression(AdditiveOperator.ADD, wrapIfRequired(template.getSegments()))); + } + replace(template, replacement); + } + + private static Expression[] wrapIfRequired(List expressions) { + // required due to possible concurrent modification (see below) + List copy = new ArrayList<>(); + for (Expression expr : expressions) { + boolean needParentheses = !(expr instanceof PrimaryExpression || expr instanceof ParameterizedAccess); + if (needParentheses) { + // this might change iterable 'expressions' (if an EMF containment reference was passed in) + copy.add(_Parenthesis(expr)); + } else { + copy.add(expr); + } + } + return copy.toArray(new Expression[0]); + } + + /** + * put raw into double quote and escape all existing double-quotes {@code '"' -> '\"' } and newlines + * {@code '\n' -> '\\n'}. + */ + private static String wrapAndQuote(String raw) { + return '"' + ValueConverterUtils.convertToEscapedString(raw, true) + '"'; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TemplateStringTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TemplateStringTransformation.xtend deleted file mode 100644 index 69ffb98d32..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TemplateStringTransformation.xtend +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Copyright (c) 2017 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.transpiler.es.transform - -import com.google.common.collect.Lists -import java.util.ArrayList -import org.eclipse.n4js.n4JS.AdditiveOperator -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.ParameterizedAccess -import org.eclipse.n4js.n4JS.PrimaryExpression -import org.eclipse.n4js.n4JS.TaggedTemplateString -import org.eclipse.n4js.n4JS.TemplateLiteral -import org.eclipse.n4js.n4JS.TemplateSegment -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.TransformationDependency.Optional -import org.eclipse.n4js.utils.parser.conversion.ValueConverterUtils - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -/** - * Transforms ES2015 template literals to a corresponding ES5 equivalent. - */ -@Optional(TemplateStringLiterals) -class TemplateStringTransformation extends Transformation { - - - override assertPreConditions() { - // true - } - - override assertPostConditions() { - // true - } - - - override analyze() { - // ignore - } - - override transform() { - collectNodes(state.im, TemplateLiteral, true).forEach[transformTemplateLiteral]; - } - - def private void transformTemplateLiteral(TemplateLiteral template) { - val parent = template.eContainer; - if (parent instanceof TaggedTemplateString) { - transformTaggedTemplateLiteral(parent, template); - } else { - transformPlainTemplateLiteral(template); - } - } - - def private void transformTaggedTemplateLiteral(TaggedTemplateString taggedTemplate, TemplateLiteral template) { - // (1) collect string segments and expression segments - val stringSegments = newArrayList; - val expressionSegments = newArrayList; - for(segment : Lists.newArrayList(template.segments)) { // avoid concurrent modification - if(segment instanceof TemplateSegment) { - stringSegments += _StringLiteral(segment.valueAsString, segment.valueAsString.wrapAndQuote); - } else { - expressionSegments += segment; - } - } - // (2) transform the tagged template literal (invoke the tag function with the segments as arguments) - val replacement = _CallExpr( - taggedTemplate.target, - taggedTemplate.optionalChaining, - #[ _ArrLit(stringSegments) ] + expressionSegments.wrapIfRequired - ); - replace(taggedTemplate, replacement); - } - - def private void transformPlainTemplateLiteral(TemplateLiteral template) { - // (1) transform contained template segments to string literals - for(segment : Lists.newArrayList(template.segments)) { // avoid concurrent modification - if(segment instanceof TemplateSegment) { - replace(segment, _StringLiteral(segment.valueAsString, segment.valueAsString.wrapAndQuote)); - } else { - // the segment is an ordinary expression -> leave without change - } - } - // (2) transform template literal itself - val replacement = switch(template.segments.size) { - case 0: - _StringLiteral("") - case 1: - template.segments.get(0) - default: - _Parenthesis( - _AdditiveExpression(AdditiveOperator.ADD, template.segments.wrapIfRequired) - ) - }; - replace(template, replacement); - } - - def private static Iterable wrapIfRequired(Iterable expressions) { - val copy = new ArrayList(expressions.toList); // required due to possible concurrent modification (see below) - return copy.map[expr| - val boolean needParentheses = !(expr instanceof PrimaryExpression || expr instanceof ParameterizedAccess); - if(needParentheses) { - return _Parenthesis(expr) // this might change iterable 'expressions' (if an EMF containment reference was passed in) - } else { - return expr - } - ]; - } - - /** put raw into double quote and escape all existing double-quotes {@code '"' -> '\"' } and newlines {@code '\n' -> '\\n'}. */ - def private static String wrapAndQuote(String raw){ - '"' + ValueConverterUtils.convertToEscapedString(raw, true) + '"' - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TrimTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TrimTransformation.java new file mode 100644 index 0000000000..968db166dc --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TrimTransformation.java @@ -0,0 +1,68 @@ +/** + * 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.transpiler.es.transform; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.N4TypeAliasDeclaration; +import org.eclipse.n4js.n4JS.N4TypeVariable; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.n4JS.TypedElement; +import org.eclipse.n4js.transpiler.Transformation; +import org.eclipse.n4js.transpiler.utils.TranspilerUtils; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.Type; + +/** + * Removes all nodes from the intermediate model that are not required in the final output. Since such nodes might + * provide important information to other transformations, this transformation should run rather late. + *

+ * Examples of removed stuff: + *

    + *
  • declared type references of {@link TypedElement}s + *
  • type variable references of {@link Type} + *
  • type alias declarations + *
+ * Note: cast expressions are already removed by {@link ExpressionTransformation}. + */ +public class TrimTransformation extends Transformation { + + @Override + public void assertPreConditions() { + // empty + } + + @Override + public void assertPostConditions() { + // empty + } + + @Override + public void analyze() { + // ignore + } + + @Override + public void transform() { + for (EObject node : collectNodes(getState().im, false, + TypeRef.class, + TypeReferenceNode.class, + N4TypeVariable.class, + N4TypeAliasDeclaration.class)) { + + removeNode(node); + } + } + + private void removeNode(EObject nodeInIM) { + EObject actualNodeToRemove = TranspilerUtils.orContainingExportDeclaration(nodeInIM); + remove(actualNodeToRemove); + } +} diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TrimTransformation.xtend b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TrimTransformation.xtend deleted file mode 100644 index 5e29d97b9b..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/TrimTransformation.xtend +++ /dev/null @@ -1,60 +0,0 @@ -/** - * 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.transpiler.es.transform - -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.N4TypeAliasDeclaration -import org.eclipse.n4js.n4JS.N4TypeVariable -import org.eclipse.n4js.n4JS.TypeReferenceNode -import org.eclipse.n4js.n4JS.TypedElement -import org.eclipse.n4js.transpiler.Transformation -import org.eclipse.n4js.transpiler.utils.TranspilerUtils -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.Type - -/** - * Removes all nodes from the intermediate model that are not required in the final output. Since such nodes might - * provide important information to other transformations, this transformation should run rather late. - *

- * Examples of removed stuff: - *

    - *
  • declared type references of {@link TypedElement}s - *
  • type variable references of {@link Type} - *
  • type alias declarations - *
- * Note: cast expressions are already removed by {@link ExpressionTransformation}. - */ -class TrimTransformation extends Transformation { - - - override assertPreConditions() { - } - - override assertPostConditions() { - } - - override analyze() { - // ignore - } - - override transform() { - collectNodes(state.im, false, - TypeRef, - TypeReferenceNode, - N4TypeVariable, - N4TypeAliasDeclaration).forEach[removeNode] - } - - def private removeNode(EObject nodeInIM) { - val actualNodeToRemove = TranspilerUtils.orContainingExportDeclaration(nodeInIM); - remove(actualNodeToRemove); - } -} diff --git a/plugins/org.eclipse.n4js.transpiler.es/xtend-gen/.gitignore b/plugins/org.eclipse.n4js.transpiler.es/xtend-gen/.gitignore deleted file mode 100644 index c96a04f008..0000000000 --- a/plugins/org.eclipse.n4js.transpiler.es/xtend-gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/plugins/org.eclipse.n4js.transpiler/.classpath b/plugins/org.eclipse.n4js.transpiler/.classpath index 3bc8444c24..bc000d436d 100644 --- a/plugins/org.eclipse.n4js.transpiler/.classpath +++ b/plugins/org.eclipse.n4js.transpiler/.classpath @@ -1,7 +1,6 @@ - diff --git a/plugins/org.eclipse.n4js.transpiler/build.properties b/plugins/org.eclipse.n4js.transpiler/build.properties index d9f34fffdd..0c38f4c755 100644 --- a/plugins/org.eclipse.n4js.transpiler/build.properties +++ b/plugins/org.eclipse.n4js.transpiler/build.properties @@ -1,5 +1,4 @@ source.. = src/,\ - xtend-gen/,\ emf-gen/ output.. = bin/ bin.includes = META-INF/,\ diff --git a/plugins/org.eclipse.n4js.transpiler/pom.xml b/plugins/org.eclipse.n4js.transpiler/pom.xml index 786855639e..142a1e8d89 100644 --- a/plugins/org.eclipse.n4js.transpiler/pom.xml +++ b/plugins/org.eclipse.n4js.transpiler/pom.xml @@ -41,10 +41,6 @@ Contributors: maven-resources-plugin ${maven-resources-plugin.version} - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/SymbolTableManagement.java b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/SymbolTableManagement.java new file mode 100644 index 0000000000..a67b88f9a0 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/SymbolTableManagement.java @@ -0,0 +1,484 @@ +/** + * 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.transpiler; + +import java.util.Collection; +import java.util.List; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.NamedElement; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.transpiler.im.ImFactory; +import org.eclipse.n4js.transpiler.im.ImPackage; +import org.eclipse.n4js.transpiler.im.ReferencingElement_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryIMOnly; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryInternal; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.transpiler.im.TypeReferenceNode_IM; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType; +import org.eclipse.n4js.ts.types.NameAndAccess; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TModule; + +/** + */ +public class SymbolTableManagement { + + /** + * Create a symbol table entry for a given original target (either a TModule element OR a variable in the original + * AST, in case of non-exported top-level variables, local variables, formal parameters, etc.). + */ + public static SymbolTableEntryOriginal createSymbolTableEntryOriginal(TranspilerState state, + IdentifiableElement originalTarget) { + if (originalTarget == null) { + throw new IllegalArgumentException("original target may not be null"); + } + SymbolTableEntryOriginal newEntry = ImFactory.eINSTANCE.createSymbolTableEntryOriginal(); + newEntry.setName(originalTarget.getName()); + newEntry.setOriginalTarget(originalTarget); + if (originalTarget instanceof NamedElement) { + newEntry.getElementsOfThisName().add((NamedElement) originalTarget); + } + + // if a namespace import exists for the module containing 'originalTarget', we use it for this new STE + newEntry.setImportSpecifier( + getExistingNamespaceImportSpecifierForModule(state, originalTarget.getContainingModule())); + + addOriginal(state, newEntry); + + return newEntry; + } + + private static NamespaceImportSpecifier getExistingNamespaceImportSpecifierForModule(TranspilerState state, + TModule module) { + if (module != null && state.steCache.mapImportedModule_2_STE.get(module) != null) { + ImportSpecifier importSpec = state.steCache.mapImportedModule_2_STE.get(module).getImportSpecifier(); + if (importSpec instanceof NamespaceImportSpecifier) { + return (NamespaceImportSpecifier) importSpec; + } + } + return null; + } + + /** add a {@link SymbolTableEntryOriginal} */ + static public void addOriginal(TranspilerState state, SymbolTableEntryOriginal steOriginal) { + addOriginal(state.steCache, steOriginal); + } + + /** + * NOTE: Internal usage in preparation step, please call + * {@link #addOriginal(TranspilerState,SymbolTableEntryOriginal)} + */ + static public void addOriginal(TranspilerState.STECache steCache, SymbolTableEntryOriginal steOriginal) { + + SymbolTableEntryOriginal old = steCache.mapOriginal.put(steOriginal.getOriginalTarget(), steOriginal); + if (old != null) + throw new IllegalStateException( + "It is not allowed to register more then one STEOriginal for the same original Target. Already had: " + + old); + IdentifiableElement originalTarget = steOriginal.getOriginalTarget(); + if (originalTarget instanceof ModuleNamespaceVirtualType) { + TModule namespaceModule = ((ModuleNamespaceVirtualType) originalTarget).getModule(); + if (namespaceModule != null) { + steCache.mapImportedModule_2_STE.put(namespaceModule, steOriginal); + } + } + steCache.im.getSymbolTable().getEntries().add(steOriginal); + inverseMap(steCache, steOriginal); + } + + static private void inverseMap(TranspilerState.STECache steManager, SymbolTableEntryOriginal steOriginal) { + // register elements of this name. + for (NamedElement ele : steOriginal.getElementsOfThisName()) { + steManager.mapNamedElement_2_STE.put(ele, steOriginal); + } + } + + /** + * Create a symbol table entry for an element in the intermediate model. This should only be used if the element in + * the IM does not have a corresponding original target (either a TModule element or an element in the + * original AST, in case of non-exported variables), for example because it was newly created by an AST + * transformation. + */ + public static SymbolTableEntryIMOnly createSymbolTableEntryIMOnly(TranspilerState state, NamedElement elementInIM) { + if (elementInIM == null) { + throw new IllegalArgumentException("element in intermediate model may not be null"); + } + if (elementInIM.getName() == null) { + throw new IllegalArgumentException( + "element in intermediate model may not be unnamed when creating a symbol table entry for it"); + } + SymbolTableEntryIMOnly newEntry = ImFactory.eINSTANCE.createSymbolTableEntryIMOnly(); + newEntry.setName(elementInIM.getName()); + newEntry.getElementsOfThisName().add(elementInIM); + addIMOnly(state, newEntry); + return newEntry; + } + + /** + * Create an internal symbol table entry. They are special and should be used only in rare exception cases. + * See {@link SymbolTableEntryInternal} for details. + */ + public static SymbolTableEntryInternal createSymbolTableEntryInternal(TranspilerState state, String name) { + if (name == null) { + throw new IllegalArgumentException("name may not be null"); + } + SymbolTableEntryInternal newEntry = ImFactory.eINSTANCE.createSymbolTableEntryInternal(); + newEntry.setName(name); + addInteral(state, newEntry); + return newEntry; + } + + /** add a {@link SymbolTableEntryInternal} */ + private static void addInteral(TranspilerState state, SymbolTableEntryInternal ste) { + SymbolTableEntryInternal old = state.steCache.mapInternal.put(ste.getName(), ste); + if (old != null) { + throw new IllegalStateException( + "It is not allowed to put the same SymbolTableEntryInternal twice into the Symboltable " + old); + } + state.im.getSymbolTable().getEntries().add(ste); + } + + /** + * Search an STE by original target and create it if not found. + */ + public static SymbolTableEntryOriginal getSymbolTableEntryOriginal(TranspilerState state, + IdentifiableElement originalTarget, boolean create) { + if (originalTarget == null) { + throw new IllegalArgumentException("original target may not be null"); + } + SymbolTableEntryOriginal existingEntry = getSteOriginal(state, originalTarget); + + if (existingEntry != null) { + return existingEntry; + } + if (create) { + return createSymbolTableEntryOriginal(state, originalTarget); + } + return null; + } + + /** + * Convenience method for {@link #getSymbolTableEntryOriginal(TranspilerState, IdentifiableElement, boolean)}, + * allowing to retrieve the member by name and access from its parent classifier. + */ + public static SymbolTableEntryOriginal getSymbolTableEntryForMember(TranspilerState state, TClassifier type, + String memberName, boolean writeAccess, boolean staticAccess, boolean create) { + if (type == null || memberName == null || memberName.isEmpty()) { + throw new IllegalArgumentException("type may not be null and memberName may not be null or empty"); + } + TMember m = type.findOwnedMember(memberName, writeAccess, staticAccess); + if (m == null) { + NameAndAccess nameAndAccess = new NameAndAccess(memberName, writeAccess, staticAccess); + throw new IllegalArgumentException("no such member found in given type: " + nameAndAccess); + } + return getSymbolTableEntryOriginal(state, m, create); + } + + /** + * Search an internal STE by name and create it if not found. + */ + public static SymbolTableEntryInternal getSymbolTableEntryInternal(TranspilerState state, String name, + boolean create) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("name may not be null or empty"); + } + + SymbolTableEntryInternal existingEntry = getSteInternal(state, name); + + if (existingEntry != null) { + return existingEntry; + } + if (create) { + return createSymbolTableEntryInternal(state, name); + } + return null; + } + + /** + * Will look up the STE for the given named element in the IM. If not found and create is set to + * true a {@code SymbolTableEntryIMOnly} is created, otherwise null is returned. + *

+ * WARNING: during look up it will find both {@link SymbolTableEntryOriginal}s and + * {@link SymbolTableEntryIMOnly}s, but when creating a new STE, it will always create a + * {@code SymbolTableEntryIMOnly} which is invalid if there exists an original target for the given + * elementInIM (then a {@link SymbolTableEntryOriginal} would have to be created)!. In such a case, + * this method must not be used.
+ * Most of the time, this won't be the case and it is safe to use this method, because all + * {@code SymbolTableEntryOriginal}s will be created up-front during the {@link PreparationStep}; in some special + * cases, however, a new element is introduced into the IM that actually has an original target (so far, static + * polyfills are the only case of this). + */ + public static SymbolTableEntry findSymbolTableEntryForElement(TranspilerState state, NamedElement elementInIM, + boolean create) { + if (elementInIM == null) { + throw new IllegalArgumentException("element in intermediate model may not be null"); + } + SymbolTableEntry existingEntry = byElementsOfThisName(state, elementInIM); + + if (existingEntry != null) { + return existingEntry; + } + if (create) { + return createSymbolTableEntryIMOnly(state, elementInIM); + } + return null; + } + + /** + * Search STE for the given name space import. + */ + public static SymbolTableEntryOriginal findSymbolTableEntryForNamespaceImport(TranspilerState state, + NamespaceImportSpecifier importspec) { + // 1. linear version: + // state.im.symbolTable.entries.filter(SymbolTableEntryOriginal) + // .filter[it.importSpecifier == importspec] + // .filter[it.originalTarget instanceof ModuleNamespaceVirtualType] + // .head + + // 2. parallel version: + // return state.im.symbolTable.entries.parallelStream() + // .filter[it instanceof SymbolTableEntryOriginal].map[ it as SymbolTableEntryOriginal] + // .filter[it.importSpecifier == importspec] + // .filter[it.originalTarget instanceof ModuleNamespaceVirtualType] + // .findAny().orElse(null); + + // 3. only the originals: + // Should be safe to use the cache. + for (SymbolTableEntryOriginal steo : state.steCache.mapOriginal.values()) { + if (steo.getImportSpecifier() == importspec + && steo.getOriginalTarget() instanceof ModuleNamespaceVirtualType) { + return steo; + } + } + + return null; + } + + // let's try to keep this at "package" visibility for now (but there'll probably be special cases when a + // transformation needs to rewire something special by calling this directly) + /* package */ static void rewireSymbolTable(TranspilerState state, EObject from, EObject to) { + + if (!requiresRewiringOfSymbolTable(from) && !requiresRewiringOfSymbolTable(to)) { + return; // nothing to rewire! + } + + if (from instanceof ReferencingElement_IM && to instanceof ReferencingElement_IM) { + // case 1 + EReference eRefThatMightPointToOriginal = ImPackage.eINSTANCE.getSymbolTableEntry_ReferencingElements(); + // TODO can be speed up + for (SymbolTableEntry ste : state.im.getSymbolTable().getEntries()) { + replaceInEReference(ste, eRefThatMightPointToOriginal, from, to); + } + + } else if (from instanceof ImportSpecifier && to instanceof ImportSpecifier) { + // case 2 + EReference eRefThatMightPointToOriginal = ImPackage.eINSTANCE.getSymbolTableEntryOriginal_ImportSpecifier(); + // TODO can be speed up + for (SymbolTableEntry ste : state.im.getSymbolTable().getEntries()) { + if (ste instanceof SymbolTableEntryOriginal) { + replaceInEReference(ste, eRefThatMightPointToOriginal, from, to); + } + } + + } else if (from instanceof NamedElement && to instanceof NamedElement) { + // case 3 // Most relevant case according to profiler + EReference eRefThatMightPointToOriginal = ImPackage.eINSTANCE.getSymbolTableEntry_ElementsOfThisName(); + // Slow version: + // state.im.symbolTable.entries_.forEach[ + // replaceInEReference(it, x, from, to); + // ]; + + SymbolTableEntry steFrom = byElementsOfThisName(state, (NamedElement) from); + if (steFrom != null) { + replaceInEReference(steFrom, eRefThatMightPointToOriginal, from, to); + // update STECache: + replacedElementOfThisName(state, steFrom, (NamedElement) from, (NamedElement) to); + } + } else { + throw new IllegalArgumentException("rewiring symbol table entries from type " + from.eClass().getName() + + " to type " + to.eClass().getName() + " is not supported yet"); + } + } + + private static boolean requiresRewiringOfSymbolTable(EObject obj) { + return obj instanceof ReferencingElement_IM || obj instanceof ImportSpecifier || obj instanceof NamedElement; + } + + private static void replaceInEReference(EObject obj, EReference eRef, T original, + TN replacement) { + // note: cannot use EcoreUtil#replace() here, because it throws exceptions if original is not in reference! + if (eRef.isMany()) { + @SuppressWarnings("unchecked") + EList l = (EList) obj.eGet(eRef); + for (int idx = 0; idx < l.size(); idx++) { + if (l.get(idx) == original) { + l.set(idx, replacement); + } + } + } else { + if (obj.eGet(eRef) == original) { + obj.eSet(eRef, replacement); + } + } + } + + /** add a {@link SymbolTableEntryIMOnly} */ + static public void addIMOnly(TranspilerState state, SymbolTableEntryIMOnly only) { + // assumption 1: freshly generated - always connected to a named element. (IDEBUG-777) + if (only.getElementsOfThisName().size() != 1) { + throw new IllegalArgumentException( + "got a STEImOnly with elmentsOfThisName != 1 : " + only.getElementsOfThisName().size()); + } + // assumption 2: there are no other things registered by this name. (IDEBUG-777) + SymbolTableEntry old = state.steCache.mapNamedElement_2_STE.put(only.getElementsOfThisName().get(0), only); + if (old != null) { + throw new IllegalStateException("tries to install STEImOnly but already had one for the NamedElmeent = " + + only.getElementsOfThisName().get(0)); + } + state.im.getSymbolTable().getEntries().add(only); + } + + /** lookup a {@link SymbolTableEntryIMOnly} associated to an {@link IdentifiableElement} */ + static public SymbolTableEntryOriginal getSteOriginal(TranspilerState state, IdentifiableElement element) { + return state.steCache.mapOriginal.get(element); + } + + /** lookup an {@link SymbolTableEntryInternal} based on a plain name ({@link String}) */ + static public SymbolTableEntryInternal getSteInternal(TranspilerState state, String name) { + return state.steCache.mapInternal.get(name); + } + + /** lookup a {@link SymbolTableEntry} based on a {@link NamedElement} contained in the IM */ + static public SymbolTableEntry byElementsOfThisName(TranspilerState state, NamedElement elementInIM) { + SymbolTableEntry lookup = state.steCache.mapNamedElement_2_STE.get(elementInIM); + if (lookup != null) { + if (lookup.getElementsOfThisName().contains(elementInIM)) { + return lookup; + } + throw new IllegalStateException( + "Did find STE by NamedElement which is not contained in the list STE.elementsOfThisName. elementInIM=" + + elementInIM + " found wrong STE=" + lookup); + } + + return null; + } + + /** + * Update data structure for NamedElements after the list of {@link SymbolTableEntry#getElementsOfThisName()} of + * {@code entry} has been modified + * + * @param entry + * the updated STE (wherein elmentsOfThisName has been modified to contain {@code to} instead of + * {@code from} + * @param from + * old NamedElement + * @param to + * new NamedElement + */ + static public void replacedElementOfThisName(TranspilerState state, SymbolTableEntry entry, NamedElement from, + NamedElement to) { + + // internal check: + SymbolTableEntry steRegisteredWithFrom = state.steCache.mapNamedElement_2_STE.get(from); + if (steRegisteredWithFrom != entry) + throw new IllegalArgumentException( + "This method must be called directly after the replacement and only once." + + "Expected from=" + from + " to be related to entry=" + entry + + " in mapNamedElement_2_STE but found: " + steRegisteredWithFrom); + // repair map: + state.steCache.mapNamedElement_2_STE.remove(from); + state.steCache.mapNamedElement_2_STE.put(to, entry); + } + + /***/ + static public SymbolTableEntryOriginal findSymbolTableEntryForNamedImport(TranspilerState state, + NamedImportSpecifier importspec) { + + for (SymbolTableEntryOriginal steo : state.steCache.mapOriginal.values()) { + if (steo.getImportSpecifier() == importspec) { + return steo; + } + } + return null; + } + + /** + * This method defaults to {@link #findSymbolTableEntryForNamedImport(TranspilerState, NamedImportSpecifier)}. + */ + static public Collection findSymbolTableEntriesForVersionedTypeImport( + TranspilerState state, NamedImportSpecifier importspec) { + return List.of(findSymbolTableEntryForNamedImport(state, importspec)); + } + + /** + * Records in property {@link TypeReferenceNode_IM#getRewiredReferences() rewiredReferences} that the given type + * reference node refers to the type represented by the given symbol table entry. + */ + static public void recordReferenceToType(TranspilerState state, TypeReferenceNode_IM typeRefNode, + SymbolTableEntryOriginal ste) { + + // 1) record the reference to the type represented by 'ste' itself + typeRefNode.addRewiredTarget(ste); + // 2) record the reference to the namespace iff the type represented by 'ste' was imported via a namespace + // import + ImportSpecifier importSpec = ste.getImportSpecifier(); + if (importSpec instanceof NamespaceImportSpecifier) { + ModuleNamespaceVirtualType namespaceType = state.info + .getOriginalDefinedType((NamespaceImportSpecifier) importSpec); + if (namespaceType != null) { + SymbolTableEntryOriginal namespaceSTE = getSymbolTableEntryOriginal(state, namespaceType, false); + if (namespaceSTE != null) { + typeRefNode.addRewiredTarget(namespaceSTE); + } + } + } + } + + /***/ + static public void rename(SymbolTableEntry entry, String name) { + if (entry instanceof SymbolTableEntryInternal) { + throw new UnsupportedOperationException("cannot rename internal STEs " + entry); + + } else if (entry instanceof SymbolTableEntryIMOnly) { + entry.setName(name); + + } else if (entry instanceof SymbolTableEntryOriginal) { + + entry.setName(name); + + // should do something like the following: + // (not possible at the moment, because NamedElement does not have a setter for property 'name') + // entry.elementsOfThisName.forEach[it.name=newName]; + + if (((SymbolTableEntryOriginal) entry).getImportSpecifier() != null) { + throw new UnsupportedOperationException( + "renaming of symbol table entries not tested yet for imported elements!"); + } + // should be something like the following: + // switch(impSpec) { + // NamedImportSpecifier: if(impSpec.alias!=null) impSpec.alias = newName + // NamespaceImportSpecifier: if(impSpec.alias!=null) impSpec.alias = newName + // } + } else { + throw new UnsupportedOperationException( + "Rename request for SymboltableEntries of unkown type : " + entry); + } + } + +} diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/SymbolTableManagement.xtend b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/SymbolTableManagement.xtend deleted file mode 100644 index 744a9e1ae8..0000000000 --- a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/SymbolTableManagement.xtend +++ /dev/null @@ -1,451 +0,0 @@ -/** - * 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.transpiler - -import java.util.Collection -import org.eclipse.emf.common.util.EList -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.EReference -import org.eclipse.n4js.n4JS.ImportSpecifier -import org.eclipse.n4js.n4JS.NamedElement -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.transpiler.im.ImFactory -import org.eclipse.n4js.transpiler.im.ImPackage -import org.eclipse.n4js.transpiler.im.ReferencingElement_IM -import org.eclipse.n4js.transpiler.im.SymbolTableEntry -import org.eclipse.n4js.transpiler.im.SymbolTableEntryIMOnly -import org.eclipse.n4js.transpiler.im.SymbolTableEntryInternal -import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal -import org.eclipse.n4js.transpiler.im.TypeReferenceNode_IM -import org.eclipse.n4js.ts.types.IdentifiableElement -import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType -import org.eclipse.n4js.ts.types.NameAndAccess -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TModule - -/** - */ -class SymbolTableManagement { - - /** - * Create a symbol table entry for a given original target (either a TModule element OR a variable in the original - * AST, in case of non-exported top-level variables, local variables, formal parameters, etc.). - */ - def public static SymbolTableEntryOriginal createSymbolTableEntryOriginal(TranspilerState state, IdentifiableElement originalTarget) { - if(originalTarget===null) { - throw new IllegalArgumentException("original target may not be null"); - } - val newEntry = ImFactory.eINSTANCE.createSymbolTableEntryOriginal; - newEntry.name = originalTarget.name; - newEntry.originalTarget = originalTarget; - if(originalTarget instanceof NamedElement) { - newEntry.elementsOfThisName += originalTarget as NamedElement; - } - - // if a namespace import exists for the module containing 'originalTarget', we use it for this new STE - newEntry.importSpecifier = getExistingNamespaceImportSpecifierForModule(state, originalTarget.containingModule); - - state.addOriginal(newEntry) - - return newEntry; - } - - def private static NamespaceImportSpecifier getExistingNamespaceImportSpecifierForModule(TranspilerState state, TModule module) { - if (module !== null) { - val importSpec = state.steCache.mapImportedModule_2_STE.get(module)?.importSpecifier; - if (importSpec instanceof NamespaceImportSpecifier) { - return importSpec; - } - } - return null; - } - - /** add a {@link SymbolTableEntryOriginal} */ - def static public void addOriginal(TranspilerState state, SymbolTableEntryOriginal steOriginal) { - addOriginal ( state.steCache, steOriginal ) ; - } - - /** NOTE: Internal usage in preparation step, please call {@link #addOriginal(TranspilerState,SymbolTableEntryOriginal)} */ - def static public void addOriginal(TranspilerState.STECache steCache, SymbolTableEntryOriginal steOriginal) { - - val SymbolTableEntryOriginal old = steCache.mapOriginal.put(steOriginal.getOriginalTarget(), steOriginal); - if (old !== null) - throw new IllegalStateException( - "It is not allowed to register more then one STEOriginal for the same original Target. Already had: " - + old); - val originalTarget = steOriginal.originalTarget; - if (originalTarget instanceof ModuleNamespaceVirtualType) { - val namespaceModule = originalTarget.module; - if (namespaceModule !== null) { - steCache.mapImportedModule_2_STE.put(namespaceModule, steOriginal); - } - } - steCache.im.getSymbolTable().getEntries().add(steOriginal); - steCache.inverseMap(steOriginal); - } - - - def static private void inverseMap(TranspilerState.STECache steManager, SymbolTableEntryOriginal steOriginal) { - // register elements of this name. - steOriginal.getElementsOfThisName().forEach[ele | steManager.mapNamedElement_2_STE.put(ele, steOriginal)]; - } - - - /** - * Create a symbol table entry for an element in the intermediate model. This should only be used if the element - * in the IM does not have a corresponding original target (either a TModule element or an element - * in the original AST, in case of non-exported variables), for example because it was newly created by an AST - * transformation. - */ - def public static SymbolTableEntryIMOnly createSymbolTableEntryIMOnly(TranspilerState state, NamedElement elementInIM) { - if(elementInIM===null) { - throw new IllegalArgumentException("element in intermediate model may not be null"); - } - if(elementInIM.name===null) { - throw new IllegalArgumentException("element in intermediate model may not be unnamed when creating a symbol table entry for it"); - } - val newEntry = ImFactory.eINSTANCE.createSymbolTableEntryIMOnly; - newEntry.name = elementInIM.name; - newEntry.elementsOfThisName += elementInIM; - state.addIMOnly( newEntry ); - return newEntry; - } - - /** - * Create an internal symbol table entry. They are special and should be used only in rare exception cases. - * See {@link SymbolTableEntryInternal} for details. - */ - def public static SymbolTableEntryInternal createSymbolTableEntryInternal(TranspilerState state, String name) { - if(name===null) { - throw new IllegalArgumentException("name may not be null"); - } - val newEntry = ImFactory.eINSTANCE.createSymbolTableEntryInternal; - newEntry.name = name; - state.addInteral( newEntry ); - return newEntry; - } - - - - /** add a {@link SymbolTableEntryInternal} */ - def private static void addInteral(TranspilerState state, SymbolTableEntryInternal ste) { - val SymbolTableEntryInternal old = state.steCache.mapInternal.put(ste.getName(), ste); - if (old !== null) - throw new IllegalStateException( - "It is not allowed to put the same SymbolTableEntryInternal twice into the Symboltable " + old); - state.im.getSymbolTable().getEntries().add(ste); - } - - - - /** - * Search an STE by original target and create it if not found. - */ - def public static SymbolTableEntryOriginal getSymbolTableEntryOriginal(TranspilerState state, IdentifiableElement originalTarget, boolean create) { - if(originalTarget===null) { - throw new IllegalArgumentException("original target may not be null"); - } - val existingEntry = state.getSteOriginal(originalTarget); - - if(existingEntry!==null) { - return existingEntry; - } - if(create) { - return createSymbolTableEntryOriginal(state, originalTarget); - } - return null; - } - - /** - * Convenience method for {@link #getSymbolTableEntryOriginal(TranspilerState, IdentifiableElement, boolean}, - * allowing to retrieve the member by name and access from its parent classifier. - */ - def public static SymbolTableEntryOriginal getSymbolTableEntryForMember(TranspilerState state, TClassifier type, - String memberName, boolean writeAccess, boolean staticAccess, boolean create) { - if(type===null || memberName===null || memberName.empty) { - throw new IllegalArgumentException("type may not be null and memberName may not be null or empty"); - } - val m = type.findOwnedMember(memberName, writeAccess, staticAccess); - if(m===null) { - val nameAndAccess = new NameAndAccess(memberName, writeAccess, staticAccess); - throw new IllegalArgumentException("no such member found in given type: " + nameAndAccess); - } - return getSymbolTableEntryOriginal(state, m, create); - } - - /** - * Search an internal STE by name and create it if not found. - */ - def public static SymbolTableEntryInternal getSymbolTableEntryInternal(TranspilerState state, String name, boolean create) { - if(name===null || name.empty) { - throw new IllegalArgumentException("name may not be null or empty"); - } - - val existingEntry = state.getSteInternal(name); - - if(existingEntry!==null) { - return existingEntry; - } - if(create) { - return createSymbolTableEntryInternal(state, name); - } - return null; - } - - /** - * Will look up the STE for the given named element in the IM. If not found and create is set to - * true a {@code SymbolTableEntryIMOnly} is created, otherwise null is returned. - *

- * WARNING: during look up it will find both {@link SymbolTableEntryOriginal}s and {@link SymbolTableEntryIMOnly}s, - * but when creating a new STE, it will always create a {@code SymbolTableEntryIMOnly} which is invalid if there - * exists an original target for the given elementInIM (then a {@link SymbolTableEntryOriginal} would - * have to be created)!. In such a case, this method must not be used.
- * Most of the time, this won't be the case and it is safe to use this method, because all - * {@code SymbolTableEntryOriginal}s will be created up-front during the {@link PreparationStep}; in some special - * cases, however, a new element is introduced into the IM that actually has an original target (so far, static - * polyfills are the only case of this). - */ - def public static SymbolTableEntry findSymbolTableEntryForElement(TranspilerState state, NamedElement elementInIM, boolean create) { - if(elementInIM===null) { - throw new IllegalArgumentException("element in intermediate model may not be null"); - } - val existingEntry = state.byElementsOfThisName(elementInIM); - - if(existingEntry!==null) { - return existingEntry; - } - if(create) { - return createSymbolTableEntryIMOnly(state, elementInIM); - } - return null; - } - - /** - * Search STE for the given name space import. - */ - def public static SymbolTableEntryOriginal findSymbolTableEntryForNamespaceImport(TranspilerState state, NamespaceImportSpecifier importspec) { - // 1. linear version: - // state.im.symbolTable.entries.filter(SymbolTableEntryOriginal) - // .filter[it.importSpecifier === importspec] - // .filter[it.originalTarget instanceof ModuleNamespaceVirtualType] - // .head - - // 2. parallel version: - // return state.im.symbolTable.entries.parallelStream() - // .filter[it instanceof SymbolTableEntryOriginal].map[ it as SymbolTableEntryOriginal] - // .filter[it.importSpecifier === importspec] - // .filter[it.originalTarget instanceof ModuleNamespaceVirtualType] - // .findAny().orElse(null); - - // 3. only the originals: - // Should be safe to use the cache. - return state.steCache.mapOriginal.values.parallelStream() - .filter[it.importSpecifier === importspec] - .filter[it.originalTarget instanceof ModuleNamespaceVirtualType] - .findAny().orElse(null); - } - - - - // let's try to keep this at "package" visibility for now (but there'll probably be special cases when a - // transformation needs to rewire something special by calling this directly) - def /*package*/ static void rewireSymbolTable(TranspilerState state, EObject from, EObject to) { - if(!from.requiresRewiringOfSymbolTable && !to.requiresRewiringOfSymbolTable) { - return; // nothing to rewire! - } - if(from instanceof ReferencingElement_IM && to instanceof ReferencingElement_IM) { - // case 1 - val eRefThatMightPointToOriginal = ImPackage.eINSTANCE.symbolTableEntry_ReferencingElements; - // TODO can be speed up - state.im.symbolTable.entries.parallelStream - .forEach[ - replaceInEReference(it, eRefThatMightPointToOriginal, from, to); - ]; - - } else if(from instanceof ImportSpecifier && to instanceof ImportSpecifier) { - // case 2 - val eRefThatMightPointToOriginal = ImPackage.eINSTANCE.symbolTableEntryOriginal_ImportSpecifier; - // TODO can be speed up - state.im.symbolTable.entries.parallelStream.filter[it instanceof SymbolTableEntryOriginal] - .forEach[ - replaceInEReference(it, eRefThatMightPointToOriginal, from, to); - ]; - - } else if(from instanceof NamedElement && to instanceof NamedElement) { - // case 3 // Most relevant case according to profiler - val eRefThatMightPointToOriginal = ImPackage.eINSTANCE.symbolTableEntry_ElementsOfThisName; - // Slow version: - // state.im.symbolTable.entries_.forEach[ - // replaceInEReference(it, x, from, to); - // ]; - - val steFrom = state.byElementsOfThisName(from as NamedElement); - if( steFrom !== null ) { - replaceInEReference(steFrom, eRefThatMightPointToOriginal, from , to ); - // update STECache: - state.replacedElementOfThisName( steFrom, from as NamedElement, to as NamedElement ) - } - } else { - throw new IllegalArgumentException("rewiring symbol table entries from type " + from.eClass.name + - " to type " + to.eClass.name + " is not supported yet"); - } - } - - def private static boolean requiresRewiringOfSymbolTable(EObject obj) { - return obj instanceof ReferencingElement_IM || obj instanceof ImportSpecifier || obj instanceof NamedElement; - } - - def private static void replaceInEReference(EObject obj, EReference eRef, T original, TN replacement) { - // note: cannot use EcoreUtil#replace() here, because it throws exceptions if original is not in reference! - if(eRef.many) { - val l = obj.eGet(eRef) as EList; - for(idx : 0.. findSymbolTableEntriesForVersionedTypeImport(TranspilerState state, NamedImportSpecifier importspec) { - return #[findSymbolTableEntryForNamedImport(state, importspec)]; - } - - - /** - * Records in property {@link TypeReferenceNode_IM#getRewiredReferences() rewiredReferences} that the given type reference node refers - * to the type represented by the given symbol table entry. - */ - def static public void recordReferenceToType(TranspilerState state, TypeReferenceNode_IM typeRefNode, SymbolTableEntryOriginal ste) { - // 1) record the reference to the type represented by 'ste' itself - typeRefNode.addRewiredTarget(ste); - // 2) record the reference to the namespace iff the type represented by 'ste' was imported via a namespace import - val importSpec = ste.importSpecifier; - if (importSpec instanceof NamespaceImportSpecifier) { - val namespaceType = state.info.getOriginalDefinedType(importSpec); - if (namespaceType !== null) { - val namespaceSTE = getSymbolTableEntryOriginal(state, namespaceType, false); - if (namespaceSTE !== null) { - typeRefNode.addRewiredTarget(namespaceSTE); - } - } - } - } - - - def static public void rename(TranspilerState state, SymbolTableEntry entry, String name) { - - if (entry instanceof SymbolTableEntryInternal) { - throw new UnsupportedOperationException("cannot rename internal STEs " + entry); - - } else if (entry instanceof SymbolTableEntryIMOnly) { - entry.setName(name); - - } else if (entry instanceof SymbolTableEntryOriginal) { - - entry.setName(name); - - // should do something like the following: - // (not possible at the moment, because NamedElement does not have a setter for property 'name') - // entry.elementsOfThisName.forEach[it.name=newName]; - - if (entry.getImportSpecifier() !== null) - throw new UnsupportedOperationException( - "renaming of symbol table entries not tested yet for imported elements!"); - // should be something like the following: - // switch(impSpec) { - // NamedImportSpecifier: if(impSpec.alias!==null) impSpec.alias = newName - // NamespaceImportSpecifier: if(impSpec.alias!==null) impSpec.alias = newName - // } - } else { - throw new UnsupportedOperationException( - "Rename request for SymboltableEntries of unkown type : " + entry); - } - - } -} diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerBuilderBlocks.java b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerBuilderBlocks.java new file mode 100644 index 0000000000..1840cbeb79 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerBuilderBlocks.java @@ -0,0 +1,954 @@ +/** + * 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.transpiler; + +import static com.google.common.collect.Iterables.toArray; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filterNull; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.isEmpty; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.reduce; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; +import static org.eclipse.xtext.xbase.lib.ListExtensions.map; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.n4JS.AdditiveExpression; +import org.eclipse.n4js.n4JS.AdditiveOperator; +import org.eclipse.n4js.n4JS.AnnotableN4MemberDeclaration; +import org.eclipse.n4js.n4JS.Annotation; +import org.eclipse.n4js.n4JS.AnnotationList; +import org.eclipse.n4js.n4JS.Argument; +import org.eclipse.n4js.n4JS.ArrayElement; +import org.eclipse.n4js.n4JS.ArrayLiteral; +import org.eclipse.n4js.n4JS.ArrayPadding; +import org.eclipse.n4js.n4JS.ArrowFunction; +import org.eclipse.n4js.n4JS.AssignmentExpression; +import org.eclipse.n4js.n4JS.AssignmentOperator; +import org.eclipse.n4js.n4JS.BinaryLogicalExpression; +import org.eclipse.n4js.n4JS.BinaryLogicalOperator; +import org.eclipse.n4js.n4JS.BindingProperty; +import org.eclipse.n4js.n4JS.Block; +import org.eclipse.n4js.n4JS.BooleanLiteral; +import org.eclipse.n4js.n4JS.CommaExpression; +import org.eclipse.n4js.n4JS.ConditionalExpression; +import org.eclipse.n4js.n4JS.DefaultImportSpecifier; +import org.eclipse.n4js.n4JS.EmptyStatement; +import org.eclipse.n4js.n4JS.EqualityExpression; +import org.eclipse.n4js.n4JS.EqualityOperator; +import org.eclipse.n4js.n4JS.ExportDeclaration; +import org.eclipse.n4js.n4JS.ExportableElement; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ExpressionStatement; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.FunctionDeclaration; +import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor; +import org.eclipse.n4js.n4JS.IfStatement; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.IndexedAccessExpression; +import org.eclipse.n4js.n4JS.IntLiteral; +import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4EnumDeclaration; +import org.eclipse.n4js.n4JS.N4EnumLiteral; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4GetterDeclaration; +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration; +import org.eclipse.n4js.n4JS.N4JSFactory; +import org.eclipse.n4js.n4JS.N4MemberAnnotationList; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.N4MethodDeclaration; +import org.eclipse.n4js.n4JS.N4Modifier; +import org.eclipse.n4js.n4JS.N4SetterDeclaration; +import org.eclipse.n4js.n4JS.N4TypeVariable; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.NewExpression; +import org.eclipse.n4js.n4JS.NullLiteral; +import org.eclipse.n4js.n4JS.NumericLiteral; +import org.eclipse.n4js.n4JS.ObjectBindingPattern; +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.n4JS.ParenExpression; +import org.eclipse.n4js.n4JS.PropertyAssignment; +import org.eclipse.n4js.n4JS.PropertyAssignmentAnnotationList; +import org.eclipse.n4js.n4JS.PropertyGetterDeclaration; +import org.eclipse.n4js.n4JS.PropertyNameKind; +import org.eclipse.n4js.n4JS.PropertyNameOwner; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.n4JS.RelationalExpression; +import org.eclipse.n4js.n4JS.RelationalOperator; +import org.eclipse.n4js.n4JS.ReturnStatement; +import org.eclipse.n4js.n4JS.Statement; +import org.eclipse.n4js.n4JS.StringLiteral; +import org.eclipse.n4js.n4JS.SuperLiteral; +import org.eclipse.n4js.n4JS.ThisLiteral; +import org.eclipse.n4js.n4JS.ThrowStatement; +import org.eclipse.n4js.n4JS.UnaryExpression; +import org.eclipse.n4js.n4JS.UnaryOperator; +import org.eclipse.n4js.n4JS.VariableBinding; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.VariableDeclarationOrBinding; +import org.eclipse.n4js.n4JS.VariableStatement; +import org.eclipse.n4js.n4JS.VariableStatementKeyword; +import org.eclipse.n4js.n4JS.YieldExpression; +import org.eclipse.n4js.postprocessing.CompileTimeExpressionProcessor; +import org.eclipse.n4js.postprocessing.ComputedNameProcessor; +import org.eclipse.n4js.transpiler.im.IdentifierRef_IM; +import org.eclipse.n4js.transpiler.im.ImFactory; +import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM; +import org.eclipse.n4js.transpiler.im.Snippet; +import org.eclipse.n4js.transpiler.im.StringLiteralForSTE; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.TypeReferenceNode_IM; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.TSetter; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.xtext.xbase.lib.Pair; + +/** + * Builder methods for intermediate elements. + */ +@SuppressWarnings("javadoc") +public class TranspilerBuilderBlocks { + + // ############################################################################################ + // n4js.xcore + + public static ImportDeclaration _ImportDecl(ImportSpecifier... importSpecifiers) { + ImportDeclaration result = N4JSFactory.eINSTANCE.createImportDeclaration(); + result.setModule(null); // must always be null, because we are in the intermediate model + result.getImportSpecifiers().addAll(toList(filterNull(Arrays.asList(importSpecifiers)))); + result.setImportFrom(result.getImportSpecifiers().size() > 0); + return result; + } + + public static NamedImportSpecifier _NamedImportSpecifier(String importedElementName, String alias, + boolean usedInCode) { + + NamedImportSpecifier result = N4JSFactory.eINSTANCE.createNamedImportSpecifier(); + result.setImportedElement(null); // must always be null, because we are in the intermediate model + result.setImportedElementAsText(importedElementName); + result.setAlias(alias); + result.setFlaggedUsedInCode(usedInCode); + return result; + } + + public static NamedImportSpecifier _DefaultImportSpecifier(String importedElementName, boolean usedInCode) { + DefaultImportSpecifier result = N4JSFactory.eINSTANCE.createDefaultImportSpecifier(); + result.setImportedElement(null); // must always be null, because we are in the intermediate model + result.setImportedElementAsText(importedElementName); + result.setFlaggedUsedInCode(usedInCode); + return result; + } + + public static NamespaceImportSpecifier _NamespaceImportSpecifier(String namespaceName, boolean usedInCode) { + NamespaceImportSpecifier result = N4JSFactory.eINSTANCE.createNamespaceImportSpecifier(); + result.setAlias(namespaceName); + result.setFlaggedUsedInCode(usedInCode); + return result; + } + + public static VariableStatement _VariableStatement(VariableDeclaration... varDecls) { + return _VariableStatement(VariableStatementKeyword.VAR, varDecls); + } + + public static VariableStatement _VariableStatement(VariableStatementKeyword keyword, + VariableDeclarationOrBinding... varDecls) { + + VariableStatement result = N4JSFactory.eINSTANCE.createVariableStatement(); + result.setVarStmtKeyword(keyword); + result.getVarDeclsOrBindings().addAll(toList(filterNull(Arrays.asList(varDecls)))); + return result; + } + + public static VariableDeclaration _VariableDeclaration(String name) { + VariableDeclaration result = N4JSFactory.eINSTANCE.createVariableDeclaration(); + result.setName(name); + return result; + } + + public static VariableDeclaration _VariableDeclaration(String name, Expression exp) { + VariableDeclaration result = N4JSFactory.eINSTANCE.createVariableDeclaration(); + result.setName(name); + result.setExpression(exp); + return result; + } + + public static VariableBinding _VariableBinding(Iterable properties, Expression exp) { + ObjectBindingPattern pattern = N4JSFactory.eINSTANCE.createObjectBindingPattern(); + pattern.getProperties().addAll(toList(properties)); + VariableBinding result = N4JSFactory.eINSTANCE.createVariableBinding(); + result.setPattern(pattern); + result.setExpression(exp); + return result; + } + + public static ExportDeclaration _ExportDeclaration(ExportableElement exported) { + ExportDeclaration result = N4JSFactory.eINSTANCE.createExportDeclaration(); + result.setExportedElement(exported); + return result; + } + + public static ReturnStatement _ReturnStmnt() { + ReturnStatement result = N4JSFactory.eINSTANCE.createReturnStatement(); + return result; + } + + public static ReturnStatement _ReturnStmnt(Expression expr) { + ReturnStatement result = N4JSFactory.eINSTANCE.createReturnStatement(); + result.setExpression(expr); + return result; + } + + public static IfStatement _IfStmnt(Expression condition, Statement ifStmnt) { + return _IfStmnt(condition, ifStmnt, null); + } + + public static IfStatement _IfStmnt(Expression condition, Statement ifStmnt, Statement elseStmnt) { + IfStatement result = N4JSFactory.eINSTANCE.createIfStatement(); + result.setExpression(condition); + result.setIfStmt(ifStmnt); + result.setElseStmt(elseStmnt); + return result; + } + + public static ThrowStatement _ThrowStmnt(Expression expression) { + ThrowStatement result = N4JSFactory.eINSTANCE.createThrowStatement(); + result.setExpression(expression); + return result; + } + + public static ConditionalExpression _ConditionalExpr(Expression condition, Expression trueExpr, + Expression falseExpr) { + + ConditionalExpression result = N4JSFactory.eINSTANCE.createConditionalExpression(); + result.setExpression(condition); + result.setTrueExpression(trueExpr); + result.setFalseExpression(falseExpr); + return result; + } + + public static YieldExpression _YieldExpr(Expression expr) { + YieldExpression result = N4JSFactory.eINSTANCE.createYieldExpression(); + result.setExpression(expr); + return result; + } + + public static ParameterizedCallExpression _CallExpr() { + ParameterizedCallExpression result = N4JSFactory.eINSTANCE.createParameterizedCallExpression(); + return result; + } + + public static ParameterizedCallExpression _CallExpr(Expression target, Expression... arguments) { + return _CallExpr(target, false, arguments); + } + + public static ParameterizedCallExpression _CallExpr(Expression target, boolean optionalChaining, + Expression... arguments) { + ParameterizedCallExpression result = N4JSFactory.eINSTANCE.createParameterizedCallExpression(); + result.setTarget(target); + result.setOptionalChaining(optionalChaining); + result.getArguments().addAll(toList(map(filterNull(Arrays.asList(arguments)), arg -> _Argument(arg)))); + return result; + } + + public static Argument _Argument(Expression expression) { + return _Argument(false, expression); + } + + public static Argument _Argument(boolean spread, Expression expression) { + Argument result = N4JSFactory.eINSTANCE.createArgument(); + result.setSpread(spread); + result.setExpression(expression); + return result; + } + + public static ExpressionStatement _ExprStmnt(Expression expr) { + ExpressionStatement result = N4JSFactory.eINSTANCE.createExpressionStatement(); + result.setExpression(expr); + return result; + } + + public static AssignmentExpression _AssignmentExpr() { + AssignmentExpression result = N4JSFactory.eINSTANCE.createAssignmentExpression(); + result.setOp(AssignmentOperator.ASSIGN); + return result; + } + + public static AssignmentExpression _AssignmentExpr(Expression lhs, Expression rhs) { + AssignmentExpression result = N4JSFactory.eINSTANCE.createAssignmentExpression(); + result.setLhs(lhs); + result.setOp(AssignmentOperator.ASSIGN); + result.setRhs(rhs); + return result; + } + + public static ParameterizedPropertyAccessExpression_IM _PropertyAccessExpr() { + ParameterizedPropertyAccessExpression_IM result = ImFactory.eINSTANCE + .createParameterizedPropertyAccessExpression_IM(); + return result; + } + + public static ParameterizedPropertyAccessExpression_IM _PropertyAccessExpr(SymbolTableEntry target, + SymbolTableEntry... properties) { + return _PropertyAccessExpr(_IdentRef(target), properties); + } + + public static ParameterizedPropertyAccessExpression_IM _PropertyAccessExpr(Expression target, + SymbolTableEntry... properties) { + if (properties == null || exists(Arrays.asList(properties), p -> p == null)) { + throw new IllegalArgumentException("none of the properties may be null"); + } + var result = ImFactory.eINSTANCE.createParameterizedPropertyAccessExpression_IM(); + result.setTarget(target); + if (properties.length > 0) { + result.setRewiredTarget(properties[0]); + for (int idx = 1; idx < properties.length; idx++) { + ParameterizedPropertyAccessExpression_IM newResult = ImFactory.eINSTANCE + .createParameterizedPropertyAccessExpression_IM(); + newResult.setTarget(result); + newResult.setRewiredTarget(properties[idx]); + result = newResult; + } + } + return result; + } + + public static IndexedAccessExpression _IndexAccessExpr() { + return _IndexAccessExpr((Expression) null, null); + } + + public static IndexedAccessExpression _IndexAccessExpr(SymbolTableEntry target, Expression index) { + return _IndexAccessExpr(_IdentRef(target), index); + } + + public static IndexedAccessExpression _IndexAccessExpr(Expression target, Expression index) { + IndexedAccessExpression result = N4JSFactory.eINSTANCE.createIndexedAccessExpression(); + result.setTarget(target); + result.setIndex(index); + return result; + } + + public static NewExpression _NewExpr(Expression callee, Expression... arguments) { + NewExpression result = N4JSFactory.eINSTANCE.createNewExpression(); + result.setCallee(callee); + result.setWithArgs(!isEmpty(filterNull(Arrays.asList(arguments)))); + result.getArguments().addAll(toList(map(filterNull(Arrays.asList(arguments)), a -> _Argument(a)))); + return result; + } + + public static RelationalExpression _RelationalExpr(Expression lhs, RelationalOperator op, Expression rhs) { + RelationalExpression result = N4JSFactory.eINSTANCE.createRelationalExpression(); + result.setLhs(lhs); + result.setOp(op); + result.setRhs(rhs); + return result; + } + + public static EqualityExpression _EqualityExpr(Expression lhs, EqualityOperator op, Expression rhs) { + EqualityExpression result = N4JSFactory.eINSTANCE.createEqualityExpression(); + result.setLhs(lhs); + result.setOp(op); + result.setRhs(rhs); + return result; + } + + public static UnaryExpression _NOT(Expression expr) { + return _UnaryExpr(UnaryOperator.NOT, expr); + } + + public static Expression _OR(Expression... operands) { + return reduce(Arrays.asList(operands), (op1, op2) -> _BinaryLogicalExpr(op1, BinaryLogicalOperator.OR, op2)); + } + + public static Expression _AND(Expression... operands) { + return reduce(Arrays.asList(operands), (op1, op2) -> _BinaryLogicalExpr(op1, BinaryLogicalOperator.AND, op2)); + } + + public static UnaryExpression _Void0() { + return _Void(_NumericLiteral(0)); + } + + public static UnaryExpression _Void(Expression expr) { + return _UnaryExpr(UnaryOperator.VOID, expr); + } + + public static UnaryExpression _UnaryExpr(UnaryOperator op, Expression expr) { + UnaryExpression result = N4JSFactory.eINSTANCE.createUnaryExpression(); + result.setOp(op); + result.setExpression(expr); + return result; + } + + public static BinaryLogicalExpression _BinaryLogicalExpr(Expression lhs, BinaryLogicalOperator op, Expression rhs) { + BinaryLogicalExpression result = N4JSFactory.eINSTANCE.createBinaryLogicalExpression(); + result.setLhs(lhs); + result.setOp(op); + result.setRhs(rhs); + return result; + } + + public static CommaExpression _CommaExpression(Expression... expressions) { + CommaExpression result = N4JSFactory.eINSTANCE.createCommaExpression(); + result.getExprs().addAll(Arrays.asList(expressions)); + return result; + } + + public static AdditiveExpression _AdditiveExpression(Expression lhs, AdditiveOperator op, Expression rhs) { + AdditiveExpression result = N4JSFactory.eINSTANCE.createAdditiveExpression(); + result.setLhs(lhs); + result.setOp(op); + result.setRhs(rhs); + return result; + } + + public static AdditiveExpression _AdditiveExpression(AdditiveOperator op, Expression... operands) { + if (operands == null || exists(Arrays.asList(operands), e -> e == null)) { + throw new IllegalArgumentException("none of the operands may be null"); + } + if (operands.length < 2) { + throw new IllegalArgumentException("need at least two operands"); + } + var result = N4JSFactory.eINSTANCE.createAdditiveExpression(); + result.setLhs(operands[0]); + result.setOp(op); + result.setRhs(operands[1]); + for (int idx = 2; idx < operands.length; idx++) { + AdditiveExpression newResult = N4JSFactory.eINSTANCE.createAdditiveExpression(); + newResult.setLhs(result); + newResult.setOp(op); + newResult.setRhs(operands[idx]); + result = newResult; + } + return result; + } + + public static ObjectLiteral _ObjLit() { // required to resolve the ambiguity between the other two methods + return _ObjLit((PropertyAssignment[]) null); + } + + /** + * Convenience method for creating object literals that only contain {@link PropertyNameValuePair}s. It is legal to + * pass in one or more null values (they will be ignored). + */ + @SuppressWarnings("unchecked") + public static ObjectLiteral _ObjLit(Pair... nameValuePairs) { + return _ObjLit(toArray(map(filterNull(Arrays.asList(nameValuePairs)), + p -> _PropertyNameValuePair(p.getKey(), p.getValue())), PropertyNameValuePair.class)); + } + + public static ObjectLiteral _ObjLit(PropertyAssignment... pas) { + ObjectLiteral result = N4JSFactory.eINSTANCE.createObjectLiteral(); + if (pas != null) { + result.getPropertyAssignments().addAll(toList(filterNull(Arrays.asList(pas)))); + } + return result; + } + + public static PropertyNameValuePair _PropertyNameValuePair(String name, Expression value) { + return _PropertyNameValuePair(_LiteralOrComputedPropertyName(name), value); + } + + public static PropertyNameValuePair _PropertyNameValuePair(LiteralOrComputedPropertyName name, Expression value) { + PropertyNameValuePair result = N4JSFactory.eINSTANCE.createPropertyNameValuePair(); + result.setDeclaredName(name); + result.setExpression(value); + return result; + } + + public static PropertyGetterDeclaration _PropertyGetterDecl(String name, Statement... stmnts) { + PropertyGetterDeclaration result = N4JSFactory.eINSTANCE.createPropertyGetterDeclaration(); + result.setDeclaredName(_LiteralOrComputedPropertyName(name)); + result.setBody(_Block(stmnts)); + return result; + } + + public static ArrayLiteral _ArrLit() { // required to resolve the ambiguity between the other two methods + return _ArrLit((ArrayElement[]) null); + } + + public static ArrayLiteral _ArrLit(Expression... elements) { + return _ArrLit( + toArray(map(filterNull(Arrays.asList(elements)), e -> _ArrayElement(e)), ArrayElement.class)); + } + + public static ArrayLiteral _ArrLit(ArrayElement... elements) { + ArrayLiteral result = N4JSFactory.eINSTANCE.createArrayLiteral(); + if (elements != null) { + result.getElements().addAll(toList(filterNull(Arrays.asList(elements)))); + } + return result; + } + + public static ArrayElement _ArrayElement(Expression expression) { + return _ArrayElement(false, expression); + } + + public static ArrayElement _ArrayElement(boolean spread, Expression expression) { + ArrayElement result = N4JSFactory.eINSTANCE.createArrayElement(); + result.setSpread(spread); + result.setExpression(expression); + return result; + } + + public static ArrayPadding _ArrayPadding() { + ArrayPadding result = N4JSFactory.eINSTANCE.createArrayPadding(); + return result; + } + + public static FunctionDeclaration _FunDecl(String name, Statement... statements) { + return _FunDecl(name, new FormalParameter[0], statements); + } + + public static FunctionDeclaration _FunDecl(String name, FormalParameter[] fpars, Statement... statements) { + FunctionDeclaration result = N4JSFactory.eINSTANCE.createFunctionDeclaration(); + result.setName(name); + result.getFpars().addAll(Arrays.asList(fpars)); + result.setBody(_Block(statements)); + return result; + } + + public static FunctionExpression _FunExpr(boolean async, Statement... statements) { + return _FunExpr(async, null, new FormalParameter[0], statements); + } + + public static FunctionExpression _FunExpr(boolean async, String name, Statement... statements) { + return _FunExpr(async, name, new FormalParameter[0], statements); + } + + public static FunctionExpression _FunExpr(boolean async, String name, FormalParameter... formalParams) { + return _FunExpr(async, name, formalParams, new Statement[0]); + } + + public static FunctionExpression _FunExpr(boolean async, String name, FormalParameter[] fpars, + Statement... statements) { + if (statements != null && statements.length == 1 && statements[0] instanceof Block) { + // safe guard: in case complex EMF inheritance hierarchy causes wrong overload to be invoked + return _FunExprWithBlock(async, name, fpars, (Block) statements[0]); + } + FunctionExpression result = N4JSFactory.eINSTANCE.createFunctionExpression(); + result.setDeclaredAsync(async); + result.setName(name); + result.getFpars().addAll(Arrays.asList(fpars)); + result.setBody(_Block(statements)); + return result; + } + + public static FormalParameter _FormalParameter(String name) { + FormalParameter result = N4JSFactory.eINSTANCE.createFormalParameter(); + result.setName(name); + return result; + } + + public static FunctionExpression _FunExpr(boolean async, String name, FormalParameter[] fpars, Block block) { + return _FunExprWithBlock(async, name, fpars, block); + } + + private static FunctionExpression _FunExprWithBlock(boolean async, String name, FormalParameter[] fpars, + Block block) { + FunctionExpression result = N4JSFactory.eINSTANCE.createFunctionExpression(); + result.setDeclaredAsync(async); + result.setName(name); + result.getFpars().addAll(Arrays.asList(fpars)); + result.setBody(block); + return result; + } + + /** Creates a {@link ArrowFunction#isSingleExprImplicitReturn() single-expression arrow function}. */ + public static ArrowFunction _ArrowFunc(boolean async, FormalParameter[] fpars, Expression expression) { + ArrowFunction result = N4JSFactory.eINSTANCE.createArrowFunction(); + result.setDeclaredAsync(async); + result.getFpars().addAll(Arrays.asList(fpars)); + result.setBody(_Block(_ExprStmnt(expression))); + result.setHasBracesAroundBody(false); + return result; + } + + public static ArrowFunction _ArrowFunc(boolean async, FormalParameter[] fpars, Statement... statements) { + ArrowFunction result = N4JSFactory.eINSTANCE.createArrowFunction(); + result.setDeclaredAsync(async); + result.getFpars().addAll(Arrays.asList(fpars)); + result.setBody(_Block(statements)); + result.setHasBracesAroundBody(true); + return result; + } + + public static N4MemberDeclaration _N4MemberDecl(TMember template, Statement... statements) { + if (template instanceof TField && statements.length > 0) { + throw new IllegalArgumentException("fields cannot have statements"); + } + PropertyNameOwner result; + if (template instanceof TField) { + result = N4JSFactory.eINSTANCE.createN4FieldDeclaration(); + } else if (template instanceof TGetter) { + result = N4JSFactory.eINSTANCE.createN4GetterDeclaration(); + } else if (template instanceof TSetter) { + result = N4JSFactory.eINSTANCE.createN4SetterDeclaration(); + } else if (template instanceof TMethod) { + result = N4JSFactory.eINSTANCE.createN4MethodDeclaration(); + } else { + throw new IllegalArgumentException("unsupported subtype of TMember: " + template.eClass().getName()); + } + + AnnotableN4MemberDeclaration resultAsMD = (AnnotableN4MemberDeclaration) result; + + // basic properties + result.setDeclaredName(_LiteralOrComputedPropertyName(template.getName())); + // body + if (result instanceof FunctionOrFieldAccessor) { + ((FunctionOrFieldAccessor) result).setBody(_Block( + toArray(filterNull(Arrays.asList(statements)), Statement.class))); + } + // formal parameters + if (template instanceof TSetter) { + String fparName = "value"; + if (((TSetter) template).getFpar() != null) { + fparName = ((TSetter) template).getFpar().getName(); + } + ((N4SetterDeclaration) result).setFpar(_Fpar(fparName)); + } + if (template instanceof TMethod) { + TMethod tMethod = (TMethod) template; + ((N4MethodDeclaration) result).getFpars().addAll( + toList(map(tMethod.getFpars(), fpar -> _Fpar(fpar.getName())))); + ((N4MethodDeclaration) result).setDeclaredAsync(tMethod.isDeclaredAsync()); + } + // static / non-static + if (template.isStatic()) { + resultAsMD.getDeclaredModifiers().add(N4Modifier.STATIC); + } + // access modifiers + switch (template.getMemberAccessModifier()) { + case PUBLIC: + resultAsMD.getDeclaredModifiers().add(N4Modifier.PUBLIC); + break; + case PUBLIC_INTERNAL: + resultAsMD.getDeclaredModifiers().add(N4Modifier.PUBLIC); + getOrCreateMemberAnnotationList(resultAsMD).getAnnotations() + .add(_Annotation(AnnotationDefinition.INTERNAL)); + break; + case PROTECTED: + resultAsMD.getDeclaredModifiers().add(N4Modifier.PROTECTED); + break; + case PROTECTED_INTERNAL: + resultAsMD.getDeclaredModifiers().add(N4Modifier.PROTECTED); + getOrCreateMemberAnnotationList(resultAsMD).getAnnotations() + .add(_Annotation(AnnotationDefinition.INTERNAL)); + break; + case PROJECT: + resultAsMD.getDeclaredModifiers().add(N4Modifier.PROJECT); + break; + case PRIVATE: + resultAsMD.getDeclaredModifiers().add(N4Modifier.PRIVATE); + break; + case UNDEFINED: { + /* NOP */} + } + + return resultAsMD; + } + + private static N4MemberAnnotationList getOrCreateMemberAnnotationList(AnnotableN4MemberDeclaration memberDecl) { + N4MemberAnnotationList annList = memberDecl.getAnnotationList(); + if (annList == null) { + annList = N4JSFactory.eINSTANCE.createN4MemberAnnotationList(); + memberDecl.setAnnotationList(annList); + } + return annList; + } + + public static N4FieldDeclaration _N4FieldDecl(boolean isStatic, String declaredName, Expression initExpr) { + return _N4FieldDecl(isStatic, _LiteralOrComputedPropertyName(declaredName), initExpr); + } + + public static N4FieldDeclaration _N4FieldDecl(boolean isStatic, LiteralOrComputedPropertyName declaredName, + Expression initExpr) { + N4FieldDeclaration result = N4JSFactory.eINSTANCE.createN4FieldDeclaration(); + if (isStatic) { + result.getDeclaredModifiers().add(N4Modifier.STATIC); + } + result.setDeclaredName(declaredName); + result.setExpression(initExpr); + return result; + } + + public static N4GetterDeclaration _N4GetterDecl(LiteralOrComputedPropertyName declaredName, Block body) { + N4GetterDeclaration result = N4JSFactory.eINSTANCE.createN4GetterDeclaration(); + result.setDeclaredName(declaredName); + result.setBody(body); + return result; + } + + public static N4SetterDeclaration _N4SetterDecl(LiteralOrComputedPropertyName declaredName, FormalParameter fpar, + Block body) { + N4SetterDeclaration result = N4JSFactory.eINSTANCE.createN4SetterDeclaration(); + result.setDeclaredName(declaredName); + result.setFpar(fpar); + result.setBody(body); + return result; + } + + public static N4MethodDeclaration _N4MethodDecl(String name, Statement... statements) { + return _N4MethodDecl(name, new FormalParameter[0], statements); + } + + public static N4MethodDeclaration _N4MethodDecl(String name, FormalParameter[] fpars, Statement... statements) { + return _N4MethodDecl(false, _LiteralOrComputedPropertyName(name), fpars, + _Block(toArray(filterNull(Arrays.asList(statements)), Statement.class))); + } + + public static N4MethodDeclaration _N4MethodDecl(LiteralOrComputedPropertyName declaredName, Block body) { + return _N4MethodDecl(false, declaredName, new FormalParameter[0], body); + } + + public static N4MethodDeclaration _N4MethodDecl(boolean isStatic, LiteralOrComputedPropertyName declaredName, + FormalParameter[] fpars, Block body) { + N4MethodDeclaration result = N4JSFactory.eINSTANCE.createN4MethodDeclaration(); + if (isStatic) { + result.getDeclaredModifiers().add(N4Modifier.STATIC); + } + result.setDeclaredName(declaredName); + result.getFpars().addAll(Arrays.asList(fpars)); + result.setBody(body); + return result; + } + + public static FormalParameter _Fpar() { + return _Fpar(null, false, false); + } + + public static FormalParameter _Fpar(String name) { + return _Fpar(name, false, false); + } + + public static FormalParameter _Fpar(String name, boolean variadic) { + return _Fpar(name, variadic, false); + } + + public static FormalParameter _Fpar(String name, boolean variadic, boolean isSpecFpar) { + FormalParameter result = N4JSFactory.eINSTANCE.createFormalParameter(); + result.setName(name); + result.setVariadic(variadic); + if (isSpecFpar) { + result.getAnnotations().add(_Annotation(AnnotationDefinition.SPEC)); + } + return result; + } + + public static Annotation _Annotation(AnnotationDefinition annDef) { + Annotation result = N4JSFactory.eINSTANCE.createAnnotation(); + result.setName(annDef.name); + return result; + } + + public static AnnotationList _AnnotationList(List annDef) { + AnnotationList result = N4JSFactory.eINSTANCE.createAnnotationList(); + if (annDef != null) + result.getAnnotations().addAll(map(annDef, ad -> _Annotation(ad))); + return result; + } + + public static PropertyAssignmentAnnotationList _PropertyAssignmentAnnotationList(Annotation[] annotations) { + PropertyAssignmentAnnotationList result = N4JSFactory.eINSTANCE.createPropertyAssignmentAnnotationList(); + result.getAnnotations().addAll(Arrays.asList(annotations)); + return result; + } + + public static Block _Block(Statement... statements) { + Block result = N4JSFactory.eINSTANCE.createBlock(); + result.getStatements().addAll(toList(filterNull(Arrays.asList(statements)))); + return result; + } + + public static ParenExpression _Parenthesis(Expression expr) { + ParenExpression result = N4JSFactory.eINSTANCE.createParenExpression(); + result.setExpression(expr); + return result; + } + + public static ParameterizedCallExpression _ParameterizedCallExpression(Expression expr) { + ParameterizedCallExpression result = N4JSFactory.eINSTANCE.createParameterizedCallExpression(); + result.setTarget(expr); + return result; + } + + public static NullLiteral _NULL() { + return N4JSFactory.eINSTANCE.createNullLiteral(); + } + + public static BooleanLiteral _TRUE() { + return _BooleanLiteral(true); + } + + public static BooleanLiteral _FALSE() { + return _BooleanLiteral(false); + } + + public static BooleanLiteral _BooleanLiteral(boolean value) { + BooleanLiteral result = N4JSFactory.eINSTANCE.createBooleanLiteral(); + result.setTrue(value); + return result; + } + + public static NumericLiteral _NumericLiteral(int num) { + return _NumericLiteral(BigDecimal.valueOf(num)); + } + + public static NumericLiteral _NumericLiteral(BigDecimal num) { + NumericLiteral result = N4JSFactory.eINSTANCE.createNumericLiteral(); + result.setValue(num); + return result; + } + + public static StringLiteral _StringLiteral(String s, String rawValue) { + StringLiteral result = _StringLiteral(s); + result.setRawValue(rawValue); + return result; + } + + public static StringLiteral _StringLiteral(String s) { + StringLiteral result = N4JSFactory.eINSTANCE.createStringLiteral(); + result.setValue(s); + return result; + } + + public static StringLiteral _StringLiteralForSTE(SymbolTableEntry symbolTableEntry) { + return _StringLiteralForSTE(symbolTableEntry, false); + } + + public static StringLiteral _StringLiteralForSTE(SymbolTableEntry symbolTableEntry, boolean useExportedName) { + StringLiteralForSTE result = ImFactory.eINSTANCE.createStringLiteralForSTE(); + result.setEntry(symbolTableEntry); + result.setUseExportedName(useExportedName); + return result; + } + + public static IntLiteral _IntLiteral(int i) { + IntLiteral result = N4JSFactory.eINSTANCE.createIntLiteral(); + result.setValue(BigDecimal.valueOf(i)); + return result; + } + + public static ThisLiteral _ThisLiteral() { + ThisLiteral result = N4JSFactory.eINSTANCE.createThisLiteral(); + return result; + } + + public static SuperLiteral _SuperLiteral() { + SuperLiteral result = N4JSFactory.eINSTANCE.createSuperLiteral(); + return result; + } + + public static EmptyStatement _emptyStatement() { + return N4JSFactory.eINSTANCE.createEmptyStatement(); + } + + public static N4EnumDeclaration _EnumDeclaration(String name, List literals) { + N4EnumDeclaration result = N4JSFactory.eINSTANCE.createN4EnumDeclaration(); + result.setName(name); + result.getLiterals().addAll(literals); + return result; + } + + public static N4EnumLiteral _EnumLiteral(String name, String value) { + N4EnumLiteral result = N4JSFactory.eINSTANCE.createN4EnumLiteral(); + result.setName(name); + result.setValueExpression((value != null) ? _StringLiteral(value) : null); + return result; + } + + public static N4ClassDeclaration _N4ClassDeclaration(String name) { + N4ClassDeclaration result = N4JSFactory.eINSTANCE.createN4ClassDeclaration(); + result.setName(name); + return result; + } + + public static N4InterfaceDeclaration _N4InterfaceDeclaration(String name) { + N4InterfaceDeclaration result = N4JSFactory.eINSTANCE.createN4InterfaceDeclaration(); + result.setName(name); + return result; + } + + public static N4TypeVariable _N4TypeVariable(String name, boolean covariant, boolean contravariant) { + N4TypeVariable result = N4JSFactory.eINSTANCE.createN4TypeVariable(); + result.setName(name); + result.setDeclaredCovariant(covariant); + result.setDeclaredContravariant(contravariant); + return result; + } + + public static LiteralOrComputedPropertyName _LiteralOrComputedPropertyName(String name) { + LiteralOrComputedPropertyName result = N4JSFactory.eINSTANCE.createLiteralOrComputedPropertyName(); + result.setKind(PropertyNameKind.STRING); + result.setLiteralName(name); + return result; + } + + /** + * @param computedName + * the string representation of the computed property name. This should be the value that is usually + * computed and set by {@link CompileTimeExpressionProcessor} and {@link ComputedNameProcessor}. + */ + public static LiteralOrComputedPropertyName _LiteralOrComputedPropertyName(Expression nameExpr, + String computedName) { + LiteralOrComputedPropertyName result = N4JSFactory.eINSTANCE.createLiteralOrComputedPropertyName(); + result.setKind(PropertyNameKind.COMPUTED); + result.setExpression(nameExpr); + result.setComputedName(computedName); + return result; + } + + // ############################################################################################ + // IM.xcore + + public static TypeReferenceNode_IM _TypeReferenceNode(TranspilerState state, + TypeRef typeRef) { + TypeReferenceNode_IM result = ImFactory.eINSTANCE.createTypeReferenceNode_IM(); + if (typeRef != null) { + state.info.setOriginalProcessedTypeRef_internal(result, TypeUtils.copyIfContained(typeRef)); + } + return result; + } + + public static IdentifierRef_IM _IdentRef(SymbolTableEntry symbolTableEntry) { + if (symbolTableEntry == null) { + throw new IllegalArgumentException("when creating an IdentifierRef_IM: symbol table entry may not be null"); + } + IdentifierRef_IM result = ImFactory.eINSTANCE.createIdentifierRef_IM(); + result.setRewiredTarget(symbolTableEntry); + return result; + } + + public static SymbolTableEntry _SymbolTableEntry(@SuppressWarnings("unused") String name) { + throw new UnsupportedOperationException( + "do not manually create symbol table entries; use methods #createSymbolTableEntry() or #getSymbolTableEntry() instead"); + } + + public static ExpressionStatement _SnippetAsStmnt(String code) { + return _ExprStmnt(_Snippet(code)); + } + + public static Snippet _Snippet(String codeToEmit) { + Snippet result = ImFactory.eINSTANCE.createSnippet(); + result.setCodeToEmit(codeToEmit); + return result; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerBuilderBlocks.xtend b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerBuilderBlocks.xtend deleted file mode 100644 index 561f6121a2..0000000000 --- a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerBuilderBlocks.xtend +++ /dev/null @@ -1,870 +0,0 @@ -/** - * 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.transpiler - -import java.math.BigDecimal -import java.util.List -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.AdditiveExpression -import org.eclipse.n4js.n4JS.AdditiveOperator -import org.eclipse.n4js.n4JS.AnnotableN4MemberDeclaration -import org.eclipse.n4js.n4JS.Annotation -import org.eclipse.n4js.n4JS.AnnotationList -import org.eclipse.n4js.n4JS.Argument -import org.eclipse.n4js.n4JS.ArrayElement -import org.eclipse.n4js.n4JS.ArrayLiteral -import org.eclipse.n4js.n4JS.ArrayPadding -import org.eclipse.n4js.n4JS.ArrowFunction -import org.eclipse.n4js.n4JS.AssignmentExpression -import org.eclipse.n4js.n4JS.AssignmentOperator -import org.eclipse.n4js.n4JS.BinaryLogicalExpression -import org.eclipse.n4js.n4JS.BinaryLogicalOperator -import org.eclipse.n4js.n4JS.BindingProperty -import org.eclipse.n4js.n4JS.Block -import org.eclipse.n4js.n4JS.BooleanLiteral -import org.eclipse.n4js.n4JS.CommaExpression -import org.eclipse.n4js.n4JS.ConditionalExpression -import org.eclipse.n4js.n4JS.EqualityExpression -import org.eclipse.n4js.n4JS.EqualityOperator -import org.eclipse.n4js.n4JS.ExportDeclaration -import org.eclipse.n4js.n4JS.ExportableElement -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.ExpressionStatement -import org.eclipse.n4js.n4JS.FormalParameter -import org.eclipse.n4js.n4JS.FunctionDeclaration -import org.eclipse.n4js.n4JS.FunctionExpression -import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor -import org.eclipse.n4js.n4JS.IfStatement -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.ImportSpecifier -import org.eclipse.n4js.n4JS.IndexedAccessExpression -import org.eclipse.n4js.n4JS.IntLiteral -import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName -import org.eclipse.n4js.n4JS.N4EnumDeclaration -import org.eclipse.n4js.n4JS.N4EnumLiteral -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.N4GetterDeclaration -import org.eclipse.n4js.n4JS.N4JSFactory -import org.eclipse.n4js.n4JS.N4MemberAnnotationList -import org.eclipse.n4js.n4JS.N4MemberDeclaration -import org.eclipse.n4js.n4JS.N4MethodDeclaration -import org.eclipse.n4js.n4JS.N4Modifier -import org.eclipse.n4js.n4JS.N4SetterDeclaration -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.n4JS.NewExpression -import org.eclipse.n4js.n4JS.NullLiteral -import org.eclipse.n4js.n4JS.NumericLiteral -import org.eclipse.n4js.n4JS.ObjectLiteral -import org.eclipse.n4js.n4JS.ParameterizedCallExpression -import org.eclipse.n4js.n4JS.ParenExpression -import org.eclipse.n4js.n4JS.PropertyAssignment -import org.eclipse.n4js.n4JS.PropertyAssignmentAnnotationList -import org.eclipse.n4js.n4JS.PropertyGetterDeclaration -import org.eclipse.n4js.n4JS.PropertyNameKind -import org.eclipse.n4js.n4JS.PropertyNameValuePair -import org.eclipse.n4js.n4JS.RelationalExpression -import org.eclipse.n4js.n4JS.RelationalOperator -import org.eclipse.n4js.n4JS.ReturnStatement -import org.eclipse.n4js.n4JS.Statement -import org.eclipse.n4js.n4JS.StringLiteral -import org.eclipse.n4js.n4JS.SuperLiteral -import org.eclipse.n4js.n4JS.ThisLiteral -import org.eclipse.n4js.n4JS.ThrowStatement -import org.eclipse.n4js.n4JS.UnaryExpression -import org.eclipse.n4js.n4JS.UnaryOperator -import org.eclipse.n4js.n4JS.VariableBinding -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.n4JS.VariableDeclarationOrBinding -import org.eclipse.n4js.n4JS.VariableStatement -import org.eclipse.n4js.n4JS.VariableStatementKeyword -import org.eclipse.n4js.n4JS.YieldExpression -import org.eclipse.n4js.postprocessing.CompileTimeExpressionProcessor -import org.eclipse.n4js.postprocessing.ComputedNameProcessor -import org.eclipse.n4js.transpiler.im.IdentifierRef_IM -import org.eclipse.n4js.transpiler.im.ImFactory -import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM -import org.eclipse.n4js.transpiler.im.Snippet -import org.eclipse.n4js.transpiler.im.SymbolTableEntry -import org.eclipse.n4js.transpiler.im.TypeReferenceNode_IM -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.TField -import org.eclipse.n4js.ts.types.TGetter -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.ts.types.TSetter -import org.eclipse.n4js.types.utils.TypeUtils - -/** - * Builder methods for intermediate elements. - */ -public class TranspilerBuilderBlocks -{ - - // ############################################################################################ - // n4js.xcore - - public static def ImportDeclaration _ImportDecl(ImportSpecifier... importSpecifiers) { - val result = N4JSFactory.eINSTANCE.createImportDeclaration; - result.module = null; // must always be null, because we are in the intermediate model - result.importSpecifiers += importSpecifiers.filterNull; - result.importFrom = importSpecifiers.length > 0; - return result; - } - - public static def NamedImportSpecifier _NamedImportSpecifier(String importedElementName, String alias, boolean usedInCode) { - val result = N4JSFactory.eINSTANCE.createNamedImportSpecifier; - result.importedElement = null; // must always be null, because we are in the intermediate model - result.importedElementAsText = importedElementName; - result.alias = alias; - result.flaggedUsedInCode = usedInCode; - return result; - } - - public static def NamedImportSpecifier _DefaultImportSpecifier(String importedElementName, boolean usedInCode) { - val result = N4JSFactory.eINSTANCE.createDefaultImportSpecifier; - result.importedElement = null; // must always be null, because we are in the intermediate model - result.importedElementAsText = importedElementName; - result.flaggedUsedInCode = usedInCode; - return result; - } - - public static def NamespaceImportSpecifier _NamespaceImportSpecifier(String namespaceName, boolean usedInCode) { - val result = N4JSFactory.eINSTANCE.createNamespaceImportSpecifier; - result.alias = namespaceName; - result.flaggedUsedInCode = usedInCode; - return result; - } - - public static def VariableStatement _VariableStatement(VariableDeclaration... varDecls) { - return _VariableStatement(VariableStatementKeyword.VAR, varDecls); - } - - public static def VariableStatement _VariableStatement(VariableStatementKeyword keyword, VariableDeclarationOrBinding... varDecls) { - val result = N4JSFactory.eINSTANCE.createVariableStatement; - result.varStmtKeyword = keyword; - result.varDeclsOrBindings += varDecls.filterNull; - return result; - } - - public static def VariableDeclaration _VariableDeclaration(String name) { - val result = N4JSFactory.eINSTANCE.createVariableDeclaration; - result.name = name; - return result; - } - - public static def VariableDeclaration _VariableDeclaration(String name, Expression exp) { - val result = N4JSFactory.eINSTANCE.createVariableDeclaration; - result.name = name; - result.expression = exp; - return result; - } - - public static def VariableBinding _VariableBinding(Iterable properties, Expression exp) { - val pattern = N4JSFactory.eINSTANCE.createObjectBindingPattern; - pattern.properties += properties; - val result = N4JSFactory.eINSTANCE.createVariableBinding; - result.pattern = pattern; - result.expression = exp; - return result; - } - - public static def ExportDeclaration _ExportDeclaration(ExportableElement exported) { - val result = N4JSFactory.eINSTANCE.createExportDeclaration; - result.exportedElement = exported - return result; - } - - public static def ReturnStatement _ReturnStmnt() { - val result = N4JSFactory.eINSTANCE.createReturnStatement; - return result; - } - - public static def ReturnStatement _ReturnStmnt(Expression expr) { - val result = N4JSFactory.eINSTANCE.createReturnStatement; - result.expression = expr; - return result; - } - - public static def IfStatement _IfStmnt(Expression condition, Statement ifStmnt) { - return _IfStmnt(condition, ifStmnt, null); - } - - public static def IfStatement _IfStmnt(Expression condition, Statement ifStmnt, Statement elseStmnt) { - val result = N4JSFactory.eINSTANCE.createIfStatement; - result.expression = condition; - result.ifStmt = ifStmnt; - result.elseStmt = elseStmnt; - return result; - } - - public static def ThrowStatement _ThrowStmnt(Expression expression) { - val result = N4JSFactory.eINSTANCE.createThrowStatement; - result.expression = expression; - return result; - } - - public static def ConditionalExpression _ConditionalExpr(Expression condition, Expression trueExpr, Expression falseExpr) { - val result = N4JSFactory.eINSTANCE.createConditionalExpression; - result.expression = condition; - result.trueExpression = trueExpr; - result.falseExpression = falseExpr; - return result; - } - - public static def YieldExpression _YieldExpr(Expression expr) { - val result = N4JSFactory.eINSTANCE.createYieldExpression; - result.expression = expr; - return result; - } - - public static def ParameterizedCallExpression _CallExpr() { - val result = N4JSFactory.eINSTANCE.createParameterizedCallExpression; - return result; - } - - public static def ParameterizedCallExpression _CallExpr(Expression target, Expression... arguments) { - return _CallExpr(target, false, arguments); - } - - public static def ParameterizedCallExpression _CallExpr(Expression target, boolean optionalChaining, Expression... arguments) { - val result = N4JSFactory.eINSTANCE.createParameterizedCallExpression; - result.target = target; - result.optionalChaining = optionalChaining; - result.arguments += arguments.filterNull.map[_Argument]; - return result; - } - - public static def Argument _Argument(Expression expression) { - return _Argument(false, expression); - } - public static def Argument _Argument(boolean spread, Expression expression) { - val result = N4JSFactory.eINSTANCE.createArgument; - result.spread = spread; - result.expression = expression; - return result; - } - - public static def ExpressionStatement _ExprStmnt(Expression expr) { - val result = N4JSFactory.eINSTANCE.createExpressionStatement; - result.expression = expr; - return result; - } - - public static def AssignmentExpression _AssignmentExpr() { - val result = N4JSFactory.eINSTANCE.createAssignmentExpression; - result.op = AssignmentOperator.ASSIGN; - return result; - } - - public static def AssignmentExpression _AssignmentExpr(Expression lhs, Expression rhs) { - val result = N4JSFactory.eINSTANCE.createAssignmentExpression; - result.lhs = lhs; - result.op = AssignmentOperator.ASSIGN; - result.rhs = rhs; - return result; - } - - public static def ParameterizedPropertyAccessExpression_IM _PropertyAccessExpr() { - val result = ImFactory.eINSTANCE.createParameterizedPropertyAccessExpression_IM; - return result; - } - - public static def ParameterizedPropertyAccessExpression_IM _PropertyAccessExpr(SymbolTableEntry target, - SymbolTableEntry... properties) { - return _PropertyAccessExpr(_IdentRef(target), properties); - } - - public static def ParameterizedPropertyAccessExpression_IM _PropertyAccessExpr(Expression target, - SymbolTableEntry... properties) { - if(properties===null || properties.exists[it===null]) { - throw new IllegalArgumentException("none of the properties may be null") - } - var result = ImFactory.eINSTANCE.createParameterizedPropertyAccessExpression_IM; - result.target = target; - if(properties.length>0) { - result.rewiredTarget = properties.get(0); - for(idx : 1..null values (they will be ignored). - */ - public static def ObjectLiteral _ObjLit(Pair... nameValuePairs) { - return _ObjLit(nameValuePairs.filterNull.map[_PropertyNameValuePair(key,value)]); - } - - public static def ObjectLiteral _ObjLit(PropertyAssignment... pas) { - val result = N4JSFactory.eINSTANCE.createObjectLiteral; - if(pas!==null) { - result.propertyAssignments += pas.filterNull; - } - return result; - } - - public static def PropertyNameValuePair _PropertyNameValuePair(String name, Expression value) { - return _PropertyNameValuePair(_LiteralOrComputedPropertyName(name), value); - } - public static def PropertyNameValuePair _PropertyNameValuePair(LiteralOrComputedPropertyName name, Expression value) { - val result = N4JSFactory.eINSTANCE.createPropertyNameValuePair; - result.declaredName = name; - result.expression = value; - return result; - } - - public static def PropertyGetterDeclaration _PropertyGetterDecl(String name, Statement... stmnts) { - val result = N4JSFactory.eINSTANCE.createPropertyGetterDeclaration; - result.declaredName = _LiteralOrComputedPropertyName(name); - result.body = _Block(stmnts); - return result; - } - - public static def ArrayLiteral _ArrLit() { // required to resolve the ambiguity between the other two methods - return _ArrLit(null as ArrayElement[]); - } - - public static def ArrayLiteral _ArrLit(Expression... elements) { - return _ArrLit(elements.filterNull.map[_ArrayElement(it)]); - } - - public static def ArrayLiteral _ArrLit(ArrayElement... elements) { - val result = N4JSFactory.eINSTANCE.createArrayLiteral; - if(elements!==null) { - result.elements += elements.filterNull; - } - return result; - } - - public static def ArrayElement _ArrayElement(Expression expression) { - return _ArrayElement(false, expression); - } - public static def ArrayElement _ArrayElement(boolean spread, Expression expression) { - val result = N4JSFactory.eINSTANCE.createArrayElement; - result.spread = spread; - result.expression = expression; - return result; - } - public static def ArrayPadding _ArrayPadding() { - val result = N4JSFactory.eINSTANCE.createArrayPadding; - return result; - } - - public static def FunctionDeclaration _FunDecl(String name, Statement... statements) { - return _FunDecl(name, #[], statements); - } - - public static def FunctionDeclaration _FunDecl(String name, FormalParameter[] fpars, Statement... statements) { - val result = N4JSFactory.eINSTANCE.createFunctionDeclaration; - result.name = name; - result.fpars += fpars; - result.body = _Block(statements); - return result; - } - - public static def FunctionExpression _FunExpr(boolean async, Statement... statements) { - return _FunExpr(async, null, #[], statements); - } - - public static def FunctionExpression _FunExpr(boolean async, String name, Statement... statements) { - return _FunExpr(async, name, #[], statements); - } - - public static def FunctionExpression _FunExpr(boolean async, String name, FormalParameter... formalParams) { - return _FunExpr(async, name, formalParams, #[]); - } - - public static def FunctionExpression _FunExpr(boolean async, String name, FormalParameter[] fpars, Statement... statements) { - if(statements !== null && statements.length===1 && statements.get(0) instanceof Block) { - // safe guard: in case complex EMF inheritance hierarchy causes wrong overload to be invoked - return _FunExprWithBlock(async, name, fpars, statements.get(0) as Block); - } - val result = N4JSFactory.eINSTANCE.createFunctionExpression; - result.declaredAsync = async; - result.name = name; - result.fpars += fpars; - result.body = _Block(statements); - return result; - } - - public static def FormalParameter _FormalParameter(String name) { - val result = N4JSFactory.eINSTANCE.createFormalParameter; - result.name = name; - return result; - } - - public static def FunctionExpression _FunExpr(boolean async, String name, FormalParameter[] fpars, Block block) { - return _FunExprWithBlock(async, name, fpars, block); - } - private static def FunctionExpression _FunExprWithBlock(boolean async, String name, FormalParameter[] fpars, Block block) { - val result = N4JSFactory.eINSTANCE.createFunctionExpression; - result.declaredAsync = async; - result.name = name; - result.fpars += fpars; - result.body = block; - return result; - } - - /** Creates a {@link ArrowFunction#isSingleExprImplicitReturn() single-expression arrow function}. */ - public static def ArrowFunction _ArrowFunc(boolean async, FormalParameter[] fpars, Expression expression) { - val result = N4JSFactory.eINSTANCE.createArrowFunction; - result.declaredAsync = async; - result.fpars += fpars; - result.body = _Block(_ExprStmnt(expression)); - result.hasBracesAroundBody = false; - return result; - } - - public static def ArrowFunction _ArrowFunc(boolean async, FormalParameter[] fpars, Statement... statements) { - val result = N4JSFactory.eINSTANCE.createArrowFunction; - result.declaredAsync = async; - result.fpars += fpars; - result.body = _Block(statements); - result.hasBracesAroundBody = true; - return result; - } - - public static def N4MemberDeclaration _N4MemberDecl(TMember template, Statement... statements) { - if(template instanceof TField && !statements.empty) { - throw new IllegalArgumentException("fields cannot have statements"); - } - val result = switch(template) { - TField: N4JSFactory.eINSTANCE.createN4FieldDeclaration - TGetter: N4JSFactory.eINSTANCE.createN4GetterDeclaration - TSetter: N4JSFactory.eINSTANCE.createN4SetterDeclaration - TMethod: N4JSFactory.eINSTANCE.createN4MethodDeclaration - default: throw new IllegalArgumentException("unsupported subtype of TMember: " + template.eClass.name) - }; - // basic properties - result.declaredName = _LiteralOrComputedPropertyName(template.name); - // body - if(result instanceof FunctionOrFieldAccessor) { - result.body = _Block(statements.filterNull); - } - // formal parameters - if(template instanceof TSetter) { - val fparName = template.fpar?.name ?: "value"; - (result as N4SetterDeclaration).fpar = _Fpar(fparName); - } - if(template instanceof TMethod) { - (result as N4MethodDeclaration).fpars += template.fpars.map[_Fpar(name)]; - (result as N4MethodDeclaration).declaredAsync = template.declaredAsync; - } - // static / non-static - if(template.static) { - result.declaredModifiers += N4Modifier.STATIC; - } - // access modifiers - switch(template.memberAccessModifier) { - case PUBLIC: result.declaredModifiers += N4Modifier.PUBLIC - case PUBLIC_INTERNAL: { - result.declaredModifiers += N4Modifier.PUBLIC; - result.getOrCreateMemberAnnotationList.annotations += _Annotation(AnnotationDefinition.INTERNAL); - } - case PROTECTED: result.declaredModifiers += N4Modifier.PROTECTED - case PROTECTED_INTERNAL: { - result.declaredModifiers += N4Modifier.PROTECTED; - result.getOrCreateMemberAnnotationList.annotations += _Annotation(AnnotationDefinition.INTERNAL); - } - case PROJECT: result.declaredModifiers += N4Modifier.PROJECT - case PRIVATE: result.declaredModifiers += N4Modifier.PRIVATE - case UNDEFINED: {/* NOP */} - } - return result; - } - private static def N4MemberAnnotationList getOrCreateMemberAnnotationList(AnnotableN4MemberDeclaration memberDecl) { - var annList = memberDecl.annotationList; - if(annList===null) { - annList = N4JSFactory.eINSTANCE.createN4MemberAnnotationList; - memberDecl.annotationList = annList; - } - return annList; - } - - public static def N4FieldDeclaration _N4FieldDecl(boolean isStatic, String declaredName, Expression initExpr) { - return _N4FieldDecl(isStatic, _LiteralOrComputedPropertyName(declaredName), initExpr); - } - - public static def N4FieldDeclaration _N4FieldDecl(boolean isStatic, LiteralOrComputedPropertyName declaredName, Expression initExpr) { - val result = N4JSFactory.eINSTANCE.createN4FieldDeclaration; - if (isStatic) { - result.declaredModifiers += N4Modifier.STATIC; - } - result.declaredName = declaredName; - result.expression = initExpr; - return result; - } - - public static def N4GetterDeclaration _N4GetterDecl(LiteralOrComputedPropertyName declaredName, Block body) { - val result = N4JSFactory.eINSTANCE.createN4GetterDeclaration; - result.declaredName = declaredName; - result.body = body; - return result; - } - - public static def N4SetterDeclaration _N4SetterDecl(LiteralOrComputedPropertyName declaredName, FormalParameter fpar, Block body) { - val result = N4JSFactory.eINSTANCE.createN4SetterDeclaration; - result.declaredName = declaredName; - result.fpar = fpar; - result.body = body; - return result; - } - - public static def N4MethodDeclaration _N4MethodDecl(String name, Statement... statements) { - return _N4MethodDecl(name, #[], statements); - } - public static def N4MethodDeclaration _N4MethodDecl(String name, FormalParameter[] fpars, Statement... statements) { - return _N4MethodDecl(false, _LiteralOrComputedPropertyName(name), fpars, _Block(statements.filterNull)); - } - public static def N4MethodDeclaration _N4MethodDecl(LiteralOrComputedPropertyName declaredName, Block body) { - return _N4MethodDecl(false, declaredName, #[], body); - } - public static def N4MethodDeclaration _N4MethodDecl(boolean isStatic, LiteralOrComputedPropertyName declaredName, FormalParameter[] fpars, Block body) { - val result = N4JSFactory.eINSTANCE.createN4MethodDeclaration; - if (isStatic) { - result.declaredModifiers += N4Modifier.STATIC - } - result.declaredName = declaredName; - result.fpars += fpars; - result.body = body; - return result; - } - - public static def FormalParameter _Fpar() { - return _Fpar(null, false, false); - } - public static def FormalParameter _Fpar(String name) { - return _Fpar(name, false, false); - } - public static def FormalParameter _Fpar(String name, boolean variadic) { - return _Fpar(name, variadic, false); - } - public static def FormalParameter _Fpar(String name, boolean variadic, boolean isSpecFpar) { - val result = N4JSFactory.eINSTANCE.createFormalParameter; - result.name = name; - result.variadic = variadic; - if(isSpecFpar) { - result.annotations += _Annotation(AnnotationDefinition.SPEC); - } - return result; - } - - public static def Annotation _Annotation(AnnotationDefinition annDef) { - val result = N4JSFactory.eINSTANCE.createAnnotation; - result.name = annDef.name; - return result; - } - - public static def AnnotationList _AnnotationList(List annDef) { - val result = N4JSFactory.eINSTANCE.createAnnotationList; - if( annDef !== null ) - result.annotations += annDef.map[ _Annotation(it) ]; - return result; - } - - public static def PropertyAssignmentAnnotationList _PropertyAssignmentAnnotationList(Annotation[] annotations) { - val result = N4JSFactory.eINSTANCE.createPropertyAssignmentAnnotationList; - result.annotations += annotations; - return result; - } - - public static def Block _Block(Statement... statements) { - val result = N4JSFactory.eINSTANCE.createBlock; - result.statements += statements.filterNull; - return result; - } - - public static def ParenExpression _Parenthesis(Expression expr) { - val result = N4JSFactory.eINSTANCE.createParenExpression; - result.expression = expr; - return result; - } - - public static def ParameterizedCallExpression _ParameterizedCallExpression(Expression expr) { - val result = N4JSFactory.eINSTANCE.createParameterizedCallExpression; - result.target = expr; - return result; - } - - public static def NullLiteral _NULL() { - return N4JSFactory.eINSTANCE.createNullLiteral; - } - - public static def BooleanLiteral _TRUE() { - return _BooleanLiteral(true); - } - public static def BooleanLiteral _FALSE() { - return _BooleanLiteral(false); - } - public static def BooleanLiteral _BooleanLiteral(boolean value) { - val result = N4JSFactory.eINSTANCE.createBooleanLiteral; - result.^true = value; - return result; - } - - public static def NumericLiteral _NumericLiteral(int num) { - return _NumericLiteral(BigDecimal.valueOf(num)); - } - - public static def NumericLiteral _NumericLiteral(BigDecimal num) { - val result = N4JSFactory.eINSTANCE.createNumericLiteral; - result.value = num; - return result; - } - - public static def StringLiteral _StringLiteral(String s, String rawValue) { - val result = _StringLiteral(s); - result.rawValue = rawValue; - return result; - } - - public static def StringLiteral _StringLiteral(String s) { - val result = N4JSFactory.eINSTANCE.createStringLiteral; - result.value = s; - return result; - } - - public static def StringLiteral _StringLiteralForSTE(SymbolTableEntry symbolTableEntry) { - return _StringLiteralForSTE(symbolTableEntry, false); - } - - public static def StringLiteral _StringLiteralForSTE(SymbolTableEntry symbolTableEntry, boolean useExportedName) { - val result = ImFactory.eINSTANCE.createStringLiteralForSTE; - result.entry = symbolTableEntry; - result.useExportedName = useExportedName; - return result; - } - - public static def IntLiteral _IntLiteral(int i) { - val result = N4JSFactory.eINSTANCE.createIntLiteral; - result.value = BigDecimal.valueOf(i); - return result; - } - - public static def ThisLiteral _ThisLiteral() { - val result = N4JSFactory.eINSTANCE.createThisLiteral; - return result; - } - - public static def SuperLiteral _SuperLiteral() { - val result = N4JSFactory.eINSTANCE.createSuperLiteral; - return result; - } - - public static def _emptyStatement() { - return N4JSFactory.eINSTANCE.createEmptyStatement - } - - public static def N4EnumDeclaration _EnumDeclaration(String name, List literals) { - val result = N4JSFactory.eINSTANCE.createN4EnumDeclaration; - result.name = name; - result.literals += literals; - return result; - } - - public static def _EnumLiteral(String name, String value) { - val result = N4JSFactory.eINSTANCE.createN4EnumLiteral; - result.name = name; - result.valueExpression = if (value !== null) _StringLiteral(value); - return result; - } - - public static def _N4ClassDeclaration(String name){ - val result = N4JSFactory.eINSTANCE.createN4ClassDeclaration; - result.name = name; - return result; - } - - public static def _N4InterfaceDeclaration(String name){ - val result = N4JSFactory.eINSTANCE.createN4InterfaceDeclaration; - result.name = name; - return result; - } - - public static def _N4TypeVariable(String name, boolean covariant, boolean contravariant) { - val result = N4JSFactory.eINSTANCE.createN4TypeVariable; - result.name = name; - result.declaredCovariant = covariant; - result.declaredContravariant = contravariant; - return result; - } - - public static def _LiteralOrComputedPropertyName(String name) { - val result = N4JSFactory.eINSTANCE.createLiteralOrComputedPropertyName; - result.kind = PropertyNameKind.STRING; - result.literalName = name; - return result; - } - - /** - * @param computedName the string representation of the computed property name. This should be the value that - * is usually computed and set by {@link CompileTimeExpressionProcessor} and {@link ComputedNameProcessor}. - */ - public static def _LiteralOrComputedPropertyName(Expression nameExpr, String computedName) { - val result = N4JSFactory.eINSTANCE.createLiteralOrComputedPropertyName; - result.kind = PropertyNameKind.COMPUTED; - result.expression = nameExpr; - result.computedName = computedName; - return result; - } - - // ############################################################################################ - // IM.xcore - - public static def TypeReferenceNode_IM _TypeReferenceNode(TranspilerState state, TypeRef typeRef) { - val TypeReferenceNode_IM result = ImFactory.eINSTANCE.createTypeReferenceNode_IM(); - if (typeRef !== null) { - state.info.setOriginalProcessedTypeRef_internal(result, TypeUtils.copyIfContained(typeRef)); - } - return result; - } - - public static def IdentifierRef_IM _IdentRef(SymbolTableEntry symbolTableEntry) { - if(symbolTableEntry===null) { - throw new IllegalArgumentException("when creating an IdentifierRef_IM: symbol table entry may not be null"); - } - val result = ImFactory.eINSTANCE.createIdentifierRef_IM; - result.rewiredTarget = symbolTableEntry; - return result; - } - - public static def SymbolTableEntry _SymbolTableEntry(String name) { - throw new UnsupportedOperationException("do not manually create symbol table entries; use methods #createSymbolTableEntry() or #getSymbolTableEntry() instead"); - } - - public static def ExpressionStatement _SnippetAsStmnt(String code) { - return _ExprStmnt(_Snippet(code)); - } - - public static def Snippet _Snippet(String codeToEmit) { - val result = ImFactory.eINSTANCE.createSnippet; - result.codeToEmit = codeToEmit; - return result; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerComponent.java b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerComponent.java index 85f9363a4f..746941abf3 100644 --- a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerComponent.java +++ b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerComponent.java @@ -12,6 +12,7 @@ import java.util.Collection; import java.util.List; +import java.util.function.Consumer; import org.eclipse.emf.ecore.EObject; import org.eclipse.n4js.n4JS.ArrowFunction; @@ -49,7 +50,6 @@ import org.eclipse.n4js.ts.types.TClassifier; import org.eclipse.n4js.ts.types.TModule; import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; -import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; import com.google.inject.Inject; import com.google.inject.Singleton; @@ -130,7 +130,7 @@ protected void setTarget(ParameterizedPropertyAccessExpression_IM accExpr, Expre @SuppressWarnings("javadoc") protected void addArgument(ParameterizedCallExpression callExpr, int index, Expression newArgument) { - TranspilerStateOperations.addArgument(state, callExpr, index, newArgument); + TranspilerStateOperations.addArgument(callExpr, index, newArgument); } @SuppressWarnings("javadoc") @@ -207,19 +207,18 @@ protected void replaceAndRelocate(FormalParameter fPar_to_remove, VariableStatem @SuppressWarnings("javadoc") protected void wrapExistingExpression(T exprToWrap, Expression outerExpr_without_exprToWrap, - Procedure1 inserterFunction) { - TranspilerStateOperations.wrapExistingExpression(state, exprToWrap, outerExpr_without_exprToWrap, - inserterFunction); + Consumer inserterFunction) { + TranspilerStateOperations.wrapExistingExpression(exprToWrap, outerExpr_without_exprToWrap, inserterFunction); } - /** Delegates to {@link TranspilerStateOperations#insertBefore(TranspilerState, EObject, EObject...)}. */ + /** Delegates to {@link TranspilerStateOperations#insertBefore( EObject, EObject...)}. */ protected void insertBefore(EObject elementInIntermediateModel, EObject... newElements) { - TranspilerStateOperations.insertBefore(state, elementInIntermediateModel, newElements); + TranspilerStateOperations.insertBefore(elementInIntermediateModel, newElements); } - /** Delegates to {@link TranspilerStateOperations#insertAfter(TranspilerState, EObject, EObject...)}. */ + /** Delegates to {@link TranspilerStateOperations#insertAfter( EObject, EObject...)}. */ protected void insertAfter(EObject elementInIntermediateModel, EObject... newElements) { - TranspilerStateOperations.insertAfter(state, elementInIntermediateModel, newElements); + TranspilerStateOperations.insertAfter(elementInIntermediateModel, newElements); } /** Delegates to {@link TranspilerStateOperations#copy(TranspilerState, EObject)}. */ @@ -307,7 +306,7 @@ protected void recordReferenceToType(TypeReferenceNode_IM typeRefNode, Symbol @SuppressWarnings("javadoc") protected void rename(SymbolTableEntry entry, String newName) { - TranspilerStateOperations.rename(state, entry, newName); + TranspilerStateOperations.rename(entry, newName); } @SuppressWarnings("javadoc") diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.java b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.java new file mode 100644 index 0000000000..d7c090b1f2 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.java @@ -0,0 +1,653 @@ +/** + * 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.transpiler; + +import static org.eclipse.n4js.transpiler.SymbolTableManagement.findSymbolTableEntryForElement; +import static org.eclipse.n4js.transpiler.SymbolTableManagement.getSymbolTableEntryOriginal; +import static org.eclipse.n4js.transpiler.SymbolTableManagement.rewireSymbolTable; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._Argument; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ImportDecl; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._NamedImportSpecifier; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._NamespaceImportSpecifier; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ReturnStmnt; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableDeclaration; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._VariableStatement; +import static org.eclipse.n4js.utils.Strings.join; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.function.Consumer; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.util.EObjectContainmentEList; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.n4js.n4JS.ArrowFunction; +import org.eclipse.n4js.n4JS.Block; +import org.eclipse.n4js.n4JS.EmptyStatement; +import org.eclipse.n4js.n4JS.ExportDeclaration; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ExpressionStatement; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.FunctionDeclaration; +import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4EnumDeclaration; +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.n4JS.ReturnStatement; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.n4JS.ScriptElement; +import org.eclipse.n4js.n4JS.Statement; +import org.eclipse.n4js.n4JS.VariableBinding; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.VariableEnvironmentElement; +import org.eclipse.n4js.n4JS.VariableStatement; +import org.eclipse.n4js.n4JS.VariableStatementKeyword; +import org.eclipse.n4js.transpiler.im.ImPackage; +import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM; +import org.eclipse.n4js.transpiler.im.ReferencingElement_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryIMOnly; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.transpiler.utils.TranspilerUtils; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.xtext.xbase.lib.Pair; + +import com.google.common.collect.Lists; + +/** + * Methods of this class provide elementary operations on a transpiler state, mainly on the intermediate model. The + * intermediate model should only be changed through the operations defined by this class. + *

+ * Main clients are AST transformations, but they should not invoke these operations directly, but instead use the + * delegation methods in {@link Transformation}. + */ +public class TranspilerStateOperations { + + /** + * Creates a new namespace import for the given module and adds it to the intermediate model of the given transpiler + * state. The returned symbol table entry can be used to create references to the namespace, e.g. by passing it to + * {@link TranspilerBuilderBlocks#_IdentRef(SymbolTableEntry)}. The newly created import can be obtained by calling + * {@link SymbolTableEntryOriginal#getImportSpecifier()} on the returned symbol table entry. + *

+ * IMPORTANT: this method does not check if an import for the given module exists already or if the given namespace + * name is unique (i.e. does not avoid name clashes!). + */ + public static SymbolTableEntryOriginal addNamespaceImport(TranspilerState state, TModule moduleToImport, + String namespaceName) { + + // 1) create import declaration & specifier + NamespaceImportSpecifier importSpec = _NamespaceImportSpecifier(namespaceName, true); + ImportDeclaration importDecl = _ImportDecl(importSpec); + // 2) create a temporary type to use as original target + ModuleNamespaceVirtualType typeForNamespace = TypesFactory.eINSTANCE.createModuleNamespaceVirtualType(); + typeForNamespace.setName(namespaceName); + state.resource.addTemporaryType(typeForNamespace); // make sure our temporary type is contained in a resource + // 3) create a symbol table entry + SymbolTableEntryOriginal steForNamespace = getSymbolTableEntryOriginal(state, typeForNamespace, true); + steForNamespace.setImportSpecifier(importSpec); + // 4) add import to intermediate model + EList scriptElements = state.im.getScriptElements(); + if (scriptElements.isEmpty()) { + scriptElements.add(importDecl); + } else { + insertBefore(scriptElements.get(0), importDecl); + } + // 5) update info registry + state.info.setImportedModule(importDecl, moduleToImport); + return steForNamespace; + } + + /** + * Creates a new named import for the given element and adds it to the intermediate model of the given transpiler + * state. The returned symbol table entry can be used to create references to the imported element, e.g. by passing + * it to {@link TranspilerBuilderBlocks#_IdentRef(SymbolTableEntry)}. The newly created import can be obtained by + * calling {@link SymbolTableEntryOriginal#getImportSpecifier()} on the returned symbol table entry. + *

+ * If a named import already exists for the given element, nothing will be changed in the intermediate model and its + * symbol table entry will be returned as described above. If the given element is of type + * {@link ModuleNamespaceVirtualType} an exception will be thrown (because only namespace imports can be created for + * those types). + *

+ * IMPORTANT: this method does not check if the given namespace name is unique (i.e. does not avoid name clashes!). + */ + public static SymbolTableEntryOriginal addNamedImport(TranspilerState state, IdentifiableElement elementToImport, + String aliasOrNull) { + SymbolTableEntryOriginal steOfElementToImport = getSymbolTableEntryOriginal(state, elementToImport, true); + addNamedImport(state, steOfElementToImport, aliasOrNull); + return steOfElementToImport; + } + + /** + * Creates a new named import for the given STE and adds it to the intermediate model of the given transpiler state. + * The passed-in symbol table entry can be used to create references to the imported element, e.g. by passing it to + * {@link TranspilerBuilderBlocks#_IdentRef(SymbolTableEntry)}. The newly created import can be obtained by calling + * {@link SymbolTableEntryOriginal#getImportSpecifier()} on the passed-in symbol table entry. + *

+ * If a named import already exists for the given element, nothing will be changed in the intermediate model. If the + * original target of the given symbol table entry is of type {@link ModuleNamespaceVirtualType} an exception will + * be thrown (because only namespace imports can be created for those types). + *

+ * IMPORTANT: this method does not check if the given namespace name is unique (i.e. does not avoid name clashes!). + */ + public static void addNamedImport(TranspilerState state, SymbolTableEntryOriginal steOfElementToImport, + String aliasOrNull) { + // check for valid type of element to be imported (i.e. the original target) + IdentifiableElement originalTarget = steOfElementToImport.getOriginalTarget(); + if (originalTarget instanceof ModuleNamespaceVirtualType) { + throw new IllegalArgumentException("cannot create named import for a ModuleNamespaceVirtualType"); + } + // check for existing import + ImportSpecifier existingImportSpec = steOfElementToImport.getImportSpecifier(); + if (existingImportSpec != null) { + // import already exists, nothing to be done + return; + } + + // 1) create import declaration & specifier + NamedImportSpecifier importSpec = _NamedImportSpecifier(steOfElementToImport.getExportedName(), aliasOrNull, + true); + ImportDeclaration importDecl = _ImportDecl(importSpec); + // 2) add import to intermediate model + EList scriptElements = state.im.getScriptElements(); + if (scriptElements.isEmpty()) { + scriptElements.add(importDecl); + } else { + insertBefore(scriptElements.get(0), importDecl); + } + // 3) link symbol table entry to its newly created import specifier + steOfElementToImport.setImportSpecifier(importSpec); + // 4) update info registry + TModule moduleOfOriginalTarget = originalTarget.getContainingModule(); + state.info.setImportedModule(importDecl, moduleOfOriginalTarget); + } + + /** + * Adds an "empty" import to the intermediate model, i.e. an import of the form: + * + *

+	 * import "<moduleSpecifier>";
+	 * 
+ */ + public static void addEmptyImport(TranspilerState state, String moduleSpecifier) { + // 1) create import declaration + ImportDeclaration importDecl = _ImportDecl(); + importDecl.setModuleSpecifierAsText(moduleSpecifier); + // 2) add import to intermediate model + EList scriptElements = state.im.getScriptElements(); + if (scriptElements.isEmpty()) { + scriptElements.add(importDecl); + } else { + insertBefore(scriptElements.get(0), importDecl); + } + } + + /** + * Returns the symbol table entry to a temporary variable with the given name, intended for use at the location of + * "nodeInIM" in the intermediate model. If no such variable exists yet, a new variable statement and declaration + * will be created. + *

+ * When newly created, the temporary declarations will be added to the body of the closest ancestor + * function/accessor (or on the top level if no such ancestor exists), even if a temporary variable of the same name + * already exists in an outer variable environment (i.e. an outer function/accessor or on top level if inside a + * function/accessor). + */ + public static SymbolTableEntryIMOnly addOrGetTemporaryVariable(TranspilerState state, String name, + EObject nodeInIM) { + FunctionOrFieldAccessor contextFunctionOrAccessor = getContextFunctionOrAccessor(nodeInIM); + VariableEnvironmentElement context = contextFunctionOrAccessor != null ? contextFunctionOrAccessor : state.im; + SymbolTableEntryIMOnly tempVarSTE = state.temporaryVariables.get(Pair.of(context, name)); + if (tempVarSTE != null) { + return tempVarSTE; + } + // need to create a new temporary variable below context + VariableStatement tempVarStmnt = addOrGetTemporaryVariableStatement(state, context); + VariableDeclaration tempVarDecl = _VariableDeclaration(name); + tempVarStmnt.getVarDeclsOrBindings().add(tempVarDecl); + SymbolTableEntryIMOnly tempVarSTENew = (SymbolTableEntryIMOnly) findSymbolTableEntryForElement(state, + tempVarDecl, true); + state.temporaryVariables.put(Pair.of(context, name), tempVarSTENew); + return tempVarSTENew; + } + + private static FunctionOrFieldAccessor getContextFunctionOrAccessor(EObject nodeInIM) { + if (nodeInIM == null) { + return null; + } + if (nodeInIM instanceof FunctionOrFieldAccessor) { + return (FunctionOrFieldAccessor) nodeInIM; + } + EObject parent = nodeInIM.eContainer(); + if (parent instanceof FormalParameter + && parent.eContainer() instanceof FunctionOrFieldAccessor + && ((FormalParameter) parent).getInitializer() == nodeInIM) { + // special case: since the expression of a default parameter cannot access a function"s local variables, + // the directly containing function of a default parameter is not a valid context function for temporary + // variables used in the default parameter"s initializer expression. + EObject parentOfContainingFunctionOrAccessor = parent.eContainer().eContainer(); + return getContextFunctionOrAccessor(parentOfContainingFunctionOrAccessor); + } + return getContextFunctionOrAccessor(parent); + } + + /** If context is absent, then the temporary variable statement will be created on the top level. */ + private static VariableStatement addOrGetTemporaryVariableStatement(TranspilerState state, + VariableEnvironmentElement context) { + VariableStatement tempVarStmnt = state.temporaryVariableStatements.get(context); + if (tempVarStmnt != null) { + return tempVarStmnt; + } + // need to create a new temporary variable statement + VariableStatement tempVarStmntNew = _VariableStatement(VariableStatementKeyword.LET); + state.temporaryVariableStatements.put(context, tempVarStmntNew); + if (context instanceof FunctionOrFieldAccessor) { + // add to body of function/accessor + if (context instanceof ArrowFunction) { + ArrowFunction af = (ArrowFunction) context; + if (!af.isHasBracesAroundBody()) { + // to allow for declarations inside the body, we have to turn single-expression arrow functions into + // ordinary arrow functions + if (af.isSingleExprImplicitReturn()) { + ExpressionStatement singleExprStmnt = (ExpressionStatement) af.getBody().getStatements().get(0); // we + // know + // this, + // because + // #isSingleExprImplicitReturn() + // returned + // true + replace(state, singleExprStmnt, _ReturnStmnt(singleExprStmnt.getExpression())); + } + af.setHasBracesAroundBody(true); + } + } + ((FunctionOrFieldAccessor) context).getBody().getStatements().add(0, tempVarStmntNew); + } else if (context instanceof Script) { + Script script = (Script) context; + // add on top level before the first non-empty, non-import statement + Iterator iter = script.getScriptElements().iterator(); + ScriptElement elem; + do { + elem = (iter.hasNext()) ? iter.next() : null; + } while (elem instanceof EmptyStatement || elem instanceof ImportDeclaration); + if (elem != null) { + insertBefore(elem, tempVarStmntNew); + } else { + script.getScriptElements().add(tempVarStmntNew); + } + } + return tempVarStmntNew; + } + + /***/ + public static void setTarget(TranspilerState state, ParameterizedCallExpression callExpr, Expression newTarget) { + Expression oldTarget = callExpr.getTarget(); + if (oldTarget != null) { + replaceWithoutRewire(state, oldTarget, newTarget); + } else { + callExpr.setTarget(newTarget); + } + } + + /***/ + public static void setTarget(TranspilerState state, ParameterizedPropertyAccessExpression_IM accExpr, + Expression newTarget) { + Expression oldTarget = accExpr.getTarget(); + if (oldTarget != null) { + replaceWithoutRewire(state, oldTarget, newTarget); + } else { + accExpr.setTarget(newTarget); + } + } + + /***/ + public static void addArgument(ParameterizedCallExpression callExpr, int index, Expression newArgument) { + callExpr.getArguments().add(index, _Argument(newArgument)); + } + + /***/ + public static void removeAll(TranspilerState state, Iterable elementsInIM) { + for (EObject elementInIM : Lists.newArrayList(elementsInIM)) { + remove(state, elementInIM); + } + } + + /***/ + public static void remove(TranspilerState state, EObject elementInIM) { + replaceWithoutRewire(state, elementInIM); // i.e. replace with nothing (will update tracer) + if (elementInIM instanceof ReferencingElement_IM) { + ((ReferencingElement_IM) elementInIM).setRewiredTarget(null); // important here: will remove elementInIM + // from its symbol table entry"s + // "referencingElements" list! + // note: this update of the symbol table is incomplete; elementInIM may be the root of an entire subtree + // of the IM, so we would have to iterate over all successors + } + } + + /** + * Removes the export-container (ExportDeclaration) by creating a new VariableStatement {@code varStmt}, moving all + * content from {@code exVarStmnt} into it and replacing the ExportDeclaration with the newly created + * {@code varStmt} + */ + public static void removeExport(TranspilerState state, VariableStatement exVarStmnt) { + + if (!TranspilerUtils.isIntermediateModelElement(exVarStmnt)) { + throw new IllegalArgumentException("not an element in the intermediate model: " + exVarStmnt); + } + + ExportDeclaration exportDecl = (ExportDeclaration) exVarStmnt.eContainer(); + + replaceWithoutRewire(state, exportDecl, exVarStmnt); + } + + /***/ + public static void replace(TranspilerState state, Statement stmnt, ReturnStatement returnStmnt) { + replaceWithoutRewire(state, stmnt, returnStmnt); + } + + /***/ + public static void replace(TranspilerState state, N4ClassDeclaration classDecl, FunctionDeclaration funDecl) { + replaceWithoutRewire(state, classDecl, funDecl); + rewireSymbolTable(state, classDecl, funDecl); + } + + /** + * Replace an interface declaration by a variable declaration. The variable declaration will be wrapped in a newly + * created [Exported]VariableStatement. + */ + public static void replace(TranspilerState state, N4InterfaceDeclaration ifcDecl, VariableDeclaration varDecl) { + VariableStatement varStmnt = _VariableStatement(VariableStatementKeyword.CONST, varDecl); + replaceWithoutRewire(state, ifcDecl, varStmnt); + rewireSymbolTable(state, ifcDecl, varDecl); + } + + /***/ + public static void replace(TranspilerState state, N4EnumDeclaration enumDecl, N4ClassDeclaration classDecl) { + replaceWithoutRewire(state, enumDecl, classDecl); + rewireSymbolTable(state, enumDecl, classDecl); + } + + /***/ + public static void replace(TranspilerState state, FunctionDeclaration funDecl, VariableDeclaration varDecl) { + VariableStatement varStmnt = _VariableStatement(varDecl); + replaceWithoutRewire(state, funDecl, varStmnt); + rewireSymbolTable(state, funDecl, varDecl); + // need to rewire the local arguments variable, to enable renaming: + Expression varValue = varDecl.getExpression(); + if (varValue instanceof FunctionExpression) { + rewireSymbolTable(state, funDecl.getImplicitArgumentsVariable(), + ((FunctionExpression) varValue).getImplicitArgumentsVariable()); + } else { + throw new IllegalArgumentException( + "when replacing a function declaration by a variable declaration, " + + "we expect the variable to be initialized with a function expression"); + } + } + + /***/ + public static void replace(TranspilerState state, FunctionDeclaration functionDecl, ExpressionStatement stmt) { + replaceWithoutRewire(state, functionDecl, stmt); + } + + /***/ + public static void replace(TranspilerState state, N4MemberDeclaration memberDecl, N4MemberDeclaration replacement) { + replaceWithoutRewire(state, memberDecl, replacement); + rewireSymbolTable(state, memberDecl, replacement); + } + + /***/ + public static void replace(TranspilerState state, VariableStatement varStmnt, Statement... newStmnts) { + replaceWithoutRewire(state, varStmnt, newStmnts); + } + + /***/ + public static void replace(TranspilerState state, VariableBinding varBinding, VariableDeclaration... varDecls) { + replaceWithoutRewire(state, varBinding, varDecls); + } + + /***/ + public static void replace(TranspilerState state, Expression exprOld, Expression exprNew) { + replaceWithoutRewire(state, exprOld, exprNew); + } + + /***/ + public static void replace(TranspilerState state, ArrowFunction exprOld, ParameterizedCallExpression exprNew, + FunctionExpression rewireTarget) { + replaceWithoutRewire(state, exprOld, exprNew); + rewireSymbolTable(state, exprOld, rewireTarget); + } + + /** Replace formal parameter with a variableStmt. Rewire the fpar to the VariableDeclaration. Relocate the Stmt */ + public static void replaceAndRelocate(TranspilerState state, FormalParameter fPar_to_remove, + VariableStatement varStmnt, + VariableDeclaration varDecl_wireTo, Block newContainer) { + if (varDecl_wireTo.eContainer() != varStmnt) { + throw new IllegalArgumentException("varDecl must be contained in varStmnt"); + } + replaceAndRelocateWithoutRewire_internal(state, fPar_to_remove, varStmnt, newContainer.getStatements(), 0); + + rewireSymbolTable(state, fPar_to_remove, varDecl_wireTo); + } + + /***/ + public static void wrapExistingExpression(T exprToWrap, + Expression outerExpr_without_exprToWrap, Consumer inserterFunction) { + + insertOrReplace_internal(exprToWrap, List.of(outerExpr_without_exprToWrap), true, false); + inserterFunction.accept(exprToWrap); + } + + /* + * append( pos < 0 or > current size ), prepend(pos==0) or insert at {@code pos} the object {@code insertThis} to + * {@code newContainer}. Also delete {@code removeThis} from the IM. Does not rewire. But keeps trace. + */ + private static void replaceAndRelocateWithoutRewire_internal(TranspilerState state, EObject removeThis, + EObject insertThis, + EList newContainer, int pos) { + + EReference eRefRemove = checkedContainmentFeature(removeThis); + + if (insertThis.eContainer() != null) + throw new IllegalArgumentException("The new element must not be contained anywhere." + + " insertThis=" + insertThis + " is currently contained in " + insertThis.eContainer()); + + if (newContainer instanceof EObjectContainmentEList) { + @SuppressWarnings("unchecked") + EObjectContainmentEList newContainerCasted = (EObjectContainmentEList) newContainer; + + //// Tracing: + state.tracer.copyTrace(removeThis, insertThis); + state.tracer.discardIntermediateModelNode(removeThis); + + //////////////////////////////////// + //// remove: + if (eRefRemove.getUpperBound() == 1) { // single-value + if (eRefRemove.isUnsettable()) + removeThis.eContainer().eUnset(eRefRemove); + else + removeThis.eContainer().eSet(eRefRemove, null); + } else { // multivalue + @SuppressWarnings("unchecked") + List l = (List) removeThis.eContainer().eGet(eRefRemove); // c.f. type check above + int idx = l.indexOf(removeThis); + l.remove(idx); + } + + //////////////////////////////////// + //// insert: + int idx = pos; // insert + + if (pos < 0 || pos >= newContainer.size()) { + // append + idx = newContainer.size(); + } + newContainerCasted.add(idx, insertThis); + + } else { + throw new IllegalArgumentException( + "designated new container-list must be a subtype of type EObjectContainmentList"); + } + } + + /** + * {@code elementInIntermediateModel} is going away (ie, should be garbage-collected) and therefore we clear all + * references to it from tracing. The {@code replacements} IM nodes take over whatever AST node was previously + * traced-back-to via the element going away. + */ + private static void replaceWithoutRewire(TranspilerState state, EObject elementInIntermediateModel, + EObject... replacements) { + + state.tracer.copyTrace(elementInIntermediateModel, replacements); + state.tracer.discardIntermediateModelNode(elementInIntermediateModel); + insertOrReplace_internal(elementInIntermediateModel, Arrays.asList(replacements), true, false); + } + + /***/ + public static void insertBefore(EObject elementInIntermediateModel, EObject... newElements) { + insertOrReplace_internal(elementInIntermediateModel, Arrays.asList(newElements), false, false); + } + + /***/ + public static void insertAfter(EObject elementInIntermediateModel, EObject... newElements) { + insertOrReplace_internal(elementInIntermediateModel, Arrays.asList(newElements), false, true); + } + + private static void insertOrReplace_internal(EObject elementInIntermediateModel, + List newElements, boolean replace, boolean after) { + if (newElements.isEmpty() && !replace) { + return; // nothing to be inserted + } + EReference eRef = checkedContainmentFeature(elementInIntermediateModel); + EClass eRefType = eRef.getEReferenceType(); + List replElemsOfWrongType = toList( + filter(newElements, elem -> !eRefType.isSuperTypeOf(elem.eClass()))); + if (!replElemsOfWrongType.isEmpty()) { + throw new IllegalArgumentException("one or more elements are of wrong type, expected: " + + eRef.getEReferenceType().getName() + ", actual: " + + join(", ", map(replElemsOfWrongType, eobj -> eobj.eClass().getName()))); + } + if (eRef.getUpperBound() == 1) { + // single valued + if (newElements.size() > 1) { + throw new IllegalArgumentException( + "the single-valued reference " + eRef.getName() + " in class " + eRef.getEContainingClass() + + " is not able to hold " + newElements.size() + " elements."); + } + if (newElements.size() == 1) { + if (!replace) { + throw new IllegalArgumentException( + "Cannot insert another element into a single-valued containment reference " + eRef.getName() + + " in class " + eRef.getEContainingClass()); + } + elementInIntermediateModel.eContainer().eSet(eRef, newElements.get(0)); + } else { + if (!replace) { + throw new IllegalArgumentException("Inserting zero elements with replace==false is pointless."); + } + // no element, so remove + if (eRef.isUnsettable()) { + elementInIntermediateModel.eContainer().eUnset(eRef); + } else { + elementInIntermediateModel.eContainer().eSet(eRef, null); + } + } + + } else { + // multi-valued + @SuppressWarnings("unchecked") + // c.f. type check above + List l = (List) elementInIntermediateModel.eContainer().eGet(eRef); + int idx = l.indexOf(elementInIntermediateModel); + if (replace) { + l.remove(idx); + } else { + // note: before/after only applicable if !replace + if (after) { + idx++; // always safe to increment, because we know there exists an element at index "idx" + } + } + l.addAll(idx, newElements); + } + } + + /** + * Retrieves the EReference of the Container. Throws Exceptions if a) not part of the IM or b) not contained + * anywhere + */ + private static EReference checkedContainmentFeature(EObject elementInIntermediateModel) { + if (!TranspilerUtils.isIntermediateModelElement(elementInIntermediateModel)) { + throw new IllegalArgumentException( + "not an element in the intermediate model: " + elementInIntermediateModel); + } + EReference eRef = elementInIntermediateModel.eContainmentFeature(); + if (eRef == null) { + throw new IllegalArgumentException("element is not contained anywhere"); + } + return eRef; + } + + /** + * Rename the given symbol table entry and all named elements in the intermediate model that are using this name. + * During AST transformations in the transpiler, the "name" property of a symbol table entry should never be changed + * directly, but this operation should be used instead. + *

+ * WARNING: renaming is currently only implemented partially and used only in a single, very specific use + * case; if renaming is required in the future, then the implementation of this method has to be complemented! + */ + public static void rename(SymbolTableEntry entry, String newName) { + SymbolTableManagement.rename(entry, newName); + } + + /** + * Copy a subtree of the intermediate model. + */ + @SuppressWarnings("unchecked") + public static T copy(TranspilerState state, T elementInIM) { + // create a copy with a special copier to take care of reference ReferencingElement_IM#rewiredTarget + IM2IMCopier copier = new IM2IMCopier(); + EObject result = copier.copy(elementInIM); + copier.copyReferences(); + // copy tracing information + state.tracer.copyTrace(elementInIM, result); // note: copying trace for all nodes would be more fine grained + return (T) result; + } + + private static final class IM2IMCopier extends EcoreUtil.Copier { + private static final EReference eRef__ReferencingElement_IM__rewiredTarget = ImPackage.eINSTANCE + .getReferencingElement_IM_RewiredTarget(); + + @Override + protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject) { + if (eReference == eRef__ReferencingElement_IM__rewiredTarget) { + ((ReferencingElement_IM) copyEObject) + .setRewiredTarget(((ReferencingElement_IM) eObject).getRewiredTarget()); + } else { + super.copyReference(eReference, eObject, copyEObject); + } + } + + } +} diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.xtend b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.xtend deleted file mode 100644 index 3da26775c5..0000000000 --- a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.xtend +++ /dev/null @@ -1,571 +0,0 @@ -/** - * 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.transpiler - -import com.google.common.collect.Lists -import java.util.List -import org.eclipse.emf.common.util.EList -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.EReference -import org.eclipse.emf.ecore.util.EObjectContainmentEList -import org.eclipse.emf.ecore.util.EcoreUtil -import org.eclipse.n4js.n4JS.ArrowFunction -import org.eclipse.n4js.n4JS.Block -import org.eclipse.n4js.n4JS.EmptyStatement -import org.eclipse.n4js.n4JS.ExportDeclaration -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.ExpressionStatement -import org.eclipse.n4js.n4JS.FormalParameter -import org.eclipse.n4js.n4JS.FunctionDeclaration -import org.eclipse.n4js.n4JS.FunctionExpression -import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.n4JS.N4EnumDeclaration -import org.eclipse.n4js.n4JS.N4InterfaceDeclaration -import org.eclipse.n4js.n4JS.N4MemberDeclaration -import org.eclipse.n4js.n4JS.ParameterizedCallExpression -import org.eclipse.n4js.n4JS.ReturnStatement -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.n4JS.ScriptElement -import org.eclipse.n4js.n4JS.Statement -import org.eclipse.n4js.n4JS.VariableBinding -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.n4JS.VariableEnvironmentElement -import org.eclipse.n4js.n4JS.VariableStatement -import org.eclipse.n4js.n4JS.VariableStatementKeyword -import org.eclipse.n4js.transpiler.im.ImPackage -import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM -import org.eclipse.n4js.transpiler.im.ReferencingElement_IM -import org.eclipse.n4js.transpiler.im.SymbolTableEntry -import org.eclipse.n4js.transpiler.im.SymbolTableEntryIMOnly -import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal -import org.eclipse.n4js.transpiler.utils.TranspilerUtils -import org.eclipse.n4js.ts.types.IdentifiableElement -import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.ts.types.TypesFactory - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.transpiler.SymbolTableManagement.* - -/** - * Methods of this class provide elementary operations on a transpiler state, mainly on the intermediate model. The - * intermediate model should only be changed through the operations defined by this class. - *

- * Main clients are AST transformations, but they should not invoke these operations directly, but instead use the - * delegation methods in {@link Transformation}. - */ -class TranspilerStateOperations { - - /** - * Creates a new namespace import for the given module and adds it to the intermediate model of the given transpiler - * state. The returned symbol table entry can be used to create references to the namespace, e.g. by passing it to - * {@link TranspilerBuilderBlocks#_IdentRef(SymbolTableEntry)}. The newly created import can be obtained by calling - * {@link SymbolTableEntryOriginal#getImportSpecifier()} on the returned symbol table entry. - *

- * IMPORTANT: this method does not check if an import for the given module exists already or if the given namespace - * name is unique (i.e. does not avoid name clashes!). - */ - def public static SymbolTableEntryOriginal addNamespaceImport(TranspilerState state, TModule moduleToImport, - String namespaceName) { - - // 1) create import declaration & specifier - val importSpec = _NamespaceImportSpecifier(namespaceName, true); - val importDecl = _ImportDecl(importSpec); - // 2) create a temporary type to use as original target - val typeForNamespace = TypesFactory.eINSTANCE.createModuleNamespaceVirtualType(); - typeForNamespace.name = namespaceName; - state.resource.addTemporaryType(typeForNamespace); // make sure our temporary type is contained in a resource - // 3) create a symbol table entry - val steForNamespace = getSymbolTableEntryOriginal(state, typeForNamespace, true); - steForNamespace.importSpecifier = importSpec; - // 4) add import to intermediate model - val scriptElements = state.im.scriptElements; - if(scriptElements.empty) { - scriptElements.add(importDecl); - } else { - insertBefore(state, scriptElements.get(0), importDecl); - } - // 5) update info registry - state.info.setImportedModule(importDecl, moduleToImport); - return steForNamespace; - } - - /** - * Creates a new named import for the given element and adds it to the intermediate model of the given transpiler - * state. The returned symbol table entry can be used to create references to the imported element, e.g. by passing - * it to {@link TranspilerBuilderBlocks#_IdentRef(SymbolTableEntry)}. The newly created import can be obtained by - * calling {@link SymbolTableEntryOriginal#getImportSpecifier()} on the returned symbol table entry. - *

- * If a named import already exists for the given element, nothing will be changed in the intermediate model and its - * symbol table entry will be returned as described above. If the given element is of type - * {@link ModuleNamespaceVirtualType} an exception will be thrown (because only namespace imports can be created for - * those types). - *

- * IMPORTANT: this method does not check if the given namespace name is unique (i.e. does not avoid name clashes!). - */ - def public static SymbolTableEntryOriginal addNamedImport(TranspilerState state, IdentifiableElement elementToImport, String aliasOrNull) { - val steOfElementToImport = getSymbolTableEntryOriginal(state, elementToImport, true); - addNamedImport(state, steOfElementToImport, aliasOrNull); - return steOfElementToImport; - } - - /** - * Creates a new named import for the given STE and adds it to the intermediate model of the given transpiler - * state. The passed-in symbol table entry can be used to create references to the imported element, e.g. by passing - * it to {@link TranspilerBuilderBlocks#_IdentRef(SymbolTableEntry)}. The newly created import can be obtained by - * calling {@link SymbolTableEntryOriginal#getImportSpecifier()} on the passed-in symbol table entry. - *

- * If a named import already exists for the given element, nothing will be changed in the intermediate model. If the - * original target of the given symbol table entry is of type {@link ModuleNamespaceVirtualType} an exception will - * be thrown (because only namespace imports can be created for those types). - *

- * IMPORTANT: this method does not check if the given namespace name is unique (i.e. does not avoid name clashes!). - */ - def public static void addNamedImport(TranspilerState state, SymbolTableEntryOriginal steOfElementToImport, String aliasOrNull) { - // check for valid type of element to be imported (i.e. the original target) - val originalTarget = steOfElementToImport.originalTarget; - if(originalTarget instanceof ModuleNamespaceVirtualType) { - throw new IllegalArgumentException("cannot create named import for a ModuleNamespaceVirtualType"); - } - // check for existing import - val existingImportSpec = steOfElementToImport.importSpecifier; - if(existingImportSpec!==null) { - // import already exists, nothing to be done - return; - } - - // 1) create import declaration & specifier - val importSpec = _NamedImportSpecifier(steOfElementToImport.exportedName, aliasOrNull, true); - val importDecl = _ImportDecl(importSpec); - // 2) add import to intermediate model - val scriptElements = state.im.scriptElements; - if(scriptElements.empty) { - scriptElements.add(importDecl); - } else { - insertBefore(state, scriptElements.get(0), importDecl); - } - // 3) link symbol table entry to its newly created import specifier - steOfElementToImport.importSpecifier = importSpec; - // 4) update info registry - val moduleOfOriginalTarget = originalTarget.containingModule; - state.info.setImportedModule(importDecl, moduleOfOriginalTarget); - } - - /** - * Adds an "empty" import to the intermediate model, i.e. an import of the form: - *

-	 * import "<moduleSpecifier>";
-	 * 
- */ - def public static void addEmptyImport(TranspilerState state, String moduleSpecifier) { - // 1) create import declaration - val importDecl = _ImportDecl() => [ - moduleSpecifierAsText = moduleSpecifier - ]; - // 2) add import to intermediate model - val scriptElements = state.im.scriptElements; - if(scriptElements.empty) { - scriptElements.add(importDecl); - } else { - insertBefore(state, scriptElements.get(0), importDecl); - } - } - - /** - * Returns the symbol table entry to a temporary variable with the given name, intended for use at the location - * of 'nodeInIM' in the intermediate model. If no such variable exists yet, a new variable statement and declaration - * will be created. - *

- * When newly created, the temporary declarations will be added to the body of the closest ancestor function/accessor - * (or on the top level if no such ancestor exists), even if a temporary variable of the same name already exists in - * an outer variable environment (i.e. an outer function/accessor or on top level if inside a function/accessor). - */ - def public static SymbolTableEntryIMOnly addOrGetTemporaryVariable(TranspilerState state, String name, EObject nodeInIM) { - val contextFunctionOrAccessor = getContextFunctionOrAccessor(nodeInIM); - val context = contextFunctionOrAccessor ?: state.im; - val tempVarSTE = state.temporaryVariables.get(context -> name); - if (tempVarSTE !== null) { - return tempVarSTE; - } - // need to create a new temporary variable below context - val tempVarStmnt = state.addOrGetTemporaryVariableStatement(context); - val tempVarDecl = _VariableDeclaration(name); - tempVarStmnt.varDeclsOrBindings += tempVarDecl; - val tempVarSTENew = state.findSymbolTableEntryForElement(tempVarDecl, true) as SymbolTableEntryIMOnly; - state.temporaryVariables.put(context -> name, tempVarSTENew); - return tempVarSTENew; - } - - def private static FunctionOrFieldAccessor getContextFunctionOrAccessor(EObject nodeInIM) { - if (nodeInIM === null) { - return null; - } - if (nodeInIM instanceof FunctionOrFieldAccessor) { - return nodeInIM; - } - val parent = nodeInIM.eContainer(); - if (parent instanceof FormalParameter - && parent.eContainer() instanceof FunctionOrFieldAccessor - && (parent as FormalParameter).initializer === nodeInIM) { - // special case: since the expression of a default parameter cannot access a function's local variables, - // the directly containing function of a default parameter is not a valid context function for temporary - // variables used in the default parameter's initializer expression. - val parentOfContainingFunctionOrAccessor = parent.eContainer().eContainer(); - return getContextFunctionOrAccessor(parentOfContainingFunctionOrAccessor); - } - return getContextFunctionOrAccessor(parent); - } - - /** If context is absent, then the temporary variable statement will be created on the top level. */ - def private static VariableStatement addOrGetTemporaryVariableStatement(TranspilerState state, VariableEnvironmentElement context) { - val tempVarStmnt = state.temporaryVariableStatements.get(context); - if (tempVarStmnt !== null) { - return tempVarStmnt; - } - // need to create a new temporary variable statement - val tempVarStmntNew = _VariableStatement(VariableStatementKeyword.LET); - state.temporaryVariableStatements.put(context, tempVarStmntNew); - if (context instanceof FunctionOrFieldAccessor) { - // add to body of function/accessor - if (context instanceof ArrowFunction) { - if (!context.hasBracesAroundBody) { - // to allow for declarations inside the body, we have to turn single-expression arrow functions into ordinary arrow functions - if (context.isSingleExprImplicitReturn) { - val singleExprStmnt = context.body.statements.head as ExpressionStatement; // we know this, because #isSingleExprImplicitReturn() returned true - state.replace(singleExprStmnt, _ReturnStmnt(singleExprStmnt.expression)); - } - context.hasBracesAroundBody = true; - } - } - context.body.statements.add(0, tempVarStmntNew); - } else if (context instanceof Script) { - // add on top level before the first non-empty, non-import statement - val iter = context.scriptElements.iterator; - var ScriptElement elem; - do { - elem = if (iter.hasNext()) iter.next() else null; - } while(elem instanceof EmptyStatement || elem instanceof ImportDeclaration); - if (elem !== null) { - state.insertBefore(elem, tempVarStmntNew); - } else { - context.scriptElements += tempVarStmntNew; - } - } - return tempVarStmntNew; - } - - def public static void setTarget(TranspilerState state, ParameterizedCallExpression callExpr, Expression newTarget) { - val oldTarget = callExpr.target; - if(oldTarget!==null) { - state.replaceWithoutRewire(oldTarget, newTarget); - } else { - callExpr.target = newTarget; - } - } - - def public static void setTarget(TranspilerState state, ParameterizedPropertyAccessExpression_IM accExpr, Expression newTarget) { - val oldTarget = accExpr.target; - if(oldTarget!==null) { - state.replaceWithoutRewire(oldTarget, newTarget); - } else { - accExpr.target = newTarget; - } - } - - def public static void addArgument(TranspilerState state, ParameterizedCallExpression callExpr, int index, Expression newArgument) { - callExpr.arguments.add(index, _Argument(newArgument)); - } - - def public static void removeAll(TranspilerState state, Iterable elementsInIM) { - for (EObject elementInIM : Lists.newArrayList(elementsInIM)) { - remove(state, elementInIM); - } - } - - def public static void remove(TranspilerState state, EObject elementInIM) { - state.replaceWithoutRewire(elementInIM) // i.e. replace with nothing (will update tracer) - if(elementInIM instanceof ReferencingElement_IM) { - elementInIM.rewiredTarget = null; // important here: will remove elementInIM from its symbol table entry's 'referencingElements' list! - // note: this update of the symbol table is incomplete; elementInIM may be the root of an entire subtree - // of the IM, so we would have to iterate over all successors - } - } - - /** - * Removes the export-container (ExportDeclaration) by creating a new VariableStatement {@code varStmt}, moving all content from {@code exVarStmnt} - * into it and replacing the ExportDeclaration with the newly created {@code varStmt} - * @return newly created {@code varStmt} (already part of the intermediate model). - */ - def public static void removeExport(TranspilerState state, VariableStatement exVarStmnt) { - - if(!TranspilerUtils.isIntermediateModelElement(exVarStmnt)) { - throw new IllegalArgumentException("not an element in the intermediate model: " + exVarStmnt); - } - - val exportDecl = exVarStmnt.eContainer as ExportDeclaration - - state.replaceWithoutRewire(exportDecl,exVarStmnt); - } - - - def public static void replace(TranspilerState state, Statement stmnt, ReturnStatement returnStmnt) { - state.replaceWithoutRewire(stmnt, returnStmnt); - } - - def public static void replace(TranspilerState state, N4ClassDeclaration classDecl, FunctionDeclaration funDecl) { - state.replaceWithoutRewire(classDecl, funDecl); - state.rewireSymbolTable(classDecl, funDecl); - } - - /** - * Replace an interface declaration by a variable declaration. The variable declaration will be wrapped in a - * newly created [Exported]VariableStatement. - */ - def public static void replace(TranspilerState state, N4InterfaceDeclaration ifcDecl, VariableDeclaration varDecl) { - val varStmnt = _VariableStatement(VariableStatementKeyword.CONST, varDecl); - state.replaceWithoutRewire(ifcDecl, varStmnt); - state.rewireSymbolTable(ifcDecl, varDecl); - } - - def public static void replace(TranspilerState state, N4EnumDeclaration enumDecl, N4ClassDeclaration classDecl) { - state.replaceWithoutRewire(enumDecl, classDecl); - state.rewireSymbolTable(enumDecl, classDecl); - } - - def public static void replace(TranspilerState state, FunctionDeclaration funDecl, VariableDeclaration varDecl) { - val varStmnt = _VariableStatement(varDecl); - state.replaceWithoutRewire(funDecl, varStmnt); - state.rewireSymbolTable(funDecl,varDecl); - // need to rewire the local arguments variable, to enable renaming: - val varValue = varDecl.expression; - if(varValue instanceof FunctionExpression) { - state.rewireSymbolTable(funDecl.implicitArgumentsVariable, varValue.implicitArgumentsVariable); - } else { - throw new IllegalArgumentException( - "when replacing a function declaration by a variable declaration, " + - "we expect the variable to be initialized with a function expression"); - } - } - - def public static void replace(TranspilerState state, FunctionDeclaration functionDecl, ExpressionStatement stmt) { - state.replaceWithoutRewire(functionDecl, stmt); - } - - def public static void replace(TranspilerState state, N4MemberDeclaration memberDecl, N4MemberDeclaration replacement) { - state.replaceWithoutRewire(memberDecl, replacement); - state.rewireSymbolTable(memberDecl, replacement); - } - - def public static void replace(TranspilerState state, VariableStatement varStmnt, Statement... newStmnts) { - state.replaceWithoutRewire(varStmnt, newStmnts); - } - - def public static void replace(TranspilerState state, VariableBinding varBinding, VariableDeclaration... varDecls) { - state.replaceWithoutRewire(varBinding, varDecls); - } - - def public static void replace(TranspilerState state, Expression exprOld, Expression exprNew) { - state.replaceWithoutRewire(exprOld, exprNew); - } - - def public static void replace(TranspilerState state, ArrowFunction exprOld, ParameterizedCallExpression exprNew, FunctionExpression rewireTarget) { - state.replaceWithoutRewire(exprOld, exprNew); - state.rewireSymbolTable(exprOld, rewireTarget); - } - - - /** Replace formal parameter with a variableStmt. Rewire the fpar to the VariableDeclaration. Relocate the Stmt */ - def public static void replaceAndRelocate(TranspilerState state, FormalParameter fPar_to_remove, VariableStatement varStmnt, - VariableDeclaration varDecl_wireTo, Block newContainer ) { - if(varDecl_wireTo.eContainer!==varStmnt) { - throw new IllegalArgumentException("varDecl must be contained in varStmnt"); - } - state.replaceAndRelocateWithoutRewire_internal(fPar_to_remove, varStmnt, newContainer.statements, 0); - - state.rewireSymbolTable(fPar_to_remove, varDecl_wireTo); - } - - def public static void wrapExistingExpression(TranspilerState state, - T exprToWrap, Expression outerExpr_without_exprToWrap, (T)=>void inserterFunction - ) { - state.insertOrReplace_internal(exprToWrap, #[outerExpr_without_exprToWrap], true, false); - inserterFunction.apply(exprToWrap) - } - - /* append( pos < 0 or > current size ), prepend(pos==0) or insert at {@code pos} the object {@code insertThis} - * to {@code newContainer}. Also delete {@code removeThis} from the IM. Does not rewire. But keeps trace.*/ - def private static void replaceAndRelocateWithoutRewire_internal(TranspilerState state, EObject removeThis, EObject insertThis, - EList newContainer, int pos ) { - - - val eRefRemove = checkedContainmentFeature(removeThis); - - if( insertThis.eContainer !== null ) throw new IllegalArgumentException("The new element must not be contained anywhere."+ - " insertThis="+insertThis+" is currently contained in "+insertThis.eContainer); - - if( newContainer instanceof EObjectContainmentEList ){ - val newContainerCasted = newContainer as EObjectContainmentEList; - - //// Tracing: - state.tracer.copyTrace(removeThis, insertThis); - state.tracer.discardIntermediateModelNode(removeThis); - - //////////////////////////////////// - //// remove: - if( eRefRemove.upperBound == 1 ) { // single-value - if( eRefRemove.isUnsettable ) - removeThis.eContainer.eUnset(eRefRemove) - else - removeThis.eContainer.eSet(eRefRemove,null) - } else { // multivalue - val l = removeThis.eContainer.eGet(eRefRemove) as List; // c.f. type check above - var idx = l.indexOf(removeThis); - l.remove(idx); - } - - //////////////////////////////////// - //// insert: - val idx = if( pos < 0 || pos >= newContainer.size ) { - // append - newContainer.size - } else { - // insert - pos - }; - newContainerCasted.add(idx,insertThis) - - } else { - throw new IllegalArgumentException("designated new container-list must be a subtype of type EObjectContainmentList") - } - } - - /** - * {@code elementInIntermediateModel} is going away (ie, should be garbage-collected) and therefore we clear all - * references to it from tracing. The {@code replacements} IM nodes take over whatever AST node was previously - * traced-back-to via the element going away. - */ - def private static void replaceWithoutRewire(TranspilerState state, EObject elementInIntermediateModel, EObject... replacements) { - state.tracer.copyTrace(elementInIntermediateModel, replacements); - state.tracer.discardIntermediateModelNode(elementInIntermediateModel); - state.insertOrReplace_internal(elementInIntermediateModel, replacements, true, false); - } - - - def public static void insertBefore(TranspilerState state, EObject elementInIntermediateModel, EObject... newElements) { - state.insertOrReplace_internal(elementInIntermediateModel, newElements, false, false); - } - - def public static void insertAfter(TranspilerState state, EObject elementInIntermediateModel, EObject... newElements) { - state.insertOrReplace_internal(elementInIntermediateModel, newElements, false, true); - } - - def private static void insertOrReplace_internal(TranspilerState state, EObject elementInIntermediateModel, - EObject[] newElements, boolean replace, boolean after - ) { - if(newElements.empty && ! replace) { - return; // nothing to be inserted - } - val eRef = checkedContainmentFeature(elementInIntermediateModel); - val eRefType = eRef.getEReferenceType; - val replElemsOfWrongType = newElements.filter[!eRefType.isSuperTypeOf(it.eClass)]; - if(!replElemsOfWrongType.empty) { - throw new IllegalArgumentException("one or more elements are of wrong type, expected: " - + eRef.EReferenceType.name + ", actual: " + replElemsOfWrongType.map[eClass.name].join(', ')); - } - if( eRef.upperBound == 1 ) { - // single valued - if( newElements.length > 1 ) - throw new IllegalArgumentException("the single-valued reference "+eRef.name+" in class "+eRef.EContainingClass - + " is not able to hold "+newElements.length +" elements."); - if( newElements.length == 1 ) - { - if( !replace ) - throw new IllegalArgumentException("Cannot insert another element into a single-valued containment reference "+eRef.name+" in class "+eRef.EContainingClass ); - elementInIntermediateModel.eContainer.eSet(eRef,newElements.get(0)); - } else { - if( !replace ) - throw new IllegalArgumentException("Inserting zero elements with replace==false is pointless."); - // no element, so remove - if( eRef.isUnsettable ) - elementInIntermediateModel.eContainer.eUnset(eRef) - else - elementInIntermediateModel.eContainer.eSet(eRef,null) - } - - } else { - // multi-valued - val l = elementInIntermediateModel.eContainer.eGet(eRef) as List; // c.f. type check above - var idx = l.indexOf(elementInIntermediateModel); - if(replace) { - l.remove(idx); - } else { - // note: before/after only applicable if !replace - if(after) { - idx++; // always safe to increment, because we know there exists an element at index 'idx' - } - } - l.addAll(idx, newElements); - } - } - - /** Retrieves the EReference of the Container. Throws Exceptions if a) not part of the IM or b) not contained anywhere*/ - def private static EReference checkedContainmentFeature(EObject elementInIntermediateModel) { - if(!TranspilerUtils.isIntermediateModelElement(elementInIntermediateModel)) { - throw new IllegalArgumentException("not an element in the intermediate model: " + elementInIntermediateModel); - } - val eRef = elementInIntermediateModel.eContainmentFeature; - if(eRef===null) { - throw new IllegalArgumentException("element is not contained anywhere"); - } - return eRef; - } - - /** - * Rename the given symbol table entry and all named elements in the intermediate model that are using this name. - * During AST transformations in the transpiler, the 'name' property of a symbol table entry should never be changed - * directly, but this operation should be used instead. - *

- * WARNING: renaming is currently only implemented partially and used only in a single, very specific use - * case; if renaming is required in the future, then the implementation of this method has to be complemented! - */ - def public static void rename(TranspilerState state, SymbolTableEntry entry, String newName) { - SymbolTableManagement.rename(state, entry, newName ); - } - - /** - * Copy a subtree of the intermediate model. - */ - def public static T copy(TranspilerState state, T elementInIM) { - // create a copy with a special copier to take care of reference ReferencingElement_IM#rewiredTarget - val copier = new IM2IMCopier(); - val result = copier.copy(elementInIM); - copier.copyReferences(); - // copy tracing information - state.tracer.copyTrace(elementInIM, result); // note: copying trace for all nodes would be more fine grained - return result as T; - } - - private static final class IM2IMCopier extends EcoreUtil.Copier { - private static final EReference eRef__ReferencingElement_IM__rewiredTarget = ImPackage.eINSTANCE.referencingElement_IM_RewiredTarget; - - override protected copyReference(EReference eReference, EObject eObject, EObject copyEObject) { - if(eReference===eRef__ReferencingElement_IM__rewiredTarget) { - (copyEObject as ReferencingElement_IM).rewiredTarget = (eObject as ReferencingElement_IM).rewiredTarget; - } else { - super.copyReference(eReference, eObject, copyEObject); - } - } - - } -} diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/assistants/TypeAssistant.java b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/assistants/TypeAssistant.java new file mode 100644 index 0000000000..2170c6c66e --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/assistants/TypeAssistant.java @@ -0,0 +1,228 @@ +/** + * 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.transpiler.assistants; + +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.n4ObjectType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.symbolObjectType; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filterNull; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.flatten; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.forall; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.AnnotationList; +import org.eclipse.n4js.n4JS.ExportDeclaration; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.n4JS.TypeDefiningElement; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.transpiler.AbstractTranspiler; +import org.eclipse.n4js.transpiler.InformationRegistry; +import org.eclipse.n4js.transpiler.TransformationAssistant; +import org.eclipse.n4js.transpiler.TranspilerState; +import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.transpiler.utils.ConcreteMembersOrderedForTranspiler; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TInterface; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.validation.JavaScriptVariantHelper; + +import com.google.inject.Inject; + +/** + */ +public class TypeAssistant extends TransformationAssistant { + + @Inject + private JavaScriptVariantHelper jsVariantHelper; + + /** + * Some assertions related to {@link N4ClassifierDeclaration}s that apply to several transformations and are + * therefore factored out into this helper method. + */ + public void assertClassifierPreConditions() { + if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { + List allClassifierDecls = collectNodes(getState().im, + N4ClassifierDeclaration.class, false); + assertTrue("all classifier declarations must have an original defined type", + forall(allClassifierDecls, cd -> getState().info.getOriginalDefinedType(cd) != null)); + + assertTrue("all class declarations must have a superClassRef pointing to a TClass (if non-null)", + forall(filterNull(map(filter(allClassifierDecls, N4ClassDeclaration.class), + cd -> cd.getSuperClassRef())), + scr -> { + TypeRef tRef = getState().info.getOriginalProcessedTypeRef(scr); + Type originalDeclType = tRef == null ? null : tRef.getDeclaredType(); + return originalDeclType instanceof TClass; + })); + + assertTrue( + "all classifier declarations must have all implementedOrExtendedInterfaceRefs pointing to a TInterface", + forall(flatten(map(allClassifierDecls, + cd -> cd.getImplementedOrExtendedInterfaceRefs())), + ir -> { + TypeRef tRef = getState().info.getOriginalProcessedTypeRef(ir); + Type originalDeclType = tRef == null ? null : tRef.getDeclaredType(); + return originalDeclType instanceof TInterface; + })); + + } + } + + /** + * Same as {@link InformationRegistry#getOriginalProcessedTypeRef(TypeReferenceNode)}. + */ + public TypeRef getOriginalOrContainedTypeRef(TypeReferenceNode typeRefNodeInIM) { + TypeRef originalTypeRef = getState().info.getOriginalProcessedTypeRef(typeRefNodeInIM); + if (originalTypeRef != null) { + return originalTypeRef; + } + // note: typeRefNodeInIM.getTypeRefInAST() will always be 'null', so no point in using that + return null; + } + + /***/ + // keep aligned to following method! + public SymbolTableEntryOriginal getOriginalDeclaredTypeSTE(TypeReferenceNode typeRefNodeInIM) { + TypeRef typeRef = getOriginalOrContainedTypeRef(typeRefNodeInIM); + Type declType = typeRef == null ? null : typeRef.getDeclaredType(); + if (declType != null) { + return getSymbolTableEntryOriginal(declType, true); + } + return null; + } + + /***/ + // keep aligned to previous method! + public Type getOriginalDeclaredType(TypeReferenceNode typeRefNodeInIM) { + TypeRef typeRef = getOriginalOrContainedTypeRef(typeRefNodeInIM); + return typeRef == null ? null : typeRef.getDeclaredType(); + } + + /** + * Returns symbol table entry for super class of given class declaration. + */ + public SymbolTableEntryOriginal getSuperClassSTE(N4ClassDeclaration classDecl) { + TypeReferenceNode superClassRef = classDecl == null ? null : classDecl.getSuperClassRef(); + if (superClassRef != null) { + SymbolTableEntryOriginal superClassSTE = getOriginalDeclaredTypeSTE(superClassRef); + if (superClassSTE != null) { + return superClassSTE; + } + } + return getSymbolTableEntryOriginal(n4ObjectType(getState().G), true); + } + + /** + * Returns super interfaces (i.e. implemented or extended interfaces) of given classifier. + */ + public List getSuperInterfacesSTEs(N4ClassifierDeclaration classifierDecl) { + List> superIfcRefNodes; + + if (classifierDecl instanceof N4ClassDeclaration) { + superIfcRefNodes = ((N4ClassDeclaration) classifierDecl).getImplementedInterfaceRefs(); + } else if (classifierDecl instanceof N4InterfaceDeclaration) { + superIfcRefNodes = ((N4InterfaceDeclaration) classifierDecl).getSuperInterfaceRefs(); + } else { + throw new IllegalStateException("unsupported subclass of N4ClassifierDeclaration: " + + (classifierDecl == null ? null : classifierDecl.getName())); + } + return toList(filterNull(map(superIfcRefNodes, si -> getOriginalDeclaredTypeSTE(si)))); + } + + /** + * Tells if the given classifier is declared on top level. + */ + public boolean isTopLevel(TypeDefiningElement typeDef) { + EObject parent = typeDef.eContainer(); + while (parent instanceof ExportDeclaration || parent instanceof AnnotationList) { + parent = parent.eContainer(); + } + return parent instanceof Script; + } + + /** + * Tells if the given type is defined in an N4JSD file. + *

+ * WARNING: for interfaces it is not enough to check {@link TInterface#isExternal()}, for this purpose, because + * structural interfaces in N4JSD files need not be declared external! + */ + public boolean inN4JSD(Type type) { + return jsVariantHelper.isExternalMode(type); + } + + /** + * For a member name that represents a symbol, such as #iterator, this method will return a property + * access expression that will evaluate to the corresponding symbol, e.g. Symbol.iterator. + */ + public ParameterizedPropertyAccessExpression_IM getMemberNameAsSymbol(String memberName) { + if (!memberName.startsWith(N4JSLanguageUtils.SYMBOL_IDENTIFIER_PREFIX)) { + throw new IllegalArgumentException("given member name does not denote a symbol"); + } + return _PropertyAccessExpr( + getSymbolTableEntryOriginal(symbolObjectType(getState().G), true), + getSymbolTableEntryInternal(memberName.substring(1), true)); + } + + /** + * Returns an instance of {@link ConcreteMembersOrderedForTranspiler} for the given classifier, using a cached + * instance if available. + */ + public ConcreteMembersOrderedForTranspiler getOrCreateCMOFT(TClassifier classifier) { + ConcreteMembersOrderedForTranspiler cachedCMOFT = getState().info.getCachedCMOFT(classifier); + if (cachedCMOFT != null) { + return cachedCMOFT; + } else { + ConcreteMembersOrderedForTranspiler newCMOFT = ConcreteMembersOrderedForTranspiler.create(getState(), + classifier); + getState().info.cacheCMOFT(classifier, newCMOFT); + return newCMOFT; + } + } + + /** + * From a given {@link FunctionDefinition} of the IM, this methods returns the {@link TypeRef} of the return type. + */ + public TypeRef getReturnTypeRef(TranspilerState state, FunctionDefinition funDef) { + EObject astNode = state.tracer.getOriginalASTNode(funDef); + if (astNode instanceof FunctionDefinition) { + TFunction tFunction = ((FunctionDefinition) astNode).getDefinedFunction(); + if (tFunction != null) { + TypeRef outerReturnTypeRef = tFunction.getReturnTypeRef(); + if (outerReturnTypeRef == null) { + // If you get an exception here: a transformation might have created an async and/or generator + // FunctionDefinition without the expected Promise<...> / [Async]Generator<...> return type + // (therefore the above call to method #hasExpectedSpecialReturnType() returned false); + // automatically deriving the outer from an inner return type is not supported for + // FunctionDefinitions created by transformations! + throw new IllegalStateException( + "unable to obtain outer return type of function from TModule"); + } + return outerReturnTypeRef; + } + } + return null; + } +} diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/assistants/TypeAssistant.xtend b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/assistants/TypeAssistant.xtend deleted file mode 100644 index 236867c783..0000000000 --- a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/assistants/TypeAssistant.xtend +++ /dev/null @@ -1,204 +0,0 @@ -/** - * 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.transpiler.assistants - -import com.google.inject.Inject -import java.util.List -import org.eclipse.n4js.n4JS.AnnotationList -import org.eclipse.n4js.n4JS.ExportDeclaration -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.n4JS.N4InterfaceDeclaration -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.n4JS.TypeDefiningElement -import org.eclipse.n4js.n4JS.TypeReferenceNode -import org.eclipse.n4js.transpiler.AbstractTranspiler -import org.eclipse.n4js.transpiler.InformationRegistry -import org.eclipse.n4js.transpiler.TransformationAssistant -import org.eclipse.n4js.transpiler.TranspilerState -import org.eclipse.n4js.transpiler.im.ParameterizedPropertyAccessExpression_IM -import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal -import org.eclipse.n4js.transpiler.utils.ConcreteMembersOrderedForTranspiler -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TInterface -import org.eclipse.n4js.ts.types.Type -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.validation.JavaScriptVariantHelper - -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks.* - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - */ -class TypeAssistant extends TransformationAssistant { - - @Inject private JavaScriptVariantHelper jsVariantHelper; - - /** - * Some assertions related to {@link N4ClassifierDeclaration}s that apply to several transformations and are - * therefore factored out into this helper method. - */ - def public void assertClassifierPreConditions() { - if (AbstractTranspiler.DEBUG_PERFORM_ASSERTIONS) { - val allClassifierDecls = collectNodes(state.im, N4ClassifierDeclaration, false); - assertTrue("all classifier declarations must have an original defined type", - allClassifierDecls.forall[state.info.getOriginalDefinedType(it)!==null]); - assertTrue("all class declarations must have a superClassRef pointing to a TClass (if non-null)", - allClassifierDecls.filter(N4ClassDeclaration).map[superClassRef].filterNull - .forall[ - val originalDeclType = state.info.getOriginalProcessedTypeRef(it)?.declaredType; - return originalDeclType instanceof TClass; - ]); - assertTrue("all classifier declarations must have all implementedOrExtendedInterfaceRefs pointing to a TInterface", - allClassifierDecls.map[implementedOrExtendedInterfaceRefs].flatten - .forall[ - val originalDeclType = state.info.getOriginalProcessedTypeRef(it)?.declaredType; - return originalDeclType instanceof TInterface; - ]); - - } - } - - /** - * Same as {@link InformationRegistry#getOriginalProcessedTypeRef(TypeReferenceNode)}. - */ - def public TypeRef getOriginalOrContainedTypeRef(TypeReferenceNode typeRefNodeInIM) { - val originalTypeRef = state.info.getOriginalProcessedTypeRef(typeRefNodeInIM); - if (originalTypeRef !== null) { - return originalTypeRef; - } - // note: typeRefNodeInIM.getTypeRefInAST() will always be 'null', so no point in using that - return null; - } - - // keep aligned to following method! - def public SymbolTableEntryOriginal getOriginalDeclaredTypeSTE(TypeReferenceNode typeRefNodeInIM) { - val typeRef = getOriginalOrContainedTypeRef(typeRefNodeInIM); - val declType = typeRef?.declaredType; - if (declType !== null) { - return getSymbolTableEntryOriginal(declType, true); - } - return null; - } - - // keep aligned to previous method! - def public Type getOriginalDeclaredType(TypeReferenceNode typeRefNodeInIM) { - val typeRef = getOriginalOrContainedTypeRef(typeRefNodeInIM); - return typeRef?.declaredType; - } - - /** - * Returns symbol table entry for super class of given class declaration. - */ - def public SymbolTableEntryOriginal getSuperClassSTE(N4ClassDeclaration classDecl) { - val superClassRef = classDecl?.superClassRef; - if (superClassRef !== null) { - val superClassSTE = getOriginalDeclaredTypeSTE(superClassRef); - if(superClassSTE !== null) { - return superClassSTE; - } - } - return getSymbolTableEntryOriginal(state.G.n4ObjectType, true); - } - - /** - * Returns super interfaces (i.e. implemented or extended interfaces) of given classifier. - */ - def public List getSuperInterfacesSTEs(N4ClassifierDeclaration classifierDecl) { - val superIfcRefNodes = switch(classifierDecl) { - N4ClassDeclaration: classifierDecl.implementedInterfaceRefs - N4InterfaceDeclaration: classifierDecl.superInterfaceRefs - default: throw new IllegalStateException("unsupported subclass of N4ClassifierDeclaration: " + classifierDecl?.name) - } - return superIfcRefNodes - .map[getOriginalDeclaredTypeSTE(it)] - .filterNull - .toList; - } - - /** - * Tells if the given classifier is declared on top level. - */ - def public boolean isTopLevel(TypeDefiningElement typeDef) { - var parent = typeDef.eContainer; - while(parent instanceof ExportDeclaration || parent instanceof AnnotationList) { - parent = parent.eContainer; - } - return parent instanceof Script; - } - - /** - * Tells if the given type is defined in an N4JSD file. - *

- * WARNING: for interfaces it is not enough to check {@link TInterface#isExternal()}, for this purpose, - * because structural interfaces in N4JSD files need not be declared external! - */ - def public boolean inN4JSD(Type type) { - return jsVariantHelper.isExternalMode(type); - } - - /** - * For a member name that represents a symbol, such as #iterator, this method will return a property - * access expression that will evaluate to the corresponding symbol, e.g. Symbol.iterator. - */ - def public ParameterizedPropertyAccessExpression_IM getMemberNameAsSymbol(String memberName) { - if(!memberName.startsWith(N4JSLanguageUtils.SYMBOL_IDENTIFIER_PREFIX)) { - throw new IllegalArgumentException("given member name does not denote a symbol"); - } - return _PropertyAccessExpr( - getSymbolTableEntryOriginal(state.G.symbolObjectType, true), - getSymbolTableEntryInternal(memberName.substring(1), true) - ); - } - - /** - * Returns an instance of {@link ConcreteMembersOrderedForTranspiler} for the given classifier, using a cached - * instance if available. - */ - def public ConcreteMembersOrderedForTranspiler getOrCreateCMOFT(TClassifier classifier) { - val cachedCMOFT = state.info.getCachedCMOFT(classifier); - if(cachedCMOFT!==null) { - return cachedCMOFT; - } else { - val newCMOFT = ConcreteMembersOrderedForTranspiler.create(state, classifier); - state.info.cacheCMOFT(classifier, newCMOFT); - return newCMOFT; - } - } - - /** - * From a given {@link FunctionDefinition} of the IM, this methods returns the {@link TypeRef} of the return type. - */ - def public TypeRef getReturnTypeRef(TranspilerState state, FunctionDefinition funDef) { - val astNode = state.tracer.getOriginalASTNode(funDef); - if (astNode instanceof FunctionDefinition) { - val tFunction = astNode.getDefinedFunction(); - if (tFunction !== null) { - val outerReturnTypeRef = tFunction.getReturnTypeRef(); - if (outerReturnTypeRef === null) { - // If you get an exception here: a transformation might have created an async and/or generator - // FunctionDefinition without the expected Promise<...> / [Async]Generator<...> return type - // (therefore the above call to method #hasExpectedSpecialReturnType() returned false); - // automatically deriving the outer from an inner return type is not supported for - // FunctionDefinitions created by transformations! - throw new IllegalStateException( - "unable to obtain outer return type of function from TModule"); - } - return outerReturnTypeRef; - } - } - return null; - } -} diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/utils/TranspilerDebugUtils.java b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/utils/TranspilerDebugUtils.java new file mode 100644 index 0000000000..db34156653 --- /dev/null +++ b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/utils/TranspilerDebugUtils.java @@ -0,0 +1,233 @@ +/** + * 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.transpiler.utils; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.forall; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.findFirst; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.NamedElement; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.transpiler.TranspilerState; +import org.eclipse.n4js.transpiler.im.Script_IM; +import org.eclipse.n4js.transpiler.im.SymbolTable; +import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; +import org.eclipse.n4js.ts.typeRefs.TypeRefsPackage; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.xtext.EcoreUtil2; + +/** + * Some utilities for transpiler debugging, mainly dumping a {@link TranspilerState} to {@code stdout}, etc. + */ +public class TranspilerDebugUtils { + + /** + * Perform some consistency checks on the transpiler state. For example, this asserts that no node in the + * intermediate model has a direct cross-reference to the original AST or an original TModule element. + */ + public void validateState(TranspilerState state, boolean allowDanglingSecondaryReferencesInSTEs) + throws AssertionError { + // IM should not contain entities from n4js.xcore / TypeRefs.xcore for which a replacement in IM.xcore exists + List replacedEClasses = List.of( + N4JSPackage.eINSTANCE.getParameterizedPropertyAccessExpression(), + N4JSPackage.eINSTANCE.getIdentifierRef(), + TypeRefsPackage.eINSTANCE.getParameterizedTypeRef()); + EObject badObject = findFirst(state.im.eAllContents(), elem -> replacedEClasses.contains(elem.eClass())); + assertNull("intermediate model should not contain objects of type " + + (badObject != null + ? badObject.eClass() != null ? badObject.eClass().getName() : "null" + : "null"), + badObject); + // no cross reference in the IM to an element outside the IM (except in SymbolTableEntry) + assertFalse( + "intermediate model should not have a cross-reference to an element outside the intermediate model" + + " (except for SymbolTableEntry)", + exists(filter(state.im.eAllContents(), elem -> !(allowedCrossRefToOutside(elem))), + elem -> hasCrossRefToOutsideOf(elem, state))); + + // symbol table should exist + SymbolTable st = state.im.getSymbolTable(); + assertNotNull("intermediate model should have a symbol table", st); + // check entries in symbol table + for (SymbolTableEntry ste : st.getEntries()) { + if (ste instanceof SymbolTableEntryOriginal) { + assertNotNull("originalTarget should not be null", + ((SymbolTableEntryOriginal) ste).getOriginalTarget()); + assertFalse("originalTarget should not be an element in the intermediate model", + isElementInIntermediateModelOf(((SymbolTableEntryOriginal) ste).getOriginalTarget(), state)); + } + if (allowDanglingSecondaryReferencesInSTEs) { + // we allow dangling references in this case for the time being to make replacements in IM faster + // -> no checks here + // TODO consider disallowing dangling secondary references in symbol table entries + } else { + assertTrue("all elementsOfThisName should be elements in the intermediate model", + forall(ste.getElementsOfThisName(), elem -> isElementInIntermediateModelOf(elem, state))); + assertTrue("all referencingElements should be elements in the intermediate model", + forall(ste.getReferencingElements(), elem -> isElementInIntermediateModelOf(elem, state))); + if (ste instanceof SymbolTableEntryOriginal) { + if (((SymbolTableEntryOriginal) ste).getImportSpecifier() != null) { + assertTrue("importSpecifier should be an element in the intermediate model", + isElementInIntermediateModelOf(((SymbolTableEntryOriginal) ste).getImportSpecifier(), + state)); + } + } + } + } + } + + private boolean allowedCrossRefToOutside(EObject eobj) { + if (eobj instanceof SymbolTableEntry) { + return true; + } + return false; + } + + private static boolean hasCrossRefToOutsideOf(EObject elementInIntermediateModel, TranspilerState state) { + return exists(elementInIntermediateModel.eCrossReferences(), + cref -> !isElementInIntermediateModelOf(cref, state)); + } + + private static boolean isElementInIntermediateModelOf(EObject eobj, TranspilerState state) { + return EcoreUtil2.getContainerOfType(eobj, Script_IM.class) == state.im; + } + + /** Asserts {@code value} to be true and throws an {@link AssertionError} otherwise. */ + public static void assertTrue(String message, boolean value) throws AssertionError { + if (!value) + assertionFailure(message); + } + + /** Asserts {@code value} to be false and throws an {@link AssertionError} otherwise. */ + public static void assertFalse(String message, boolean value) throws AssertionError { + if (value) + assertionFailure(message); + } + + /** Asserts {@code value} to be null and throws an {@link AssertionError} otherwise. */ + public static void assertNull(String message, Object value) throws AssertionError { + if (value != null) + assertionFailure(message); + } + + /** Asserts {@code value} to be non-null and throws an {@link AssertionError} otherwise. */ + public static void assertNotNull(String message, Object value) throws AssertionError { + if (value == null) + assertionFailure(message); + } + + private static void assertionFailure(String message) throws AssertionError { + AssertionError ex = new AssertionError(message); + ex.printStackTrace(); // make sure we see this on the console even if exceptions are eaten up by someone + throw ex; + } + + /***/ + public static void dump(TranspilerState state) { + System.out.println(dumpToString(state)); + } + + /***/ + public static String dumpToString(TranspilerState state) { + StringWriter w = new StringWriter(); + dump(state, w); + return w.toString(); + } + + /** + * Dumps the transpiler state to the given writer. + */ + public static void dump(TranspilerState state, Writer out) { + PrintWriter w = new PrintWriter(out); + dump(w, state.im, 0); + } + + private static void dump(PrintWriter w, EObject obj, int indentLevel) { + indent(w, indentLevel); + printObj(w, obj, true, indentLevel); + w.println(); + + for (EObject child : obj.eContents()) { + dump(w, child, indentLevel + 1); + } + } + + private static void printObj(PrintWriter w, EObject obj, boolean includeCrossRefs, int indentLevel) { + w.print(obj.eClass().getName()); + if (obj instanceof IdentifiableElement || obj instanceof NamedElement || obj instanceof VariableDeclaration + || obj instanceof ImportSpecifier || obj instanceof SymbolTableEntry) { + w.print(" @" + Integer.toHexString(obj.hashCode())); + } + String objStr = obj.toString(); + int idx = objStr.indexOf("("); + if (idx >= 0) { + w.print(" " + objStr.substring(idx)); + } + if (includeCrossRefs) { + List crossRefs = toList(filter(obj.eClass().getEAllReferences(), ref -> !ref.isContainment())); + if (!crossRefs.isEmpty()) { + for (EReference ref : crossRefs) { + w.println(); + indent(w, indentLevel); + w.print("--" + ref.getName() + "--> "); + if (ref.isMany()) { + w.print("["); + @SuppressWarnings("unchecked") + EList targets = (EList) obj.eGet(ref); + Iterator iter = targets.iterator(); + while (iter.hasNext()) { + EObject currTarget = iter.next(); + if (currTarget != null) { + printObj(w, currTarget, false, indentLevel); + } else { + w.print("null"); + } + if (iter.hasNext()) { + w.print(", "); + } + } + w.print("]"); + } else { + EObject target = (EObject) obj.eGet(ref); + if (target != null) { + printObj(w, target, false, indentLevel); + } else { + w.print("null"); + } + } + } + } + } + } + + private static void indent(PrintWriter w, int indentLevel) { + for (int i = 0; i < indentLevel; i++) { + w.print("\t"); + } + } +} diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/utils/TranspilerDebugUtils.xtend b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/utils/TranspilerDebugUtils.xtend deleted file mode 100644 index 114ef77aab..0000000000 --- a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/utils/TranspilerDebugUtils.xtend +++ /dev/null @@ -1,207 +0,0 @@ -/** - * 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.transpiler.utils - -import java.io.PrintWriter -import java.io.StringWriter -import java.io.Writer -import org.eclipse.emf.common.util.EList -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.ImportSpecifier -import org.eclipse.n4js.n4JS.N4JSPackage -import org.eclipse.n4js.n4JS.NamedElement -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.transpiler.InformationRegistry -import org.eclipse.n4js.transpiler.TranspilerState -import org.eclipse.n4js.transpiler.im.Script_IM -import org.eclipse.n4js.transpiler.im.SymbolTableEntry -import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal -import org.eclipse.n4js.ts.typeRefs.TypeRefsPackage -import org.eclipse.n4js.ts.types.IdentifiableElement -import org.eclipse.xtext.EcoreUtil2 - -/** - * Some utilities for transpiler debugging, mainly dumping a {@link TranspilerState} to {@code stdout}, etc. - */ -class TranspilerDebugUtils { - - /** - * Perform some consistency checks on the transpiler state. For example, this asserts that no node in the - * intermediate model has a direct cross-reference to the original AST or an original TModule element. - */ - def public void validateState(TranspilerState state, boolean allowDanglingSecondaryReferencesInSTEs) throws AssertionError { - // IM should not contain entities from n4js.xcore / TypeRefs.xcore for which a replacement in IM.xcore exists - val replacedEClasses = #[ - N4JSPackage.eINSTANCE.parameterizedPropertyAccessExpression, - N4JSPackage.eINSTANCE.identifierRef, - TypeRefsPackage.eINSTANCE.parameterizedTypeRef - ]; - val badObject = state.im.eAllContents.findFirst[replacedEClasses.contains(it.eClass)]; - assertNull("intermediate model should not contain objects of type " + badObject?.eClass?.name, badObject); - // no cross reference in the IM to an element outside the IM (except in SymbolTableEntry) - assertFalse( - "intermediate model should not have a cross-reference to an element outside the intermediate model" - + " (except for SymbolTableEntry)", - state.im.eAllContents.filter[!(allowedCrossRefToOutside(state.info))].exists[hasCrossRefToOutsideOf(state)]); - // symbol table should exist - val st = state.im.symbolTable; - assertNotNull("intermediate model should have a symbol table", st); - // check entries in symbol table - for(ste : st.entries) { - if(ste instanceof SymbolTableEntryOriginal) { - assertNotNull("originalTarget should not be null", ste.originalTarget); - assertFalse("originalTarget should not be an element in the intermediate model", - ste.originalTarget.isElementInIntermediateModelOf(state)); - } - if(allowDanglingSecondaryReferencesInSTEs) { - // we allow dangling references in this case for the time being to make replacements in IM faster - // -> no checks here - // TODO consider disallowing dangling secondary references in symbol table entries - } else { - assertTrue("all elementsOfThisName should be elements in the intermediate model", - ste.elementsOfThisName.forall[isElementInIntermediateModelOf(state)]); - assertTrue("all referencingElements should be elements in the intermediate model", - ste.referencingElements.forall[isElementInIntermediateModelOf(state)]); - if(ste instanceof SymbolTableEntryOriginal) { - if(ste.importSpecifier!==null) { - assertTrue("importSpecifier should be an element in the intermediate model", - ste.importSpecifier.isElementInIntermediateModelOf(state)); - } - } - } - } - } - - def private allowedCrossRefToOutside(EObject eobj, InformationRegistry info) { - switch eobj { - SymbolTableEntry: true - default: false - } - } - - def private static boolean hasCrossRefToOutsideOf(EObject elementInIntermediateModel, TranspilerState state) { - return elementInIntermediateModel.eCrossReferences.exists[ - if(!isElementInIntermediateModelOf(state)) { - return true; - } - return false; - ]; - } - - def private static boolean isElementInIntermediateModelOf(EObject eobj, TranspilerState state) { - return EcoreUtil2.getContainerOfType(eobj,Script_IM)===state.im - } - - /** Asserts {@code value} to be true and throws an {@link AssertionError} otherwise. */ - def public static void assertTrue(String message, boolean value) throws AssertionError { - if (!value) assertionFailure(message); - } - - /** Asserts {@code value} to be false and throws an {@link AssertionError} otherwise. */ - def public static void assertFalse(String message, boolean value) throws AssertionError { - if (value) assertionFailure(message); - } - - /** Asserts {@code value} to be null and throws an {@link AssertionError} otherwise. */ - def public static void assertNull(String message, Object value) throws AssertionError { - if (value!==null) assertionFailure(message); - } - - /** Asserts {@code value} to be non-null and throws an {@link AssertionError} otherwise. */ - def public static void assertNotNull(String message, Object value) throws AssertionError { - if (value===null) assertionFailure(message); - } - - def private static void assertionFailure(String message) throws AssertionError { - val ex = new AssertionError(message); - ex.printStackTrace; // make sure we see this on the console even if exceptions are eaten up by someone - throw ex; - } - - def public static void dump(TranspilerState state) { - println(dumpToString(state)); - } - def public static String dumpToString(TranspilerState state) { - val w = new StringWriter(); - dump(state, w); - return w.toString; - } - /** - * Dumps the transpiler state to the given writer. - */ - def public static void dump(TranspilerState state, Writer out) { - val w = new PrintWriter(out); - w.dump(state.im, 0); - } - - def private static void dump(PrintWriter w, EObject obj, int indentLevel) { - w.indent(indentLevel); - w.printObj(obj, true, indentLevel); - w.println(); - - for(child : obj.eContents) { - w.dump(child, indentLevel+1); - } - } - - def private static void printObj(PrintWriter w, EObject obj, boolean includeCrossRefs, int indentLevel) { - w.print(obj.eClass.name); - if(obj instanceof IdentifiableElement || obj instanceof NamedElement || obj instanceof VariableDeclaration - || obj instanceof ImportSpecifier || obj instanceof SymbolTableEntry) { - w.print(' @'+Integer.toHexString(obj.hashCode)); - } - val objStr = obj.toString; - val idx = objStr.indexOf('('); - if(idx>=0) { - w.print(' ' + objStr.substring(idx)); - } - if(includeCrossRefs) { - val crossRefs = obj.eClass.getEAllReferences.filter[!containment]; - if(!crossRefs.empty) { - for(ref : crossRefs) { - w.println(); - w.indent(indentLevel); - w.print('--'+ref.name+'--> '); - if(ref.many) { - w.print('['); - val targets = obj.eGet(ref) as EList; - val iter = targets.iterator(); - while(iter.hasNext) { - val currTarget = iter.next; - if(currTarget!==null) { - w.printObj(currTarget, false, indentLevel); - } else { - w.print('null'); - } - if(iter.hasNext) { - w.print(', '); - } - } - w.print(']'); - } else { - val target = obj.eGet(ref) as EObject; - if(target!==null) { - w.printObj(target, false, indentLevel); - } else { - w.print('null'); - } - } - } - } - } - } - - def private static void indent(PrintWriter w, int indentLevel) { - for(i : 0 ..< indentLevel) { - w.print('\t'); - } - } -} diff --git a/plugins/org.eclipse.n4js.transpiler/xtend-gen/.gitignore b/plugins/org.eclipse.n4js.transpiler/xtend-gen/.gitignore deleted file mode 100644 index c96a04f008..0000000000 --- a/plugins/org.eclipse.n4js.transpiler/xtend-gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/FindReferenceHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/FindReferenceHelper.java index 60828d33cd..c8dc10033e 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/FindReferenceHelper.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/FindReferenceHelper.java @@ -104,14 +104,14 @@ public URI getMemberRefURIInDestructuring(EObject instanceOrProxy) { public TMember getMemberInDestructuring(EObject instanceOrProxy) { // If the EObject is a variable in a destructuring, we add that variable DestructNode destructNode = DestructureUtils.getCorrespondingDestructNode(instanceOrProxy); - if (destructNode != null && destructNode.getAssignedElem() != null) { - TypableElement assignedElem = destructNode.getAssignedElem(); + if (destructNode != null && destructNode.assignedElem != null) { + TypableElement assignedElem = destructNode.assignedElem; TypeRef type = typeSystem.type(RuleEnvironmentExtensions.newRuleEnvironment(assignedElem), assignedElem); MemberCollector memberCollector = containerTypesHelper.fromContext(assignedElem); Type declaredType = type.getDeclaredType(); if (declaredType instanceof ContainerType) { - String name = destructNode.getPropName(); + String name = destructNode.propName; TMember member = memberCollector.findMember((ContainerType) declaredType, name, true, false); if (member == null) { member = memberCollector.findMember((ContainerType) declaredType, name, false, false); diff --git a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/TestWorkspaceManager.java b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/TestWorkspaceManager.java index 8944490d9c..27371cf37e 100644 --- a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/TestWorkspaceManager.java +++ b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/TestWorkspaceManager.java @@ -492,7 +492,11 @@ public Project createTestOnDisk(Path destination, Workspace workspace) { } destination.toFile().mkdirs(); - workspace.create(destination); + try { + workspace.create(destination); + } catch (IOException e) { + throw new IllegalStateException(e); + } createdProject = workspace.getProjects().get(0); // TODO return createdProject; diff --git a/testhelpers/org.eclipse.n4js.tests.helper/.classpath b/testhelpers/org.eclipse.n4js.tests.helper/.classpath index 8334a30eac..3628e33687 100644 --- a/testhelpers/org.eclipse.n4js.tests.helper/.classpath +++ b/testhelpers/org.eclipse.n4js.tests.helper/.classpath @@ -1,6 +1,5 @@ - diff --git a/testhelpers/org.eclipse.n4js.tests.helper/build.properties b/testhelpers/org.eclipse.n4js.tests.helper/build.properties index aaedd5b241..17daa5b49c 100644 --- a/testhelpers/org.eclipse.n4js.tests.helper/build.properties +++ b/testhelpers/org.eclipse.n4js.tests.helper/build.properties @@ -1,5 +1,4 @@ -source.. = src/,\ - xtend-gen/ +source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ diff --git a/testhelpers/org.eclipse.n4js.tests.helper/pom.xml b/testhelpers/org.eclipse.n4js.tests.helper/pom.xml index 5479f36127..984e0e897b 100644 --- a/testhelpers/org.eclipse.n4js.tests.helper/pom.xml +++ b/testhelpers/org.eclipse.n4js.tests.helper/pom.xml @@ -30,10 +30,6 @@ Contributors: org.apache.maven.plugins maven-clean-plugin - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Class.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Class.java new file mode 100644 index 0000000000..fdc4242ae2 --- /dev/null +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Class.java @@ -0,0 +1,111 @@ +/** + * 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.tests.codegen; + +import java.util.LinkedList; +import java.util.List; + +import com.google.common.base.Strings; + +/** + * Generates the code for a class. + */ +public class Class extends Classifier { + String superClass; + List implementedInterfaces = new LinkedList<>(); + + /** + * Creates a new instance with the given parameters. + * + * @param name + * the name of the class + */ + public Class(String name) { + super(name); + } + + /** + * Sets the super class. + * + * @param superClass + * the super class or interface. + */ + public Class setSuperClass(Class superClass) { + return setSuperClass(superClass.getName()); + } + + /** + * Sets the super class. + * + * @param superClass + * the name of the super class or interface. + */ + public Class setSuperClass(String superClass) { + this.superClass = superClass; + return this; + } + + /** + * Adds an interface implemented by the class to be built. + * + * @param implementedInterface + * the name of the interface to implement + * + * @return this builder + */ + public Class addInterface(Interface implementedInterface) { + return addInterface(implementedInterface.getName()); + } + + /** + * Adds an interface implemented by the class to be built. + * + * @param implementedInterface + * the interface to implement + */ + public Class addInterface(String implementedInterface) { + implementedInterfaces.add(implementedInterface); + return this; + } + + @Override + protected String generateType() { + return "class "; + } + + @Override + protected String generateTypeRelations() { + return generateSuperClass() + generateImplementedInterfaces(); + } + + private String generateSuperClass() { + if (!Strings.isNullOrEmpty(superClass)) { + return " extends " + superClass; + } + return ""; + } + + private String generateImplementedInterfaces() { + String result = ""; + if (!implementedInterfaces.isEmpty()) { + result += " implements "; + boolean isFirst = true; + for (String inf : implementedInterfaces) { + if (!isFirst) { + result += ", "; + } + result += inf; + isFirst = false; + } + } + return result; + } +} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Class.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Class.xtend deleted file mode 100644 index c11d7d8327..0000000000 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Class.xtend +++ /dev/null @@ -1,80 +0,0 @@ -/** - * 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.tests.codegen - -import java.util.List - -/** - * Generates the code for a class. - */ -class Class extends Classifier { - String superClass; - List implementedInterfaces; - - /** - * Creates a new instance with the given parameters. - * - * @param name the name of the class - */ - public new(String name) { - super(name) - } - - /** - * Sets the super class. - * - * @param superClass the super class or interface. - */ - public def Class setSuperClass(Class superClass) { - return setSuperClass(superClass.name) - } - - /** - * Sets the super class. - * - * @param superClass the name of the super class or interface. - */ - public def Class setSuperClass(String superClass) { - this.superClass = superClass; - return this; - } - - /** - * Adds an interface implemented by the class to be built. - * - * @param implementedInterface the name of the interface to implement - * - * @return this builder - */ - public def Class addInterface(Interface implementedInterface) { - return addInterface(implementedInterface.name) - } - - /** - * Adds an interface implemented by the class to be built. - * - * @param implementedInterface the interface to implement - */ - public def Class addInterface(String implementedInterface) { - if (implementedInterfaces === null) - implementedInterfaces = newLinkedList(); - implementedInterfaces.add(implementedInterface); - return this; - } - - override protected def generateType() '''class ''' - - override protected def CharSequence generateTypeRelations() '''«generateSuperClass()»«generateImplementedInterfaces()»''' - - private def CharSequence generateSuperClass() '''«IF !superClass.nullOrEmpty» extends «superClass»«ENDIF»''' - - private def CharSequence generateImplementedInterfaces() '''«IF !implementedInterfaces.nullOrEmpty»«FOR i : implementedInterfaces BEFORE ' implements ' SEPARATOR ', '»«i»«ENDFOR»«ENDIF»''' -} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Classifier.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Classifier.java new file mode 100644 index 0000000000..d616f3ce52 --- /dev/null +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Classifier.java @@ -0,0 +1,212 @@ +/** + * 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.tests.codegen; + +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +import org.eclipse.n4js.utils.Strings; + +/** + * Abstract base class for classifiers. + */ +abstract public class Classifier> extends Fragment { + /** + * Possible visibility modifiers for classifiers. + */ + public static enum Visibility { + PRIVATE, PROJECT, PUBLIC_INTERNAL, PUBLIC + } + + /** + * Extension methods for the {@link Visibility} enumeration. + */ + public static class VisibilityExtensions { + /** + * Builds a classifier name from the given name and visibility by appending an appropriate string to the given + * name. + * + * @param visibility + * the visibility value + * @param classifierName + * classifier name prefix + * + * @return the newly created classifier name + */ + static String makeName(Visibility visibility, String classifierName) { + return classifierName + getNameExtension(visibility); + } + + /** + * Returns an appropriate classifier name extension depending on the given visibility. + * + * @param visibility + * the visibility value + * + * @return the name extension + */ + static String getNameExtension(Visibility visibility) { + switch (visibility) { + case PRIVATE: + return "_private"; + case PROJECT: + return "_project"; + case PUBLIC_INTERNAL: + return "_public_internal"; + case PUBLIC: + return "_public"; + } + return ""; + } + + /** + * Builds an appropriate code fragment for the given classifier visibility. + * + * @param visibility + * the visibility value + * + * @return the code fragment + */ + static String generate(Visibility visibility) { + switch (visibility) { + case PRIVATE: + return "/* private */"; + case PROJECT: + return "export project"; + case PUBLIC_INTERNAL: + return "export @Internal public"; + case PUBLIC: + return "export public"; + } + return ""; + } + } + + Visibility visibility = Visibility.PRIVATE; + String name; + List> members = new LinkedList<>(); + + /** + * Creates a new classifier instance with the given name. + * + * @param name + * the name of the new classifier + */ + protected Classifier(String name) { + this.name = Objects.requireNonNull(name); + } + + /** + * Returns the name of this classifier. + * + * @return the name of this classifier + */ + public String getName() { + return name; + } + + /** + * Set the visibility to project. + */ + public T makeProjectVisible() { + return setVisibility(Visibility.PROJECT); + } + + /** + * Set the visibility to public @Internal. + */ + public T makePublicInternal() { + return setVisibility(Visibility.PUBLIC_INTERNAL); + } + + /** + * Set the visibility to public. + */ + public T makePublic() { + return setVisibility(Visibility.PUBLIC); + } + + /** + * Set the visibility. + * + * @param visibility + * the visibility to set + */ + @SuppressWarnings("unchecked") + public T setVisibility(Visibility visibility) { + this.visibility = visibility; + return (T) this; + } + + /** + * Add the given member to this builder. + * + * @param member + * the member to add + */ + @SuppressWarnings("unchecked") + public T addMember(Member member) { + members.add(Objects.requireNonNull(member)); + return (T) this; + } + + @Override + public String generate() { + String result = generateVisibility() + generateAbstract() + generateType() + name + generateTypeRelations(); + if (hasMembers()) { + result += " {\n\t" + generateMembers() + "\n}"; + } else { + result += " {}"; + } + return result; + } + + /** + * Generate an appropriate code fragment for this classifier's visibility. + * + * @return the generated visibility code fragment + */ + protected String generateVisibility() { + return VisibilityExtensions.generate(visibility) + " "; + } + + /** + * Generate the code fragments for each of this classifier's members. + * + * @return the generated member code fragment + */ + protected String generateMembers() { + return Strings.join("\n\t", m -> m.generate(), members); + } + + /** + * Generates a code fragment for the actual type of this classifier. + * + * @return the generated code fragment + */ + protected abstract CharSequence generateType(); + + /** + * Generates a code fragment for the type relations of this classifier, e.g. its base types or implemented + * interfaces. + */ + protected abstract CharSequence generateTypeRelations(); + + private boolean hasMembers() { + return members != null && !members.isEmpty(); + } + + @Override + public String toString() { + return generate().toString(); + } +} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Classifier.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Classifier.xtend deleted file mode 100644 index 04f0bdc0a3..0000000000 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Classifier.xtend +++ /dev/null @@ -1,190 +0,0 @@ -/** - * 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.tests.codegen - -import java.util.List -import java.util.Objects - -/** - * Abstract base class for classifiers. - */ -abstract class Classifier> extends Fragment { - /** - * Possible visibility modifiers for classifiers. - */ - public static enum Visibility { - PRIVATE, - PROJECT, - PUBLIC_INTERNAL, - PUBLIC - } - - /** - * Extension methods for the {@link Visibility} enumeration. - */ - public static class VisibilityExtensions { - /** - * Builds a classifier name from the given name and visibility by appending an appropriate string - * to the given name. - * - * @param visibility the visibility value - * @param the classifier name prefix - * - * @return the newly created classifier name - */ - static def String makeName(Visibility visibility, String classifierName) { - classifierName + visibility.nameExtension - } - - /** - * Returns an appropriate classifier name extension depending on the given visibility. - * - * @param visibility the visibility value - * - * @return the name extension - */ - static def String getNameExtension(Visibility visibility) { - switch visibility { - case PRIVATE: "_private" - case PROJECT: "_project" - case PUBLIC_INTERNAL: "_public_internal" - case PUBLIC: "_public" - } - } - - /** - * Builds an appropriate code fragment for the given classifier visibility. - * - * @param visibility the visibility value - * - * @return the code fragment - */ - static def String generate(Visibility visibility) { - switch visibility { - case PRIVATE: "/* private */" - case PROJECT: "export project" - case PUBLIC_INTERNAL: "export @Internal public" - case PUBLIC: "export public" - } - } - } - - Visibility visibility = Visibility.PRIVATE; - String name; - List> members; - - /** - * Creates a new classifier instance with the given name. - * - * @param name the name of the new classifier - */ - protected new(String name) { - this.name = Objects.requireNonNull(name); - } - - /** - * Returns the name of this classifier. - * - * @return the name of this classifier - */ - public def String getName() { - return name; - } - - /** - * Set the visibility to project. - */ - public def T makeProjectVisible() { - return setVisibility(Visibility.PROJECT); - } - - /** - * Set the visibility to public @Internal. - */ - public def T makePublicInternal() { - return setVisibility(Visibility.PUBLIC_INTERNAL); - } - - /** - * Set the visibility to public. - */ - public def T makePublic() { - return setVisibility(Visibility.PUBLIC); - } - - /** - * Set the visibility. - * - * @param visibility the visibility to set - */ - public def T setVisibility(Visibility visibility) { - this.visibility = visibility; - return this as T; - } - - /** - * Add the given member to this builder. - * - * @param member the member to add - */ - public def T addMember(Member member) { - if (members === null) - members = newLinkedList(); - members.add(Objects.requireNonNull(member)); - return this as T; - } - - override def generate() ''' - «generateVisibility()»«generateAbstract()»«generateType()»«name»«generateTypeRelations()» «IF !hasMembers»{}«ELSE»{ - «generateMembers()» - } - «ENDIF» - ''' - - /** - * Generate an appropriate code fragment for this classifier's visibility. - * - * @return the generated visibility code fragment - */ - protected def generateVisibility() '''«VisibilityExtensions.generate(visibility)» ''' - - /** - * Generate the code fragments for each of this classifier's members. - * - * @return the generated member code fragment - */ - protected def generateMembers() ''' - «FOR m : members» - «m.generate()» - «ENDFOR» - ''' - - /** - * Generates a code fragment for the actual type of this classifier. - * - * @return the generated code fragment - */ - protected abstract def CharSequence generateType() - - /** - * Generates a code fragment for the type relations of this classifier, e.g. - * its base types or implemented interfaces. - */ - protected abstract def CharSequence generateTypeRelations() - - private def boolean hasMembers() { - members !== null && !members.empty - } - - override public def String toString() { - return generate().toString(); - } -} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Field.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Field.java new file mode 100644 index 0000000000..beba72450e --- /dev/null +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Field.java @@ -0,0 +1,67 @@ +/** + * 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.tests.codegen; + +import com.google.common.base.Strings; + +/** + * Generates code for a field of a {@link Classifier}. + */ +public class Field extends Member { + String fieldType; + String defaultValue; + + /** + * Creates a new field with the given values. + * + * @param name + * the name of this field + */ + public Field(String name) { + super(name); + } + + /** + * Sets the field type. + * + * @param fieldType + * the field type + */ + public Field setFieldType(String fieldType) { + this.fieldType = fieldType; + return this; + } + + /** + * Sets the default value or expression. + * + * @param defaultValue + * the default value + */ + public Field setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + @Override + protected String generateMember() { + String result = ""; + if (!Strings.isNullOrEmpty(fieldType)) { + result += fieldType + " "; + } + result += name; + if (!Strings.isNullOrEmpty(defaultValue)) { + result += " = " + defaultValue; + } + result += ";\n"; + return result; + } +} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Field.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Field.xtend deleted file mode 100644 index 76e03d88c8..0000000000 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Field.xtend +++ /dev/null @@ -1,52 +0,0 @@ -/** - * 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.tests.codegen - -/** - * Generates code for a field of a {@link Classifier}. - */ -class Field extends Member { - String fieldType - String defaultValue - - /** - * Creates a new field with the given values. - * - * @param name the name of this field - */ - public new(String name) { - super(name) - } - - /** - * Sets the field type. - * - * @param fieldType the field type - */ - public def Field setFieldType(String fieldType) { - this.fieldType = fieldType; - return this; - } - - /** - * Sets the default value or expression. - * - * @param defaultValue the default value - */ - public def Field setDefaultValue(String defaultValue) { - this.defaultValue = defaultValue - return this; - } - - override protected generateMember() ''' - «IF !fieldType.nullOrEmpty»«fieldType» «ENDIF»«name»«IF !defaultValue.nullOrEmpty» = «defaultValue»«ENDIF»; - ''' -} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Folder.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Folder.java similarity index 52% rename from testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Folder.xtend rename to testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Folder.java index eccff9fa2a..5f04d1929b 100644 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Folder.xtend +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Folder.java @@ -4,109 +4,121 @@ * 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.tests.codegen +package org.eclipse.n4js.tests.codegen; -import java.io.File -import java.io.IOException -import java.util.List -import java.util.Objects +import java.io.File; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; /** * Represents a source folder that has a name and contains modules. */ public class Folder { final public String name; - final public List modules = newLinkedList(); - final public List files = newLinkedList(); + final public List modules = new LinkedList<>(); + final public List files = new LinkedList<>(); final public boolean isSourceFolder; /** * Creates a new instance with the given parameters. - * - * @param name the name of this source folder + * + * @param name + * the name of this source folder */ - public new(String name) { + public Folder(String name) { this(name, true); } /** * Creates a new instance with the given parameters. * - * @param name the name of this source folder - * @param isSourceFolder iff true it will be listed as a source folder in the package.json + * @param name + * the name of this source folder + * @param isSourceFolder + * iff true it will be listed as a source folder in the package.json */ - public new(String name, boolean isSourceFolder) { + public Folder(String name, boolean isSourceFolder) { this.name = Objects.requireNonNull(name); this.isSourceFolder = isSourceFolder; } /** * Adds the given module to the source folder to created. - * - * @param module the module to add - * + * + * @param module + * the module to add + * * @return this source folder */ - public def addModule(Module module) { + public Folder addModule(Module module) { modules.add(Objects.requireNonNull(module)); return this; } /** * Returns a list of all modules of this source folder. - * + * * @return list of all modules of this source folder */ - public def List getModules() { + public List getModules() { return modules; } /** * Returns a list of all non-modules of this folder. - * + * * @return list of all non-modules of this folder */ - public def List getOtherFiles() { + public List getOtherFiles() { return files; } /** * Creates this source folder within the given parent directory, which must exist. - * - * This method first creates a new folder within the given parent directory, and then - * it creates all of its modules within that folder by calling their {@link Module#create(File)} - * function with the newly created folder as the parameter. - * - * @param parentDirectory a file representing the parent directory of this source folder + * + * This method first creates a new folder within the given parent directory, and then it creates all of its modules + * within that folder by calling their {@link Module#create(File)} function with the newly created folder as the + * parameter. + * + * @param parentDirectory + * a file representing the parent directory of this source folder */ - public def create(File parentDirectory) { + public void create(File parentDirectory) throws IOException { Objects.requireNonNull(parentDirectory); - if (!parentDirectory.exists) + if (!parentDirectory.exists()) { throw new IOException("Directory '" + parentDirectory + "' does not exist"); - if (!parentDirectory.directory) + } + if (!parentDirectory.isDirectory()) { throw new IOException("'" + parentDirectory + "' is not a directory"); + } - val File folder = new File(parentDirectory, name); + File folder = new File(parentDirectory, name); folder.mkdirs(); - for (module : modules) - module.create(folder) - for (file : files) - file.create(folder) + for (Module module : modules) { + module.create(folder); + } + for (OtherFile file : files) { + file.create(folder); + } } - override equals(Object o) { + @Override + public boolean equals(Object o) { if (o instanceof Folder) { - Objects.equals(name, o.name); + Objects.equals(name, ((Folder) o).name); } return false; } - override hashCode() { + @Override + public int hashCode() { return name.hashCode(); } } diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Fragment.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Fragment.java similarity index 54% rename from testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Fragment.xtend rename to testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Fragment.java index 6b42493568..da2283c257 100644 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Fragment.xtend +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Fragment.java @@ -8,18 +8,17 @@ * Contributors: * NumberFour AG - Initial API and implementation */ -package org.eclipse.n4js.tests.codegen +package org.eclipse.n4js.tests.codegen; /** * Abstract base class for constructs that can be abstract or concrete. */ -abstract class Fragment> { +abstract public class Fragment> { /** * Possible values for abstractness. */ public static enum Abstract { - YES, - NO + YES, NO } /** @@ -27,46 +26,55 @@ public static enum Abstract { */ public static abstract class AbstractExtensions { /** - * Return a name for the given classifier name and abstractness. The created name - * has the classifier name as a prefix. If the given value indicates an abstract - * construct, then the prefix is followed by an underscore and the word 'abstract'. - * Otherwise, there is no suffix. + * Return a name for the given classifier name and abstractness. The created name has the classifier name as a + * prefix. If the given value indicates an abstract construct, then the prefix is followed by an underscore and + * the word 'abstract'. Otherwise, there is no suffix. * - * @param abstract_ whether or not the construct of interest is abstract - * @param classifierName the classifier name prefix + * @param abstract_ + * whether or not the construct of interest is abstract + * @param classifierName + * the classifier name prefix * * @return the generated name */ - static def String makeName(Abstract abstract_, String classifierName) { - classifierName + abstract_.classifierExtension + static String makeName(Abstract abstract_, String classifierName) { + return classifierName + getClassifierExtension(abstract_); } /** * Return the appropriate extension for a classifier name depending on the given value. * - * @param abstract_ whether or not the construct of interest is abstract + * @param abstract_ + * whether or not the construct of interest is abstract * * @return the name extension */ - static def String getClassifierExtension(Abstract abstract_) { - switch abstract_ { - case YES: "_abstract" - case NO: "" + static String getClassifierExtension(Abstract abstract_) { + switch (abstract_) { + case YES: + return "_abstract"; + case NO: + return ""; } + return ""; } /** * Returns the generated string for the given value. * - * @param abstract_ whether or not the construct of interest is abstract + * @param abstract_ + * whether or not the construct of interest is abstract * * @return the generated string */ - static def String generate(Abstract abstract_) { - switch abstract_ { - case YES: "abstract " - case NO: "" + static String generate(Abstract abstract_) { + switch (abstract_) { + case YES: + return "abstract "; + case NO: + return ""; } + return ""; } } @@ -75,14 +83,16 @@ static def String generate(Abstract abstract_) { /** * Creates a new instance. */ - protected new() {} + protected Fragment() { + } /** * Specifies that the this fragment should be abstract. */ - public def T makeAbstract() { + @SuppressWarnings("unchecked") + public T makeAbstract() { abstract_ = Abstract.YES; - return this as T; + return (T) this; } /** @@ -90,8 +100,8 @@ public def T makeAbstract() { * * @return true if this construct is abstract and false otherwise */ - protected def boolean isAbstract() { - abstract_ == Abstract.YES + protected boolean isAbstract() { + return abstract_ == Abstract.YES; } /** @@ -99,14 +109,14 @@ protected def boolean isAbstract() { * * @return the generated code */ - abstract def CharSequence generate() + abstract CharSequence generate(); /** * Generates the appropriate keyword for this fragment, depending on whether or not it is abstract. * * @return the generated keyword, followed by a blank */ - protected def generateAbstract() { - AbstractExtensions.generate(abstract_) + protected String generateAbstract() { + return AbstractExtensions.generate(abstract_); } } diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Getter.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Getter.java new file mode 100644 index 0000000000..9f3b8c3916 --- /dev/null +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Getter.java @@ -0,0 +1,74 @@ +/** + * 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.tests.codegen; + +import com.google.common.base.Strings; + +/** + * Generates code for a getter method of a {@link Classifier}. + */ +public class Getter extends Member { + String fieldType; + String defaultValue; + + /** + * Creates a new getter with the given parameters. + * + * @param name + * the getter's name + */ + public Getter(String name) { + super(name); + } + + /** + * Sets the field type. + * + * @param fieldType + * the field type + */ + public Getter setFieldType(String fieldType) { + this.fieldType = fieldType; + return this; + } + + /** + * Sets the default value or expression. + * + * @param defaultValue + * the default value + */ + public Getter setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + @Override + protected String generateMember() { + String result = generateAbstract(); + result += "get " + name + "()"; + if (!Strings.isNullOrEmpty(fieldType)) { + result += ": " + fieldType; + } + if (isAbstract()) { + result += ":"; + } else { + result += " { return "; + if (!Strings.isNullOrEmpty(defaultValue)) { + result += defaultValue; + } else { + result += "null"; + } + result += "; }"; + } + return result; + } +} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Getter.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Getter.xtend deleted file mode 100644 index 4dce2f0cb6..0000000000 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Getter.xtend +++ /dev/null @@ -1,52 +0,0 @@ -/** - * 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.tests.codegen - -/** - * Generates code for a getter method of a {@link Classifier}. - */ -class Getter extends Member { - String fieldType - String defaultValue; - - /** - * Creates a new getter with the given parameters. - * - * @param name the getter's name - */ - public new(String name) { - super(name) - } - - /** - * Sets the field type. - * - * @param fieldType the field type - */ - public def Getter setFieldType(String fieldType) { - this.fieldType = fieldType; - return this; - } - - /** - * Sets the default value or expression. - * - * @param defaultValue the default value - */ - public def Getter setDefaultValue(String defaultValue) { - this.defaultValue = defaultValue - return this; - } - - override protected generateMember() ''' - «generateAbstract()»get «name»()«IF !fieldType.nullOrEmpty»: «fieldType»«ENDIF»«IF abstract»;«ELSE» { return «IF defaultValue.nullOrEmpty»null«ELSE»defaultValue«ENDIF»; }«ENDIF» - ''' -} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Interface.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Interface.java new file mode 100644 index 0000000000..8bc2c81826 --- /dev/null +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Interface.java @@ -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.tests.codegen; + +import java.util.LinkedList; +import java.util.List; + +/** + * Generates the code for an interface. + */ +public class Interface extends Classifier { + List extendedInterfaces = new LinkedList<>(); + + /** + * Creates a new instance with the given parameters. + * + * @param name + * the name of the interface + */ + public Interface(String name) { + super(name); + } + + /** + * Adds a super interface to this interface + * + * @param implementedInterface + * the interface to add + * + * @return this builder + */ + public Interface addSuperInterface(Interface implementedInterface) { + return addSuperInterface(implementedInterface.name); + } + + /** + * Adds a super interface to this interface + * + * @param implementedInterface + * the name of the interface to add + */ + public Interface addSuperInterface(String implementedInterface) { + extendedInterfaces.add(implementedInterface); + return this; + } + + @Override + protected String generateType() { + return "interface "; + } + + @Override + protected String generateTypeRelations() { + if (!extendedInterfaces.isEmpty()) { + String result = " extends "; + boolean isFirst = true; + for (String inf : extendedInterfaces) { + if (!isFirst) { + result += ", "; + } + result += inf; + isFirst = false; + } + return result; + } + return ""; + } +} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Interface.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Interface.xtend deleted file mode 100644 index 89b40d933f..0000000000 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Interface.xtend +++ /dev/null @@ -1,59 +0,0 @@ -/** - * 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.tests.codegen - -import java.util.List - -/** - * Generates the code for an interface. - */ -class Interface extends Classifier { - List extendedInterfaces; - - /** - * Creates a new instance with the given parameters. - * - * @param name the name of the interface - */ - public new(String name) { - super(name) - } - - /** - * Adds a super interface to this interface - * - * @param implementedInterface the interface to add - * - * @return this builder - */ - public def Interface addSuperInterface(Interface implementedInterface) { - return addSuperInterface(implementedInterface.name) - } - - /** - * Adds a super interface to this interface - * - * @param implementedInterface the name of the interface to add - */ - public def Interface addSuperInterface(String implementedInterface) { - if (extendedInterfaces === null) - extendedInterfaces = newLinkedList(); - extendedInterfaces.add(implementedInterface); - return this; - } - - - override protected def generateType() '''interface ''' - - override protected def CharSequence generateTypeRelations() ''' - «IF extendedInterfaces !== null»«FOR i : extendedInterfaces BEFORE ' extends ' SEPARATOR ', '»«i»«ENDFOR»«ENDIF» - ''' -} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Member.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Member.java similarity index 52% rename from testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Member.xtend rename to testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Member.java index 68e93d978c..d6a29d92ac 100644 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Member.xtend +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Member.java @@ -8,12 +8,12 @@ * Contributors: * NumberFour AG - Initial API and implementation */ -package org.eclipse.n4js.tests.codegen +package org.eclipse.n4js.tests.codegen; /** * Abstract base class for code generators that generate code for members of a {@link Classifier}. */ -abstract class Member> extends Fragment { +abstract public class Member> extends Fragment { /** * Possible visibilities for members. */ @@ -49,52 +49,69 @@ public static enum Visibility { */ public static class VisibilityExtensions { /** - * Builds a member name from the given name and visibility by appending an appropriate string - * to the given name. + * Builds a member name from the given name and visibility by appending an appropriate string to the given name. * - * @param visibility the visibility value - * @param the member name prefix + * @param visibility + * the visibility value + * @param memberName + * member name prefix * * @return the newly created member name */ - static def String makeName(Visibility visibility, String memberName) { - memberName + visibility.nameExtension + static String makeName(Visibility visibility, String memberName) { + return memberName + getNameExtension(visibility); } /** * Returns an appropriate member name extension depending on the given visibility. * - * @param visibility the visibility value + * @param visibility + * the visibility value * * @return the name extension */ - static def String getNameExtension(Visibility visibility) { - switch visibility { - case PRIVATE: "_private" - case PROJECT: "_project" - case PROTECTED_INTERNAL: "_protected_internal" - case PROTECTED: "_protected" - case PUBLIC_INTERNAL: "_public_internal" - case PUBLIC: "_public" + static String getNameExtension(Visibility visibility) { + switch (visibility) { + case PRIVATE: + return "_private"; + case PROJECT: + return "_project"; + case PROTECTED_INTERNAL: + return "_protected_internal"; + case PROTECTED: + return "_protected"; + case PUBLIC_INTERNAL: + return "_public_internal"; + case PUBLIC: + return "_public"; } + return ""; } /** * Builds an appropriate code fragment for the given member visibility. * - * @param visibility the visibility value + * @param visibility + * the visibility value * * @return the code fragment */ - static def String generate(Visibility visibility) { - switch visibility { - case PRIVATE: "private" - case PROJECT: "project" - case PROTECTED_INTERNAL: "@Internal protected" - case PROTECTED: "protected" - case PUBLIC_INTERNAL: "@Internal public" - case PUBLIC: "public" + static String generate(Visibility visibility) { + switch (visibility) { + case PRIVATE: + return "private"; + case PROJECT: + return "project"; + case PROTECTED_INTERNAL: + return "@Internal protected"; + case PROTECTED: + return "protected"; + case PUBLIC_INTERNAL: + return "@Internal public"; + case PUBLIC: + return "public"; } + return ""; } } @@ -115,9 +132,8 @@ public enum Static { /** * Possible values for whether or not a member overrides an inherited member. */ - static enum Override { - YES, - NO + static enum HasOverride { + YES, NO } /** @@ -125,106 +141,119 @@ static enum Override { */ public static class StaticExtensions { /** - * Builds a member name from the given name and static specifier by appending an appropriate string - * to the given name. + * Builds a member name from the given name and static specifier by appending an appropriate string to the given + * name. * - * @param static_ whether or not the member is static - * @param the member name prefix + * @param static_ + * whether or not the member is static + * @param classifierName + * name prefix * * @return the newly created member name */ - static def String makeName(Static static_, String classifierName) { - classifierName + static_.nameExtension + static String makeName(Static static_, String classifierName) { + return classifierName + getNameExtension(static_); } /** * Returns an appropriate member name extension depending on the given static specification. * - * @param static_ whether or not the member is static + * @param static_ + * whether or not the member is static * * @return the name extension */ - static def String getNameExtension(Static static_) { - switch static_ { - case YES: "_static" - case NO: "" + static String getNameExtension(Static static_) { + switch (static_) { + case YES: + return "_static"; + case NO: + return ""; } + return ""; } /** * Returns an appropriate code fragment depending on the given static specification. * - * @param static_ whether or not the member is static + * @param static_ + * whether or not the member is static * * @return the code fragment */ - static def String generate(Static static_) { - switch static_ { - case YES: "static " - case NO: "" + static String generate(Static static_) { + switch (static_) { + case YES: + return "static "; + case NO: + return ""; } + return ""; } } protected Visibility visibility = Visibility.PUBLIC; protected Static static_ = Static.NO; protected String name; - protected Override override_ = Override.NO; + protected HasOverride override_ = HasOverride.NO; /** * Creates a new member with the given parameters. * - * @param name the name of the member + * @param name + * the name of the member */ - protected new(String name) { - this.name = name + protected Member(String name) { + this.name = name; } /** * Sets visibility to project visible. */ - public def T makeProjectVisible() { + public T makeProjectVisible() { return setVisibility(Visibility.PROJECT); } /** * Sets visibility to internal protected. */ - public def T makeProtectedInternal() { + public T makeProtectedInternal() { return setVisibility(Visibility.PROTECTED_INTERNAL); } /** * Sets visibility to protected. */ - public def T makeProtected() { + public T makeProtected() { return setVisibility(Visibility.PROTECTED); } /** * Sets visibility to internal public. */ - public def T makePublicInternal() { + public T makePublicInternal() { return setVisibility(Visibility.PUBLIC_INTERNAL); } /** * Sets visibility to public. */ - public def T makePublic() { + public T makePublic() { return setVisibility(Visibility.PUBLIC); } /** * Set the visibility. * - * @param visibility the visibility to set + * @param visibility + * the visibility to set * * @return this builder */ - public def T setVisibility(Visibility visibility) { + @SuppressWarnings("unchecked") + public T setVisibility(Visibility visibility) { this.visibility = visibility; - return this as T; + return (T) this; } /** @@ -232,18 +261,20 @@ public def T setVisibility(Visibility visibility) { * * @return this builder */ - public def T makeStatic() { + public T makeStatic() { return setStatic(Static.YES); } /** * Specify whether the member is static. * - * @param static_ whether or not the member is static + * @param static_ + * whether or not the member is static */ - public def T setStatic(Static static_) { + @SuppressWarnings("unchecked") + public T setStatic(Static static_) { this.static_ = static_; - return this as T; + return (T) this; } /** @@ -251,25 +282,27 @@ public def T setStatic(Static static_) { * * @return true if this member is static and false otherwise */ - public def boolean isStatic() { - static_ == Static.YES + public boolean isStatic() { + return static_ == Static.YES; } /** * Set the member to override. */ - public def T makeOverride() { - return setOverride(Override.YES); + public T makeOverride() { + return setOverride(HasOverride.YES); } /** * Set the override status of the member. * - * @param override_ the override status + * @param override_ + * the override status */ - public def T setOverride(Override override_) { - this.override_ = override_ - return this as T; + @SuppressWarnings("unchecked") + public T setOverride(HasOverride override_) { + this.override_ = override_; + return (T) this; } /** @@ -277,30 +310,38 @@ public def T setOverride(Override override_) { * * @return true if this member overrides */ - public def boolean isOverride() { - return override_== Override.YES; + public boolean isOverride() { + return override_ == HasOverride.YES; } - override def generate() ''' - «generateOverride()»«generateVisibility()»«generateStatic()»«generateMember()» - ''' + @Override + public String generate() { + return generateOverride() + generateVisibility() + generateStatic() + generateMember(); + } - private def generateOverride() '''«IF override»@Override «ENDIF»''' + private String generateOverride() { + if (isOverride()) { + return "@Override "; + } + return ""; + } /** * Generates a code fragment for the visibility of this member. * * @return the code fragment */ - private def generateVisibility() '''«VisibilityExtensions.generate(visibility)» ''' + private String generateVisibility() { + return VisibilityExtensions.generate(visibility) + " "; + } /** * Generates a code fragment according to whether this member is static or not. * * @return the code fragment */ - private def generateStatic() { - StaticExtensions.generate(static_) + private String generateStatic() { + return StaticExtensions.generate(static_); } /** @@ -308,9 +349,10 @@ private def generateStatic() { * * @return the generated code fragment */ - protected abstract def CharSequence generateMember() + protected abstract CharSequence generateMember(); - override public def String toString() { + @Override + public String toString() { return generate().toString(); } } diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Method.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Method.java new file mode 100644 index 0000000000..52684268b7 --- /dev/null +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Method.java @@ -0,0 +1,129 @@ +/** + * 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.tests.codegen; + +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +import com.google.common.base.Strings; + +/** + * Code generator for member methods of a {@link Classifier}. + */ +public class Method extends Member { + /** + * A method parameter specification. + */ + static class Param { + String type; + String name; + + /** + * Creates a new instance with the given type and name. + * + * @param type + * the parameter type + * @param name + * the parameter name + */ + Param(String type, String name) { + this.type = type; + this.name = name; + } + } + + String returnType; + List params = new LinkedList<>(); + String body; + + /** + * Creates a new instance with the given parameters. + * + * @param name + * the method name + */ + public Method(String name) { + super(name); + } + + /** + * Sets the return type of this method. + * + * @param returnType + * the return type + */ + public Method setReturnType(String returnType) { + this.returnType = returnType; + return this; + } + + /** + * Adds a parameter to this method. + * + * @param param + * the parameter to add + */ + public Method addParameter(Param param) { + this.params.add(Objects.requireNonNull(param)); + return this; + } + + /** + * Sets the body of this method. + * + * @param body + * the body to set + */ + public Method setBody(String body) { + this.body = body; + return this; + } + + @Override + protected String generateMember() { + String result = generateAbstract(); + result += name + "("; + boolean isFirst = true; + for (Param p : params) { + if (!isFirst) { + result += ", "; + } + result += p.name + ": " + p.type; + isFirst = false; + } + result += ")"; + if (!Strings.isNullOrEmpty(returnType)) { + result += ": " + returnType; + } + if (isAbstract()) { + result += ";"; + } else { + if (hasBody()) { + result += " { "; + if (!Strings.isNullOrEmpty(body)) { + result += body; + } else if (!Strings.isNullOrEmpty(returnType)) { + result += "return new " + returnType + "();"; + } + result += " }"; + } else { + result += " {}"; + } + } + + return result; + } + + private boolean hasBody() { + return !Strings.isNullOrEmpty(body) || !Strings.isNullOrEmpty(returnType); + } +} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Method.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Method.xtend deleted file mode 100644 index a4f633ed52..0000000000 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Method.xtend +++ /dev/null @@ -1,98 +0,0 @@ -/** - * 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.tests.codegen - -import java.util.List -import java.util.Objects - -/** - * Code generator for member methods of a {@link Classifier}. - */ -class Method extends Member { - /** - * A method parameter specification. - */ - static class Param { - String type; - String name; - - /** - * Creates a new instance with the given type and name. - * - * @param type the parameter type - * @param name the parameter name - */ - new(String type, String name) { - this.type = type; - this.name = name; - } - } - - String returnType; - List params; - String body; - - /** - * Creates a new instance with the given parameters. - * - * @param name the method name - */ - public new(String name) { - super(name); - } - - /** - * Sets the return type of this method. - * - * @param returnType the return type - */ - public def Method setReturnType(String returnType) { - this.returnType = returnType; - return this; - } - - /** - * Adds a parameter to this method. - * - * @param param the parameter to add - */ - public def Method addParameter(Param param) { - if (this.params === null) - this.params = newLinkedList(); - this.params.add(Objects.requireNonNull(param)); - return this; - } - - /** - * Sets the body of this method. - * - * @param body the body to set - */ - public def Method setBody(String body) { - this.body = body; - return this; - } - - override protected generateMember() ''' - «generateAbstract()»«name»(«IF params !== null»«FOR p : params»«p.name»: «p.type»«ENDFOR»«ENDIF»)«IF !returnType.nullOrEmpty»: «returnType»«ENDIF»«IF abstract»;«ELSE» «IF !hasBody»{}«ELSE»{ - «IF !body.nullOrEmpty» - «body» - «ELSEIF !returnType.nullOrEmpty» - return new «returnType»() - «ENDIF» - }«ENDIF» - «ENDIF» - ''' - - private def boolean hasBody() { - !body.nullOrEmpty || !returnType.nullOrEmpty - } -} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Module.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Module.java new file mode 100644 index 0000000000..9221207323 --- /dev/null +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Module.java @@ -0,0 +1,156 @@ +/** + * 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.tests.codegen; + +import static com.google.common.base.Strings.isNullOrEmpty; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.eclipse.n4js.N4JSGlobals; +import org.eclipse.n4js.utils.Strings; + +/** + * Generates code for a module containing imports and either given classifiers or contents. + */ +public class Module extends OtherFile { + List> classifiers = new LinkedList<>(); + Map> imports = new HashMap<>(); + + /** + * Creates a new instance with the given parameters. + * + * @param name + * the module name without extension + */ + public Module(String name) { + super(name, N4JSGlobals.N4JS_FILE_EXTENSION, null); + } + + /** + * Creates a new instance with the given parameters. + * + * @param name + * the module name without extension + */ + public Module(String name, String fExtension, String fromFileName) { + super(name, fExtension, fromFileName); + } + + /** + * Adds the given classifier to the module built by this builder. Note that the classifiers are ignored iff the + * contents are set. + * + * @param classifier + * the classifier to add + */ + public Module addClassifier(Classifier classifier) { + classifiers.add(Objects.requireNonNull(classifier)); + return this; + } + + /** + * Adds an import to the module built by this builder. + * + * @param importedType + * the name of the type to be imported + * @param sourceModule + * the module containing the imported type + */ + public Module addImport(String importedType, Module sourceModule) { + return addImport(importedType, sourceModule.name); + } + + /** + * Adds an import to the module built by this builder. + * + * @param importedType + * the classifier representing the type to be imported + * @param sourceModule + * the module containing the imported type + */ + public Module addImport(Classifier importedType, Module sourceModule) { + return addImport(importedType.name, sourceModule); + } + + /** + * Adds an import to the module built by this builder. + * + * @param importedType + * the name of the type to be imported + * @param sourceModule + * the name of the module containing the imported type + */ + public Module addImport(String importedType, String sourceModule) { + List importedTypesForModule = imports.get(Objects.requireNonNull(sourceModule)); + if (importedTypesForModule == null) { + importedTypesForModule = new LinkedList<>(); + imports.put(sourceModule, importedTypesForModule); + } + + importedTypesForModule.add(Objects.requireNonNull(importedType)); + return this; + } + + /** + * Generates the N4JS code for this module. + */ + @Override + public String generate() { + String result = ""; + if (hasImports()) { + result += generateImports(); + } + if (hasContents()) { + result += content; + } + if (hasClassifiers()) { + result += generateClassifiers(); + } + return result; + } + + private String generateImports() { + String result = ""; + for (Map.Entry> entry : imports.entrySet()) { + result += "import { "; + boolean isFirst = true; + for (String type : entry.getValue()) { + if (!isFirst) { + result += ", "; + } + result += type; + isFirst = false; + } + result += " } from \"" + entry.getKey() + "\";"; + } + return result; + } + + private String generateClassifiers() { + return Strings.join("", c -> c.generate(), classifiers); + } + + private boolean hasClassifiers() { + return !classifiers.isEmpty(); + } + + private boolean hasImports() { + return !imports.isEmpty(); + } + + private boolean hasContents() { + return !isNullOrEmpty(content); + } +} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Module.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Module.xtend deleted file mode 100644 index 0ca8b8242e..0000000000 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Module.xtend +++ /dev/null @@ -1,133 +0,0 @@ -/** - * 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.tests.codegen - -import java.util.List -import java.util.Map -import java.util.Objects -import org.eclipse.n4js.N4JSGlobals - -/** - * Generates code for a module containing imports and either given classifiers or contents. - */ -class Module extends OtherFile { - List> classifiers; - Map> imports; - - /** - * Creates a new instance with the given parameters. - * - * @param name the module name without extension - */ - public new(String name) { - super(name, N4JSGlobals.N4JS_FILE_EXTENSION, null); - } - - /** - * Creates a new instance with the given parameters. - * - * @param name the module name without extension - */ - public new(String name, String fExtension, String fromFileName) { - super(name, fExtension, fromFileName); - } - - /** - * Adds the given classifier to the module built by this builder. - * Note that the classifiers are ignored iff the contents are set. - * - * @param classifier the classifier to add - */ - public def Module addClassifier(Classifier classifier) { - if (classifiers === null) - classifiers = newLinkedList(); - classifiers.add(Objects.requireNonNull(classifier)); - return this; - } - - /** - * Adds an import to the module built by this builder. - * - * @param importedType the name of the type to be imported - * @param sourceModule the module containing the imported type - */ - public def Module addImport(String importedType, Module sourceModule) { - return addImport(importedType, sourceModule.name) - } - - /** - * Adds an import to the module built by this builder. - * - * @param importedType the classifier representing the type to be imported - * @param sourceModule the module containing the imported type - */ - public def Module addImport(Classifier importedType, Module sourceModule) { - return addImport(importedType.name, sourceModule) - } - - /** - * Adds an import to the module built by this builder. - * - * @param importedType the name of the type to be imported - * @param sourceModule the name of the module containing the imported type - */ - public def Module addImport(String importedType, String sourceModule) { - if (imports === null) - imports = newHashMap(); - - var List importedTypesForModule = imports.get(Objects.requireNonNull(sourceModule)); - if (importedTypesForModule === null) { - importedTypesForModule = newLinkedList(); - imports.put(sourceModule, importedTypesForModule); - } - - importedTypesForModule.add(Objects.requireNonNull(importedType)) - return this; - } - - /** - * Generates the N4JS code for this module. - */ - public override generate() ''' - «IF hasImports» - «generateImports()» - «ENDIF» - «IF hasContents» - «content» - «ELSEIF hasClassifiers» - «generateClassifiers()» - «ENDIF» - ''' - - private def generateImports() ''' - «FOR entry : imports.entrySet()» - import { «FOR type: entry.value SEPARATOR ', '»«type»«ENDFOR» } from "«entry.key»"; - «ENDFOR» - ''' - - private def generateClassifiers() ''' - «FOR classifier : classifiers» - «classifier.generate()» - «ENDFOR» - ''' - - private def boolean hasClassifiers() { - return classifiers !== null && !classifiers.empty; - } - - private def boolean hasImports() { - return imports !== null && !imports.empty - } - - private def boolean hasContents() { - return content !== null && !content.empty - } -} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/OtherFile.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/OtherFile.java similarity index 60% rename from testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/OtherFile.xtend rename to testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/OtherFile.java index 1d849c4727..7cf537916d 100644 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/OtherFile.xtend +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/OtherFile.java @@ -4,27 +4,28 @@ * 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.tests.codegen +package org.eclipse.n4js.tests.codegen; -import java.io.File -import java.io.FileWriter -import java.io.IOException -import java.util.Objects -import org.eclipse.n4js.N4JSGlobals +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Objects; + +import org.eclipse.n4js.N4JSGlobals; /** * Generates code for a module containing imports and either given classifiers or contents. */ -class OtherFile { +public class OtherFile { /** The file name without extension. */ final protected String name; /** - * The file extension. Will be null for files without extension and empty string for files - * with a name ending in ".". + * The file extension. Will be null for files without extension and empty string for files with a name + * ending in ".". */ final protected String fExtension; /** File name provided using the {@code from=""} syntax or null if not provided. */ @@ -33,19 +34,21 @@ class OtherFile { /** * Creates a new instance with the given parameters. - * - * @param name the module name without extension + * + * @param name + * the module name without extension */ - public new(String name) { + public OtherFile(String name) { this(name, N4JSGlobals.N4JS_FILE_EXTENSION, null); } /** * Creates a new instance with the given parameters. - * - * @param name the module name without extension + * + * @param name + * the module name without extension */ - public new(String name, String fExtension, String fromFileName) { + public OtherFile(String name, String fExtension, String fromFileName) { this.name = Objects.requireNonNull(name); this.fExtension = fExtension; this.fromFileName = fromFileName; @@ -53,82 +56,87 @@ public new(String name, String fExtension, String fromFileName) { /** * Returns the name of this module. - * + * * @return the name of this module */ - public def String getName() { + public String getName() { return name; } /** - * Returns the file extension of this module. Will be null for files without extension - * and the empty string for files with a name ending in ".". - * + * Returns the file extension of this module. Will be null for files without extension and the empty + * string for files with a name ending in ".". + * * @return the file extension of this module or null. */ - public def String getExtension() { + public String getExtension() { return fExtension; } /** @return filename with extension (if any). */ - public def String getNameWithExtension() { - return fExtension !== null ? name + "." + fExtension : name; + public String getNameWithExtension() { + return fExtension != null ? name + "." + fExtension : name; } /** File name provided using the {@code from=""} syntax or null if not provided. */ - public def String getFromFileName() { + public String getFromFileName() { return fromFileName; } /** - * Sets the given string of contents to the module built by this builder. - * This will cause the classifiers to be ignored. - * - * @param contents the contents to add + * Sets the given string of contents to the module built by this builder. This will cause the classifiers to be + * ignored. + * + * @param contents + * the contents to add */ - public def OtherFile setContents(String contents) { + public OtherFile setContents(String contents) { this.content = contents; return this; } /** * Returns the contents of this module. - * + * * @return the contents of this module */ - public def String getContents() { + public String getContents() { return content; } /** * Creates this module as a file in the given parent directory, which must already exist. - * - * @param parentDirectory a file representing the parent directory + * + * @param parentDirectory + * a file representing the parent directory */ - public def create(File parentDirectory) { + public void create(File parentDirectory) throws IOException { Objects.requireNonNull(parentDirectory); - if (!parentDirectory.exists) + if (!parentDirectory.exists()) { throw new IOException("Directory '" + parentDirectory + "' does not exist"); - if (!parentDirectory.directory) + } + if (!parentDirectory.isDirectory()) { throw new IOException("'" + parentDirectory + "' is not a directory"); + } - val File filePath = new File(parentDirectory, this.getNameWithExtension().replace('/', File.separatorChar)); - filePath.parentFile.mkdirs(); + File filePath = new File(parentDirectory, this.getNameWithExtension().replace('/', File.separatorChar)); + filePath.getParentFile().mkdirs(); - var FileWriter out = null; + FileWriter out = null; try { out = new FileWriter(filePath); out.write(generate().toString()); } finally { - if (out !== null) + if (out != null) { out.close(); + } } } /** * Generates the N4JS code for this module. */ - public def generate() { + public String generate() { return content; } } diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Project.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Project.java new file mode 100644 index 0000000000..3f61fc6516 --- /dev/null +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Project.java @@ -0,0 +1,462 @@ +/** + * 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.tests.codegen; + +import static org.eclipse.n4js.utils.Strings.join; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import org.eclipse.n4js.N4JSGlobals; +import org.eclipse.n4js.packagejson.projectDescription.ProjectType; +import org.eclipse.n4js.utils.io.FileDeleter; + +import com.google.common.base.Strings; + +/** + * Generates the code for a project. + */ +public class Project { + final String projectName; + final String vendorId; + final String vendorName; + final LinkedHashSet folders = new LinkedHashSet<>(); + final Set projectDependencies = new LinkedHashSet<>(); + final Map scripts = new LinkedHashMap<>(); + final Map nodeModuleProjects = new HashMap<>(); + ProjectType projectType; + String projectVersion = "1.0.0"; + String mainModule = null; + String outputFolder = "src-gen"; + String projectDescriptionContent = null; + boolean generateDts = false; + + /** + * Same as {@link #Project(String, String, String, ProjectType)}, but with a default project type of + * {@link ProjectType#LIBRARY LIBRARY}. + */ + public Project(String projectName, String vendorId, String vendorName) { + this(projectName, vendorId, vendorName, ProjectType.LIBRARY); + } + + /** + * Creates a new instance with the given parameters. + * + * @param projectName + * the project ID + * @param vendorId + * the vendor ID + * @param vendorName + * the vendor name + * @param projectType + * the project type + */ + public Project(String projectName, String vendorId, String vendorName, ProjectType projectType) { + this.projectName = Objects.requireNonNull(projectName); + this.vendorId = Objects.requireNonNull(vendorId); + this.vendorName = Objects.requireNonNull(vendorName); + this.projectType = Objects.requireNonNull(projectType); + } + + /** + * Returns the project name. + * + * @return the project name. + */ + public String getName() { + return projectName; + } + + /** + * Returns the project type. + * + * @return the project type. + */ + public ProjectType getType() { + return projectType; + } + + /** + * Sets the project type. + * + * @param projectType + * the project type to set + */ + public Project setType(ProjectType projectType) { + this.projectType = projectType; + return this; + } + + /** + * Gets the project version. + * + * @return projectVersion the project + */ + public String getVersion() { + return this.projectVersion; + } + + /** + * Sets the project version. + * + * @param projectVersion + * the project version + */ + public Project setVersion(String projectVersion) { + this.projectVersion = projectVersion; + return this; + } + + /** + * Gets the project's main module. + * + * @return main module of the project. + */ + public String getMainModule() { + return this.mainModule; + } + + /** + * Sets the project's main module. + * + * @param mainModule + * the main module. + */ + public Project setMainModule(String mainModule) { + this.mainModule = mainModule; + return this; + } + + /** + * Returns the output folder. + * + * @return the output folder. + */ + public String getOutputFolder() { + return outputFolder; + } + + /** + * Sets the output folder. + * + * @param outputFolder + * the output folder to set + */ + public Project setOutputFolder(String outputFolder) { + this.outputFolder = outputFolder; + return this; + } + + /** + * @return true iff "generator"/"d.ts" is set to true. + */ + public boolean isGenerateDts() { + return generateDts; + } + + /** + * Turns on/off generation of .d.ts files. + */ + public Project setGenerateDts(boolean generateDts) { + this.generateDts = generateDts; + return this; + } + + /** + * Sets the content of the project description file 'package.json' + * + * @param projectDescriptionContent + * content of package.json + */ + public Project setProjectDescriptionContent(String projectDescriptionContent) { + this.projectDescriptionContent = projectDescriptionContent; + return this; + } + + /** + * Returns content of package.json. + * + * @return content of package.json. + */ + public String getProjectDescriptionContent() { + return projectDescriptionContent; + } + + /** + * Creates a folder with the given name to this project. + * + * @param name + * the name of the source folder to add + * + * @return the added source folder + */ + public Folder createFolder(String name) { + Folder result = new Folder(name, false); + addSourceFolder(result); + return result; + } + + /** + * Creates a source folder with the given name to this project. + * + * @param name + * the name of the source folder to add + * + * @return the added source folder + */ + public Folder createSourceFolder(String name) { + Folder result = new Folder(name, true); + addSourceFolder(result); + return result; + } + + /** + * Adds a source folder to this project. + * + * @param sourceFolder + * the source folder to add + */ + public Project addSourceFolder(Folder sourceFolder) { + folders.add(Objects.requireNonNull(sourceFolder)); + return this; + } + + /** + * Returns a list of all source folders of this project. + * + * @return list of all source folders of this project. + */ + public LinkedHashSet getSourceFolders() { + return folders; + } + + /** + * Adds a project dependency to this project. + * + * @param projectDependency + * the name of the project to add to the list of dependencies. + */ + public Project addProjectDependency(String projectDependency) { + projectDependencies.add(Objects.requireNonNull(projectDependency)); + return this; + } + + public void addScript(String name, String script) { + scripts.put(name, script); + } + + /** + * Returns a list of project dependencies of this project. + * + * @return projectDependencies the project + */ + public Set getProjectDependencies() { + return this.projectDependencies; + } + + public void addNodeModuleProject(Project project) { + this.nodeModuleProjects.put(project.projectName, project); + } + + public Project getNodeModuleProject(String _projectName) { + return this.nodeModuleProjects.get(_projectName); + } + + public Collection getNodeModuleProjects() { + List projects = new ArrayList<>(); + projects.addAll(nodeModuleProjects.values()); + return projects; + } + + /** + * Generates the {@link N4JSGlobals#PACKAGE_JSON} for this project. + */ + public String generate() { + if (!Strings.isNullOrEmpty(projectDescriptionContent)) { + return projectDescriptionContent; + } + + String scriptsStr = ""; + if (!scriptsStr.isEmpty()) { + scriptsStr = join(",\n\t", e -> "\"%s\": \"%s\"".formatted(e.getKey(), e.getValue()), scripts.entrySet()); + } + + String vendorIdStr = "\"vendorId\": \"%s\"".formatted(vendorId); + String vendorNameStr = "\"vendorName\": \"%s\"".formatted(vendorName); + String projectTypeStr = "\"projectType\": \"%s\"".formatted(projectTypeToString(projectType)); + String mainModuleStr = mainModule == null ? "" : "\"mainModule\": \"%s\"".formatted(mainModule); + String outputFolderStr = outputFolder == null ? "" : "\"output\": \"%s\"".formatted(outputFolder); + String generateDtsStr = generateDts ? "\"generator\": { \"d.ts\": true }".formatted(outputFolder) : ""; + String sourcesStr = ""; + if (!folders.isEmpty()) { + sourcesStr += "\"sources\": {\n\t\t\t\"source\": ["; + boolean isFirst = true; + for (Folder sourceFolder : filter(folders, f -> f.isSourceFolder)) { + if (!isFirst) { + sourcesStr += ", "; + } + sourcesStr += "\"%s\"".formatted(sourceFolder.name); + isFirst = false; + } + sourcesStr += "]\n\t\t}"; + } + + String n4jsProps = ""; + boolean isFirst = true; + for (String prop : List.of(vendorIdStr, vendorNameStr, projectTypeStr, mainModuleStr, outputFolderStr, + generateDtsStr, sourcesStr)) { + + if (!Strings.isNullOrEmpty(prop)) { + if (!isFirst) { + n4jsProps += ",\n\t\t"; + } + n4jsProps += prop; + isFirst = false; + } + } + + String deps = ""; + if (!projectDependencies.isEmpty()) { + deps = join(",\n\t", d -> "\"%s\": \"\"".formatted(d), projectDependencies); + } + + String result = """ + { + "name": "%s", + "version": "%s", + "type": "module", + "scripts": {%s}, + "n4js": { + %s + }, + "dependencies": {%s} + } + """.formatted( + projectName, + projectVersion, + scriptsStr, + n4jsProps, + deps); + + return result; + } + + private static String projectTypeToString(ProjectType type) { + switch (type) { + case API: + return "api"; + case APPLICATION: + return "application"; + case LIBRARY: + return "library"; + case PROCESSOR: + return "processor"; + case RUNTIME_ENVIRONMENT: + return "runtimeEnvironment"; + case RUNTIME_LIBRARY: + return "runtimeLibrary"; + case TEST: + return "test"; + case PLAINJS: + return "plainjs"; + case VALIDATION: + return "validation"; + case DEFINITION: + return "definition"; + } + return ""; + } + + /** + * Creates this project in the given parent directory, which must exist. + * + * This method first creates a directory with the same name as the {@link #projectName} within the given parent + * directory. If there already exists a file or directory with that name within the given parent directory, that + * file or directory will be (recursively) deleted. + * + * Afterward, the package.json file and the source folders are created within the newly created project directory. + * + * @param parentDirectoryPath + * the path to the parent directory + * + * @return the project directory + */ + public File create(Path parentDirectoryPath) throws IOException { + File parentDirectory = Objects.requireNonNull(parentDirectoryPath).toFile(); + if (!parentDirectory.exists()) { + throw new IOException("'" + parentDirectory + "' does not exist"); + } + if (!parentDirectory.isDirectory()) { + throw new IOException("'" + parentDirectory + "' is not a directory"); + } + + File projectDirectory = new File(parentDirectory, projectName); + rmkdirs(projectDirectory); + + createProjectDescriptionFile(projectDirectory); + createModules(projectDirectory); + + if (!nodeModuleProjects.isEmpty()) { + File nodeModulesDirectory = new File(projectDirectory, N4JSGlobals.NODE_MODULES); + if (nodeModulesDirectory.exists()) { + FileDeleter.delete(nodeModulesDirectory); + } + nodeModulesDirectory.mkdir(); + createNodeModuleProjects(nodeModulesDirectory); + } + + return projectDirectory; + } + + private void createProjectDescriptionFile(File parentDirectory) throws IOException { + File filePath = new File(parentDirectory, N4JSGlobals.PACKAGE_JSON); + FileWriter out = null; + try { + out = new FileWriter(filePath); + out.write(generate().toString()); + } finally { + if (out != null) { + out.close(); + } + } + } + + private void createModules(File parentDirectory) throws IOException { + for (Folder sourceFolder : folders) { + sourceFolder.create(parentDirectory); + } + } + + private void createNodeModuleProjects(File parentDirectory) throws IOException { + for (Project nodeModuleProject : nodeModuleProjects.values()) { + nodeModuleProject.create(parentDirectory.toPath()); + } + } + + void rmkdirs(File file) throws IOException { + if (file.exists()) { + FileDeleter.delete(file); + } + file.mkdirs(); + } +} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Project.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Project.xtend deleted file mode 100644 index 5d195e3481..0000000000 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Project.xtend +++ /dev/null @@ -1,402 +0,0 @@ -/** - * 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.tests.codegen - -import java.io.File -import java.io.FileWriter -import java.io.IOException -import java.nio.file.Path -import java.util.Collection -import java.util.LinkedHashSet -import java.util.Map -import java.util.Objects -import java.util.Set -import org.eclipse.n4js.N4JSGlobals -import org.eclipse.n4js.packagejson.projectDescription.ProjectType -import org.eclipse.n4js.utils.io.FileDeleter - -/** - * Generates the code for a project. - */ -public class Project { - final String projectName; - final String vendorId; - final String vendorName; - final LinkedHashSet folders = newLinkedHashSet(); - final Set projectDependencies = newLinkedHashSet(); - final Map scripts = newLinkedHashMap(); - final Map nodeModuleProjects = newHashMap(); - ProjectType projectType; - String projectVersion = "1.0.0"; - String mainModule = null; - String outputFolder = "src-gen"; - String projectDescriptionContent = null; - boolean generateDts = false; - - /** - * Same as {@link #Project(String, String, String, ProjectType)}, but with - * a default project type of {@link ProjectType#LIBRARY LIBRARY}. - */ - public new(String projectName, String vendorId, String vendorName) { - this(projectName, vendorId, vendorName, ProjectType.LIBRARY); - } - - /** - * Creates a new instance with the given parameters. - * - * @param projectName the project ID - * @param vendorId the vendor ID - * @param vendorName the vendor name - * @param projectType the project type - */ - public new(String projectName, String vendorId, String vendorName, ProjectType projectType) { - this.projectName = Objects.requireNonNull(projectName); - this.vendorId = Objects.requireNonNull(vendorId); - this.vendorName = Objects.requireNonNull(vendorName); - this.projectType = Objects.requireNonNull(projectType); - } - - /** - * Returns the project name. - * - * @return the project name. - */ - public def String getName() { - return projectName; - } - - /** - * Returns the project type. - * - * @return the project type. - */ - public def ProjectType getType() { - return projectType; - } - - /** - * Sets the project type. - * - * @param projectType the project type to set - */ - public def Project setType(ProjectType projectType) { - this.projectType = projectType; - return this; - } - - /** - * Gets the project version. - * - * @return projectVersion the project - */ - public def String getVersion() { - return this.projectVersion; - } - - /** - * Sets the project version. - * - * @param projectVersion the project version - */ - public def Project setVersion(String projectVersion) { - this.projectVersion = projectVersion; - return this; - } - - /** - * Gets the project's main module. - * - * @return main module of the project. - */ - public def String getMainModule() { - return this.mainModule; - } - - /** - * Sets the project's main module. - * - * @param mainModule the main module. - */ - public def Project setMainModule(String mainModule) { - this.mainModule = mainModule; - return this; - } - - /** - * Returns the output folder. - * - * @return the output folder. - */ - public def String getOutputFolder() { - return outputFolder; - } - - /** - * Sets the output folder. - * - * @param outputFolder the output folder to set - */ - public def Project setOutputFolder(String outputFolder) { - this.outputFolder = outputFolder; - return this; - } - - /** - * @return true iff "generator"/"d.ts" is set to true. - */ - public def boolean isGenerateDts() { - return generateDts; - } - - /** - * Turns on/off generation of .d.ts files. - */ - public def Project setGenerateDts(boolean generateDts) { - this.generateDts = generateDts; - return this; - } - - /** - * Sets the content of the project description file 'package.json' - * - * @param projectDescriptionContent content of package.json - */ - public def Project setProjectDescriptionContent(String projectDescriptionContent) { - this.projectDescriptionContent = projectDescriptionContent; - return this; - } - - /** - * Returns content of package.json. - * - * @return content of package.json. - */ - public def String getProjectDescriptionContent() { - return projectDescriptionContent; - } - - /** - * Creates a folder with the given name to this project. - * - * @param name the name of the source folder to add - * - * @return the added source folder - */ - public def Folder createFolder(String name) { - val Folder result = new Folder(name, false); - addSourceFolder(result); - return result; - } - - /** - * Creates a source folder with the given name to this project. - * - * @param name the name of the source folder to add - * - * @return the added source folder - */ - public def Folder createSourceFolder(String name) { - val Folder result = new Folder(name, true); - addSourceFolder(result); - return result; - } - - /** - * Adds a source folder to this project. - * - * @param sourceFolder the source folder to add - */ - public def Project addSourceFolder(Folder sourceFolder) { - folders.add(Objects.requireNonNull(sourceFolder)); - return this; - } - - /** - * Returns a list of all source folders of this project. - * - * @return list of all source folders of this project. - */ - public def LinkedHashSet getSourceFolders() { - return folders; - } - - /** - * Adds a project dependency to this project. - * - * @param projectDependency the name of the project to add to the list of dependencies. - */ - public def Project addProjectDependency(String projectDependency) { - projectDependencies.add(Objects.requireNonNull(projectDependency)); - return this; - } - - public def void addScript(String name, String script) { - scripts.put(name, script); - } - - /** - * Returns a list of project dependencies of this project. - * - * @return projectDependencies the project - */ - public def Set getProjectDependencies() { - return this.projectDependencies; - } - - public def void addNodeModuleProject(Project project) { - this.nodeModuleProjects.put(project.projectName, project); - } - - public def Project getNodeModuleProject(String projectName) { - return this.nodeModuleProjects.get(projectName); - } - - public def Collection getNodeModuleProjects() { - val projects = newArrayList(); - projects.addAll(nodeModuleProjects.values); - return projects; - } - - /** - * Generates the {@link N4JSGlobals#PACKAGE_JSON} for this project. - */ - public def String generate() ''' - «IF !projectDescriptionContent.nullOrEmpty»« - projectDescriptionContent» - «ELSE» - { - "name": "«projectName»", - "version": "«projectVersion»", - "type": "module", - «IF !scripts.empty» - "scripts": { - «FOR script : scripts.entrySet SEPARATOR ','» - "«script.key»": "«script.value»" - «ENDFOR» - }, - «ENDIF» - "n4js": { - "vendorId": "«vendorId»", - "vendorName": "«vendorName»", - "projectType": "«projectType.projectTypeToString»" - «IF mainModule !== null - »,"mainModule": "«mainModule»" - «ENDIF» - «IF !outputFolder.nullOrEmpty - »,"output": "«outputFolder»" - «ENDIF» - «IF generateDts» - ,"generator": { - "d.ts": true - } - «ENDIF» - «IF !folders.nullOrEmpty - »,"sources": { - "source": [ - «FOR sourceFolder : folders.filter[isSourceFolder] SEPARATOR ','» - "«sourceFolder.name»" - «ENDFOR» - ] - } - «ENDIF» - }, - "dependencies": { - «IF !projectDependencies.nullOrEmpty» - «FOR dep : projectDependencies SEPARATOR ','» - "«dep»": "" - «ENDFOR» - «ENDIF» - } - } - «ENDIF» - ''' - - private static def String projectTypeToString(ProjectType type) { - return switch (type) { - case API: "api" - case APPLICATION: "application" - case LIBRARY: "library" - case PROCESSOR: "processor" - case RUNTIME_ENVIRONMENT: "runtimeEnvironment" - case RUNTIME_LIBRARY: "runtimeLibrary" - case TEST: "test" - case PLAINJS: "plainjs" - case VALIDATION: "validation" - case DEFINITION: "definition" - }; - } - - /** - * Creates this project in the given parent directory, which must exist. - * - * This method first creates a directory with the same name as the {@link #projectName} within - * the given parent directory. If there already exists a file or directory with that name - * within the given parent directory, that file or directory will be (recursively) deleted. - * - * Afterward, the package.json file and the source folders are created within the newly created - * project directory. - * - * @param parentDirectoryPath the path to the parent directory - * - * @return the project directory - */ - public def File create(Path parentDirectoryPath) { - var File parentDirectory = Objects.requireNonNull(parentDirectoryPath).toFile - if (!parentDirectory.exists) - throw new IOException("'" + parentDirectory + "' does not exist") - if (!parentDirectory.directory) - throw new IOException("'" + parentDirectory + "' is not a directory"); - - val File projectDirectory = new File(parentDirectory, projectName); - rmkdirs(projectDirectory); - - createProjectDescriptionFile(projectDirectory); - createModules(projectDirectory); - - if (!nodeModuleProjects.isEmpty()) { - val File nodeModulesDirectory = new File(projectDirectory, N4JSGlobals.NODE_MODULES); - if (nodeModulesDirectory.exists) - FileDeleter.delete(nodeModulesDirectory); - nodeModulesDirectory.mkdir(); - createNodeModuleProjects(nodeModulesDirectory); - } - - return projectDirectory; - } - - private def void createProjectDescriptionFile(File parentDirectory) { - val File filePath = new File(parentDirectory, N4JSGlobals.PACKAGE_JSON); - var FileWriter out = null; - try { - out = new FileWriter(filePath); - out.write(generate().toString()); - } finally { - if (out !== null) - out.close(); - } - } - - private def void createModules(File parentDirectory) { - for (sourceFolder : folders) - sourceFolder.create(parentDirectory); - } - - private def void createNodeModuleProjects(File parentDirectory) { - for (nodeModuleProject : nodeModuleProjects.values) - nodeModuleProject.create(parentDirectory.toPath()); - } - - def void rmkdirs(File file) { - if (file.exists) - FileDeleter.delete(file); - file.mkdirs(); - } -} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Setter.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Setter.java new file mode 100644 index 0000000000..5d3d64841f --- /dev/null +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Setter.java @@ -0,0 +1,57 @@ +/** + * 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.tests.codegen; + +import com.google.common.base.Strings; + +/** + * Generates code for a setter method of a {@link Classifier}. + */ +public class Setter extends Member { + protected String fieldType; + + /** + * Creates a new setter with the given parameters. + * + * @param name + * the setter's name + */ + public Setter(String name) { + super(name); + } + + /** + * Sets the field type of this setter. + * + * @param fieldType + * the field type + */ + public Setter setFieldType(String fieldType) { + this.fieldType = fieldType; + return this; + } + + @Override + protected String generateMember() { + String result = generateAbstract(); + result += "set " + name + "(value"; + if (Strings.isNullOrEmpty(fieldType)) { + result += ": " + fieldType; + } + result += ")"; + if (isAbstract()) { + result += ";"; + } else { + result += "{}"; + } + return result; + } +} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Setter.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Setter.xtend deleted file mode 100644 index 702817ac37..0000000000 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Setter.xtend +++ /dev/null @@ -1,41 +0,0 @@ -/** - * 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.tests.codegen - -/** - * Generates code for a setter method of a {@link Classifier}. - */ -class Setter extends Member { - protected String fieldType - - /** - * Creates a new setter with the given parameters. - * - * @param name the setter's name - */ - public new(String name) { - super(name) - } - - /** - * Sets the field type of this setter. - * - * @param fieldType the field type - */ - public def Setter setFieldType(String fieldType) { - this.fieldType = fieldType; - return this; - } - - override protected generateMember() ''' - «generateAbstract()»set «name»(value«IF !fieldType.nullOrEmpty»: «fieldType»«ENDIF»)«IF abstract»;«ELSE» {}«ENDIF» - ''' -} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Workspace.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Workspace.java new file mode 100644 index 0000000000..c47cc70348 --- /dev/null +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Workspace.java @@ -0,0 +1,92 @@ +/** + * 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.tests.codegen; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import org.eclipse.n4js.utils.io.FileDeleter; + +/** + * Generates code for a workspace. + */ +public class Workspace { + final List projects = new ArrayList<>(); + + public void addProject(Project project) { + this.projects.add(project); + } + + public void clearProjects() { + this.projects.clear(); + } + + public List getProjects() { + return this.projects; + } + + /** + * Similar to {@link #getProjects()}, but also includes the member projects of {@link YarnWorkspaceProject}s. + */ + public List getAllProjects() { + List allProjects = new ArrayList<>(); + for (Project p : projects) { + allProjects.add(p); + if (p instanceof YarnWorkspaceProject) { + YarnWorkspaceProject ywp = (YarnWorkspaceProject) p; + allProjects.addAll(ywp.getMemberProjects()); + allProjects.addAll(ywp.getNodeModuleProjects()); + } + } + return allProjects; + } + + public void simplifyIfPossible() { + if (isYarnToSingleProjectConvertable()) { + YarnWorkspaceProject yarnWorkspaceProject = (YarnWorkspaceProject) getProjects().get(0); + Project project = yarnWorkspaceProject.getMemberProjects().iterator().next(); + clearProjects(); + addProject(project); + } + } + + public boolean isYarnToSingleProjectConvertable() { + return getProjects().size() == 1 + && getAllProjects().size() == 2 // this includes the yarn project and the single project in packages + && getProjects().get(0) instanceof YarnWorkspaceProject + && ((YarnWorkspaceProject) getProjects().get(0)).getMemberProjects().size() == 1; + } + + public File create(Path parentDirectoryPath) throws IOException { + File wsDirectory = Objects.requireNonNull(parentDirectoryPath).toFile(); + if (!wsDirectory.exists()) { + throw new IOException("'" + wsDirectory + "' does not exist"); + } + if (!wsDirectory.isDirectory()) { + throw new IOException("'" + wsDirectory + "' is not a directory"); + } + + if (wsDirectory.exists()) { + FileDeleter.delete(wsDirectory); + } + wsDirectory.mkdirs(); + + for (Project project : projects) { + project.create(wsDirectory.toPath()); + } + + return wsDirectory; + } +} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Workspace.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Workspace.xtend deleted file mode 100644 index 77af8bf177..0000000000 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/Workspace.xtend +++ /dev/null @@ -1,82 +0,0 @@ -/** - * 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.tests.codegen - -import java.io.File -import java.io.IOException -import java.nio.file.Path -import java.util.List -import java.util.Objects -import org.eclipse.n4js.utils.io.FileDeleter - -/** - * Generates code for a workspace. - */ -class Workspace { - final List projects = newArrayList(); - - def addProject(Project project) { - this.projects.add(project); - } - - def clearProjects() { - this.projects.clear(); - } - - def List getProjects() { - return this.projects; - } - - /** - * Similar to {@link #getProjects()}, but also includes the member projects of {@link YarnWorkspaceProject}s. - */ - def Iterable getAllProjects() { - return this.projects.flatMap[p| - if (p instanceof YarnWorkspaceProject) - #[p] + p.memberProjects + p.nodeModuleProjects - else - #[p] - ]; - } - - def void simplifyIfPossible() { - if (isYarnToSingleProjectConvertable()) { - val YarnWorkspaceProject yarnWorkspaceProject = getProjects().get(0) as YarnWorkspaceProject; - val Project project = yarnWorkspaceProject.getMemberProjects().iterator().next(); - clearProjects(); - addProject(project); - } - } - - def boolean isYarnToSingleProjectConvertable() { - return getProjects().size() == 1 - && getAllProjects().size() == 2 // this includes the yarn project and the single project in packages - && getProjects().get(0) instanceof YarnWorkspaceProject - && (getProjects().get(0) as YarnWorkspaceProject).getMemberProjects().size() == 1; - } - - public def File create(Path parentDirectoryPath) { - var File wsDirectory = Objects.requireNonNull(parentDirectoryPath).toFile - if (!wsDirectory.exists) - throw new IOException("'" + wsDirectory + "' does not exist") - if (!wsDirectory.directory) - throw new IOException("'" + wsDirectory + "' is not a directory"); - - if (wsDirectory.exists) - FileDeleter.delete(wsDirectory); - wsDirectory.mkdirs(); - - for (project : projects) - project.create(wsDirectory.toPath()); - - return wsDirectory; - } -} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/YarnWorkspaceProject.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/YarnWorkspaceProject.java new file mode 100644 index 0000000000..28795ee0d0 --- /dev/null +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/YarnWorkspaceProject.java @@ -0,0 +1,159 @@ +/** + * 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.tests.codegen; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; + +import org.eclipse.n4js.N4JSGlobals; +import org.eclipse.n4js.packagejson.projectDescription.ProjectType; +import org.eclipse.n4js.utils.Strings; + +/** + * Generates the code for a yarn workspace project. + */ +public class YarnWorkspaceProject extends Project { + + /** Name of the 'packages' folder, i.e. the folder containing the actual projects. */ + public static final String PACKAGES = "packages"; + + final Map> memberProjects = new LinkedHashMap<>(); + + /** + * Same as {@link Project#Project(String, String, String, ProjectType)}, but with a default project type of + * {@link ProjectType#PLAINJS PLAINJS}. + */ + public YarnWorkspaceProject(String projectName, String vendorId, String vendorName) { + this(projectName, vendorId, vendorName, PACKAGES); + } + + /** + * Same as {@link Project#Project(String, String, String, ProjectType)}, but with a default project type of + * {@link ProjectType#PLAINJS PLAINJS}. + */ + public YarnWorkspaceProject(String projectName, String vendorId, String vendorName, String workspacesFolderName) { + super(projectName, vendorId, vendorName, ProjectType.PLAINJS); + this.memberProjects.put(workspacesFolderName, new HashMap<>()); + } + + public void addWorkspaceName(String workspacesFolderName) { + this.memberProjects.put(workspacesFolderName, new HashMap<>()); + } + + public void addMemberProject(Project project) { + addMemberProject(memberProjects.keySet().iterator().next(), project); + } + + public void addMemberProject(String workspaceFolderName, Project project) { + this.memberProjects.putIfAbsent(workspaceFolderName, new HashMap<>()); + this.memberProjects.get(workspaceFolderName).put(project.getName(), project); + } + + public Collection getMemberProjects() { + Collection projects = new ArrayList<>(); + for (Map name2prj : memberProjects.values()) { + projects.addAll(name2prj.values()); + } + return projects; + } + + public Project getMemberProject(String _projectName) { + return getMemberProject(memberProjects.keySet().iterator().next(), _projectName); + } + + public Project getMemberProject(String workspaceFolderName, String _projectName) { + return this.memberProjects.get(workspaceFolderName).get(_projectName); + } + + /** + * Generates the {@link N4JSGlobals#PACKAGE_JSON} for this project. + */ + @Override + public String generate() { + if (!com.google.common.base.Strings.isNullOrEmpty(projectDescriptionContent)) { + return projectDescriptionContent; + } + + String workspaces = Strings.join(", ", ws -> "\"%s/*\"".formatted(ws), memberProjects.keySet()); + String deps = Strings.join(",\n", d -> "\"%s\": \"*\"".formatted(d), projectDependencies); + + return """ + { + "name": "%s", + "version": "%s", + "private": true, + "workspaces": [ + %s + ], + "dependencies": { + %s + } + } + """.formatted( + getName(), + getVersion(), + workspaces, + deps); + } + + /** + * Creates this project in the given parent directory, which must exist. + * + * This method first creates a directory with the same name as the {@link #projectName} within the given parent + * directory. If there already exists a file or directory with that name within the given parent directory, that + * file or directory will be (recursively) deleted. + * + * Afterward, the package.json file and the source folders are created within the newly created project directory. + * + * @param parentDirectoryPath + * the path to the parent directory + * + * @return the project directory + */ + @Override + public File create(Path parentDirectoryPath) throws IOException { + super.create(parentDirectoryPath); + + File parentDirectory = Objects.requireNonNull(parentDirectoryPath).toFile(); + File projectDirectory = new File(parentDirectory, getName()); + File nodeModulesDirectory = new File(projectDirectory, N4JSGlobals.NODE_MODULES); + nodeModulesDirectory.mkdirs(); + + for (String workspacesFolderName : memberProjects.keySet()) { + File workspacesDirectory = new File(new File(parentDirectory, getName()), workspacesFolderName); + rmkdirs(workspacesDirectory); + + createWorkspaceProjects(memberProjects.get(workspacesFolderName), nodeModulesDirectory, + workspacesDirectory); + } + + return projectDirectory; + } + + private void createWorkspaceProjects(Map name2projects, File nodeModulesDirectory, + File parentDirectory) throws IOException { + + for (Project project : name2projects.values()) { + File projectDir = project.create(parentDirectory.toPath()); + Path symProjectDirectory = new File(nodeModulesDirectory, project.getName()).toPath(); + symProjectDirectory.getParent().toFile().mkdir(); + Files.createSymbolicLink(symProjectDirectory, projectDir.toPath()); + } + } +} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/YarnWorkspaceProject.xtend b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/YarnWorkspaceProject.xtend deleted file mode 100644 index a457efa27a..0000000000 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/codegen/YarnWorkspaceProject.xtend +++ /dev/null @@ -1,145 +0,0 @@ -/** - * 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.tests.codegen - -import java.io.File -import java.nio.file.Files -import java.nio.file.Path -import java.util.Collection -import java.util.Map -import java.util.Objects -import org.eclipse.n4js.N4JSGlobals -import org.eclipse.n4js.packagejson.projectDescription.ProjectType -import org.eclipse.n4js.utils.Strings - -/** - * Generates the code for a yarn workspace project. - */ -public class YarnWorkspaceProject extends Project { - - /** Name of the 'packages' folder, i.e. the folder containing the actual projects. */ - public static final String PACKAGES = "packages"; - - final Map> memberProjects = newLinkedHashMap(); - - /** - * Same as {@link #Project(String, String, String, ProjectType)}, but with - * a default project type of {@link ProjectType#PLAINJS PLAINJS}. - */ - public new(String projectName, String vendorId, String vendorName) { - this(projectName, vendorId, vendorName, PACKAGES); - } - - /** - * Same as {@link #Project(String, String, String, ProjectType)}, but with - * a default project type of {@link ProjectType#PLAINJS PLAINJS}. - */ - public new(String projectName, String vendorId, String vendorName, String workspacesFolderName) { - super(projectName, vendorId, vendorName, ProjectType.PLAINJS); - this.memberProjects.put(workspacesFolderName, newHashMap()); - } - - public def void addWorkspaceName(String workspacesFolderName) { - this.memberProjects.put(workspacesFolderName, newHashMap()); - } - - public def void addMemberProject(Project project) { - addMemberProject(memberProjects.keySet.iterator.next, project); - } - - public def void addMemberProject(String workspaceFolderName, Project project) { - this.memberProjects.putIfAbsent(workspaceFolderName, newHashMap()); - this.memberProjects.get(workspaceFolderName).put(project.name, project); - } - - public def Collection getMemberProjects() { - val projects = newArrayList(); - for (name2prj : memberProjects.values) - projects.addAll(name2prj.values); - return projects; - } - - public def Project getMemberProject(String projectName) { - getMemberProject(memberProjects.keySet.iterator.next, projectName); - } - - public def Project getMemberProject(String workspaceFolderName, String projectName) { - return this.memberProjects.get(workspaceFolderName).get(projectName); - } - - - /** - * Generates the {@link N4JSGlobals#PACKAGE_JSON} for this project. - */ - public override String generate() ''' - «IF !projectDescriptionContent.nullOrEmpty»« - projectDescriptionContent» - «ELSE» - { - "name": "«name»", - "version": "«version»", - "private": true, - "workspaces": [ - «Strings.join(", ", [wsName | '''"«wsName»/*"'''], memberProjects.keySet())» - ], - "dependencies": { - «IF !projectDependencies.nullOrEmpty» - «FOR dep : projectDependencies SEPARATOR ','» - "«dep»": "*" - «ENDFOR» - «ENDIF» - } - } - «ENDIF» - ''' - - - /** - * Creates this project in the given parent directory, which must exist. - * - * This method first creates a directory with the same name as the {@link #projectName} within - * the given parent directory. If there already exists a file or directory with that name - * within the given parent directory, that file or directory will be (recursively) deleted. - * - * Afterward, the package.json file and the source folders are created within the newly created - * project directory. - * - * @param parentDirectoryPath the path to the parent directory - * - * @return the project directory - */ - public override File create(Path parentDirectoryPath) { - super.create(parentDirectoryPath); - - var File parentDirectory = Objects.requireNonNull(parentDirectoryPath).toFile - val File projectDirectory = new File(parentDirectory, name); - val File nodeModulesDirectory = new File(projectDirectory, N4JSGlobals.NODE_MODULES); - nodeModulesDirectory.mkdirs(); - - for (workspacesFolderName : memberProjects.keySet()) { - val File workspacesDirectory = new File(new File(parentDirectory, name), workspacesFolderName); - rmkdirs(workspacesDirectory); - - createWorkspaceProjects(memberProjects.get(workspacesFolderName), nodeModulesDirectory, workspacesDirectory); - } - - return projectDirectory; - } - - private def void createWorkspaceProjects(Map name2projects, File nodeModulesDirectory, File parentDirectory) { - for (project: name2projects.values()) { - val projectDir = project.create(parentDirectory.toPath); - val Path symProjectDirectory = new File(nodeModulesDirectory, project.name).toPath(); - symProjectDirectory.parent.toFile.mkdir; - Files.createSymbolicLink(symProjectDirectory, projectDir.toPath()); - } - } -} diff --git a/testhelpers/org.eclipse.n4js.tests.helper/xtend-gen/.gitignore b/testhelpers/org.eclipse.n4js.tests.helper/xtend-gen/.gitignore deleted file mode 100644 index c96a04f008..0000000000 --- a/testhelpers/org.eclipse.n4js.tests.helper/xtend-gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/tests/org.eclipse.n4js.accesscontrol.tests/src/org/eclipse/n4js/accesscontrol/tests/ScenarioGenerator.java b/tests/org.eclipse.n4js.accesscontrol.tests/src/org/eclipse/n4js/accesscontrol/tests/ScenarioGenerator.java index 8f32511363..afe67dd6e2 100644 --- a/tests/org.eclipse.n4js.accesscontrol.tests/src/org/eclipse/n4js/accesscontrol/tests/ScenarioGenerator.java +++ b/tests/org.eclipse.n4js.accesscontrol.tests/src/org/eclipse/n4js/accesscontrol/tests/ScenarioGenerator.java @@ -11,6 +11,7 @@ package org.eclipse.n4js.accesscontrol.tests; import java.io.File; +import java.io.IOException; import java.nio.file.Path; import java.util.LinkedList; import java.util.List; @@ -62,7 +63,7 @@ class ScenarioGenerator { * the path to generate the scenario in * @return a list files representing the root directories of the created projects */ - public List generateScenario(Path destination) { + public List generateScenario(Path destination) throws IOException { List result = new LinkedList<>(); // Create the required classifiers for the scenario. diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/bugreports/pending/GH_2004_ReviewImportedNamesComputationTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/bugreports/pending/GH_2004_ReviewImportedNamesComputationTest.java index 28bef84c5f..1c3bd2ac11 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/bugreports/pending/GH_2004_ReviewImportedNamesComputationTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/bugreports/pending/GH_2004_ReviewImportedNamesComputationTest.java @@ -57,7 +57,7 @@ public m() {} new FileEvent(otherFileURI.toString(), FileChangeType.Deleted)))); joinServerRequests(); assertIsAffectedBug("ProjectOther/" + PACKAGE_JSON, - "(Error, [8:17 - 8:34], Main module specifier some/path/Other does not exist.)"); + "(Error, [9:16 - 9:33], Main module specifier some/path/Other does not exist.)"); } @Test diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/CyclicDependenciesBuilderNoRebuildTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/CyclicDependenciesBuilderNoRebuildTest.java index b03e6f4045..78204d0b3c 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/CyclicDependenciesBuilderNoRebuildTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/CyclicDependenciesBuilderNoRebuildTest.java @@ -54,18 +54,18 @@ public void testStableCycleNoRebuild() { assertIssues2( Pair.of("P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)")), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)")), Pair.of("P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); executeCommand(N4JSCommandService.N4JS_REFRESH); joinServerRequests(); assertIssues2( Pair.of("P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)")), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)")), Pair.of("P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); } @Override @@ -73,15 +73,13 @@ protected Optional> getOverridingModule() { return Optional.of(Test_Module.class); } - public static final class Test_Module extends AbstractGenericModule { - + public Class bindXWorkspaceManager() { return Test_N4JSWorkspaceManager.class; } } - @Singleton public static class Test_N4JSWorkspaceManager extends N4JSWorkspaceManager { @Override diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/CyclicDependenciesBuilderTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/CyclicDependenciesBuilderTest.java index 59566bef79..a7a2cdc39b 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/CyclicDependenciesBuilderTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/CyclicDependenciesBuilderTest.java @@ -105,9 +105,9 @@ public void testAddCycle() { assertIssues2(Map.of( "P1/package.json", List.of( - "(Error, [16:23 - 16:27], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:38 - 14:42], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); } @Test @@ -118,9 +118,9 @@ public void testRemoveCycle() { assertIssues2(Map.of( "P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); openFile("P1/package.json"); @@ -139,9 +139,9 @@ public void testOnlyDirtyStateBuildInsideCycle() { assertIssues2(Map.of( "P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); openFile("M1"); @@ -149,27 +149,27 @@ public void testOnlyDirtyStateBuildInsideCycle() { assertIssues2(Map.of( "P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "M1", List.of("(Error, [0:25 - 1:0], extraneous input '#\\n' expecting '}')"))); saveOpenedFile("M1"); assertIssues2(Map.of( "P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "M1", List.of("(Error, [0:25 - 1:0], extraneous input '#\\n' expecting '}')"))); closeFile("M1"); assertIssues2(Map.of( "P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); } @Test @@ -180,9 +180,9 @@ public void testBuildDirtyAfterRemoveCycle1() { assertIssues2(Map.of( "P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); openFile("M1"); @@ -190,27 +190,27 @@ public void testBuildDirtyAfterRemoveCycle1() { assertIssues2(Map.of( "P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "M1", List.of("(Error, [0:25 - 1:0], extraneous input '#\\n' expecting '}')"))); saveOpenedFile("M1"); assertIssues2(Map.of( "P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "M1", List.of("(Error, [0:25 - 1:0], extraneous input '#\\n' expecting '}')"))); closeFile("M1"); assertIssues2(Map.of( "P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); // remove cycle openFile("P1/package.json"); @@ -229,9 +229,9 @@ public void testBuildDirtyAfterRemoveCycle2() { assertIssues2(Map.of( "P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"))); openFile("M1"); @@ -239,18 +239,18 @@ public void testBuildDirtyAfterRemoveCycle2() { assertIssues2(Map.of( "P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "M1", List.of("(Error, [0:25 - 1:0], extraneous input '#\\n' expecting '}')"))); saveOpenedFile("M1"); assertIssues2(Map.of( "P1/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "P2/package.json", List.of( - "(Error, [16:3 - 16:7], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), + "(Error, [14:18 - 14:22], Dependency cycle of the projects: yarn-test-project/packages/P1, yarn-test-project/packages/P2.)"), "M1", List.of("(Error, [0:25 - 1:0], extraneous input '#\\n' expecting '}')"))); // remove cycle diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/IncrementalBuilderWorkspaceChangesTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/IncrementalBuilderWorkspaceChangesTest.java index 6c246c317f..14e0950488 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/IncrementalBuilderWorkspaceChangesTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/IncrementalBuilderWorkspaceChangesTest.java @@ -55,7 +55,7 @@ public m() {} "(Error, [0:26 - 0:33], Cannot resolve plain module specifier (without project name as first segment): no matching module found.)", "(Error, [1:5 - 1:15], Couldn't resolve reference to IdentifiableElement 'OtherClass'.)"), "MainProject/" + PACKAGE_JSON, List.of( - "(Error, [16:3 - 16:21], Project does not exist with project ID: OtherProject.)")); + "(Error, [14:18 - 14:36], Project does not exist with project ID: OtherProject.)")); @Test public void testCreateProject() throws IOException { @@ -286,7 +286,7 @@ public m() {} "OtherProject/package.json", List.of( " (Warning, [1:9 - 1:25], As a convention the package name 'RenamedProject' should match the name of the project folder 'OtherProject' on the file system.)"), "MainProject/package.json", List.of( - " (Error, [16:3 - 16:21], Project does not exist with project ID: OtherProject.)"), + " (Error, [14:18 - 14:36], Project does not exist with project ID: OtherProject.)"), "Main.n4js", List.of( " (Error, [0:26 - 0:33], Cannot resolve plain module specifier (without project name as first segment): no matching module found.)", " (Error, [1:5 - 1:15], Couldn't resolve reference to IdentifiableElement 'OtherClass'.)"))); @@ -419,10 +419,10 @@ private void doTestAddRemoveDependency(Pair dependency, boolean // unfortunately we have an additional error in the open, non-saved package.json file when a dependency to a // plain-JS-project is added // (due to the optimization in ProjectDiscoveryHelper of hiding all unnecessary PLAINJS projects) - int tpnLength = 29 + targetProjectName.length(); + int tpnLength = 44 + targetProjectName.length(); Map> errorsBeforeSaving = new HashMap<>(originalErrors); errorsBeforeSaving.put(sourceProjectName + "/" + PACKAGE_JSON, List.of( - "(Error, [16:23 - 16:" + tpnLength + "], Project does not exist with project ID: " + "(Error, [14:38 - 14:" + tpnLength + "], Project does not exist with project ID: " + targetProjectName + ".)")); assertIssues2(errorsBeforeSaving); // changes in package.json not saved yet, so still the original errors + // 1 error in the unsaved package.json editor diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/InitialBuildTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/InitialBuildTest.java index 38199da176..ebd318bede 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/InitialBuildTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/InitialBuildTest.java @@ -219,7 +219,7 @@ public void testAddRemoveProjectBetweenServerSessions() throws IOException { "(Error, [0:25 - 0:37], Cannot resolve plain module specifier (without project name as first segment): no matching module found.)", "(Error, [1:10 - 1:19], Couldn't resolve reference to Type 'SomeClass'.)")), Pair.of("ClientProject/" + PACKAGE_JSON, List.of( - "(Error, [16:3 - 16:24], Project does not exist with project ID: ProviderProject.)")) }; + "(Error, [14:18 - 14:39], Project does not exist with project ID: ProviderProject.)")) }; assertIssues2(errorsWithProviderProjectMissing); shutdownLspServer(); diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/RebuildFindsNewNpmPackageTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/RebuildFindsNewNpmPackageTest.java index 8d89cdae6e..986d8568ba 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/RebuildFindsNewNpmPackageTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/RebuildFindsNewNpmPackageTest.java @@ -75,7 +75,7 @@ private void performTest(File rootProjectFolder, File mainProjectFolder) throws getFileURIFromModuleName("Main"), List.of( "(Error, [0:21 - 0:32], Cannot resolve plain module specifier (without project name as first segment): no matching module found.)"), packageJsonFileURI, List.of( - "(Error, [16:3 - 16:12], Project does not exist with project ID: lib.)")); + "(Error, [14:18 - 14:27], Project does not exist with project ID: lib.)")); assertIssues(errorsWhenNpmPackageMissing); // create the missing npm package (without notifications to the server) diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/spec/ImportsUnresolvedTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/spec/ImportsUnresolvedTest.java index 580339502d..751b2b6ebf 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/spec/ImportsUnresolvedTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/spec/ImportsUnresolvedTest.java @@ -127,6 +127,6 @@ public void testProjectImport_mainModuleDefinedButDoesNotExist() { "Main", List.of( "(Error, [0:16 - 0:30], Cannot resolve project import: no matching module found.)"), "OtherProject/" + PACKAGE_JSON, List.of( - "(Error, [8:17 - 8:24], Main module specifier Other does not exist.)"))); + "(Error, [9:16 - 9:23], Main module specifier Other does not exist.)"))); } } diff --git a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/project/MultiProjectIdeTest.java b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/project/MultiProjectIdeTest.java index df127412d9..08b9aa5b5d 100644 --- a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/project/MultiProjectIdeTest.java +++ b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/project/MultiProjectIdeTest.java @@ -138,7 +138,7 @@ class C extends D {} "(Error, [0:18 - 0:21], Cannot resolve plain module specifier (without project name as first segment): no matching module found.)", "(Error, [1:16 - 1:17], Couldn't resolve reference to Type 'D'.)")), Pair.of("multiProjectTest.first/package.json", List.of( - "(Error, [17:8 - 17:27], Project does not exist with project ID: thirdProject.)"))); + "(Error, [18:8 - 18:27], Project does not exist with project ID: thirdProject.)"))); FileURI fileURI = toFileURI(getProjectLocation().toPath().resolve("thirdProject")); fileURI.appendSegment("src").toFile().mkdirs(); @@ -199,7 +199,7 @@ export public class D {} joinServerRequests(); assertIssues2( Pair.of("multiProjectTest.first/package.json", List.of( - "(Error, [16:3 - 16:32], Project does not exist with project ID: multiProjectTest.second.)")), + "(Error, [14:18 - 14:47], Project does not exist with project ID: multiProjectTest.second.)")), Pair.of("C", List.of( "(Error, [0:18 - 0:21], Cannot resolve plain module specifier (without project name as first segment): no matching module found.)", "(Error, [1:16 - 1:17], Couldn't resolve reference to Type 'D'.)"))); @@ -266,21 +266,21 @@ public void testChangeProjectTypeWithoutOpenedEditors() { joinServerRequests(); assertIssues2( Pair.of(PROJECT1_NAME + "/package.json", List.of( - "(Warning, [7:58 - 7:83], Project multiProjectTest.second of type library cannot be declared among the required runtime libraries.)"))); + "(Warning, [8:58 - 8:83], Project multiProjectTest.second of type library cannot be declared among the required runtime libraries.)"))); changeNonOpenedFile(toFileURI(getPackageJsonFile(PROJECT2_NAME)), Pair.of("\"projectType\": \"library\"", "\"projectType\": \"runtimeLibrary\"")); joinServerRequests(); assertIssues2( Pair.of(PROJECT2_NAME + "/package.json", List.of( - "(Warning, [16:3 - 16:21], Project n4js-runtime of type runtime environment cannot be declared among the dependencies or devDependencies.)"))); + "(Warning, [14:18 - 14:36], Project n4js-runtime of type runtime environment cannot be declared among the dependencies or devDependencies.)"))); changeNonOpenedFile(toFileURI(getPackageJsonFile(PROJECT2_NAME)), Pair.of("\"projectType\": \"runtimeLibrary\"", "\"projectType\": \"library\"")); joinServerRequests(); assertIssues2( Pair.of(PROJECT1_NAME + "/package.json", List.of( - "(Warning, [7:58 - 7:83], Project multiProjectTest.second of type library cannot be declared among the required runtime libraries.)"))); + "(Warning, [8:58 - 8:83], Project multiProjectTest.second of type library cannot be declared among the required runtime libraries.)"))); } @Test @@ -299,7 +299,7 @@ class C {} joinServerRequests(); assertIssues2( Pair.of(PROJECT1_NAME + "/package.json", List.of( - "(Warning, [9:30 - 9:35], Source container path ext does not exist.)"))); + "(Warning, [10:29 - 10:34], Source container path ext does not exist.)"))); File extFolder = getProjectRoot(PROJECT1_NAME).toPath().resolve("ext").toFile(); Assert.assertTrue("External folder 'ext' should be missing", !extFolder.exists()); @@ -320,7 +320,7 @@ class C {} cleanBuildAndWait(); assertIssues2( Pair.of(PROJECT1_NAME + "/package.json", List.of( - "(Warning, [9:30 - 9:35], Source container path ext does not exist.)"))); + "(Warning, [10:29 - 10:34], Source container path ext does not exist.)"))); } private void addSecondProjectToDependencies() throws IOException { diff --git a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/project/NoValidationIdeTest.java b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/project/NoValidationIdeTest.java index 27ae81a8c0..8f3a44ed68 100644 --- a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/project/NoValidationIdeTest.java +++ b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/project/NoValidationIdeTest.java @@ -147,7 +147,7 @@ export public class Shadow {} assertIssues2( Pair.of(DEFAULT_PROJECT_NAME + "/package.json", List.of( - "(Error, [7:69 - 7:79], Module filters of type noValidate must not match N4JS modules/files.)"))); + "(Error, [8:69 - 8:79], Module filters of type noValidate must not match N4JS modules/files.)"))); assertEquals("file package.json should have 1 marker since the module filter is invalid", 1, getIssuesInFile(packageJsonFileURI).size()); assertEquals("file src/js/Shadowed.js should have 0 markers", 0, getIssuesInFile(fileImpl).size()); diff --git a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/project/SingleProjectIdeTest.java b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/project/SingleProjectIdeTest.java index dc58d12221..0c13d003b6 100644 --- a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/project/SingleProjectIdeTest.java +++ b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/project/SingleProjectIdeTest.java @@ -249,7 +249,7 @@ class C extends D {} assertIssues2( Pair.of(DEFAULT_PROJECT_NAME + "/package.json", List.of( - "(Warning, [12:16 - 12:22], Source container path src3 does not exist.)")), + "(Warning, [13:16 - 13:22], Source container path src3 does not exist.)")), Pair.of("C", List.of( "(Error, [0:18 - 0:21], Cannot resolve plain module specifier (without project name as first segment): no matching module found.)", "(Error, [1:16 - 1:17], Couldn't resolve reference to Type 'D'.)"))); From 8999137676069e6b711f9b595795866b7bd97c69 Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Wed, 20 Dec 2023 09:17:57 +0100 Subject: [PATCH 09/26] GH-2586: Small enhancements fixed in between --- .../src/org/eclipse/n4js/cli/N4jscModule.java | 1 - .../n4js/json/ide/codeActions/JSONCodeActionService.java | 2 +- .../src/org/eclipse/n4js/utils/languages/N4LanguageUtils.java | 1 - .../eclipse/n4js/xtext/serializer/SerializerPatchModule.java | 2 +- .../src/org/eclipse/n4js/cli/N4jscTestFactory.java | 1 - .../src/org/eclipse/n4js/N4JSInjectorProviderWithIndex.java | 1 - .../n4js/ide/tests/builder/YarnProjectDuplicateNames.java | 2 +- .../ide/tests/xtext/server/ChunkedResourceDescriptionsTest.java | 2 +- .../n4js/tests/dirtystate/BuilderParticipantIdeTest.java | 1 - .../eclipse/n4js/tests/dirtystate/testdata/StaticTestFiles.java | 1 - 10 files changed, 4 insertions(+), 10 deletions(-) diff --git a/plugins/org.eclipse.n4js.cli/src/org/eclipse/n4js/cli/N4jscModule.java b/plugins/org.eclipse.n4js.cli/src/org/eclipse/n4js/cli/N4jscModule.java index a6e22a2140..8581ef2591 100644 --- a/plugins/org.eclipse.n4js.cli/src/org/eclipse/n4js/cli/N4jscModule.java +++ b/plugins/org.eclipse.n4js.cli/src/org/eclipse/n4js/cli/N4jscModule.java @@ -15,7 +15,6 @@ /** * Use this class to override bindings for the cli use case. */ -@SuppressWarnings({ "javadoc" }) public class N4jscModule extends AbstractGenericModule { // public Class bindDocumentExtensions() { diff --git a/plugins/org.eclipse.n4js.json.ide/src/org/eclipse/n4js/json/ide/codeActions/JSONCodeActionService.java b/plugins/org.eclipse.n4js.json.ide/src/org/eclipse/n4js/json/ide/codeActions/JSONCodeActionService.java index 3fd6c8e277..086c71e830 100644 --- a/plugins/org.eclipse.n4js.json.ide/src/org/eclipse/n4js/json/ide/codeActions/JSONCodeActionService.java +++ b/plugins/org.eclipse.n4js.json.ide/src/org/eclipse/n4js/json/ide/codeActions/JSONCodeActionService.java @@ -54,7 +54,7 @@ public List> getCodeActions(Options options) { if (options.getCodeActionParams() != null && options.getCodeActionParams().getContext() != null) { List diagnostics = options.getCodeActionParams().getContext().getDiagnostics(); for (Diagnostic diag : diagnostics) { - if (IssueCodes.NON_EXISTING_PROJECT.equals(diag.getCode().getLeft())) { + if (IssueCodes.NON_EXISTING_PROJECT.name().equals(diag.getCode().getLeft())) { Command cmd = createInstallNpmCommand(options, diag); if (cmd != null) { result.add(Either.forLeft(cmd)); diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/languages/N4LanguageUtils.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/languages/N4LanguageUtils.java index e5c2cdbae6..cb72918da2 100644 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/languages/N4LanguageUtils.java +++ b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/languages/N4LanguageUtils.java @@ -39,7 +39,6 @@ */ public class N4LanguageUtils { - @SuppressWarnings("javadoc") public static final class ParseResult { /** The AST. May be null in case of error. */ public final T ast; diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/xtext/serializer/SerializerPatchModule.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/xtext/serializer/SerializerPatchModule.java index 593915805c..5c3684a250 100644 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/xtext/serializer/SerializerPatchModule.java +++ b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/xtext/serializer/SerializerPatchModule.java @@ -20,7 +20,7 @@ import com.google.inject.AbstractModule; -@SuppressWarnings({ "javadoc", "restriction" }) +@SuppressWarnings("restriction") public class SerializerPatchModule extends AbstractModule { @Override diff --git a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/N4jscTestFactory.java b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/N4jscTestFactory.java index a08b68467d..cfebacc5fd 100644 --- a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/N4jscTestFactory.java +++ b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/N4jscTestFactory.java @@ -27,7 +27,6 @@ public class N4jscTestFactory extends N4jscFactory { /** An {@link N4jscFactory} and related global state. */ - @SuppressWarnings("javadoc") public static final class State { public final N4jscFactory n4jscFactory; public final GlobalStateMemento globalState; diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSInjectorProviderWithIndex.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSInjectorProviderWithIndex.java index 6b860408d0..50de556920 100644 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSInjectorProviderWithIndex.java +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/N4JSInjectorProviderWithIndex.java @@ -21,7 +21,6 @@ public N4JSInjectorProviderWithIndex() { super(new EagerResourceSetModule()); } - @SuppressWarnings("javadoc") public static class EagerResourceSetModule extends BaseTestModule { public Class bindResourceDescriptions() { return EagerResourceSetBasedResourceDescriptions.class; diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnProjectDuplicateNames.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnProjectDuplicateNames.java index 69f0c555a9..71d345d25e 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnProjectDuplicateNames.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnProjectDuplicateNames.java @@ -28,7 +28,7 @@ /** * Test two cases of projects with the same project name within a yarn setup */ -@SuppressWarnings({ "javadoc", "unchecked" }) +@SuppressWarnings("unchecked") public class YarnProjectDuplicateNames extends AbstractIncrementalBuilderTest { private static Map> testData1 = Map.of( diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/xtext/server/ChunkedResourceDescriptionsTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/xtext/server/ChunkedResourceDescriptionsTest.java index b2cf12d7a5..7e86e95f6e 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/xtext/server/ChunkedResourceDescriptionsTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/xtext/server/ChunkedResourceDescriptionsTest.java @@ -34,7 +34,7 @@ * Performance test for resource description implementations. */ @Ignore("TODO Implement a way to make this a real test with assertions on the timing") -@SuppressWarnings({ "javadoc", "restriction" }) +@SuppressWarnings("restriction") public class ChunkedResourceDescriptionsTest { @Test diff --git a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/dirtystate/BuilderParticipantIdeTest.java b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/dirtystate/BuilderParticipantIdeTest.java index 250b8081c0..484e21ace7 100644 --- a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/dirtystate/BuilderParticipantIdeTest.java +++ b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/dirtystate/BuilderParticipantIdeTest.java @@ -158,7 +158,6 @@ public void testMethodRenamedInSuperClassOfClassThatIsUsedToCallTheMethod() thro * 07. Brother should have no error markers */ //@formatter:on - @SuppressWarnings("resource") @Test // TODO: while running there is a java.lang.IndexOutOfBoundsException: Index: 2, Size: 0 at at // org.eclipse.n4js.resource.N4JSResource.getEncodedURI(N4JSResource.java:446) diff --git a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/dirtystate/testdata/StaticTestFiles.java b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/dirtystate/testdata/StaticTestFiles.java index 76bb242f67..03014d806f 100644 --- a/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/dirtystate/testdata/StaticTestFiles.java +++ b/tests/org.eclipse.n4js.ui.tests/src/org/eclipse/n4js/tests/dirtystate/testdata/StaticTestFiles.java @@ -10,7 +10,6 @@ */ package org.eclipse.n4js.tests.dirtystate.testdata; -@SuppressWarnings("unused") public class StaticTestFiles { public static String moduleFolder() { From 45de588980763d241b6b7a2a57cbc81868de7a9a Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Mon, 8 Jan 2024 08:33:36 +0100 Subject: [PATCH 10/26] GH-2589: As a developer I want to also use pnpm as a package manager (#2590) * remove obsolete code * semver support for workspace protocol * support symlinks for package dependencies * fix unrelated bug * add parser for yaml files, check workspaces in pnpm-workspaces.yaml * add tests * add warning * improve xt test setup parser * respect pnpm-workspaces.yaml * fix unrelated NPE * treat pnpm and yarn workspace equally * check for symlinks * move XtextResourceLocator * file scanner ignores nested projects * deal with failures during resource loading * fix tests due to resolving symlinks --- .../N4JSStatefulIncrementalBuilder.java | 3 +- .../build/N4JSConfigSnapshotFactory.java | 6 +- .../ide/contentassist/antlr/SemverParser.java | 13 +- .../antlr/internal/InternalSemver.g | 1218 +- .../antlr/internal/InternalSemver.tokens | 106 +- .../antlr/internal/InternalSemverLexer.java | 814 +- .../antlr/internal/InternalSemverParser.java | 10528 ++++++++++------ .../n4js/semver/Semver/SemverFactory.java | 9 + .../n4js/semver/Semver/SemverPackage.java | 139 +- .../Semver/WorkspaceVersionRequirement.java | 76 + .../semver/Semver/impl/SemverFactoryImpl.java | 12 + .../semver/Semver/impl/SemverPackageImpl.java | 47 + .../impl/WorkspaceVersionRequirementImpl.java | 254 + .../Semver/util/SemverAdapterFactory.java | 18 + .../n4js/semver/Semver/util/SemverSwitch.java | 23 + .../model/Semver.xcore | 5 + .../n4js/semver/model/SemverSerializer.java | 16 + .../org/eclipse/n4js/semver/Semver.xtextbin | Bin 21386 -> 22020 bytes .../parser/antlr/internal/InternalSemver.g | 748 +- .../antlr/internal/InternalSemver.tokens | 92 +- .../antlr/internal/InternalSemverLexer.java | 776 +- .../antlr/internal/InternalSemverParser.java | 7422 +++++++---- .../serializer/SemverSemanticSequencer.java | 47 + .../serializer/SemverSyntacticSequencer.java | 33 + .../semver/services/SemverGrammarAccess.java | 844 +- .../src/org/eclipse/n4js/semver/Semver.xtext | 128 +- .../src/org/eclipse/n4js/utils/URIUtils.java | 7 - .../src/org/eclipse/n4js/utils/UtilN4.java | 2 + .../resourceset/StandardResourceLocator.java | 2 +- .../server/build/ProjectStatePersister.java | 3 + .../n4js/xtext/ide/server/build/XIndexer.java | 6 +- .../src/org/eclipse/n4js/N4JSGlobals.java | 7 + .../n4js/generator/AbstractSubGenerator.xtend | 2 +- .../n4js/packagejson/PackageJsonHelper.java | 7 +- .../ProjectDescription.java | 30 +- .../ProjectDescriptionBuilder.java | 16 +- .../eclipse/n4js/resource/N4JSResource.java | 5 + .../n4js/resource}/XtextResourceLocator.java | 10 +- .../ConfiguredResourceSetProvider.java | 2 +- .../ResourceSetWithBuiltInSchemeProvider.java | 2 +- .../utils/NodeModulesDiscoveryHelper.java | 2 +- .../n4js/utils/ProjectDescriptionLoader.java | 41 +- .../n4js/utils/ProjectDiscoveryHelper.java | 3 + .../src/org/eclipse/n4js/utils/YamlUtil.java | 102 + .../eclipse/n4js/validation/IssueCodes.java | 4 + ...JSProjectSetupJsonValidatorExtension.xtend | 11 + .../workspace/FileSystemScannerAceptor.java | 92 + .../n4js/workspace/N4JSProjectConfig.java | 2 +- .../n4js/workspace/N4JSSourceFolder.java | 33 +- .../workspace/N4JSSourceFolderSnapshot.java | 29 +- ...4JSSourceFolderSnapshotForPackageJson.java | 2 +- .../n4js/workspace/N4JSWorkspaceConfig.java | 5 +- .../workspace/utils/FileSystemScanner.java | 36 +- .../workspace/utils/FileVisitingAcceptor.java | 64 - .../utils/SemanticDependencySupplier.java | 1 + .../tests/helper/server/xt/XtSetupParser.java | 10 + .../helper/mock/MockWorkspaceSupplier.java | 2 +- .../PDTs/yarnSymLinksInNodeModulesFolder1.pdt | 2 +- .../PDTs/yarnSymLinksInNodeModulesFolder2.pdt | 2 +- .../PDTs/yarnSymLinksInNodeModulesFolder3.pdt | 2 +- .../builder/BuilderYarnWorkspaceTest.java | 7 +- .../builder/SymbolicLinkInWorkspaceTest.java | 30 +- .../tests/buildorder/BuildOrderToDtsTest.java | 2 +- .../tests/xtext/workspace/ProjectSetTest.java | 2 +- .../semver/tests/parser/SemverParserTest.java | 17 + .../org/eclipse/n4js/utils/YamlUtilTest.java | 166 + .../package.json_workspace_arr.xt | 49 + .../package.json_workspace_obj.xt | 54 + .../package.json_workspace_prefer_yarn.xt | 50 + ...ackage.json_workspace_prefer_yarn_false.xt | 50 + 70 files changed, 16343 insertions(+), 8007 deletions(-) create mode 100644 plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/WorkspaceVersionRequirement.java create mode 100644 plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/impl/WorkspaceVersionRequirementImpl.java rename plugins/{org.eclipse.n4js.utils/src/org/eclipse/n4js/xtext/resourceset => org.eclipse.n4js/src/org/eclipse/n4js/resource}/XtextResourceLocator.java (88%) create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/YamlUtil.java create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/FileSystemScannerAceptor.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/utils/FileVisitingAcceptor.java create mode 100644 tests/org.eclipse.n4js.utils.tests/src/org/eclipse/n4js/utils/YamlUtilTest.java create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_arr.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_obj.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_prefer_yarn.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_prefer_yarn_false.xt diff --git a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/N4JSStatefulIncrementalBuilder.java b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/N4JSStatefulIncrementalBuilder.java index 9512f4c653..73028a0cff 100644 --- a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/N4JSStatefulIncrementalBuilder.java +++ b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/N4JSStatefulIncrementalBuilder.java @@ -43,6 +43,7 @@ import org.eclipse.xtext.util.IFileSystemScanner; import org.eclipse.xtext.validation.Issue; +import com.google.common.base.Strings; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; @@ -296,7 +297,7 @@ private String getAdjustedModuleSpecifierOrNull(String moduleSpecifier, N4JSProj Multimap moduleName2Uri) { ProjectDescription pd = projectConfig.getProjectDescription(); - String prjName = projectConfig.getPackageName(); + String prjName = Strings.nullToEmpty(projectConfig.getPackageName()); if (moduleName2Uri.containsKey(moduleSpecifier)) { return moduleSpecifier; } else if (moduleSpecifier.startsWith("./")) { diff --git a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/build/N4JSConfigSnapshotFactory.java b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/build/N4JSConfigSnapshotFactory.java index f1beb00328..64122009e6 100644 --- a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/build/N4JSConfigSnapshotFactory.java +++ b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/build/N4JSConfigSnapshotFactory.java @@ -14,9 +14,9 @@ import org.eclipse.emf.common.util.URI; import org.eclipse.n4js.packagejson.projectDescription.ProjectDependency; -import org.eclipse.n4js.workspace.IN4JSSourceFolder; import org.eclipse.n4js.workspace.N4JSProjectConfig; import org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot; +import org.eclipse.n4js.workspace.N4JSSourceFolder; import org.eclipse.n4js.workspace.N4JSSourceFolderForPackageJson; import org.eclipse.n4js.workspace.N4JSSourceFolderSnapshot; import org.eclipse.n4js.workspace.N4JSSourceFolderSnapshotForPackageJson; @@ -65,8 +65,8 @@ public N4JSSourceFolderSnapshot createSourceFolderSnapshot(ISourceFolder sourceF if (sourceFolder instanceof N4JSSourceFolderForPackageJson) { return new N4JSSourceFolderSnapshotForPackageJson((N4JSSourceFolderForPackageJson) sourceFolder); } - IN4JSSourceFolder sourceFolderCasted = (IN4JSSourceFolder) sourceFolder; + N4JSSourceFolder sourceFolderCasted = (N4JSSourceFolder) sourceFolder; return new N4JSSourceFolderSnapshot(sourceFolder.getName(), sourceFolder.getPath(), - sourceFolderCasted.getType(), sourceFolderCasted.getRelativePath()); + sourceFolderCasted.getType(), sourceFolderCasted.getRelativePath(), sourceFolderCasted.getWorkspaces()); } } diff --git a/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/SemverParser.java b/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/SemverParser.java index e048652fe0..0f5733090f 100644 --- a/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/SemverParser.java +++ b/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/SemverParser.java @@ -41,7 +41,9 @@ private static void init(ImmutableMap.Builder builder, builder.put(grammarAccess.getNPMVersionRequirementAccess().getAlternatives(), "rule__NPMVersionRequirement__Alternatives"); builder.put(grammarAccess.getNPMVersionRequirementAccess().getAlternatives_1_0(), "rule__NPMVersionRequirement__Alternatives_1_0"); builder.put(grammarAccess.getNPMVersionRequirementAccess().getAlternatives_1_0_1(), "rule__NPMVersionRequirement__Alternatives_1_0_1"); + builder.put(grammarAccess.getNPMVersionRequirementAccess().getAlternatives_1_0_1_1(), "rule__NPMVersionRequirement__Alternatives_1_0_1_1"); builder.put(grammarAccess.getURLVersionSpecifierAccess().getAlternatives(), "rule__URLVersionSpecifier__Alternatives"); + builder.put(grammarAccess.getWorkspaceVersionRequirementAccess().getAlternatives_1(), "rule__WorkspaceVersionRequirement__Alternatives_1"); builder.put(grammarAccess.getVersionRangeAccess().getAlternatives(), "rule__VersionRange__Alternatives"); builder.put(grammarAccess.getVersionPartAccess().getAlternatives(), "rule__VersionPart__Alternatives"); builder.put(grammarAccess.getQualifierAccess().getAlternatives(), "rule__Qualifier__Alternatives"); @@ -54,9 +56,8 @@ private static void init(ImmutableMap.Builder builder, builder.put(grammarAccess.getURL_NO_VXAccess().getAlternatives_1(), "rule__URL_NO_VX__Alternatives_1"); builder.put(grammarAccess.getURL_NO_VXAccess().getAlternatives_2(), "rule__URL_NO_VX__Alternatives_2"); builder.put(grammarAccess.getURL_NO_VXAccess().getAlternatives_3(), "rule__URL_NO_VX__Alternatives_3"); - builder.put(grammarAccess.getTAGAccess().getAlternatives_1(), "rule__TAG__Alternatives_1"); - builder.put(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getAlternatives(), "rule__ALPHA_NUMERIC_CHARS__Alternatives"); - builder.put(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getAlternatives_1(), "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1"); + builder.put(grammarAccess.getWORKSPACE_VERSIONAccess().getAlternatives(), "rule__WORKSPACE_VERSION__Alternatives"); + builder.put(grammarAccess.getALPHA_NUMERIC_CHARAccess().getAlternatives(), "rule__ALPHA_NUMERIC_CHAR__Alternatives"); builder.put(grammarAccess.getWILDCARDAccess().getAlternatives(), "rule__WILDCARD__Alternatives"); builder.put(grammarAccess.getLETTERAccess().getAlternatives(), "rule__LETTER__Alternatives"); builder.put(grammarAccess.getLETTER_NO_VXAccess().getAlternatives(), "rule__LETTER_NO_VX__Alternatives"); @@ -71,6 +72,7 @@ private static void init(ImmutableMap.Builder builder, builder.put(grammarAccess.getURLVersionSpecifierAccess().getGroup_1(), "rule__URLVersionSpecifier__Group_1__0"); builder.put(grammarAccess.getURLVersionSpecifierAccess().getGroup_2(), "rule__URLVersionSpecifier__Group_2__0"); builder.put(grammarAccess.getURLSemverAccess().getGroup(), "rule__URLSemver__Group__0"); + builder.put(grammarAccess.getWorkspaceVersionRequirementAccess().getGroup(), "rule__WorkspaceVersionRequirement__Group__0"); builder.put(grammarAccess.getGitHubVersionRequirementAccess().getGroup(), "rule__GitHubVersionRequirement__Group__0"); builder.put(grammarAccess.getGitHubVersionRequirementAccess().getGroup_1(), "rule__GitHubVersionRequirement__Group_1__0"); builder.put(grammarAccess.getVersionRangeSetRequirementAccess().getGroup(), "rule__VersionRangeSetRequirement__Group__0"); @@ -92,6 +94,7 @@ private static void init(ImmutableMap.Builder builder, builder.put(grammarAccess.getQualifierTagAccess().getGroup_1(), "rule__QualifierTag__Group_1__0"); builder.put(grammarAccess.getFILE_TAGAccess().getGroup(), "rule__FILE_TAG__Group__0"); builder.put(grammarAccess.getSEMVER_TAGAccess().getGroup(), "rule__SEMVER_TAG__Group__0"); + builder.put(grammarAccess.getWORKSPACE_TAGAccess().getGroup(), "rule__WORKSPACE_TAG__Group__0"); builder.put(grammarAccess.getURL_PROTOCOLAccess().getGroup(), "rule__URL_PROTOCOL__Group__0"); builder.put(grammarAccess.getURLAccess().getGroup(), "rule__URL__Group__0"); builder.put(grammarAccess.getURL_NO_VXAccess().getGroup(), "rule__URL_NO_VX__Group__0"); @@ -105,9 +108,11 @@ private static void init(ImmutableMap.Builder builder, builder.put(grammarAccess.getURLVersionSpecifierAccess().getCommitISHAssignment_2_1(), "rule__URLVersionSpecifier__CommitISHAssignment_2_1"); builder.put(grammarAccess.getURLSemverAccess().getWithSemverTagAssignment_1(), "rule__URLSemver__WithSemverTagAssignment_1"); builder.put(grammarAccess.getURLSemverAccess().getSimpleVersionAssignment_2(), "rule__URLSemver__SimpleVersionAssignment_2"); - builder.put(grammarAccess.getTagVersionRequirementAccess().getTagNameAssignment(), "rule__TagVersionRequirement__TagNameAssignment"); + builder.put(grammarAccess.getWorkspaceVersionRequirementAccess().getVersionAssignment_1_0(), "rule__WorkspaceVersionRequirement__VersionAssignment_1_0"); + builder.put(grammarAccess.getWorkspaceVersionRequirementAccess().getOtherVersionAssignment_1_1(), "rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1"); builder.put(grammarAccess.getGitHubVersionRequirementAccess().getGithubUrlAssignment_0(), "rule__GitHubVersionRequirement__GithubUrlAssignment_0"); builder.put(grammarAccess.getGitHubVersionRequirementAccess().getCommitISHAssignment_1_1(), "rule__GitHubVersionRequirement__CommitISHAssignment_1_1"); + builder.put(grammarAccess.getTagVersionRequirementAccess().getTagNameAssignment(), "rule__TagVersionRequirement__TagNameAssignment"); builder.put(grammarAccess.getVersionRangeSetRequirementAccess().getRangesAssignment_1_0(), "rule__VersionRangeSetRequirement__RangesAssignment_1_0"); builder.put(grammarAccess.getVersionRangeSetRequirementAccess().getRangesAssignment_1_1_3(), "rule__VersionRangeSetRequirement__RangesAssignment_1_1_3"); builder.put(grammarAccess.getHyphenVersionRangeAccess().getFromAssignment_1(), "rule__HyphenVersionRange__FromAssignment_1"); diff --git a/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemver.g b/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemver.g index cbeb5bdbd0..3b479479f3 100644 --- a/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemver.g +++ b/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemver.g @@ -182,25 +182,25 @@ finally { restoreStackSize(stackSize); } -// Entry rule entryRuleTagVersionRequirement -entryRuleTagVersionRequirement +// Entry rule entryRuleWorkspaceVersionRequirement +entryRuleWorkspaceVersionRequirement : -{ before(grammarAccess.getTagVersionRequirementRule()); } - ruleTagVersionRequirement -{ after(grammarAccess.getTagVersionRequirementRule()); } +{ before(grammarAccess.getWorkspaceVersionRequirementRule()); } + ruleWorkspaceVersionRequirement +{ after(grammarAccess.getWorkspaceVersionRequirementRule()); } EOF ; -// Rule TagVersionRequirement -ruleTagVersionRequirement +// Rule WorkspaceVersionRequirement +ruleWorkspaceVersionRequirement @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getTagVersionRequirementAccess().getTagNameAssignment()); } - (rule__TagVersionRequirement__TagNameAssignment) - { after(grammarAccess.getTagVersionRequirementAccess().getTagNameAssignment()); } + { before(grammarAccess.getWorkspaceVersionRequirementAccess().getGroup()); } + (rule__WorkspaceVersionRequirement__Group__0) + { after(grammarAccess.getWorkspaceVersionRequirementAccess().getGroup()); } ) ; finally { @@ -232,6 +232,31 @@ finally { restoreStackSize(stackSize); } +// Entry rule entryRuleTagVersionRequirement +entryRuleTagVersionRequirement +: +{ before(grammarAccess.getTagVersionRequirementRule()); } + ruleTagVersionRequirement +{ after(grammarAccess.getTagVersionRequirementRule()); } + EOF +; + +// Rule TagVersionRequirement +ruleTagVersionRequirement + @init { + int stackSize = keepStackSize(); + } + : + ( + { before(grammarAccess.getTagVersionRequirementAccess().getTagNameAssignment()); } + (rule__TagVersionRequirement__TagNameAssignment) + { after(grammarAccess.getTagVersionRequirementAccess().getTagNameAssignment()); } + ) +; +finally { + restoreStackSize(stackSize); +} + // Entry rule entryRuleVersionRangeSetRequirement entryRuleVersionRangeSetRequirement : @@ -507,6 +532,31 @@ finally { restoreStackSize(stackSize); } +// Entry rule entryRuleWORKSPACE_TAG +entryRuleWORKSPACE_TAG +: +{ before(grammarAccess.getWORKSPACE_TAGRule()); } + ruleWORKSPACE_TAG +{ after(grammarAccess.getWORKSPACE_TAGRule()); } + EOF +; + +// Rule WORKSPACE_TAG +ruleWORKSPACE_TAG + @init { + int stackSize = keepStackSize(); + } + : + ( + { before(grammarAccess.getWORKSPACE_TAGAccess().getGroup()); } + (rule__WORKSPACE_TAG__Group__0) + { after(grammarAccess.getWORKSPACE_TAGAccess().getGroup()); } + ) +; +finally { + restoreStackSize(stackSize); +} + // Entry rule entryRulePATH entryRulePATH : @@ -639,31 +689,31 @@ finally { restoreStackSize(stackSize); } -// Entry rule entryRuleALPHA_NUMERIC_CHARS -entryRuleALPHA_NUMERIC_CHARS +// Entry rule entryRuleWORKSPACE_VERSION +entryRuleWORKSPACE_VERSION : -{ before(grammarAccess.getALPHA_NUMERIC_CHARSRule()); } - ruleALPHA_NUMERIC_CHARS -{ after(grammarAccess.getALPHA_NUMERIC_CHARSRule()); } +{ before(grammarAccess.getWORKSPACE_VERSIONRule()); } + ruleWORKSPACE_VERSION +{ after(grammarAccess.getWORKSPACE_VERSIONRule()); } EOF ; -// Rule ALPHA_NUMERIC_CHARS -ruleALPHA_NUMERIC_CHARS +// Rule WORKSPACE_VERSION +ruleWORKSPACE_VERSION @init { int stackSize = keepStackSize(); } : ( ( - { before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getAlternatives()); } - (rule__ALPHA_NUMERIC_CHARS__Alternatives) - { after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getAlternatives()); } + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getAlternatives()); } + (rule__WORKSPACE_VERSION__Alternatives) + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getAlternatives()); } ) ( - { before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getAlternatives()); } - (rule__ALPHA_NUMERIC_CHARS__Alternatives)* - { after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getAlternatives()); } + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getAlternatives()); } + (rule__WORKSPACE_VERSION__Alternatives)* + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getAlternatives()); } ) ) ; @@ -696,6 +746,63 @@ finally { restoreStackSize(stackSize); } +// Entry rule entryRuleALPHA_NUMERIC_CHARS +entryRuleALPHA_NUMERIC_CHARS +: +{ before(grammarAccess.getALPHA_NUMERIC_CHARSRule()); } + ruleALPHA_NUMERIC_CHARS +{ after(grammarAccess.getALPHA_NUMERIC_CHARSRule()); } + EOF +; + +// Rule ALPHA_NUMERIC_CHARS +ruleALPHA_NUMERIC_CHARS + @init { + int stackSize = keepStackSize(); + } + : + ( + ( + { before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getALPHA_NUMERIC_CHARParserRuleCall()); } + (ruleALPHA_NUMERIC_CHAR) + { after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getALPHA_NUMERIC_CHARParserRuleCall()); } + ) + ( + { before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getALPHA_NUMERIC_CHARParserRuleCall()); } + (ruleALPHA_NUMERIC_CHAR)* + { after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getALPHA_NUMERIC_CHARParserRuleCall()); } + ) + ) +; +finally { + restoreStackSize(stackSize); +} + +// Entry rule entryRuleALPHA_NUMERIC_CHAR +entryRuleALPHA_NUMERIC_CHAR +: +{ before(grammarAccess.getALPHA_NUMERIC_CHARRule()); } + ruleALPHA_NUMERIC_CHAR +{ after(grammarAccess.getALPHA_NUMERIC_CHARRule()); } + EOF +; + +// Rule ALPHA_NUMERIC_CHAR +ruleALPHA_NUMERIC_CHAR + @init { + int stackSize = keepStackSize(); + } + : + ( + { before(grammarAccess.getALPHA_NUMERIC_CHARAccess().getAlternatives()); } + (rule__ALPHA_NUMERIC_CHAR__Alternatives) + { after(grammarAccess.getALPHA_NUMERIC_CHARAccess().getAlternatives()); } + ) +; +finally { + restoreStackSize(stackSize); +} + // Entry rule entryRuleWILDCARD entryRuleWILDCARD : @@ -825,15 +932,36 @@ rule__NPMVersionRequirement__Alternatives_1_0_1 ) | ( - { before(grammarAccess.getNPMVersionRequirementAccess().getGitHubVersionRequirementParserRuleCall_1_0_1_1()); } + { before(grammarAccess.getNPMVersionRequirementAccess().getAlternatives_1_0_1_1()); } + (rule__NPMVersionRequirement__Alternatives_1_0_1_1) + { after(grammarAccess.getNPMVersionRequirementAccess().getAlternatives_1_0_1_1()); } + ) +; +finally { + restoreStackSize(stackSize); +} + +rule__NPMVersionRequirement__Alternatives_1_0_1_1 + @init { + int stackSize = keepStackSize(); + } +: + ( + { before(grammarAccess.getNPMVersionRequirementAccess().getWorkspaceVersionRequirementParserRuleCall_1_0_1_1_0()); } + (ruleWorkspaceVersionRequirement) + { after(grammarAccess.getNPMVersionRequirementAccess().getWorkspaceVersionRequirementParserRuleCall_1_0_1_1_0()); } + ) + | + ( + { before(grammarAccess.getNPMVersionRequirementAccess().getGitHubVersionRequirementParserRuleCall_1_0_1_1_1()); } ruleGitHubVersionRequirement - { after(grammarAccess.getNPMVersionRequirementAccess().getGitHubVersionRequirementParserRuleCall_1_0_1_1()); } + { after(grammarAccess.getNPMVersionRequirementAccess().getGitHubVersionRequirementParserRuleCall_1_0_1_1_1()); } ) | ( - { before(grammarAccess.getNPMVersionRequirementAccess().getTagVersionRequirementParserRuleCall_1_0_1_2()); } + { before(grammarAccess.getNPMVersionRequirementAccess().getTagVersionRequirementParserRuleCall_1_0_1_1_2()); } ruleTagVersionRequirement - { after(grammarAccess.getNPMVersionRequirementAccess().getTagVersionRequirementParserRuleCall_1_0_1_2()); } + { after(grammarAccess.getNPMVersionRequirementAccess().getTagVersionRequirementParserRuleCall_1_0_1_1_2()); } ) ; finally { @@ -867,6 +995,27 @@ finally { restoreStackSize(stackSize); } +rule__WorkspaceVersionRequirement__Alternatives_1 + @init { + int stackSize = keepStackSize(); + } +: + ( + { before(grammarAccess.getWorkspaceVersionRequirementAccess().getVersionAssignment_1_0()); } + (rule__WorkspaceVersionRequirement__VersionAssignment_1_0) + { after(grammarAccess.getWorkspaceVersionRequirementAccess().getVersionAssignment_1_0()); } + ) + | + ( + { before(grammarAccess.getWorkspaceVersionRequirementAccess().getOtherVersionAssignment_1_1()); } + (rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1) + { after(grammarAccess.getWorkspaceVersionRequirementAccess().getOtherVersionAssignment_1_1()); } + ) +; +finally { + restoreStackSize(stackSize); +} + rule__VersionRange__Alternatives @init { int stackSize = keepStackSize(); @@ -954,27 +1103,15 @@ rule__PATH__Alternatives ) | ( - { before(grammarAccess.getPATHAccess().getHyphenMinusKeyword_3()); } - '-' - { after(grammarAccess.getPATHAccess().getHyphenMinusKeyword_3()); } - ) - | - ( - { before(grammarAccess.getPATHAccess().get_Keyword_4()); } + { before(grammarAccess.getPATHAccess().get_Keyword_3()); } '_' - { after(grammarAccess.getPATHAccess().get_Keyword_4()); } - ) - | - ( - { before(grammarAccess.getPATHAccess().getDIGITSTerminalRuleCall_5()); } - RULE_DIGITS - { after(grammarAccess.getPATHAccess().getDIGITSTerminalRuleCall_5()); } + { after(grammarAccess.getPATHAccess().get_Keyword_3()); } ) | ( - { before(grammarAccess.getPATHAccess().getLETTERParserRuleCall_6()); } - ruleLETTER - { after(grammarAccess.getPATHAccess().getLETTERParserRuleCall_6()); } + { before(grammarAccess.getPATHAccess().getALPHA_NUMERIC_CHARParserRuleCall_4()); } + ruleALPHA_NUMERIC_CHAR + { after(grammarAccess.getPATHAccess().getALPHA_NUMERIC_CHARParserRuleCall_4()); } ) ; finally { @@ -1008,27 +1145,15 @@ rule__URL__Alternatives_0 } : ( - { before(grammarAccess.getURLAccess().getHyphenMinusKeyword_0_0()); } - '-' - { after(grammarAccess.getURLAccess().getHyphenMinusKeyword_0_0()); } - ) - | - ( - { before(grammarAccess.getURLAccess().get_Keyword_0_1()); } + { before(grammarAccess.getURLAccess().get_Keyword_0_0()); } '_' - { after(grammarAccess.getURLAccess().get_Keyword_0_1()); } - ) - | - ( - { before(grammarAccess.getURLAccess().getDIGITSTerminalRuleCall_0_2()); } - RULE_DIGITS - { after(grammarAccess.getURLAccess().getDIGITSTerminalRuleCall_0_2()); } + { after(grammarAccess.getURLAccess().get_Keyword_0_0()); } ) | ( - { before(grammarAccess.getURLAccess().getLETTERParserRuleCall_0_3()); } - ruleLETTER - { after(grammarAccess.getURLAccess().getLETTERParserRuleCall_0_3()); } + { before(grammarAccess.getURLAccess().getALPHA_NUMERIC_CHARParserRuleCall_0_1()); } + ruleALPHA_NUMERIC_CHAR + { after(grammarAccess.getURLAccess().getALPHA_NUMERIC_CHARParserRuleCall_0_1()); } ) ; finally { @@ -1098,27 +1223,15 @@ rule__URL__Alternatives_2 ) | ( - { before(grammarAccess.getURLAccess().getHyphenMinusKeyword_2_4()); } - '-' - { after(grammarAccess.getURLAccess().getHyphenMinusKeyword_2_4()); } - ) - | - ( - { before(grammarAccess.getURLAccess().get_Keyword_2_5()); } + { before(grammarAccess.getURLAccess().get_Keyword_2_4()); } '_' - { after(grammarAccess.getURLAccess().get_Keyword_2_5()); } - ) - | - ( - { before(grammarAccess.getURLAccess().getDIGITSTerminalRuleCall_2_6()); } - RULE_DIGITS - { after(grammarAccess.getURLAccess().getDIGITSTerminalRuleCall_2_6()); } + { after(grammarAccess.getURLAccess().get_Keyword_2_4()); } ) | ( - { before(grammarAccess.getURLAccess().getLETTERParserRuleCall_2_7()); } - ruleLETTER - { after(grammarAccess.getURLAccess().getLETTERParserRuleCall_2_7()); } + { before(grammarAccess.getURLAccess().getALPHA_NUMERIC_CHARParserRuleCall_2_5()); } + ruleALPHA_NUMERIC_CHAR + { after(grammarAccess.getURLAccess().getALPHA_NUMERIC_CHARParserRuleCall_2_5()); } ) ; finally { @@ -1131,15 +1244,15 @@ rule__URL_NO_VX__Alternatives_0 } : ( - { before(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_0_0()); } - '-' - { after(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_0_0()); } + { before(grammarAccess.getURL_NO_VXAccess().get_Keyword_0_0()); } + '_' + { after(grammarAccess.getURL_NO_VXAccess().get_Keyword_0_0()); } ) | ( - { before(grammarAccess.getURL_NO_VXAccess().get_Keyword_0_1()); } - '_' - { after(grammarAccess.getURL_NO_VXAccess().get_Keyword_0_1()); } + { before(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_0_1()); } + '-' + { after(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_0_1()); } ) | ( @@ -1158,27 +1271,15 @@ rule__URL_NO_VX__Alternatives_1 } : ( - { before(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_1_0()); } - '-' - { after(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_1_0()); } - ) - | - ( - { before(grammarAccess.getURL_NO_VXAccess().get_Keyword_1_1()); } + { before(grammarAccess.getURL_NO_VXAccess().get_Keyword_1_0()); } '_' - { after(grammarAccess.getURL_NO_VXAccess().get_Keyword_1_1()); } - ) - | - ( - { before(grammarAccess.getURL_NO_VXAccess().getDIGITSTerminalRuleCall_1_2()); } - RULE_DIGITS - { after(grammarAccess.getURL_NO_VXAccess().getDIGITSTerminalRuleCall_1_2()); } + { after(grammarAccess.getURL_NO_VXAccess().get_Keyword_1_0()); } ) | ( - { before(grammarAccess.getURL_NO_VXAccess().getLETTERParserRuleCall_1_3()); } - ruleLETTER - { after(grammarAccess.getURL_NO_VXAccess().getLETTERParserRuleCall_1_3()); } + { before(grammarAccess.getURL_NO_VXAccess().getALPHA_NUMERIC_CHARParserRuleCall_1_1()); } + ruleALPHA_NUMERIC_CHAR + { after(grammarAccess.getURL_NO_VXAccess().getALPHA_NUMERIC_CHARParserRuleCall_1_1()); } ) ; finally { @@ -1248,108 +1349,135 @@ rule__URL_NO_VX__Alternatives_3 ) | ( - { before(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_3_4()); } - '-' - { after(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_3_4()); } - ) - | - ( - { before(grammarAccess.getURL_NO_VXAccess().get_Keyword_3_5()); } + { before(grammarAccess.getURL_NO_VXAccess().get_Keyword_3_4()); } '_' - { after(grammarAccess.getURL_NO_VXAccess().get_Keyword_3_5()); } - ) - | - ( - { before(grammarAccess.getURL_NO_VXAccess().getDIGITSTerminalRuleCall_3_6()); } - RULE_DIGITS - { after(grammarAccess.getURL_NO_VXAccess().getDIGITSTerminalRuleCall_3_6()); } + { after(grammarAccess.getURL_NO_VXAccess().get_Keyword_3_4()); } ) | ( - { before(grammarAccess.getURL_NO_VXAccess().getLETTERParserRuleCall_3_7()); } - ruleLETTER - { after(grammarAccess.getURL_NO_VXAccess().getLETTERParserRuleCall_3_7()); } + { before(grammarAccess.getURL_NO_VXAccess().getALPHA_NUMERIC_CHARParserRuleCall_3_5()); } + ruleALPHA_NUMERIC_CHAR + { after(grammarAccess.getURL_NO_VXAccess().getALPHA_NUMERIC_CHARParserRuleCall_3_5()); } ) ; finally { restoreStackSize(stackSize); } -rule__TAG__Alternatives_1 +rule__WORKSPACE_VERSION__Alternatives @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getTAGAccess().getHyphenMinusKeyword_1_0()); } - '-' - { after(grammarAccess.getTAGAccess().getHyphenMinusKeyword_1_0()); } + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getSolidusKeyword_0()); } + '/' + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getSolidusKeyword_0()); } ) | ( - { before(grammarAccess.getTAGAccess().getDIGITSTerminalRuleCall_1_1()); } - RULE_DIGITS - { after(grammarAccess.getTAGAccess().getDIGITSTerminalRuleCall_1_1()); } + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getFullStopKeyword_1()); } + '.' + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getFullStopKeyword_1()); } ) | ( - { before(grammarAccess.getTAGAccess().getLETTERParserRuleCall_1_2()); } - ruleLETTER - { after(grammarAccess.getTAGAccess().getLETTERParserRuleCall_1_2()); } + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getColonKeyword_2()); } + ':' + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getColonKeyword_2()); } ) -; -finally { - restoreStackSize(stackSize); -} - -rule__ALPHA_NUMERIC_CHARS__Alternatives - @init { - int stackSize = keepStackSize(); - } -: + | ( - { before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getHyphenMinusKeyword_0()); } - '-' - { after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getHyphenMinusKeyword_0()); } + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getCommercialAtKeyword_3()); } + '@' + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getCommercialAtKeyword_3()); } ) | ( - { before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getDIGITSTerminalRuleCall_1()); } - RULE_DIGITS - { after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getDIGITSTerminalRuleCall_1()); } + { before(grammarAccess.getWORKSPACE_VERSIONAccess().get_Keyword_4()); } + '_' + { after(grammarAccess.getWORKSPACE_VERSIONAccess().get_Keyword_4()); } ) | ( - { before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getLETTERParserRuleCall_2()); } - ruleLETTER - { after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getLETTERParserRuleCall_2()); } + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getEqualsSignKeyword_5()); } + '=' + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getEqualsSignKeyword_5()); } + ) + | + ( + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getTildeKeyword_6()); } + '~' + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getTildeKeyword_6()); } + ) + | + ( + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getCircumflexAccentKeyword_7()); } + '^' + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getCircumflexAccentKeyword_7()); } + ) + | + ( + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getLessThanSignKeyword_8()); } + '<' + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getLessThanSignKeyword_8()); } + ) + | + ( + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getGreaterThanSignKeyword_9()); } + '>' + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getGreaterThanSignKeyword_9()); } + ) + | + ( + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getLessThanSignEqualsSignKeyword_10()); } + '<=' + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getLessThanSignEqualsSignKeyword_10()); } + ) + | + ( + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getGreaterThanSignEqualsSignKeyword_11()); } + '>=' + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getGreaterThanSignEqualsSignKeyword_11()); } + ) + | + ( + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getASTERIXTerminalRuleCall_12()); } + RULE_ASTERIX + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getASTERIXTerminalRuleCall_12()); } + ) + | + ( + { before(grammarAccess.getWORKSPACE_VERSIONAccess().getALPHA_NUMERIC_CHARParserRuleCall_13()); } + ruleALPHA_NUMERIC_CHAR + { after(grammarAccess.getWORKSPACE_VERSIONAccess().getALPHA_NUMERIC_CHARParserRuleCall_13()); } ) ; finally { restoreStackSize(stackSize); } -rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 +rule__ALPHA_NUMERIC_CHAR__Alternatives @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getHyphenMinusKeyword_1_0()); } + { before(grammarAccess.getALPHA_NUMERIC_CHARAccess().getHyphenMinusKeyword_0()); } '-' - { after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getHyphenMinusKeyword_1_0()); } + { after(grammarAccess.getALPHA_NUMERIC_CHARAccess().getHyphenMinusKeyword_0()); } ) | ( - { before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getDIGITSTerminalRuleCall_1_1()); } + { before(grammarAccess.getALPHA_NUMERIC_CHARAccess().getDIGITSTerminalRuleCall_1()); } RULE_DIGITS - { after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getDIGITSTerminalRuleCall_1_1()); } + { after(grammarAccess.getALPHA_NUMERIC_CHARAccess().getDIGITSTerminalRuleCall_1()); } ) | ( - { before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getLETTERParserRuleCall_1_2()); } + { before(grammarAccess.getALPHA_NUMERIC_CHARAccess().getLETTERParserRuleCall_2()); } ruleLETTER - { after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getLETTERParserRuleCall_1_2()); } + { after(grammarAccess.getALPHA_NUMERIC_CHARAccess().getLETTERParserRuleCall_2()); } ) ; finally { @@ -1410,21 +1538,21 @@ rule__LETTER_NO_VX__Alternatives } : ( - { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_STerminalRuleCall_0()); } - RULE_LETTER_S - { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_STerminalRuleCall_0()); } + { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_ATerminalRuleCall_0()); } + RULE_LETTER_A + { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_ATerminalRuleCall_0()); } ) | ( - { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_MTerminalRuleCall_1()); } - RULE_LETTER_M - { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_MTerminalRuleCall_1()); } + { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_CTerminalRuleCall_1()); } + RULE_LETTER_C + { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_CTerminalRuleCall_1()); } ) | ( - { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_RTerminalRuleCall_2()); } - RULE_LETTER_R - { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_RTerminalRuleCall_2()); } + { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_ETerminalRuleCall_2()); } + RULE_LETTER_E + { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_ETerminalRuleCall_2()); } ) | ( @@ -1440,21 +1568,57 @@ rule__LETTER_NO_VX__Alternatives ) | ( - { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_LTerminalRuleCall_5()); } + { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_KTerminalRuleCall_5()); } + RULE_LETTER_K + { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_KTerminalRuleCall_5()); } + ) + | + ( + { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_LTerminalRuleCall_6()); } RULE_LETTER_L - { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_LTerminalRuleCall_5()); } + { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_LTerminalRuleCall_6()); } ) | ( - { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_ETerminalRuleCall_6()); } - RULE_LETTER_E - { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_ETerminalRuleCall_6()); } + { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_MTerminalRuleCall_7()); } + RULE_LETTER_M + { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_MTerminalRuleCall_7()); } + ) + | + ( + { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTerminalRuleCall_8()); } + RULE_LETTER_O + { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTerminalRuleCall_8()); } + ) + | + ( + { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_PTerminalRuleCall_9()); } + RULE_LETTER_P + { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_PTerminalRuleCall_9()); } + ) + | + ( + { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_RTerminalRuleCall_10()); } + RULE_LETTER_R + { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_RTerminalRuleCall_10()); } ) | ( - { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTHERTerminalRuleCall_7()); } + { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_STerminalRuleCall_11()); } + RULE_LETTER_S + { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_STerminalRuleCall_11()); } + ) + | + ( + { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_WTerminalRuleCall_12()); } + RULE_LETTER_W + { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_WTerminalRuleCall_12()); } + ) + | + ( + { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTHERTerminalRuleCall_13()); } RULE_LETTER_OTHER - { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTHERTerminalRuleCall_7()); } + { after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTHERTerminalRuleCall_13()); } ) ; finally { @@ -1473,39 +1637,39 @@ rule__VersionComparator__Alternatives ) | ( - { before(grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_1()); } - ('<') - { after(grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_1()); } - ) - | - ( - { before(grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_2()); } + { before(grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_1()); } ('~') - { after(grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_2()); } + { after(grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_1()); } ) | ( - { before(grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_3()); } + { before(grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_2()); } ('^') - { after(grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_3()); } + { after(grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_2()); } ) | ( - { before(grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_4()); } - ('<=') - { after(grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_4()); } + { before(grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_3()); } + ('<') + { after(grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_3()); } ) | ( - { before(grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_5()); } + { before(grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_4()); } ('>') - { after(grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_5()); } + { after(grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_4()); } ) | ( - { before(grammarAccess.getVersionComparatorAccess().getGreaterEqualsEnumLiteralDeclaration_6()); } - ('>=') - { after(grammarAccess.getVersionComparatorAccess().getGreaterEqualsEnumLiteralDeclaration_6()); } + { before(grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_5()); } + ('<=') + { after(grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_5()); } + ) + | + ( + { before(grammarAccess.getVersionComparatorAccess().getGreaterEqualsEnumLiteralDeclaration_6()); } + ('>=') + { after(grammarAccess.getVersionComparatorAccess().getGreaterEqualsEnumLiteralDeclaration_6()); } ) ; finally { @@ -2133,6 +2297,60 @@ finally { } +rule__WorkspaceVersionRequirement__Group__0 + @init { + int stackSize = keepStackSize(); + } +: + rule__WorkspaceVersionRequirement__Group__0__Impl + rule__WorkspaceVersionRequirement__Group__1 +; +finally { + restoreStackSize(stackSize); +} + +rule__WorkspaceVersionRequirement__Group__0__Impl + @init { + int stackSize = keepStackSize(); + } +: +( + { before(grammarAccess.getWorkspaceVersionRequirementAccess().getWORKSPACE_TAGParserRuleCall_0()); } + ruleWORKSPACE_TAG + { after(grammarAccess.getWorkspaceVersionRequirementAccess().getWORKSPACE_TAGParserRuleCall_0()); } +) +; +finally { + restoreStackSize(stackSize); +} + +rule__WorkspaceVersionRequirement__Group__1 + @init { + int stackSize = keepStackSize(); + } +: + rule__WorkspaceVersionRequirement__Group__1__Impl +; +finally { + restoreStackSize(stackSize); +} + +rule__WorkspaceVersionRequirement__Group__1__Impl + @init { + int stackSize = keepStackSize(); + } +: +( + { before(grammarAccess.getWorkspaceVersionRequirementAccess().getAlternatives_1()); } + (rule__WorkspaceVersionRequirement__Alternatives_1) + { after(grammarAccess.getWorkspaceVersionRequirementAccess().getAlternatives_1()); } +) +; +finally { + restoreStackSize(stackSize); +} + + rule__GitHubVersionRequirement__Group__0 @init { int stackSize = keepStackSize(); @@ -3312,521 +3530,791 @@ rule__Qualifier__Group_0_2__0__Impl } : ( - { before(grammarAccess.getQualifierAccess().getPlusSignKeyword_0_2_0()); } - '+' - { after(grammarAccess.getQualifierAccess().getPlusSignKeyword_0_2_0()); } + { before(grammarAccess.getQualifierAccess().getPlusSignKeyword_0_2_0()); } + '+' + { after(grammarAccess.getQualifierAccess().getPlusSignKeyword_0_2_0()); } +) +; +finally { + restoreStackSize(stackSize); +} + +rule__Qualifier__Group_0_2__1 + @init { + int stackSize = keepStackSize(); + } +: + rule__Qualifier__Group_0_2__1__Impl +; +finally { + restoreStackSize(stackSize); +} + +rule__Qualifier__Group_0_2__1__Impl + @init { + int stackSize = keepStackSize(); + } +: +( + { before(grammarAccess.getQualifierAccess().getBuildMetadataAssignment_0_2_1()); } + (rule__Qualifier__BuildMetadataAssignment_0_2_1) + { after(grammarAccess.getQualifierAccess().getBuildMetadataAssignment_0_2_1()); } +) +; +finally { + restoreStackSize(stackSize); +} + + +rule__Qualifier__Group_1__0 + @init { + int stackSize = keepStackSize(); + } +: + rule__Qualifier__Group_1__0__Impl + rule__Qualifier__Group_1__1 +; +finally { + restoreStackSize(stackSize); +} + +rule__Qualifier__Group_1__0__Impl + @init { + int stackSize = keepStackSize(); + } +: +( + { before(grammarAccess.getQualifierAccess().getPlusSignKeyword_1_0()); } + '+' + { after(grammarAccess.getQualifierAccess().getPlusSignKeyword_1_0()); } +) +; +finally { + restoreStackSize(stackSize); +} + +rule__Qualifier__Group_1__1 + @init { + int stackSize = keepStackSize(); + } +: + rule__Qualifier__Group_1__1__Impl +; +finally { + restoreStackSize(stackSize); +} + +rule__Qualifier__Group_1__1__Impl + @init { + int stackSize = keepStackSize(); + } +: +( + { before(grammarAccess.getQualifierAccess().getBuildMetadataAssignment_1_1()); } + (rule__Qualifier__BuildMetadataAssignment_1_1) + { after(grammarAccess.getQualifierAccess().getBuildMetadataAssignment_1_1()); } +) +; +finally { + restoreStackSize(stackSize); +} + + +rule__QualifierTag__Group__0 + @init { + int stackSize = keepStackSize(); + } +: + rule__QualifierTag__Group__0__Impl + rule__QualifierTag__Group__1 +; +finally { + restoreStackSize(stackSize); +} + +rule__QualifierTag__Group__0__Impl + @init { + int stackSize = keepStackSize(); + } +: +( + { before(grammarAccess.getQualifierTagAccess().getPartsAssignment_0()); } + (rule__QualifierTag__PartsAssignment_0) + { after(grammarAccess.getQualifierTagAccess().getPartsAssignment_0()); } +) +; +finally { + restoreStackSize(stackSize); +} + +rule__QualifierTag__Group__1 + @init { + int stackSize = keepStackSize(); + } +: + rule__QualifierTag__Group__1__Impl +; +finally { + restoreStackSize(stackSize); +} + +rule__QualifierTag__Group__1__Impl + @init { + int stackSize = keepStackSize(); + } +: +( + { before(grammarAccess.getQualifierTagAccess().getGroup_1()); } + (rule__QualifierTag__Group_1__0)* + { after(grammarAccess.getQualifierTagAccess().getGroup_1()); } +) +; +finally { + restoreStackSize(stackSize); +} + + +rule__QualifierTag__Group_1__0 + @init { + int stackSize = keepStackSize(); + } +: + rule__QualifierTag__Group_1__0__Impl + rule__QualifierTag__Group_1__1 +; +finally { + restoreStackSize(stackSize); +} + +rule__QualifierTag__Group_1__0__Impl + @init { + int stackSize = keepStackSize(); + } +: +( + { before(grammarAccess.getQualifierTagAccess().getFullStopKeyword_1_0()); } + '.' + { after(grammarAccess.getQualifierTagAccess().getFullStopKeyword_1_0()); } +) +; +finally { + restoreStackSize(stackSize); +} + +rule__QualifierTag__Group_1__1 + @init { + int stackSize = keepStackSize(); + } +: + rule__QualifierTag__Group_1__1__Impl +; +finally { + restoreStackSize(stackSize); +} + +rule__QualifierTag__Group_1__1__Impl + @init { + int stackSize = keepStackSize(); + } +: +( + { before(grammarAccess.getQualifierTagAccess().getPartsAssignment_1_1()); } + (rule__QualifierTag__PartsAssignment_1_1) + { after(grammarAccess.getQualifierTagAccess().getPartsAssignment_1_1()); } +) +; +finally { + restoreStackSize(stackSize); +} + + +rule__FILE_TAG__Group__0 + @init { + int stackSize = keepStackSize(); + } +: + rule__FILE_TAG__Group__0__Impl + rule__FILE_TAG__Group__1 +; +finally { + restoreStackSize(stackSize); +} + +rule__FILE_TAG__Group__0__Impl + @init { + int stackSize = keepStackSize(); + } +: +( + { before(grammarAccess.getFILE_TAGAccess().getLETTER_FTerminalRuleCall_0()); } + RULE_LETTER_F + { after(grammarAccess.getFILE_TAGAccess().getLETTER_FTerminalRuleCall_0()); } +) +; +finally { + restoreStackSize(stackSize); +} + +rule__FILE_TAG__Group__1 + @init { + int stackSize = keepStackSize(); + } +: + rule__FILE_TAG__Group__1__Impl + rule__FILE_TAG__Group__2 +; +finally { + restoreStackSize(stackSize); +} + +rule__FILE_TAG__Group__1__Impl + @init { + int stackSize = keepStackSize(); + } +: +( + { before(grammarAccess.getFILE_TAGAccess().getLETTER_ITerminalRuleCall_1()); } + RULE_LETTER_I + { after(grammarAccess.getFILE_TAGAccess().getLETTER_ITerminalRuleCall_1()); } +) +; +finally { + restoreStackSize(stackSize); +} + +rule__FILE_TAG__Group__2 + @init { + int stackSize = keepStackSize(); + } +: + rule__FILE_TAG__Group__2__Impl + rule__FILE_TAG__Group__3 +; +finally { + restoreStackSize(stackSize); +} + +rule__FILE_TAG__Group__2__Impl + @init { + int stackSize = keepStackSize(); + } +: +( + { before(grammarAccess.getFILE_TAGAccess().getLETTER_LTerminalRuleCall_2()); } + RULE_LETTER_L + { after(grammarAccess.getFILE_TAGAccess().getLETTER_LTerminalRuleCall_2()); } ) ; finally { restoreStackSize(stackSize); } -rule__Qualifier__Group_0_2__1 +rule__FILE_TAG__Group__3 @init { int stackSize = keepStackSize(); } : - rule__Qualifier__Group_0_2__1__Impl + rule__FILE_TAG__Group__3__Impl + rule__FILE_TAG__Group__4 ; finally { restoreStackSize(stackSize); } -rule__Qualifier__Group_0_2__1__Impl +rule__FILE_TAG__Group__3__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getQualifierAccess().getBuildMetadataAssignment_0_2_1()); } - (rule__Qualifier__BuildMetadataAssignment_0_2_1) - { after(grammarAccess.getQualifierAccess().getBuildMetadataAssignment_0_2_1()); } + { before(grammarAccess.getFILE_TAGAccess().getLETTER_ETerminalRuleCall_3()); } + RULE_LETTER_E + { after(grammarAccess.getFILE_TAGAccess().getLETTER_ETerminalRuleCall_3()); } ) ; finally { restoreStackSize(stackSize); } - -rule__Qualifier__Group_1__0 +rule__FILE_TAG__Group__4 @init { int stackSize = keepStackSize(); } : - rule__Qualifier__Group_1__0__Impl - rule__Qualifier__Group_1__1 + rule__FILE_TAG__Group__4__Impl ; finally { restoreStackSize(stackSize); } -rule__Qualifier__Group_1__0__Impl +rule__FILE_TAG__Group__4__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getQualifierAccess().getPlusSignKeyword_1_0()); } - '+' - { after(grammarAccess.getQualifierAccess().getPlusSignKeyword_1_0()); } + { before(grammarAccess.getFILE_TAGAccess().getColonKeyword_4()); } + ':' + { after(grammarAccess.getFILE_TAGAccess().getColonKeyword_4()); } ) ; finally { restoreStackSize(stackSize); } -rule__Qualifier__Group_1__1 + +rule__SEMVER_TAG__Group__0 @init { int stackSize = keepStackSize(); } : - rule__Qualifier__Group_1__1__Impl + rule__SEMVER_TAG__Group__0__Impl + rule__SEMVER_TAG__Group__1 ; finally { restoreStackSize(stackSize); } -rule__Qualifier__Group_1__1__Impl +rule__SEMVER_TAG__Group__0__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getQualifierAccess().getBuildMetadataAssignment_1_1()); } - (rule__Qualifier__BuildMetadataAssignment_1_1) - { after(grammarAccess.getQualifierAccess().getBuildMetadataAssignment_1_1()); } + { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_STerminalRuleCall_0()); } + RULE_LETTER_S + { after(grammarAccess.getSEMVER_TAGAccess().getLETTER_STerminalRuleCall_0()); } ) ; finally { restoreStackSize(stackSize); } - -rule__QualifierTag__Group__0 +rule__SEMVER_TAG__Group__1 @init { int stackSize = keepStackSize(); } : - rule__QualifierTag__Group__0__Impl - rule__QualifierTag__Group__1 + rule__SEMVER_TAG__Group__1__Impl + rule__SEMVER_TAG__Group__2 ; finally { restoreStackSize(stackSize); } -rule__QualifierTag__Group__0__Impl +rule__SEMVER_TAG__Group__1__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getQualifierTagAccess().getPartsAssignment_0()); } - (rule__QualifierTag__PartsAssignment_0) - { after(grammarAccess.getQualifierTagAccess().getPartsAssignment_0()); } + { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_ETerminalRuleCall_1()); } + RULE_LETTER_E + { after(grammarAccess.getSEMVER_TAGAccess().getLETTER_ETerminalRuleCall_1()); } ) ; finally { restoreStackSize(stackSize); } -rule__QualifierTag__Group__1 +rule__SEMVER_TAG__Group__2 @init { int stackSize = keepStackSize(); } : - rule__QualifierTag__Group__1__Impl + rule__SEMVER_TAG__Group__2__Impl + rule__SEMVER_TAG__Group__3 ; finally { restoreStackSize(stackSize); } -rule__QualifierTag__Group__1__Impl +rule__SEMVER_TAG__Group__2__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getQualifierTagAccess().getGroup_1()); } - (rule__QualifierTag__Group_1__0)* - { after(grammarAccess.getQualifierTagAccess().getGroup_1()); } + { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_MTerminalRuleCall_2()); } + RULE_LETTER_M + { after(grammarAccess.getSEMVER_TAGAccess().getLETTER_MTerminalRuleCall_2()); } ) ; finally { restoreStackSize(stackSize); } - -rule__QualifierTag__Group_1__0 +rule__SEMVER_TAG__Group__3 @init { int stackSize = keepStackSize(); } : - rule__QualifierTag__Group_1__0__Impl - rule__QualifierTag__Group_1__1 + rule__SEMVER_TAG__Group__3__Impl + rule__SEMVER_TAG__Group__4 ; finally { restoreStackSize(stackSize); } -rule__QualifierTag__Group_1__0__Impl +rule__SEMVER_TAG__Group__3__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getQualifierTagAccess().getFullStopKeyword_1_0()); } - '.' - { after(grammarAccess.getQualifierTagAccess().getFullStopKeyword_1_0()); } + { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_VTerminalRuleCall_3()); } + RULE_LETTER_V + { after(grammarAccess.getSEMVER_TAGAccess().getLETTER_VTerminalRuleCall_3()); } ) ; finally { restoreStackSize(stackSize); } -rule__QualifierTag__Group_1__1 +rule__SEMVER_TAG__Group__4 @init { int stackSize = keepStackSize(); } : - rule__QualifierTag__Group_1__1__Impl + rule__SEMVER_TAG__Group__4__Impl + rule__SEMVER_TAG__Group__5 ; finally { restoreStackSize(stackSize); } -rule__QualifierTag__Group_1__1__Impl +rule__SEMVER_TAG__Group__4__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getQualifierTagAccess().getPartsAssignment_1_1()); } - (rule__QualifierTag__PartsAssignment_1_1) - { after(grammarAccess.getQualifierTagAccess().getPartsAssignment_1_1()); } + { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_ETerminalRuleCall_4()); } + RULE_LETTER_E + { after(grammarAccess.getSEMVER_TAGAccess().getLETTER_ETerminalRuleCall_4()); } ) ; finally { restoreStackSize(stackSize); } - -rule__FILE_TAG__Group__0 +rule__SEMVER_TAG__Group__5 @init { int stackSize = keepStackSize(); } : - rule__FILE_TAG__Group__0__Impl - rule__FILE_TAG__Group__1 + rule__SEMVER_TAG__Group__5__Impl + rule__SEMVER_TAG__Group__6 ; finally { restoreStackSize(stackSize); } -rule__FILE_TAG__Group__0__Impl +rule__SEMVER_TAG__Group__5__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getFILE_TAGAccess().getLETTER_FTerminalRuleCall_0()); } - RULE_LETTER_F - { after(grammarAccess.getFILE_TAGAccess().getLETTER_FTerminalRuleCall_0()); } + { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_RTerminalRuleCall_5()); } + RULE_LETTER_R + { after(grammarAccess.getSEMVER_TAGAccess().getLETTER_RTerminalRuleCall_5()); } ) ; finally { restoreStackSize(stackSize); } -rule__FILE_TAG__Group__1 +rule__SEMVER_TAG__Group__6 @init { int stackSize = keepStackSize(); } : - rule__FILE_TAG__Group__1__Impl - rule__FILE_TAG__Group__2 + rule__SEMVER_TAG__Group__6__Impl ; finally { restoreStackSize(stackSize); } -rule__FILE_TAG__Group__1__Impl +rule__SEMVER_TAG__Group__6__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getFILE_TAGAccess().getLETTER_ITerminalRuleCall_1()); } - RULE_LETTER_I - { after(grammarAccess.getFILE_TAGAccess().getLETTER_ITerminalRuleCall_1()); } + { before(grammarAccess.getSEMVER_TAGAccess().getColonKeyword_6()); } + ':' + { after(grammarAccess.getSEMVER_TAGAccess().getColonKeyword_6()); } ) ; finally { restoreStackSize(stackSize); } -rule__FILE_TAG__Group__2 + +rule__WORKSPACE_TAG__Group__0 @init { int stackSize = keepStackSize(); } : - rule__FILE_TAG__Group__2__Impl - rule__FILE_TAG__Group__3 + rule__WORKSPACE_TAG__Group__0__Impl + rule__WORKSPACE_TAG__Group__1 ; finally { restoreStackSize(stackSize); } -rule__FILE_TAG__Group__2__Impl +rule__WORKSPACE_TAG__Group__0__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getFILE_TAGAccess().getLETTER_LTerminalRuleCall_2()); } - RULE_LETTER_L - { after(grammarAccess.getFILE_TAGAccess().getLETTER_LTerminalRuleCall_2()); } + { before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_WTerminalRuleCall_0()); } + RULE_LETTER_W + { after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_WTerminalRuleCall_0()); } ) ; finally { restoreStackSize(stackSize); } -rule__FILE_TAG__Group__3 +rule__WORKSPACE_TAG__Group__1 @init { int stackSize = keepStackSize(); } : - rule__FILE_TAG__Group__3__Impl - rule__FILE_TAG__Group__4 + rule__WORKSPACE_TAG__Group__1__Impl + rule__WORKSPACE_TAG__Group__2 ; finally { restoreStackSize(stackSize); } -rule__FILE_TAG__Group__3__Impl +rule__WORKSPACE_TAG__Group__1__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getFILE_TAGAccess().getLETTER_ETerminalRuleCall_3()); } - RULE_LETTER_E - { after(grammarAccess.getFILE_TAGAccess().getLETTER_ETerminalRuleCall_3()); } + { before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_OTerminalRuleCall_1()); } + RULE_LETTER_O + { after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_OTerminalRuleCall_1()); } ) ; finally { restoreStackSize(stackSize); } -rule__FILE_TAG__Group__4 +rule__WORKSPACE_TAG__Group__2 @init { int stackSize = keepStackSize(); } : - rule__FILE_TAG__Group__4__Impl + rule__WORKSPACE_TAG__Group__2__Impl + rule__WORKSPACE_TAG__Group__3 ; finally { restoreStackSize(stackSize); } -rule__FILE_TAG__Group__4__Impl +rule__WORKSPACE_TAG__Group__2__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getFILE_TAGAccess().getColonKeyword_4()); } - ':' - { after(grammarAccess.getFILE_TAGAccess().getColonKeyword_4()); } + { before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_RTerminalRuleCall_2()); } + RULE_LETTER_R + { after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_RTerminalRuleCall_2()); } ) ; finally { restoreStackSize(stackSize); } - -rule__SEMVER_TAG__Group__0 +rule__WORKSPACE_TAG__Group__3 @init { int stackSize = keepStackSize(); } : - rule__SEMVER_TAG__Group__0__Impl - rule__SEMVER_TAG__Group__1 + rule__WORKSPACE_TAG__Group__3__Impl + rule__WORKSPACE_TAG__Group__4 ; finally { restoreStackSize(stackSize); } -rule__SEMVER_TAG__Group__0__Impl +rule__WORKSPACE_TAG__Group__3__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_STerminalRuleCall_0()); } - RULE_LETTER_S - { after(grammarAccess.getSEMVER_TAGAccess().getLETTER_STerminalRuleCall_0()); } + { before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_KTerminalRuleCall_3()); } + RULE_LETTER_K + { after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_KTerminalRuleCall_3()); } ) ; finally { restoreStackSize(stackSize); } -rule__SEMVER_TAG__Group__1 +rule__WORKSPACE_TAG__Group__4 @init { int stackSize = keepStackSize(); } : - rule__SEMVER_TAG__Group__1__Impl - rule__SEMVER_TAG__Group__2 + rule__WORKSPACE_TAG__Group__4__Impl + rule__WORKSPACE_TAG__Group__5 ; finally { restoreStackSize(stackSize); } -rule__SEMVER_TAG__Group__1__Impl +rule__WORKSPACE_TAG__Group__4__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_ETerminalRuleCall_1()); } - RULE_LETTER_E - { after(grammarAccess.getSEMVER_TAGAccess().getLETTER_ETerminalRuleCall_1()); } + { before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_STerminalRuleCall_4()); } + RULE_LETTER_S + { after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_STerminalRuleCall_4()); } ) ; finally { restoreStackSize(stackSize); } -rule__SEMVER_TAG__Group__2 +rule__WORKSPACE_TAG__Group__5 @init { int stackSize = keepStackSize(); } : - rule__SEMVER_TAG__Group__2__Impl - rule__SEMVER_TAG__Group__3 + rule__WORKSPACE_TAG__Group__5__Impl + rule__WORKSPACE_TAG__Group__6 ; finally { restoreStackSize(stackSize); } -rule__SEMVER_TAG__Group__2__Impl +rule__WORKSPACE_TAG__Group__5__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_MTerminalRuleCall_2()); } - RULE_LETTER_M - { after(grammarAccess.getSEMVER_TAGAccess().getLETTER_MTerminalRuleCall_2()); } + { before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_PTerminalRuleCall_5()); } + RULE_LETTER_P + { after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_PTerminalRuleCall_5()); } ) ; finally { restoreStackSize(stackSize); } -rule__SEMVER_TAG__Group__3 +rule__WORKSPACE_TAG__Group__6 @init { int stackSize = keepStackSize(); } : - rule__SEMVER_TAG__Group__3__Impl - rule__SEMVER_TAG__Group__4 + rule__WORKSPACE_TAG__Group__6__Impl + rule__WORKSPACE_TAG__Group__7 ; finally { restoreStackSize(stackSize); } -rule__SEMVER_TAG__Group__3__Impl +rule__WORKSPACE_TAG__Group__6__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_VTerminalRuleCall_3()); } - RULE_LETTER_V - { after(grammarAccess.getSEMVER_TAGAccess().getLETTER_VTerminalRuleCall_3()); } + { before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_ATerminalRuleCall_6()); } + RULE_LETTER_A + { after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_ATerminalRuleCall_6()); } ) ; finally { restoreStackSize(stackSize); } -rule__SEMVER_TAG__Group__4 +rule__WORKSPACE_TAG__Group__7 @init { int stackSize = keepStackSize(); } : - rule__SEMVER_TAG__Group__4__Impl - rule__SEMVER_TAG__Group__5 + rule__WORKSPACE_TAG__Group__7__Impl + rule__WORKSPACE_TAG__Group__8 ; finally { restoreStackSize(stackSize); } -rule__SEMVER_TAG__Group__4__Impl +rule__WORKSPACE_TAG__Group__7__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_ETerminalRuleCall_4()); } - RULE_LETTER_E - { after(grammarAccess.getSEMVER_TAGAccess().getLETTER_ETerminalRuleCall_4()); } + { before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_CTerminalRuleCall_7()); } + RULE_LETTER_C + { after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_CTerminalRuleCall_7()); } ) ; finally { restoreStackSize(stackSize); } -rule__SEMVER_TAG__Group__5 +rule__WORKSPACE_TAG__Group__8 @init { int stackSize = keepStackSize(); } : - rule__SEMVER_TAG__Group__5__Impl - rule__SEMVER_TAG__Group__6 + rule__WORKSPACE_TAG__Group__8__Impl + rule__WORKSPACE_TAG__Group__9 ; finally { restoreStackSize(stackSize); } -rule__SEMVER_TAG__Group__5__Impl +rule__WORKSPACE_TAG__Group__8__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_RTerminalRuleCall_5()); } - RULE_LETTER_R - { after(grammarAccess.getSEMVER_TAGAccess().getLETTER_RTerminalRuleCall_5()); } + { before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_ETerminalRuleCall_8()); } + RULE_LETTER_E + { after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_ETerminalRuleCall_8()); } ) ; finally { restoreStackSize(stackSize); } -rule__SEMVER_TAG__Group__6 +rule__WORKSPACE_TAG__Group__9 @init { int stackSize = keepStackSize(); } : - rule__SEMVER_TAG__Group__6__Impl + rule__WORKSPACE_TAG__Group__9__Impl ; finally { restoreStackSize(stackSize); } -rule__SEMVER_TAG__Group__6__Impl +rule__WORKSPACE_TAG__Group__9__Impl @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getSEMVER_TAGAccess().getColonKeyword_6()); } + { before(grammarAccess.getWORKSPACE_TAGAccess().getColonKeyword_9()); } ':' - { after(grammarAccess.getSEMVER_TAGAccess().getColonKeyword_6()); } + { after(grammarAccess.getWORKSPACE_TAGAccess().getColonKeyword_9()); } ) ; finally { @@ -4128,16 +4616,9 @@ rule__TAG__Group__1__Impl } : ( - ( - { before(grammarAccess.getTAGAccess().getAlternatives_1()); } - (rule__TAG__Alternatives_1) - { after(grammarAccess.getTAGAccess().getAlternatives_1()); } - ) - ( - { before(grammarAccess.getTAGAccess().getAlternatives_1()); } - (rule__TAG__Alternatives_1)* - { after(grammarAccess.getTAGAccess().getAlternatives_1()); } - ) + { before(grammarAccess.getTAGAccess().getALPHA_NUMERIC_CHARSParserRuleCall_1()); } + ruleALPHA_NUMERIC_CHARS + { after(grammarAccess.getTAGAccess().getALPHA_NUMERIC_CHARSParserRuleCall_1()); } ) ; finally { @@ -4189,16 +4670,9 @@ rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl } : ( - ( - { before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getAlternatives_1()); } - (rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1) - { after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getAlternatives_1()); } - ) - ( - { before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getAlternatives_1()); } - (rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1)* - { after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getAlternatives_1()); } - ) + { before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getALPHA_NUMERIC_CHARSParserRuleCall_1()); } + ruleALPHA_NUMERIC_CHARS + { after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getALPHA_NUMERIC_CHARSParserRuleCall_1()); } ) ; finally { @@ -4326,15 +4800,30 @@ finally { restoreStackSize(stackSize); } -rule__TagVersionRequirement__TagNameAssignment +rule__WorkspaceVersionRequirement__VersionAssignment_1_0 @init { int stackSize = keepStackSize(); } : ( - { before(grammarAccess.getTagVersionRequirementAccess().getTagNameTAGParserRuleCall_0()); } - ruleTAG - { after(grammarAccess.getTagVersionRequirementAccess().getTagNameTAGParserRuleCall_0()); } + { before(grammarAccess.getWorkspaceVersionRequirementAccess().getVersionSimpleVersionParserRuleCall_1_0_0()); } + ruleSimpleVersion + { after(grammarAccess.getWorkspaceVersionRequirementAccess().getVersionSimpleVersionParserRuleCall_1_0_0()); } + ) +; +finally { + restoreStackSize(stackSize); +} + +rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1 + @init { + int stackSize = keepStackSize(); + } +: + ( + { before(grammarAccess.getWorkspaceVersionRequirementAccess().getOtherVersionWORKSPACE_VERSIONParserRuleCall_1_1_0()); } + ruleWORKSPACE_VERSION + { after(grammarAccess.getWorkspaceVersionRequirementAccess().getOtherVersionWORKSPACE_VERSIONParserRuleCall_1_1_0()); } ) ; finally { @@ -4371,6 +4860,21 @@ finally { restoreStackSize(stackSize); } +rule__TagVersionRequirement__TagNameAssignment + @init { + int stackSize = keepStackSize(); + } +: + ( + { before(grammarAccess.getTagVersionRequirementAccess().getTagNameTAGParserRuleCall_0()); } + ruleTAG + { after(grammarAccess.getTagVersionRequirementAccess().getTagNameTAGParserRuleCall_0()); } + ) +; +finally { + restoreStackSize(stackSize); +} + rule__VersionRangeSetRequirement__RangesAssignment_1_0 @init { int stackSize = keepStackSize(); @@ -4686,25 +5190,37 @@ finally { restoreStackSize(stackSize); } -RULE_LETTER_S : ('s'|'S'); +RULE_LETTER_A : ('a'|'A'); -RULE_LETTER_M : ('m'|'M'); +RULE_LETTER_C : ('c'|'C'); -RULE_LETTER_R : ('r'|'R'); +RULE_LETTER_E : ('e'|'E'); RULE_LETTER_F : ('f'|'F'); RULE_LETTER_I : ('i'|'I'); +RULE_LETTER_K : ('k'|'K'); + RULE_LETTER_L : ('l'|'L'); -RULE_LETTER_E : ('e'|'E'); +RULE_LETTER_M : ('m'|'M'); + +RULE_LETTER_O : ('o'|'O'); + +RULE_LETTER_P : ('p'|'P'); + +RULE_LETTER_R : ('r'|'R'); + +RULE_LETTER_S : ('s'|'S'); RULE_LETTER_V : ('v'|'V'); +RULE_LETTER_W : ('w'|'W'); + RULE_LETTER_X : ('x'|'X'); -RULE_LETTER_OTHER : ('a'|'A'|'b'|'B'|'c'|'C'|'d'|'D'|'g'|'G'|'h'|'H'|'j'|'J'|'k'|'K'|'n'|'N'|'o'|'O'|'p'|'P'|'q'|'Q'|'t'|'T'|'u'|'U'|'w'|'W'|'y'|'Y'|'z'|'Z'); +RULE_LETTER_OTHER : ('b'|'B'|'d'|'D'|'g'|'G'|'h'|'H'|'j'|'J'|'n'|'N'|'q'|'Q'|'t'|'T'|'u'|'U'|'y'|'Y'|'z'|'Z'); RULE_ASTERIX : '*'; diff --git a/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemver.tokens b/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemver.tokens index 277d51fa39..f6a5c8024e 100644 --- a/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemver.tokens +++ b/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemver.tokens @@ -1,56 +1,56 @@ -'#'=49 -'+'=40 -'-'=38 -'.'=36 -'/'=35 -':'=41 -'<'=43 -'<='=46 -'='=42 -'>'=47 -'>='=48 -'@'=37 -'^'=45 -'_'=39 -'||'=50 -'~'=44 -RULE_ANY_OTHER=34 -RULE_ASTERIX=6 -RULE_BOM=25 -RULE_DECIMAL_DIGIT_FRAGMENT=20 -RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT=22 -RULE_DIGITS=4 -RULE_EOL=19 -RULE_HEX_DIGIT=21 -RULE_LETTER_E=14 +'#'=55 +'+'=45 +'-'=47 +'.'=42 +'/'=41 +':'=46 +'<'=51 +'<='=53 +'='=48 +'>'=52 +'>='=54 +'@'=43 +'^'=50 +'_'=44 +'||'=56 +'~'=49 +RULE_ANY_OTHER=40 +RULE_ASTERIX=4 +RULE_BOM=31 +RULE_DECIMAL_DIGIT_FRAGMENT=26 +RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT=28 +RULE_DIGITS=5 +RULE_EOL=25 +RULE_HEX_DIGIT=27 +RULE_LETTER_A=8 +RULE_LETTER_C=9 +RULE_LETTER_E=10 RULE_LETTER_F=11 RULE_LETTER_I=12 -RULE_LETTER_L=13 -RULE_LETTER_M=9 -RULE_LETTER_OTHER=15 -RULE_LETTER_R=10 -RULE_LETTER_S=8 +RULE_LETTER_K=13 +RULE_LETTER_L=14 +RULE_LETTER_M=15 +RULE_LETTER_O=16 +RULE_LETTER_OTHER=21 +RULE_LETTER_P=17 +RULE_LETTER_R=18 +RULE_LETTER_S=19 RULE_LETTER_V=7 -RULE_LETTER_X=5 -RULE_LINE_TERMINATOR_FRAGMENT=27 -RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT=18 -RULE_ML_COMMENT_FRAGMENT=29 -RULE_SL_COMMENT_FRAGMENT=28 -RULE_UNICODE_COMBINING_MARK_FRAGMENT=30 -RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT=32 -RULE_UNICODE_DIGIT_FRAGMENT=31 -RULE_UNICODE_LETTER_FRAGMENT=33 -RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT=26 -RULE_WHITESPACE_FRAGMENT=17 -RULE_WS=16 -RULE_ZWJ=23 -RULE_ZWNJ=24 -T__35=35 -T__36=36 -T__37=37 -T__38=38 -T__39=39 -T__40=40 +RULE_LETTER_W=20 +RULE_LETTER_X=6 +RULE_LINE_TERMINATOR_FRAGMENT=33 +RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT=24 +RULE_ML_COMMENT_FRAGMENT=35 +RULE_SL_COMMENT_FRAGMENT=34 +RULE_UNICODE_COMBINING_MARK_FRAGMENT=36 +RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT=38 +RULE_UNICODE_DIGIT_FRAGMENT=37 +RULE_UNICODE_LETTER_FRAGMENT=39 +RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT=32 +RULE_WHITESPACE_FRAGMENT=23 +RULE_WS=22 +RULE_ZWJ=29 +RULE_ZWNJ=30 T__41=41 T__42=42 T__43=43 @@ -61,3 +61,9 @@ T__47=47 T__48=48 T__49=49 T__50=50 +T__51=51 +T__52=52 +T__53=53 +T__54=54 +T__55=55 +T__56=56 diff --git a/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemverLexer.java b/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemverLexer.java index 8549b7342b..21810e6226 100644 --- a/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemverLexer.java +++ b/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemverLexer.java @@ -13,50 +13,56 @@ @SuppressWarnings("all") public class InternalSemverLexer extends Lexer { public static final int T__50=50; - public static final int RULE_WHITESPACE_FRAGMENT=17; - public static final int RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT=18; - public static final int RULE_EOL=19; - public static final int RULE_LETTER_OTHER=15; - public static final int RULE_UNICODE_COMBINING_MARK_FRAGMENT=30; - public static final int RULE_ZWNJ=24; - public static final int RULE_ASTERIX=6; - public static final int RULE_LETTER_E=14; - public static final int RULE_ML_COMMENT_FRAGMENT=29; - public static final int RULE_DIGITS=4; - public static final int RULE_ZWJ=23; - public static final int RULE_SL_COMMENT_FRAGMENT=28; - public static final int RULE_UNICODE_DIGIT_FRAGMENT=31; - public static final int T__37=37; - public static final int RULE_LETTER_R=10; - public static final int T__38=38; - public static final int RULE_LETTER_S=8; - public static final int T__39=39; + public static final int RULE_WHITESPACE_FRAGMENT=23; + public static final int T__55=55; + public static final int T__56=56; + public static final int T__51=51; + public static final int T__52=52; + public static final int T__53=53; + public static final int T__54=54; + public static final int RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT=24; + public static final int RULE_EOL=25; + public static final int RULE_LETTER_OTHER=21; + public static final int RULE_UNICODE_COMBINING_MARK_FRAGMENT=36; + public static final int RULE_ZWNJ=30; + public static final int RULE_LETTER_A=8; + public static final int RULE_LETTER_C=9; + public static final int RULE_ASTERIX=4; + public static final int RULE_LETTER_E=10; + public static final int RULE_ML_COMMENT_FRAGMENT=35; + public static final int RULE_DIGITS=5; + public static final int RULE_LETTER_O=16; + public static final int RULE_ZWJ=29; + public static final int RULE_SL_COMMENT_FRAGMENT=34; + public static final int RULE_LETTER_P=17; + public static final int RULE_UNICODE_DIGIT_FRAGMENT=37; + public static final int RULE_LETTER_R=18; + public static final int RULE_LETTER_S=19; public static final int RULE_LETTER_F=11; - public static final int RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT=26; - public static final int T__35=35; - public static final int T__36=36; + public static final int RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT=32; public static final int RULE_LETTER_I=12; public static final int EOF=-1; - public static final int RULE_LETTER_L=13; - public static final int RULE_LETTER_M=9; - public static final int RULE_WS=16; - public static final int RULE_BOM=25; + public static final int RULE_LETTER_K=13; + public static final int RULE_LETTER_L=14; + public static final int RULE_LETTER_M=15; + public static final int RULE_WS=22; + public static final int RULE_BOM=31; public static final int RULE_LETTER_V=7; - public static final int RULE_LETTER_X=5; - public static final int RULE_ANY_OTHER=34; - public static final int RULE_LINE_TERMINATOR_FRAGMENT=27; - public static final int RULE_UNICODE_LETTER_FRAGMENT=33; - public static final int RULE_DECIMAL_DIGIT_FRAGMENT=20; + public static final int RULE_LETTER_W=20; + public static final int RULE_LETTER_X=6; + public static final int RULE_ANY_OTHER=40; + public static final int RULE_LINE_TERMINATOR_FRAGMENT=33; + public static final int RULE_UNICODE_LETTER_FRAGMENT=39; + public static final int RULE_DECIMAL_DIGIT_FRAGMENT=26; public static final int T__48=48; public static final int T__49=49; public static final int T__44=44; public static final int T__45=45; - public static final int RULE_HEX_DIGIT=21; - public static final int RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT=22; - public static final int RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT=32; + public static final int RULE_HEX_DIGIT=27; + public static final int RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT=28; + public static final int RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT=38; public static final int T__46=46; public static final int T__47=47; - public static final int T__40=40; public static final int T__41=41; public static final int T__42=42; public static final int T__43=43; @@ -74,10 +80,10 @@ public InternalSemverLexer(CharStream input, RecognizerSharedState state) { } public String getGrammarFileName() { return "InternalSemver.g"; } - // $ANTLR start "T__35" - public final void mT__35() throws RecognitionException { + // $ANTLR start "T__41" + public final void mT__41() throws RecognitionException { try { - int _type = T__35; + int _type = T__41; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:11:7: ( '/' ) // InternalSemver.g:11:9: '/' @@ -92,12 +98,12 @@ public final void mT__35() throws RecognitionException { finally { } } - // $ANTLR end "T__35" + // $ANTLR end "T__41" - // $ANTLR start "T__36" - public final void mT__36() throws RecognitionException { + // $ANTLR start "T__42" + public final void mT__42() throws RecognitionException { try { - int _type = T__36; + int _type = T__42; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:12:7: ( '.' ) // InternalSemver.g:12:9: '.' @@ -112,12 +118,12 @@ public final void mT__36() throws RecognitionException { finally { } } - // $ANTLR end "T__36" + // $ANTLR end "T__42" - // $ANTLR start "T__37" - public final void mT__37() throws RecognitionException { + // $ANTLR start "T__43" + public final void mT__43() throws RecognitionException { try { - int _type = T__37; + int _type = T__43; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:13:7: ( '@' ) // InternalSemver.g:13:9: '@' @@ -132,17 +138,17 @@ public final void mT__37() throws RecognitionException { finally { } } - // $ANTLR end "T__37" + // $ANTLR end "T__43" - // $ANTLR start "T__38" - public final void mT__38() throws RecognitionException { + // $ANTLR start "T__44" + public final void mT__44() throws RecognitionException { try { - int _type = T__38; + int _type = T__44; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:14:7: ( '-' ) - // InternalSemver.g:14:9: '-' + // InternalSemver.g:14:7: ( '_' ) + // InternalSemver.g:14:9: '_' { - match('-'); + match('_'); } @@ -152,17 +158,17 @@ public final void mT__38() throws RecognitionException { finally { } } - // $ANTLR end "T__38" + // $ANTLR end "T__44" - // $ANTLR start "T__39" - public final void mT__39() throws RecognitionException { + // $ANTLR start "T__45" + public final void mT__45() throws RecognitionException { try { - int _type = T__39; + int _type = T__45; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:15:7: ( '_' ) - // InternalSemver.g:15:9: '_' + // InternalSemver.g:15:7: ( '+' ) + // InternalSemver.g:15:9: '+' { - match('_'); + match('+'); } @@ -172,17 +178,17 @@ public final void mT__39() throws RecognitionException { finally { } } - // $ANTLR end "T__39" + // $ANTLR end "T__45" - // $ANTLR start "T__40" - public final void mT__40() throws RecognitionException { + // $ANTLR start "T__46" + public final void mT__46() throws RecognitionException { try { - int _type = T__40; + int _type = T__46; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:16:7: ( '+' ) - // InternalSemver.g:16:9: '+' + // InternalSemver.g:16:7: ( ':' ) + // InternalSemver.g:16:9: ':' { - match('+'); + match(':'); } @@ -192,17 +198,17 @@ public final void mT__40() throws RecognitionException { finally { } } - // $ANTLR end "T__40" + // $ANTLR end "T__46" - // $ANTLR start "T__41" - public final void mT__41() throws RecognitionException { + // $ANTLR start "T__47" + public final void mT__47() throws RecognitionException { try { - int _type = T__41; + int _type = T__47; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:17:7: ( ':' ) - // InternalSemver.g:17:9: ':' + // InternalSemver.g:17:7: ( '-' ) + // InternalSemver.g:17:9: '-' { - match(':'); + match('-'); } @@ -212,12 +218,12 @@ public final void mT__41() throws RecognitionException { finally { } } - // $ANTLR end "T__41" + // $ANTLR end "T__47" - // $ANTLR start "T__42" - public final void mT__42() throws RecognitionException { + // $ANTLR start "T__48" + public final void mT__48() throws RecognitionException { try { - int _type = T__42; + int _type = T__48; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:18:7: ( '=' ) // InternalSemver.g:18:9: '=' @@ -232,17 +238,17 @@ public final void mT__42() throws RecognitionException { finally { } } - // $ANTLR end "T__42" + // $ANTLR end "T__48" - // $ANTLR start "T__43" - public final void mT__43() throws RecognitionException { + // $ANTLR start "T__49" + public final void mT__49() throws RecognitionException { try { - int _type = T__43; + int _type = T__49; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:19:7: ( '<' ) - // InternalSemver.g:19:9: '<' + // InternalSemver.g:19:7: ( '~' ) + // InternalSemver.g:19:9: '~' { - match('<'); + match('~'); } @@ -252,17 +258,17 @@ public final void mT__43() throws RecognitionException { finally { } } - // $ANTLR end "T__43" + // $ANTLR end "T__49" - // $ANTLR start "T__44" - public final void mT__44() throws RecognitionException { + // $ANTLR start "T__50" + public final void mT__50() throws RecognitionException { try { - int _type = T__44; + int _type = T__50; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:20:7: ( '~' ) - // InternalSemver.g:20:9: '~' + // InternalSemver.g:20:7: ( '^' ) + // InternalSemver.g:20:9: '^' { - match('~'); + match('^'); } @@ -272,17 +278,17 @@ public final void mT__44() throws RecognitionException { finally { } } - // $ANTLR end "T__44" + // $ANTLR end "T__50" - // $ANTLR start "T__45" - public final void mT__45() throws RecognitionException { + // $ANTLR start "T__51" + public final void mT__51() throws RecognitionException { try { - int _type = T__45; + int _type = T__51; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:21:7: ( '^' ) - // InternalSemver.g:21:9: '^' + // InternalSemver.g:21:7: ( '<' ) + // InternalSemver.g:21:9: '<' { - match('^'); + match('<'); } @@ -292,18 +298,17 @@ public final void mT__45() throws RecognitionException { finally { } } - // $ANTLR end "T__45" + // $ANTLR end "T__51" - // $ANTLR start "T__46" - public final void mT__46() throws RecognitionException { + // $ANTLR start "T__52" + public final void mT__52() throws RecognitionException { try { - int _type = T__46; + int _type = T__52; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:22:7: ( '<=' ) - // InternalSemver.g:22:9: '<=' + // InternalSemver.g:22:7: ( '>' ) + // InternalSemver.g:22:9: '>' { - match("<="); - + match('>'); } @@ -313,17 +318,18 @@ public final void mT__46() throws RecognitionException { finally { } } - // $ANTLR end "T__46" + // $ANTLR end "T__52" - // $ANTLR start "T__47" - public final void mT__47() throws RecognitionException { + // $ANTLR start "T__53" + public final void mT__53() throws RecognitionException { try { - int _type = T__47; + int _type = T__53; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:23:7: ( '>' ) - // InternalSemver.g:23:9: '>' + // InternalSemver.g:23:7: ( '<=' ) + // InternalSemver.g:23:9: '<=' { - match('>'); + match("<="); + } @@ -333,12 +339,12 @@ public final void mT__47() throws RecognitionException { finally { } } - // $ANTLR end "T__47" + // $ANTLR end "T__53" - // $ANTLR start "T__48" - public final void mT__48() throws RecognitionException { + // $ANTLR start "T__54" + public final void mT__54() throws RecognitionException { try { - int _type = T__48; + int _type = T__54; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:24:7: ( '>=' ) // InternalSemver.g:24:9: '>=' @@ -354,12 +360,12 @@ public final void mT__48() throws RecognitionException { finally { } } - // $ANTLR end "T__48" + // $ANTLR end "T__54" - // $ANTLR start "T__49" - public final void mT__49() throws RecognitionException { + // $ANTLR start "T__55" + public final void mT__55() throws RecognitionException { try { - int _type = T__49; + int _type = T__55; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:25:7: ( '#' ) // InternalSemver.g:25:9: '#' @@ -374,12 +380,12 @@ public final void mT__49() throws RecognitionException { finally { } } - // $ANTLR end "T__49" + // $ANTLR end "T__55" - // $ANTLR start "T__50" - public final void mT__50() throws RecognitionException { + // $ANTLR start "T__56" + public final void mT__56() throws RecognitionException { try { - int _type = T__50; + int _type = T__56; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:26:7: ( '||' ) // InternalSemver.g:26:9: '||' @@ -395,17 +401,17 @@ public final void mT__50() throws RecognitionException { finally { } } - // $ANTLR end "T__50" + // $ANTLR end "T__56" - // $ANTLR start "RULE_LETTER_S" - public final void mRULE_LETTER_S() throws RecognitionException { + // $ANTLR start "RULE_LETTER_A" + public final void mRULE_LETTER_A() throws RecognitionException { try { - int _type = RULE_LETTER_S; + int _type = RULE_LETTER_A; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4689:15: ( ( 's' | 'S' ) ) - // InternalSemver.g:4689:17: ( 's' | 'S' ) + // InternalSemver.g:5193:15: ( ( 'a' | 'A' ) ) + // InternalSemver.g:5193:17: ( 'a' | 'A' ) { - if ( input.LA(1)=='S'||input.LA(1)=='s' ) { + if ( input.LA(1)=='A'||input.LA(1)=='a' ) { input.consume(); } @@ -423,17 +429,17 @@ public final void mRULE_LETTER_S() throws RecognitionException { finally { } } - // $ANTLR end "RULE_LETTER_S" + // $ANTLR end "RULE_LETTER_A" - // $ANTLR start "RULE_LETTER_M" - public final void mRULE_LETTER_M() throws RecognitionException { + // $ANTLR start "RULE_LETTER_C" + public final void mRULE_LETTER_C() throws RecognitionException { try { - int _type = RULE_LETTER_M; + int _type = RULE_LETTER_C; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4691:15: ( ( 'm' | 'M' ) ) - // InternalSemver.g:4691:17: ( 'm' | 'M' ) + // InternalSemver.g:5195:15: ( ( 'c' | 'C' ) ) + // InternalSemver.g:5195:17: ( 'c' | 'C' ) { - if ( input.LA(1)=='M'||input.LA(1)=='m' ) { + if ( input.LA(1)=='C'||input.LA(1)=='c' ) { input.consume(); } @@ -451,17 +457,17 @@ public final void mRULE_LETTER_M() throws RecognitionException { finally { } } - // $ANTLR end "RULE_LETTER_M" + // $ANTLR end "RULE_LETTER_C" - // $ANTLR start "RULE_LETTER_R" - public final void mRULE_LETTER_R() throws RecognitionException { + // $ANTLR start "RULE_LETTER_E" + public final void mRULE_LETTER_E() throws RecognitionException { try { - int _type = RULE_LETTER_R; + int _type = RULE_LETTER_E; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4693:15: ( ( 'r' | 'R' ) ) - // InternalSemver.g:4693:17: ( 'r' | 'R' ) + // InternalSemver.g:5197:15: ( ( 'e' | 'E' ) ) + // InternalSemver.g:5197:17: ( 'e' | 'E' ) { - if ( input.LA(1)=='R'||input.LA(1)=='r' ) { + if ( input.LA(1)=='E'||input.LA(1)=='e' ) { input.consume(); } @@ -479,15 +485,15 @@ public final void mRULE_LETTER_R() throws RecognitionException { finally { } } - // $ANTLR end "RULE_LETTER_R" + // $ANTLR end "RULE_LETTER_E" // $ANTLR start "RULE_LETTER_F" public final void mRULE_LETTER_F() throws RecognitionException { try { int _type = RULE_LETTER_F; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4695:15: ( ( 'f' | 'F' ) ) - // InternalSemver.g:4695:17: ( 'f' | 'F' ) + // InternalSemver.g:5199:15: ( ( 'f' | 'F' ) ) + // InternalSemver.g:5199:17: ( 'f' | 'F' ) { if ( input.LA(1)=='F'||input.LA(1)=='f' ) { input.consume(); @@ -514,8 +520,8 @@ public final void mRULE_LETTER_I() throws RecognitionException { try { int _type = RULE_LETTER_I; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4697:15: ( ( 'i' | 'I' ) ) - // InternalSemver.g:4697:17: ( 'i' | 'I' ) + // InternalSemver.g:5201:15: ( ( 'i' | 'I' ) ) + // InternalSemver.g:5201:17: ( 'i' | 'I' ) { if ( input.LA(1)=='I'||input.LA(1)=='i' ) { input.consume(); @@ -537,13 +543,41 @@ public final void mRULE_LETTER_I() throws RecognitionException { } // $ANTLR end "RULE_LETTER_I" + // $ANTLR start "RULE_LETTER_K" + public final void mRULE_LETTER_K() throws RecognitionException { + try { + int _type = RULE_LETTER_K; + int _channel = DEFAULT_TOKEN_CHANNEL; + // InternalSemver.g:5203:15: ( ( 'k' | 'K' ) ) + // InternalSemver.g:5203:17: ( 'k' | 'K' ) + { + if ( input.LA(1)=='K'||input.LA(1)=='k' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "RULE_LETTER_K" + // $ANTLR start "RULE_LETTER_L" public final void mRULE_LETTER_L() throws RecognitionException { try { int _type = RULE_LETTER_L; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4699:15: ( ( 'l' | 'L' ) ) - // InternalSemver.g:4699:17: ( 'l' | 'L' ) + // InternalSemver.g:5205:15: ( ( 'l' | 'L' ) ) + // InternalSemver.g:5205:17: ( 'l' | 'L' ) { if ( input.LA(1)=='L'||input.LA(1)=='l' ) { input.consume(); @@ -565,15 +599,15 @@ public final void mRULE_LETTER_L() throws RecognitionException { } // $ANTLR end "RULE_LETTER_L" - // $ANTLR start "RULE_LETTER_E" - public final void mRULE_LETTER_E() throws RecognitionException { + // $ANTLR start "RULE_LETTER_M" + public final void mRULE_LETTER_M() throws RecognitionException { try { - int _type = RULE_LETTER_E; + int _type = RULE_LETTER_M; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4701:15: ( ( 'e' | 'E' ) ) - // InternalSemver.g:4701:17: ( 'e' | 'E' ) + // InternalSemver.g:5207:15: ( ( 'm' | 'M' ) ) + // InternalSemver.g:5207:17: ( 'm' | 'M' ) { - if ( input.LA(1)=='E'||input.LA(1)=='e' ) { + if ( input.LA(1)=='M'||input.LA(1)=='m' ) { input.consume(); } @@ -591,15 +625,127 @@ public final void mRULE_LETTER_E() throws RecognitionException { finally { } } - // $ANTLR end "RULE_LETTER_E" + // $ANTLR end "RULE_LETTER_M" + + // $ANTLR start "RULE_LETTER_O" + public final void mRULE_LETTER_O() throws RecognitionException { + try { + int _type = RULE_LETTER_O; + int _channel = DEFAULT_TOKEN_CHANNEL; + // InternalSemver.g:5209:15: ( ( 'o' | 'O' ) ) + // InternalSemver.g:5209:17: ( 'o' | 'O' ) + { + if ( input.LA(1)=='O'||input.LA(1)=='o' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "RULE_LETTER_O" + + // $ANTLR start "RULE_LETTER_P" + public final void mRULE_LETTER_P() throws RecognitionException { + try { + int _type = RULE_LETTER_P; + int _channel = DEFAULT_TOKEN_CHANNEL; + // InternalSemver.g:5211:15: ( ( 'p' | 'P' ) ) + // InternalSemver.g:5211:17: ( 'p' | 'P' ) + { + if ( input.LA(1)=='P'||input.LA(1)=='p' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "RULE_LETTER_P" + + // $ANTLR start "RULE_LETTER_R" + public final void mRULE_LETTER_R() throws RecognitionException { + try { + int _type = RULE_LETTER_R; + int _channel = DEFAULT_TOKEN_CHANNEL; + // InternalSemver.g:5213:15: ( ( 'r' | 'R' ) ) + // InternalSemver.g:5213:17: ( 'r' | 'R' ) + { + if ( input.LA(1)=='R'||input.LA(1)=='r' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "RULE_LETTER_R" + + // $ANTLR start "RULE_LETTER_S" + public final void mRULE_LETTER_S() throws RecognitionException { + try { + int _type = RULE_LETTER_S; + int _channel = DEFAULT_TOKEN_CHANNEL; + // InternalSemver.g:5215:15: ( ( 's' | 'S' ) ) + // InternalSemver.g:5215:17: ( 's' | 'S' ) + { + if ( input.LA(1)=='S'||input.LA(1)=='s' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "RULE_LETTER_S" // $ANTLR start "RULE_LETTER_V" public final void mRULE_LETTER_V() throws RecognitionException { try { int _type = RULE_LETTER_V; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4703:15: ( ( 'v' | 'V' ) ) - // InternalSemver.g:4703:17: ( 'v' | 'V' ) + // InternalSemver.g:5217:15: ( ( 'v' | 'V' ) ) + // InternalSemver.g:5217:17: ( 'v' | 'V' ) { if ( input.LA(1)=='V'||input.LA(1)=='v' ) { input.consume(); @@ -621,13 +767,41 @@ public final void mRULE_LETTER_V() throws RecognitionException { } // $ANTLR end "RULE_LETTER_V" + // $ANTLR start "RULE_LETTER_W" + public final void mRULE_LETTER_W() throws RecognitionException { + try { + int _type = RULE_LETTER_W; + int _channel = DEFAULT_TOKEN_CHANNEL; + // InternalSemver.g:5219:15: ( ( 'w' | 'W' ) ) + // InternalSemver.g:5219:17: ( 'w' | 'W' ) + { + if ( input.LA(1)=='W'||input.LA(1)=='w' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "RULE_LETTER_W" + // $ANTLR start "RULE_LETTER_X" public final void mRULE_LETTER_X() throws RecognitionException { try { int _type = RULE_LETTER_X; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4705:15: ( ( 'x' | 'X' ) ) - // InternalSemver.g:4705:17: ( 'x' | 'X' ) + // InternalSemver.g:5221:15: ( ( 'x' | 'X' ) ) + // InternalSemver.g:5221:17: ( 'x' | 'X' ) { if ( input.LA(1)=='X'||input.LA(1)=='x' ) { input.consume(); @@ -654,10 +828,10 @@ public final void mRULE_LETTER_OTHER() throws RecognitionException { try { int _type = RULE_LETTER_OTHER; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4707:19: ( ( 'a' | 'A' | 'b' | 'B' | 'c' | 'C' | 'd' | 'D' | 'g' | 'G' | 'h' | 'H' | 'j' | 'J' | 'k' | 'K' | 'n' | 'N' | 'o' | 'O' | 'p' | 'P' | 'q' | 'Q' | 't' | 'T' | 'u' | 'U' | 'w' | 'W' | 'y' | 'Y' | 'z' | 'Z' ) ) - // InternalSemver.g:4707:21: ( 'a' | 'A' | 'b' | 'B' | 'c' | 'C' | 'd' | 'D' | 'g' | 'G' | 'h' | 'H' | 'j' | 'J' | 'k' | 'K' | 'n' | 'N' | 'o' | 'O' | 'p' | 'P' | 'q' | 'Q' | 't' | 'T' | 'u' | 'U' | 'w' | 'W' | 'y' | 'Y' | 'z' | 'Z' ) + // InternalSemver.g:5223:19: ( ( 'b' | 'B' | 'd' | 'D' | 'g' | 'G' | 'h' | 'H' | 'j' | 'J' | 'n' | 'N' | 'q' | 'Q' | 't' | 'T' | 'u' | 'U' | 'y' | 'Y' | 'z' | 'Z' ) ) + // InternalSemver.g:5223:21: ( 'b' | 'B' | 'd' | 'D' | 'g' | 'G' | 'h' | 'H' | 'j' | 'J' | 'n' | 'N' | 'q' | 'Q' | 't' | 'T' | 'u' | 'U' | 'y' | 'Y' | 'z' | 'Z' ) { - if ( (input.LA(1)>='A' && input.LA(1)<='D')||(input.LA(1)>='G' && input.LA(1)<='H')||(input.LA(1)>='J' && input.LA(1)<='K')||(input.LA(1)>='N' && input.LA(1)<='Q')||(input.LA(1)>='T' && input.LA(1)<='U')||input.LA(1)=='W'||(input.LA(1)>='Y' && input.LA(1)<='Z')||(input.LA(1)>='a' && input.LA(1)<='d')||(input.LA(1)>='g' && input.LA(1)<='h')||(input.LA(1)>='j' && input.LA(1)<='k')||(input.LA(1)>='n' && input.LA(1)<='q')||(input.LA(1)>='t' && input.LA(1)<='u')||input.LA(1)=='w'||(input.LA(1)>='y' && input.LA(1)<='z') ) { + if ( input.LA(1)=='B'||input.LA(1)=='D'||(input.LA(1)>='G' && input.LA(1)<='H')||input.LA(1)=='J'||input.LA(1)=='N'||input.LA(1)=='Q'||(input.LA(1)>='T' && input.LA(1)<='U')||(input.LA(1)>='Y' && input.LA(1)<='Z')||input.LA(1)=='b'||input.LA(1)=='d'||(input.LA(1)>='g' && input.LA(1)<='h')||input.LA(1)=='j'||input.LA(1)=='n'||input.LA(1)=='q'||(input.LA(1)>='t' && input.LA(1)<='u')||(input.LA(1)>='y' && input.LA(1)<='z') ) { input.consume(); } @@ -682,8 +856,8 @@ public final void mRULE_ASTERIX() throws RecognitionException { try { int _type = RULE_ASTERIX; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4709:14: ( '*' ) - // InternalSemver.g:4709:16: '*' + // InternalSemver.g:5225:14: ( '*' ) + // InternalSemver.g:5225:16: '*' { match('*'); @@ -702,10 +876,10 @@ public final void mRULE_DIGITS() throws RecognitionException { try { int _type = RULE_DIGITS; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4711:13: ( ( '0' .. '9' )+ ) - // InternalSemver.g:4711:15: ( '0' .. '9' )+ + // InternalSemver.g:5227:13: ( ( '0' .. '9' )+ ) + // InternalSemver.g:5227:15: ( '0' .. '9' )+ { - // InternalSemver.g:4711:15: ( '0' .. '9' )+ + // InternalSemver.g:5227:15: ( '0' .. '9' )+ int cnt1=0; loop1: do { @@ -719,7 +893,7 @@ public final void mRULE_DIGITS() throws RecognitionException { switch (alt1) { case 1 : - // InternalSemver.g:4711:16: '0' .. '9' + // InternalSemver.g:5227:16: '0' .. '9' { matchRange('0','9'); @@ -751,10 +925,10 @@ public final void mRULE_WS() throws RecognitionException { try { int _type = RULE_WS; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4713:9: ( ( RULE_WHITESPACE_FRAGMENT )+ ) - // InternalSemver.g:4713:11: ( RULE_WHITESPACE_FRAGMENT )+ + // InternalSemver.g:5229:9: ( ( RULE_WHITESPACE_FRAGMENT )+ ) + // InternalSemver.g:5229:11: ( RULE_WHITESPACE_FRAGMENT )+ { - // InternalSemver.g:4713:11: ( RULE_WHITESPACE_FRAGMENT )+ + // InternalSemver.g:5229:11: ( RULE_WHITESPACE_FRAGMENT )+ int cnt2=0; loop2: do { @@ -768,7 +942,7 @@ public final void mRULE_WS() throws RecognitionException { switch (alt2) { case 1 : - // InternalSemver.g:4713:11: RULE_WHITESPACE_FRAGMENT + // InternalSemver.g:5229:11: RULE_WHITESPACE_FRAGMENT { mRULE_WHITESPACE_FRAGMENT(); @@ -800,8 +974,8 @@ public final void mRULE_EOL() throws RecognitionException { try { int _type = RULE_EOL; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:4715:10: ( RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT ) - // InternalSemver.g:4715:12: RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT + // InternalSemver.g:5231:10: ( RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT ) + // InternalSemver.g:5231:12: RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT { mRULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT(); @@ -818,8 +992,8 @@ public final void mRULE_EOL() throws RecognitionException { // $ANTLR start "RULE_HEX_DIGIT" public final void mRULE_HEX_DIGIT() throws RecognitionException { try { - // InternalSemver.g:4717:25: ( ( RULE_DECIMAL_DIGIT_FRAGMENT | 'a' .. 'f' | 'A' .. 'F' ) ) - // InternalSemver.g:4717:27: ( RULE_DECIMAL_DIGIT_FRAGMENT | 'a' .. 'f' | 'A' .. 'F' ) + // InternalSemver.g:5233:25: ( ( RULE_DECIMAL_DIGIT_FRAGMENT | 'a' .. 'f' | 'A' .. 'F' ) ) + // InternalSemver.g:5233:27: ( RULE_DECIMAL_DIGIT_FRAGMENT | 'a' .. 'f' | 'A' .. 'F' ) { if ( (input.LA(1)>='0' && input.LA(1)<='9')||(input.LA(1)>='A' && input.LA(1)<='F')||(input.LA(1)>='a' && input.LA(1)<='f') ) { input.consume(); @@ -842,10 +1016,10 @@ public final void mRULE_HEX_DIGIT() throws RecognitionException { // $ANTLR start "RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT" public final void mRULE_DECIMAL_INTEGER_LITERAL_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:4719:48: ( ( '0' | '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* ) ) - // InternalSemver.g:4719:50: ( '0' | '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* ) + // InternalSemver.g:5235:48: ( ( '0' | '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* ) ) + // InternalSemver.g:5235:50: ( '0' | '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* ) { - // InternalSemver.g:4719:50: ( '0' | '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* ) + // InternalSemver.g:5235:50: ( '0' | '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* ) int alt4=2; int LA4_0 = input.LA(1); @@ -863,17 +1037,17 @@ else if ( ((LA4_0>='1' && LA4_0<='9')) ) { } switch (alt4) { case 1 : - // InternalSemver.g:4719:51: '0' + // InternalSemver.g:5235:51: '0' { match('0'); } break; case 2 : - // InternalSemver.g:4719:55: '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* + // InternalSemver.g:5235:55: '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* { matchRange('1','9'); - // InternalSemver.g:4719:64: ( RULE_DECIMAL_DIGIT_FRAGMENT )* + // InternalSemver.g:5235:64: ( RULE_DECIMAL_DIGIT_FRAGMENT )* loop3: do { int alt3=2; @@ -886,7 +1060,7 @@ else if ( ((LA4_0>='1' && LA4_0<='9')) ) { switch (alt3) { case 1 : - // InternalSemver.g:4719:64: RULE_DECIMAL_DIGIT_FRAGMENT + // InternalSemver.g:5235:64: RULE_DECIMAL_DIGIT_FRAGMENT { mRULE_DECIMAL_DIGIT_FRAGMENT(); @@ -916,8 +1090,8 @@ else if ( ((LA4_0>='1' && LA4_0<='9')) ) { // $ANTLR start "RULE_DECIMAL_DIGIT_FRAGMENT" public final void mRULE_DECIMAL_DIGIT_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:4721:38: ( '0' .. '9' ) - // InternalSemver.g:4721:40: '0' .. '9' + // InternalSemver.g:5237:38: ( '0' .. '9' ) + // InternalSemver.g:5237:40: '0' .. '9' { matchRange('0','9'); @@ -932,8 +1106,8 @@ public final void mRULE_DECIMAL_DIGIT_FRAGMENT() throws RecognitionException { // $ANTLR start "RULE_ZWJ" public final void mRULE_ZWJ() throws RecognitionException { try { - // InternalSemver.g:4723:19: ( '\\u200D' ) - // InternalSemver.g:4723:21: '\\u200D' + // InternalSemver.g:5239:19: ( '\\u200D' ) + // InternalSemver.g:5239:21: '\\u200D' { match('\u200D'); @@ -948,8 +1122,8 @@ public final void mRULE_ZWJ() throws RecognitionException { // $ANTLR start "RULE_ZWNJ" public final void mRULE_ZWNJ() throws RecognitionException { try { - // InternalSemver.g:4725:20: ( '\\u200C' ) - // InternalSemver.g:4725:22: '\\u200C' + // InternalSemver.g:5241:20: ( '\\u200C' ) + // InternalSemver.g:5241:22: '\\u200C' { match('\u200C'); @@ -964,8 +1138,8 @@ public final void mRULE_ZWNJ() throws RecognitionException { // $ANTLR start "RULE_BOM" public final void mRULE_BOM() throws RecognitionException { try { - // InternalSemver.g:4727:19: ( '\\uFEFF' ) - // InternalSemver.g:4727:21: '\\uFEFF' + // InternalSemver.g:5243:19: ( '\\uFEFF' ) + // InternalSemver.g:5243:21: '\\uFEFF' { match('\uFEFF'); @@ -980,8 +1154,8 @@ public final void mRULE_BOM() throws RecognitionException { // $ANTLR start "RULE_WHITESPACE_FRAGMENT" public final void mRULE_WHITESPACE_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:4729:35: ( ( '\\t' | '\\u000B' | '\\f' | ' ' | '\\u00A0' | RULE_BOM | RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT ) ) - // InternalSemver.g:4729:37: ( '\\t' | '\\u000B' | '\\f' | ' ' | '\\u00A0' | RULE_BOM | RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT ) + // InternalSemver.g:5245:35: ( ( '\\t' | '\\u000B' | '\\f' | ' ' | '\\u00A0' | RULE_BOM | RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT ) ) + // InternalSemver.g:5245:37: ( '\\t' | '\\u000B' | '\\f' | ' ' | '\\u00A0' | RULE_BOM | RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT ) { if ( input.LA(1)=='\t'||(input.LA(1)>='\u000B' && input.LA(1)<='\f')||input.LA(1)==' '||input.LA(1)=='\u00A0'||input.LA(1)=='\u1680'||(input.LA(1)>='\u2000' && input.LA(1)<='\u200A')||input.LA(1)=='\u202F'||input.LA(1)=='\u205F'||input.LA(1)=='\u3000'||input.LA(1)=='\uFEFF' ) { input.consume(); @@ -1004,8 +1178,8 @@ public final void mRULE_WHITESPACE_FRAGMENT() throws RecognitionException { // $ANTLR start "RULE_LINE_TERMINATOR_FRAGMENT" public final void mRULE_LINE_TERMINATOR_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:4731:40: ( ( '\\n' | '\\r' | '\\u2028' | '\\u2029' ) ) - // InternalSemver.g:4731:42: ( '\\n' | '\\r' | '\\u2028' | '\\u2029' ) + // InternalSemver.g:5247:40: ( ( '\\n' | '\\r' | '\\u2028' | '\\u2029' ) ) + // InternalSemver.g:5247:42: ( '\\n' | '\\r' | '\\u2028' | '\\u2029' ) { if ( input.LA(1)=='\n'||input.LA(1)=='\r'||(input.LA(1)>='\u2028' && input.LA(1)<='\u2029') ) { input.consume(); @@ -1028,10 +1202,10 @@ public final void mRULE_LINE_TERMINATOR_FRAGMENT() throws RecognitionException { // $ANTLR start "RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT" public final void mRULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:4733:49: ( ( '\\n' | '\\r' ( '\\n' )? | '\\u2028' | '\\u2029' ) ) - // InternalSemver.g:4733:51: ( '\\n' | '\\r' ( '\\n' )? | '\\u2028' | '\\u2029' ) + // InternalSemver.g:5249:49: ( ( '\\n' | '\\r' ( '\\n' )? | '\\u2028' | '\\u2029' ) ) + // InternalSemver.g:5249:51: ( '\\n' | '\\r' ( '\\n' )? | '\\u2028' | '\\u2029' ) { - // InternalSemver.g:4733:51: ( '\\n' | '\\r' ( '\\n' )? | '\\u2028' | '\\u2029' ) + // InternalSemver.g:5249:51: ( '\\n' | '\\r' ( '\\n' )? | '\\u2028' | '\\u2029' ) int alt6=4; switch ( input.LA(1) ) { case '\n': @@ -1063,17 +1237,17 @@ public final void mRULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT() throws RecognitionEx switch (alt6) { case 1 : - // InternalSemver.g:4733:52: '\\n' + // InternalSemver.g:5249:52: '\\n' { match('\n'); } break; case 2 : - // InternalSemver.g:4733:57: '\\r' ( '\\n' )? + // InternalSemver.g:5249:57: '\\r' ( '\\n' )? { match('\r'); - // InternalSemver.g:4733:62: ( '\\n' )? + // InternalSemver.g:5249:62: ( '\\n' )? int alt5=2; int LA5_0 = input.LA(1); @@ -1082,7 +1256,7 @@ public final void mRULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT() throws RecognitionEx } switch (alt5) { case 1 : - // InternalSemver.g:4733:62: '\\n' + // InternalSemver.g:5249:62: '\\n' { match('\n'); @@ -1095,14 +1269,14 @@ public final void mRULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT() throws RecognitionEx } break; case 3 : - // InternalSemver.g:4733:68: '\\u2028' + // InternalSemver.g:5249:68: '\\u2028' { match('\u2028'); } break; case 4 : - // InternalSemver.g:4733:77: '\\u2029' + // InternalSemver.g:5249:77: '\\u2029' { match('\u2029'); @@ -1123,12 +1297,12 @@ public final void mRULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT() throws RecognitionEx // $ANTLR start "RULE_SL_COMMENT_FRAGMENT" public final void mRULE_SL_COMMENT_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:4735:35: ( '//' (~ ( RULE_LINE_TERMINATOR_FRAGMENT ) )* ) - // InternalSemver.g:4735:37: '//' (~ ( RULE_LINE_TERMINATOR_FRAGMENT ) )* + // InternalSemver.g:5251:35: ( '//' (~ ( RULE_LINE_TERMINATOR_FRAGMENT ) )* ) + // InternalSemver.g:5251:37: '//' (~ ( RULE_LINE_TERMINATOR_FRAGMENT ) )* { match("//"); - // InternalSemver.g:4735:42: (~ ( RULE_LINE_TERMINATOR_FRAGMENT ) )* + // InternalSemver.g:5251:42: (~ ( RULE_LINE_TERMINATOR_FRAGMENT ) )* loop7: do { int alt7=2; @@ -1141,7 +1315,7 @@ public final void mRULE_SL_COMMENT_FRAGMENT() throws RecognitionException { switch (alt7) { case 1 : - // InternalSemver.g:4735:42: ~ ( RULE_LINE_TERMINATOR_FRAGMENT ) + // InternalSemver.g:5251:42: ~ ( RULE_LINE_TERMINATOR_FRAGMENT ) { if ( (input.LA(1)>='\u0000' && input.LA(1)<='\t')||(input.LA(1)>='\u000B' && input.LA(1)<='\f')||(input.LA(1)>='\u000E' && input.LA(1)<='\u2027')||(input.LA(1)>='\u202A' && input.LA(1)<='\uFFFF') ) { input.consume(); @@ -1173,12 +1347,12 @@ public final void mRULE_SL_COMMENT_FRAGMENT() throws RecognitionException { // $ANTLR start "RULE_ML_COMMENT_FRAGMENT" public final void mRULE_ML_COMMENT_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:4737:35: ( '/*' ( options {greedy=false; } : . )* '*/' ) - // InternalSemver.g:4737:37: '/*' ( options {greedy=false; } : . )* '*/' + // InternalSemver.g:5253:35: ( '/*' ( options {greedy=false; } : . )* '*/' ) + // InternalSemver.g:5253:37: '/*' ( options {greedy=false; } : . )* '*/' { match("/*"); - // InternalSemver.g:4737:42: ( options {greedy=false; } : . )* + // InternalSemver.g:5253:42: ( options {greedy=false; } : . )* loop8: do { int alt8=2; @@ -1203,7 +1377,7 @@ else if ( ((LA8_0>='\u0000' && LA8_0<=')')||(LA8_0>='+' && LA8_0<='\uFFFF')) ) { switch (alt8) { case 1 : - // InternalSemver.g:4737:70: . + // InternalSemver.g:5253:70: . { matchAny(); @@ -1229,8 +1403,8 @@ else if ( ((LA8_0>='\u0000' && LA8_0<=')')||(LA8_0>='+' && LA8_0<='\uFFFF')) ) { // $ANTLR start "RULE_UNICODE_COMBINING_MARK_FRAGMENT" public final void mRULE_UNICODE_COMBINING_MARK_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:4739:47: ( ( '\\u0300' .. '\\u036F' | '\\u0483' .. '\\u0487' | '\\u0591' .. '\\u05BD' | '\\u05BF' | '\\u05C1' .. '\\u05C2' | '\\u05C4' .. '\\u05C5' | '\\u05C7' | '\\u0610' .. '\\u061A' | '\\u064B' .. '\\u065F' | '\\u0670' | '\\u06D6' .. '\\u06DC' | '\\u06DF' .. '\\u06E4' | '\\u06E7' .. '\\u06E8' | '\\u06EA' .. '\\u06ED' | '\\u0711' | '\\u0730' .. '\\u074A' | '\\u07A6' .. '\\u07B0' | '\\u07EB' .. '\\u07F3' | '\\u0816' .. '\\u0819' | '\\u081B' .. '\\u0823' | '\\u0825' .. '\\u0827' | '\\u0829' .. '\\u082D' | '\\u0859' .. '\\u085B' | '\\u08E3' .. '\\u0903' | '\\u093A' .. '\\u093C' | '\\u093E' .. '\\u094F' | '\\u0951' .. '\\u0957' | '\\u0962' .. '\\u0963' | '\\u0981' .. '\\u0983' | '\\u09BC' | '\\u09BE' .. '\\u09C4' | '\\u09C7' .. '\\u09C8' | '\\u09CB' .. '\\u09CD' | '\\u09D7' | '\\u09E2' .. '\\u09E3' | '\\u0A01' .. '\\u0A03' | '\\u0A3C' | '\\u0A3E' .. '\\u0A42' | '\\u0A47' .. '\\u0A48' | '\\u0A4B' .. '\\u0A4D' | '\\u0A51' | '\\u0A70' .. '\\u0A71' | '\\u0A75' | '\\u0A81' .. '\\u0A83' | '\\u0ABC' | '\\u0ABE' .. '\\u0AC5' | '\\u0AC7' .. '\\u0AC9' | '\\u0ACB' .. '\\u0ACD' | '\\u0AE2' .. '\\u0AE3' | '\\u0B01' .. '\\u0B03' | '\\u0B3C' | '\\u0B3E' .. '\\u0B44' | '\\u0B47' .. '\\u0B48' | '\\u0B4B' .. '\\u0B4D' | '\\u0B56' .. '\\u0B57' | '\\u0B62' .. '\\u0B63' | '\\u0B82' | '\\u0BBE' .. '\\u0BC2' | '\\u0BC6' .. '\\u0BC8' | '\\u0BCA' .. '\\u0BCD' | '\\u0BD7' | '\\u0C00' .. '\\u0C03' | '\\u0C3E' .. '\\u0C44' | '\\u0C46' .. '\\u0C48' | '\\u0C4A' .. '\\u0C4D' | '\\u0C55' .. '\\u0C56' | '\\u0C62' .. '\\u0C63' | '\\u0C81' .. '\\u0C83' | '\\u0CBC' | '\\u0CBE' .. '\\u0CC4' | '\\u0CC6' .. '\\u0CC8' | '\\u0CCA' .. '\\u0CCD' | '\\u0CD5' .. '\\u0CD6' | '\\u0CE2' .. '\\u0CE3' | '\\u0D01' .. '\\u0D03' | '\\u0D3E' .. '\\u0D44' | '\\u0D46' .. '\\u0D48' | '\\u0D4A' .. '\\u0D4D' | '\\u0D57' | '\\u0D62' .. '\\u0D63' | '\\u0D82' .. '\\u0D83' | '\\u0DCA' | '\\u0DCF' .. '\\u0DD4' | '\\u0DD6' | '\\u0DD8' .. '\\u0DDF' | '\\u0DF2' .. '\\u0DF3' | '\\u0E31' | '\\u0E34' .. '\\u0E3A' | '\\u0E47' .. '\\u0E4E' | '\\u0EB1' | '\\u0EB4' .. '\\u0EB9' | '\\u0EBB' .. '\\u0EBC' | '\\u0EC8' .. '\\u0ECD' | '\\u0F18' .. '\\u0F19' | '\\u0F35' | '\\u0F37' | '\\u0F39' | '\\u0F3E' .. '\\u0F3F' | '\\u0F71' .. '\\u0F84' | '\\u0F86' .. '\\u0F87' | '\\u0F8D' .. '\\u0F97' | '\\u0F99' .. '\\u0FBC' | '\\u0FC6' | '\\u102B' .. '\\u103E' | '\\u1056' .. '\\u1059' | '\\u105E' .. '\\u1060' | '\\u1062' .. '\\u1064' | '\\u1067' .. '\\u106D' | '\\u1071' .. '\\u1074' | '\\u1082' .. '\\u108D' | '\\u108F' | '\\u109A' .. '\\u109D' | '\\u135D' .. '\\u135F' | '\\u1712' .. '\\u1714' | '\\u1732' .. '\\u1734' | '\\u1752' .. '\\u1753' | '\\u1772' .. '\\u1773' | '\\u17B4' .. '\\u17D3' | '\\u17DD' | '\\u180B' .. '\\u180D' | '\\u18A9' | '\\u1920' .. '\\u192B' | '\\u1930' .. '\\u193B' | '\\u1A17' .. '\\u1A1B' | '\\u1A55' .. '\\u1A5E' | '\\u1A60' .. '\\u1A7C' | '\\u1A7F' | '\\u1AB0' .. '\\u1ABD' | '\\u1B00' .. '\\u1B04' | '\\u1B34' .. '\\u1B44' | '\\u1B6B' .. '\\u1B73' | '\\u1B80' .. '\\u1B82' | '\\u1BA1' .. '\\u1BAD' | '\\u1BE6' .. '\\u1BF3' | '\\u1C24' .. '\\u1C37' | '\\u1CD0' .. '\\u1CD2' | '\\u1CD4' .. '\\u1CE8' | '\\u1CED' | '\\u1CF2' .. '\\u1CF4' | '\\u1CF8' .. '\\u1CF9' | '\\u1DC0' .. '\\u1DF5' | '\\u1DFC' .. '\\u1DFF' | '\\u20D0' .. '\\u20DC' | '\\u20E1' | '\\u20E5' .. '\\u20F0' | '\\u2CEF' .. '\\u2CF1' | '\\u2D7F' | '\\u2DE0' .. '\\u2DFF' | '\\u302A' .. '\\u302F' | '\\u3099' .. '\\u309A' | '\\uA66F' | '\\uA674' .. '\\uA67D' | '\\uA69E' .. '\\uA69F' | '\\uA6F0' .. '\\uA6F1' | '\\uA802' | '\\uA806' | '\\uA80B' | '\\uA823' .. '\\uA827' | '\\uA880' .. '\\uA881' | '\\uA8B4' .. '\\uA8C4' | '\\uA8E0' .. '\\uA8F1' | '\\uA926' .. '\\uA92D' | '\\uA947' .. '\\uA953' | '\\uA980' .. '\\uA983' | '\\uA9B3' .. '\\uA9C0' | '\\uA9E5' | '\\uAA29' .. '\\uAA36' | '\\uAA43' | '\\uAA4C' .. '\\uAA4D' | '\\uAA7B' .. '\\uAA7D' | '\\uAAB0' | '\\uAAB2' .. '\\uAAB4' | '\\uAAB7' .. '\\uAAB8' | '\\uAABE' .. '\\uAABF' | '\\uAAC1' | '\\uAAEB' .. '\\uAAEF' | '\\uAAF5' .. '\\uAAF6' | '\\uABE3' .. '\\uABEA' | '\\uABEC' .. '\\uABED' | '\\uFB1E' | '\\uFE00' .. '\\uFE0F' | '\\uFE20' .. '\\uFE2F' ) ) - // InternalSemver.g:4739:49: ( '\\u0300' .. '\\u036F' | '\\u0483' .. '\\u0487' | '\\u0591' .. '\\u05BD' | '\\u05BF' | '\\u05C1' .. '\\u05C2' | '\\u05C4' .. '\\u05C5' | '\\u05C7' | '\\u0610' .. '\\u061A' | '\\u064B' .. '\\u065F' | '\\u0670' | '\\u06D6' .. '\\u06DC' | '\\u06DF' .. '\\u06E4' | '\\u06E7' .. '\\u06E8' | '\\u06EA' .. '\\u06ED' | '\\u0711' | '\\u0730' .. '\\u074A' | '\\u07A6' .. '\\u07B0' | '\\u07EB' .. '\\u07F3' | '\\u0816' .. '\\u0819' | '\\u081B' .. '\\u0823' | '\\u0825' .. '\\u0827' | '\\u0829' .. '\\u082D' | '\\u0859' .. '\\u085B' | '\\u08E3' .. '\\u0903' | '\\u093A' .. '\\u093C' | '\\u093E' .. '\\u094F' | '\\u0951' .. '\\u0957' | '\\u0962' .. '\\u0963' | '\\u0981' .. '\\u0983' | '\\u09BC' | '\\u09BE' .. '\\u09C4' | '\\u09C7' .. '\\u09C8' | '\\u09CB' .. '\\u09CD' | '\\u09D7' | '\\u09E2' .. '\\u09E3' | '\\u0A01' .. '\\u0A03' | '\\u0A3C' | '\\u0A3E' .. '\\u0A42' | '\\u0A47' .. '\\u0A48' | '\\u0A4B' .. '\\u0A4D' | '\\u0A51' | '\\u0A70' .. '\\u0A71' | '\\u0A75' | '\\u0A81' .. '\\u0A83' | '\\u0ABC' | '\\u0ABE' .. '\\u0AC5' | '\\u0AC7' .. '\\u0AC9' | '\\u0ACB' .. '\\u0ACD' | '\\u0AE2' .. '\\u0AE3' | '\\u0B01' .. '\\u0B03' | '\\u0B3C' | '\\u0B3E' .. '\\u0B44' | '\\u0B47' .. '\\u0B48' | '\\u0B4B' .. '\\u0B4D' | '\\u0B56' .. '\\u0B57' | '\\u0B62' .. '\\u0B63' | '\\u0B82' | '\\u0BBE' .. '\\u0BC2' | '\\u0BC6' .. '\\u0BC8' | '\\u0BCA' .. '\\u0BCD' | '\\u0BD7' | '\\u0C00' .. '\\u0C03' | '\\u0C3E' .. '\\u0C44' | '\\u0C46' .. '\\u0C48' | '\\u0C4A' .. '\\u0C4D' | '\\u0C55' .. '\\u0C56' | '\\u0C62' .. '\\u0C63' | '\\u0C81' .. '\\u0C83' | '\\u0CBC' | '\\u0CBE' .. '\\u0CC4' | '\\u0CC6' .. '\\u0CC8' | '\\u0CCA' .. '\\u0CCD' | '\\u0CD5' .. '\\u0CD6' | '\\u0CE2' .. '\\u0CE3' | '\\u0D01' .. '\\u0D03' | '\\u0D3E' .. '\\u0D44' | '\\u0D46' .. '\\u0D48' | '\\u0D4A' .. '\\u0D4D' | '\\u0D57' | '\\u0D62' .. '\\u0D63' | '\\u0D82' .. '\\u0D83' | '\\u0DCA' | '\\u0DCF' .. '\\u0DD4' | '\\u0DD6' | '\\u0DD8' .. '\\u0DDF' | '\\u0DF2' .. '\\u0DF3' | '\\u0E31' | '\\u0E34' .. '\\u0E3A' | '\\u0E47' .. '\\u0E4E' | '\\u0EB1' | '\\u0EB4' .. '\\u0EB9' | '\\u0EBB' .. '\\u0EBC' | '\\u0EC8' .. '\\u0ECD' | '\\u0F18' .. '\\u0F19' | '\\u0F35' | '\\u0F37' | '\\u0F39' | '\\u0F3E' .. '\\u0F3F' | '\\u0F71' .. '\\u0F84' | '\\u0F86' .. '\\u0F87' | '\\u0F8D' .. '\\u0F97' | '\\u0F99' .. '\\u0FBC' | '\\u0FC6' | '\\u102B' .. '\\u103E' | '\\u1056' .. '\\u1059' | '\\u105E' .. '\\u1060' | '\\u1062' .. '\\u1064' | '\\u1067' .. '\\u106D' | '\\u1071' .. '\\u1074' | '\\u1082' .. '\\u108D' | '\\u108F' | '\\u109A' .. '\\u109D' | '\\u135D' .. '\\u135F' | '\\u1712' .. '\\u1714' | '\\u1732' .. '\\u1734' | '\\u1752' .. '\\u1753' | '\\u1772' .. '\\u1773' | '\\u17B4' .. '\\u17D3' | '\\u17DD' | '\\u180B' .. '\\u180D' | '\\u18A9' | '\\u1920' .. '\\u192B' | '\\u1930' .. '\\u193B' | '\\u1A17' .. '\\u1A1B' | '\\u1A55' .. '\\u1A5E' | '\\u1A60' .. '\\u1A7C' | '\\u1A7F' | '\\u1AB0' .. '\\u1ABD' | '\\u1B00' .. '\\u1B04' | '\\u1B34' .. '\\u1B44' | '\\u1B6B' .. '\\u1B73' | '\\u1B80' .. '\\u1B82' | '\\u1BA1' .. '\\u1BAD' | '\\u1BE6' .. '\\u1BF3' | '\\u1C24' .. '\\u1C37' | '\\u1CD0' .. '\\u1CD2' | '\\u1CD4' .. '\\u1CE8' | '\\u1CED' | '\\u1CF2' .. '\\u1CF4' | '\\u1CF8' .. '\\u1CF9' | '\\u1DC0' .. '\\u1DF5' | '\\u1DFC' .. '\\u1DFF' | '\\u20D0' .. '\\u20DC' | '\\u20E1' | '\\u20E5' .. '\\u20F0' | '\\u2CEF' .. '\\u2CF1' | '\\u2D7F' | '\\u2DE0' .. '\\u2DFF' | '\\u302A' .. '\\u302F' | '\\u3099' .. '\\u309A' | '\\uA66F' | '\\uA674' .. '\\uA67D' | '\\uA69E' .. '\\uA69F' | '\\uA6F0' .. '\\uA6F1' | '\\uA802' | '\\uA806' | '\\uA80B' | '\\uA823' .. '\\uA827' | '\\uA880' .. '\\uA881' | '\\uA8B4' .. '\\uA8C4' | '\\uA8E0' .. '\\uA8F1' | '\\uA926' .. '\\uA92D' | '\\uA947' .. '\\uA953' | '\\uA980' .. '\\uA983' | '\\uA9B3' .. '\\uA9C0' | '\\uA9E5' | '\\uAA29' .. '\\uAA36' | '\\uAA43' | '\\uAA4C' .. '\\uAA4D' | '\\uAA7B' .. '\\uAA7D' | '\\uAAB0' | '\\uAAB2' .. '\\uAAB4' | '\\uAAB7' .. '\\uAAB8' | '\\uAABE' .. '\\uAABF' | '\\uAAC1' | '\\uAAEB' .. '\\uAAEF' | '\\uAAF5' .. '\\uAAF6' | '\\uABE3' .. '\\uABEA' | '\\uABEC' .. '\\uABED' | '\\uFB1E' | '\\uFE00' .. '\\uFE0F' | '\\uFE20' .. '\\uFE2F' ) + // InternalSemver.g:5255:47: ( ( '\\u0300' .. '\\u036F' | '\\u0483' .. '\\u0487' | '\\u0591' .. '\\u05BD' | '\\u05BF' | '\\u05C1' .. '\\u05C2' | '\\u05C4' .. '\\u05C5' | '\\u05C7' | '\\u0610' .. '\\u061A' | '\\u064B' .. '\\u065F' | '\\u0670' | '\\u06D6' .. '\\u06DC' | '\\u06DF' .. '\\u06E4' | '\\u06E7' .. '\\u06E8' | '\\u06EA' .. '\\u06ED' | '\\u0711' | '\\u0730' .. '\\u074A' | '\\u07A6' .. '\\u07B0' | '\\u07EB' .. '\\u07F3' | '\\u0816' .. '\\u0819' | '\\u081B' .. '\\u0823' | '\\u0825' .. '\\u0827' | '\\u0829' .. '\\u082D' | '\\u0859' .. '\\u085B' | '\\u08E3' .. '\\u0903' | '\\u093A' .. '\\u093C' | '\\u093E' .. '\\u094F' | '\\u0951' .. '\\u0957' | '\\u0962' .. '\\u0963' | '\\u0981' .. '\\u0983' | '\\u09BC' | '\\u09BE' .. '\\u09C4' | '\\u09C7' .. '\\u09C8' | '\\u09CB' .. '\\u09CD' | '\\u09D7' | '\\u09E2' .. '\\u09E3' | '\\u0A01' .. '\\u0A03' | '\\u0A3C' | '\\u0A3E' .. '\\u0A42' | '\\u0A47' .. '\\u0A48' | '\\u0A4B' .. '\\u0A4D' | '\\u0A51' | '\\u0A70' .. '\\u0A71' | '\\u0A75' | '\\u0A81' .. '\\u0A83' | '\\u0ABC' | '\\u0ABE' .. '\\u0AC5' | '\\u0AC7' .. '\\u0AC9' | '\\u0ACB' .. '\\u0ACD' | '\\u0AE2' .. '\\u0AE3' | '\\u0B01' .. '\\u0B03' | '\\u0B3C' | '\\u0B3E' .. '\\u0B44' | '\\u0B47' .. '\\u0B48' | '\\u0B4B' .. '\\u0B4D' | '\\u0B56' .. '\\u0B57' | '\\u0B62' .. '\\u0B63' | '\\u0B82' | '\\u0BBE' .. '\\u0BC2' | '\\u0BC6' .. '\\u0BC8' | '\\u0BCA' .. '\\u0BCD' | '\\u0BD7' | '\\u0C00' .. '\\u0C03' | '\\u0C3E' .. '\\u0C44' | '\\u0C46' .. '\\u0C48' | '\\u0C4A' .. '\\u0C4D' | '\\u0C55' .. '\\u0C56' | '\\u0C62' .. '\\u0C63' | '\\u0C81' .. '\\u0C83' | '\\u0CBC' | '\\u0CBE' .. '\\u0CC4' | '\\u0CC6' .. '\\u0CC8' | '\\u0CCA' .. '\\u0CCD' | '\\u0CD5' .. '\\u0CD6' | '\\u0CE2' .. '\\u0CE3' | '\\u0D01' .. '\\u0D03' | '\\u0D3E' .. '\\u0D44' | '\\u0D46' .. '\\u0D48' | '\\u0D4A' .. '\\u0D4D' | '\\u0D57' | '\\u0D62' .. '\\u0D63' | '\\u0D82' .. '\\u0D83' | '\\u0DCA' | '\\u0DCF' .. '\\u0DD4' | '\\u0DD6' | '\\u0DD8' .. '\\u0DDF' | '\\u0DF2' .. '\\u0DF3' | '\\u0E31' | '\\u0E34' .. '\\u0E3A' | '\\u0E47' .. '\\u0E4E' | '\\u0EB1' | '\\u0EB4' .. '\\u0EB9' | '\\u0EBB' .. '\\u0EBC' | '\\u0EC8' .. '\\u0ECD' | '\\u0F18' .. '\\u0F19' | '\\u0F35' | '\\u0F37' | '\\u0F39' | '\\u0F3E' .. '\\u0F3F' | '\\u0F71' .. '\\u0F84' | '\\u0F86' .. '\\u0F87' | '\\u0F8D' .. '\\u0F97' | '\\u0F99' .. '\\u0FBC' | '\\u0FC6' | '\\u102B' .. '\\u103E' | '\\u1056' .. '\\u1059' | '\\u105E' .. '\\u1060' | '\\u1062' .. '\\u1064' | '\\u1067' .. '\\u106D' | '\\u1071' .. '\\u1074' | '\\u1082' .. '\\u108D' | '\\u108F' | '\\u109A' .. '\\u109D' | '\\u135D' .. '\\u135F' | '\\u1712' .. '\\u1714' | '\\u1732' .. '\\u1734' | '\\u1752' .. '\\u1753' | '\\u1772' .. '\\u1773' | '\\u17B4' .. '\\u17D3' | '\\u17DD' | '\\u180B' .. '\\u180D' | '\\u18A9' | '\\u1920' .. '\\u192B' | '\\u1930' .. '\\u193B' | '\\u1A17' .. '\\u1A1B' | '\\u1A55' .. '\\u1A5E' | '\\u1A60' .. '\\u1A7C' | '\\u1A7F' | '\\u1AB0' .. '\\u1ABD' | '\\u1B00' .. '\\u1B04' | '\\u1B34' .. '\\u1B44' | '\\u1B6B' .. '\\u1B73' | '\\u1B80' .. '\\u1B82' | '\\u1BA1' .. '\\u1BAD' | '\\u1BE6' .. '\\u1BF3' | '\\u1C24' .. '\\u1C37' | '\\u1CD0' .. '\\u1CD2' | '\\u1CD4' .. '\\u1CE8' | '\\u1CED' | '\\u1CF2' .. '\\u1CF4' | '\\u1CF8' .. '\\u1CF9' | '\\u1DC0' .. '\\u1DF5' | '\\u1DFC' .. '\\u1DFF' | '\\u20D0' .. '\\u20DC' | '\\u20E1' | '\\u20E5' .. '\\u20F0' | '\\u2CEF' .. '\\u2CF1' | '\\u2D7F' | '\\u2DE0' .. '\\u2DFF' | '\\u302A' .. '\\u302F' | '\\u3099' .. '\\u309A' | '\\uA66F' | '\\uA674' .. '\\uA67D' | '\\uA69E' .. '\\uA69F' | '\\uA6F0' .. '\\uA6F1' | '\\uA802' | '\\uA806' | '\\uA80B' | '\\uA823' .. '\\uA827' | '\\uA880' .. '\\uA881' | '\\uA8B4' .. '\\uA8C4' | '\\uA8E0' .. '\\uA8F1' | '\\uA926' .. '\\uA92D' | '\\uA947' .. '\\uA953' | '\\uA980' .. '\\uA983' | '\\uA9B3' .. '\\uA9C0' | '\\uA9E5' | '\\uAA29' .. '\\uAA36' | '\\uAA43' | '\\uAA4C' .. '\\uAA4D' | '\\uAA7B' .. '\\uAA7D' | '\\uAAB0' | '\\uAAB2' .. '\\uAAB4' | '\\uAAB7' .. '\\uAAB8' | '\\uAABE' .. '\\uAABF' | '\\uAAC1' | '\\uAAEB' .. '\\uAAEF' | '\\uAAF5' .. '\\uAAF6' | '\\uABE3' .. '\\uABEA' | '\\uABEC' .. '\\uABED' | '\\uFB1E' | '\\uFE00' .. '\\uFE0F' | '\\uFE20' .. '\\uFE2F' ) ) + // InternalSemver.g:5255:49: ( '\\u0300' .. '\\u036F' | '\\u0483' .. '\\u0487' | '\\u0591' .. '\\u05BD' | '\\u05BF' | '\\u05C1' .. '\\u05C2' | '\\u05C4' .. '\\u05C5' | '\\u05C7' | '\\u0610' .. '\\u061A' | '\\u064B' .. '\\u065F' | '\\u0670' | '\\u06D6' .. '\\u06DC' | '\\u06DF' .. '\\u06E4' | '\\u06E7' .. '\\u06E8' | '\\u06EA' .. '\\u06ED' | '\\u0711' | '\\u0730' .. '\\u074A' | '\\u07A6' .. '\\u07B0' | '\\u07EB' .. '\\u07F3' | '\\u0816' .. '\\u0819' | '\\u081B' .. '\\u0823' | '\\u0825' .. '\\u0827' | '\\u0829' .. '\\u082D' | '\\u0859' .. '\\u085B' | '\\u08E3' .. '\\u0903' | '\\u093A' .. '\\u093C' | '\\u093E' .. '\\u094F' | '\\u0951' .. '\\u0957' | '\\u0962' .. '\\u0963' | '\\u0981' .. '\\u0983' | '\\u09BC' | '\\u09BE' .. '\\u09C4' | '\\u09C7' .. '\\u09C8' | '\\u09CB' .. '\\u09CD' | '\\u09D7' | '\\u09E2' .. '\\u09E3' | '\\u0A01' .. '\\u0A03' | '\\u0A3C' | '\\u0A3E' .. '\\u0A42' | '\\u0A47' .. '\\u0A48' | '\\u0A4B' .. '\\u0A4D' | '\\u0A51' | '\\u0A70' .. '\\u0A71' | '\\u0A75' | '\\u0A81' .. '\\u0A83' | '\\u0ABC' | '\\u0ABE' .. '\\u0AC5' | '\\u0AC7' .. '\\u0AC9' | '\\u0ACB' .. '\\u0ACD' | '\\u0AE2' .. '\\u0AE3' | '\\u0B01' .. '\\u0B03' | '\\u0B3C' | '\\u0B3E' .. '\\u0B44' | '\\u0B47' .. '\\u0B48' | '\\u0B4B' .. '\\u0B4D' | '\\u0B56' .. '\\u0B57' | '\\u0B62' .. '\\u0B63' | '\\u0B82' | '\\u0BBE' .. '\\u0BC2' | '\\u0BC6' .. '\\u0BC8' | '\\u0BCA' .. '\\u0BCD' | '\\u0BD7' | '\\u0C00' .. '\\u0C03' | '\\u0C3E' .. '\\u0C44' | '\\u0C46' .. '\\u0C48' | '\\u0C4A' .. '\\u0C4D' | '\\u0C55' .. '\\u0C56' | '\\u0C62' .. '\\u0C63' | '\\u0C81' .. '\\u0C83' | '\\u0CBC' | '\\u0CBE' .. '\\u0CC4' | '\\u0CC6' .. '\\u0CC8' | '\\u0CCA' .. '\\u0CCD' | '\\u0CD5' .. '\\u0CD6' | '\\u0CE2' .. '\\u0CE3' | '\\u0D01' .. '\\u0D03' | '\\u0D3E' .. '\\u0D44' | '\\u0D46' .. '\\u0D48' | '\\u0D4A' .. '\\u0D4D' | '\\u0D57' | '\\u0D62' .. '\\u0D63' | '\\u0D82' .. '\\u0D83' | '\\u0DCA' | '\\u0DCF' .. '\\u0DD4' | '\\u0DD6' | '\\u0DD8' .. '\\u0DDF' | '\\u0DF2' .. '\\u0DF3' | '\\u0E31' | '\\u0E34' .. '\\u0E3A' | '\\u0E47' .. '\\u0E4E' | '\\u0EB1' | '\\u0EB4' .. '\\u0EB9' | '\\u0EBB' .. '\\u0EBC' | '\\u0EC8' .. '\\u0ECD' | '\\u0F18' .. '\\u0F19' | '\\u0F35' | '\\u0F37' | '\\u0F39' | '\\u0F3E' .. '\\u0F3F' | '\\u0F71' .. '\\u0F84' | '\\u0F86' .. '\\u0F87' | '\\u0F8D' .. '\\u0F97' | '\\u0F99' .. '\\u0FBC' | '\\u0FC6' | '\\u102B' .. '\\u103E' | '\\u1056' .. '\\u1059' | '\\u105E' .. '\\u1060' | '\\u1062' .. '\\u1064' | '\\u1067' .. '\\u106D' | '\\u1071' .. '\\u1074' | '\\u1082' .. '\\u108D' | '\\u108F' | '\\u109A' .. '\\u109D' | '\\u135D' .. '\\u135F' | '\\u1712' .. '\\u1714' | '\\u1732' .. '\\u1734' | '\\u1752' .. '\\u1753' | '\\u1772' .. '\\u1773' | '\\u17B4' .. '\\u17D3' | '\\u17DD' | '\\u180B' .. '\\u180D' | '\\u18A9' | '\\u1920' .. '\\u192B' | '\\u1930' .. '\\u193B' | '\\u1A17' .. '\\u1A1B' | '\\u1A55' .. '\\u1A5E' | '\\u1A60' .. '\\u1A7C' | '\\u1A7F' | '\\u1AB0' .. '\\u1ABD' | '\\u1B00' .. '\\u1B04' | '\\u1B34' .. '\\u1B44' | '\\u1B6B' .. '\\u1B73' | '\\u1B80' .. '\\u1B82' | '\\u1BA1' .. '\\u1BAD' | '\\u1BE6' .. '\\u1BF3' | '\\u1C24' .. '\\u1C37' | '\\u1CD0' .. '\\u1CD2' | '\\u1CD4' .. '\\u1CE8' | '\\u1CED' | '\\u1CF2' .. '\\u1CF4' | '\\u1CF8' .. '\\u1CF9' | '\\u1DC0' .. '\\u1DF5' | '\\u1DFC' .. '\\u1DFF' | '\\u20D0' .. '\\u20DC' | '\\u20E1' | '\\u20E5' .. '\\u20F0' | '\\u2CEF' .. '\\u2CF1' | '\\u2D7F' | '\\u2DE0' .. '\\u2DFF' | '\\u302A' .. '\\u302F' | '\\u3099' .. '\\u309A' | '\\uA66F' | '\\uA674' .. '\\uA67D' | '\\uA69E' .. '\\uA69F' | '\\uA6F0' .. '\\uA6F1' | '\\uA802' | '\\uA806' | '\\uA80B' | '\\uA823' .. '\\uA827' | '\\uA880' .. '\\uA881' | '\\uA8B4' .. '\\uA8C4' | '\\uA8E0' .. '\\uA8F1' | '\\uA926' .. '\\uA92D' | '\\uA947' .. '\\uA953' | '\\uA980' .. '\\uA983' | '\\uA9B3' .. '\\uA9C0' | '\\uA9E5' | '\\uAA29' .. '\\uAA36' | '\\uAA43' | '\\uAA4C' .. '\\uAA4D' | '\\uAA7B' .. '\\uAA7D' | '\\uAAB0' | '\\uAAB2' .. '\\uAAB4' | '\\uAAB7' .. '\\uAAB8' | '\\uAABE' .. '\\uAABF' | '\\uAAC1' | '\\uAAEB' .. '\\uAAEF' | '\\uAAF5' .. '\\uAAF6' | '\\uABE3' .. '\\uABEA' | '\\uABEC' .. '\\uABED' | '\\uFB1E' | '\\uFE00' .. '\\uFE0F' | '\\uFE20' .. '\\uFE2F' ) { if ( (input.LA(1)>='\u0300' && input.LA(1)<='\u036F')||(input.LA(1)>='\u0483' && input.LA(1)<='\u0487')||(input.LA(1)>='\u0591' && input.LA(1)<='\u05BD')||input.LA(1)=='\u05BF'||(input.LA(1)>='\u05C1' && input.LA(1)<='\u05C2')||(input.LA(1)>='\u05C4' && input.LA(1)<='\u05C5')||input.LA(1)=='\u05C7'||(input.LA(1)>='\u0610' && input.LA(1)<='\u061A')||(input.LA(1)>='\u064B' && input.LA(1)<='\u065F')||input.LA(1)=='\u0670'||(input.LA(1)>='\u06D6' && input.LA(1)<='\u06DC')||(input.LA(1)>='\u06DF' && input.LA(1)<='\u06E4')||(input.LA(1)>='\u06E7' && input.LA(1)<='\u06E8')||(input.LA(1)>='\u06EA' && input.LA(1)<='\u06ED')||input.LA(1)=='\u0711'||(input.LA(1)>='\u0730' && input.LA(1)<='\u074A')||(input.LA(1)>='\u07A6' && input.LA(1)<='\u07B0')||(input.LA(1)>='\u07EB' && input.LA(1)<='\u07F3')||(input.LA(1)>='\u0816' && input.LA(1)<='\u0819')||(input.LA(1)>='\u081B' && input.LA(1)<='\u0823')||(input.LA(1)>='\u0825' && input.LA(1)<='\u0827')||(input.LA(1)>='\u0829' && input.LA(1)<='\u082D')||(input.LA(1)>='\u0859' && input.LA(1)<='\u085B')||(input.LA(1)>='\u08E3' && input.LA(1)<='\u0903')||(input.LA(1)>='\u093A' && input.LA(1)<='\u093C')||(input.LA(1)>='\u093E' && input.LA(1)<='\u094F')||(input.LA(1)>='\u0951' && input.LA(1)<='\u0957')||(input.LA(1)>='\u0962' && input.LA(1)<='\u0963')||(input.LA(1)>='\u0981' && input.LA(1)<='\u0983')||input.LA(1)=='\u09BC'||(input.LA(1)>='\u09BE' && input.LA(1)<='\u09C4')||(input.LA(1)>='\u09C7' && input.LA(1)<='\u09C8')||(input.LA(1)>='\u09CB' && input.LA(1)<='\u09CD')||input.LA(1)=='\u09D7'||(input.LA(1)>='\u09E2' && input.LA(1)<='\u09E3')||(input.LA(1)>='\u0A01' && input.LA(1)<='\u0A03')||input.LA(1)=='\u0A3C'||(input.LA(1)>='\u0A3E' && input.LA(1)<='\u0A42')||(input.LA(1)>='\u0A47' && input.LA(1)<='\u0A48')||(input.LA(1)>='\u0A4B' && input.LA(1)<='\u0A4D')||input.LA(1)=='\u0A51'||(input.LA(1)>='\u0A70' && input.LA(1)<='\u0A71')||input.LA(1)=='\u0A75'||(input.LA(1)>='\u0A81' && input.LA(1)<='\u0A83')||input.LA(1)=='\u0ABC'||(input.LA(1)>='\u0ABE' && input.LA(1)<='\u0AC5')||(input.LA(1)>='\u0AC7' && input.LA(1)<='\u0AC9')||(input.LA(1)>='\u0ACB' && input.LA(1)<='\u0ACD')||(input.LA(1)>='\u0AE2' && input.LA(1)<='\u0AE3')||(input.LA(1)>='\u0B01' && input.LA(1)<='\u0B03')||input.LA(1)=='\u0B3C'||(input.LA(1)>='\u0B3E' && input.LA(1)<='\u0B44')||(input.LA(1)>='\u0B47' && input.LA(1)<='\u0B48')||(input.LA(1)>='\u0B4B' && input.LA(1)<='\u0B4D')||(input.LA(1)>='\u0B56' && input.LA(1)<='\u0B57')||(input.LA(1)>='\u0B62' && input.LA(1)<='\u0B63')||input.LA(1)=='\u0B82'||(input.LA(1)>='\u0BBE' && input.LA(1)<='\u0BC2')||(input.LA(1)>='\u0BC6' && input.LA(1)<='\u0BC8')||(input.LA(1)>='\u0BCA' && input.LA(1)<='\u0BCD')||input.LA(1)=='\u0BD7'||(input.LA(1)>='\u0C00' && input.LA(1)<='\u0C03')||(input.LA(1)>='\u0C3E' && input.LA(1)<='\u0C44')||(input.LA(1)>='\u0C46' && input.LA(1)<='\u0C48')||(input.LA(1)>='\u0C4A' && input.LA(1)<='\u0C4D')||(input.LA(1)>='\u0C55' && input.LA(1)<='\u0C56')||(input.LA(1)>='\u0C62' && input.LA(1)<='\u0C63')||(input.LA(1)>='\u0C81' && input.LA(1)<='\u0C83')||input.LA(1)=='\u0CBC'||(input.LA(1)>='\u0CBE' && input.LA(1)<='\u0CC4')||(input.LA(1)>='\u0CC6' && input.LA(1)<='\u0CC8')||(input.LA(1)>='\u0CCA' && input.LA(1)<='\u0CCD')||(input.LA(1)>='\u0CD5' && input.LA(1)<='\u0CD6')||(input.LA(1)>='\u0CE2' && input.LA(1)<='\u0CE3')||(input.LA(1)>='\u0D01' && input.LA(1)<='\u0D03')||(input.LA(1)>='\u0D3E' && input.LA(1)<='\u0D44')||(input.LA(1)>='\u0D46' && input.LA(1)<='\u0D48')||(input.LA(1)>='\u0D4A' && input.LA(1)<='\u0D4D')||input.LA(1)=='\u0D57'||(input.LA(1)>='\u0D62' && input.LA(1)<='\u0D63')||(input.LA(1)>='\u0D82' && input.LA(1)<='\u0D83')||input.LA(1)=='\u0DCA'||(input.LA(1)>='\u0DCF' && input.LA(1)<='\u0DD4')||input.LA(1)=='\u0DD6'||(input.LA(1)>='\u0DD8' && input.LA(1)<='\u0DDF')||(input.LA(1)>='\u0DF2' && input.LA(1)<='\u0DF3')||input.LA(1)=='\u0E31'||(input.LA(1)>='\u0E34' && input.LA(1)<='\u0E3A')||(input.LA(1)>='\u0E47' && input.LA(1)<='\u0E4E')||input.LA(1)=='\u0EB1'||(input.LA(1)>='\u0EB4' && input.LA(1)<='\u0EB9')||(input.LA(1)>='\u0EBB' && input.LA(1)<='\u0EBC')||(input.LA(1)>='\u0EC8' && input.LA(1)<='\u0ECD')||(input.LA(1)>='\u0F18' && input.LA(1)<='\u0F19')||input.LA(1)=='\u0F35'||input.LA(1)=='\u0F37'||input.LA(1)=='\u0F39'||(input.LA(1)>='\u0F3E' && input.LA(1)<='\u0F3F')||(input.LA(1)>='\u0F71' && input.LA(1)<='\u0F84')||(input.LA(1)>='\u0F86' && input.LA(1)<='\u0F87')||(input.LA(1)>='\u0F8D' && input.LA(1)<='\u0F97')||(input.LA(1)>='\u0F99' && input.LA(1)<='\u0FBC')||input.LA(1)=='\u0FC6'||(input.LA(1)>='\u102B' && input.LA(1)<='\u103E')||(input.LA(1)>='\u1056' && input.LA(1)<='\u1059')||(input.LA(1)>='\u105E' && input.LA(1)<='\u1060')||(input.LA(1)>='\u1062' && input.LA(1)<='\u1064')||(input.LA(1)>='\u1067' && input.LA(1)<='\u106D')||(input.LA(1)>='\u1071' && input.LA(1)<='\u1074')||(input.LA(1)>='\u1082' && input.LA(1)<='\u108D')||input.LA(1)=='\u108F'||(input.LA(1)>='\u109A' && input.LA(1)<='\u109D')||(input.LA(1)>='\u135D' && input.LA(1)<='\u135F')||(input.LA(1)>='\u1712' && input.LA(1)<='\u1714')||(input.LA(1)>='\u1732' && input.LA(1)<='\u1734')||(input.LA(1)>='\u1752' && input.LA(1)<='\u1753')||(input.LA(1)>='\u1772' && input.LA(1)<='\u1773')||(input.LA(1)>='\u17B4' && input.LA(1)<='\u17D3')||input.LA(1)=='\u17DD'||(input.LA(1)>='\u180B' && input.LA(1)<='\u180D')||input.LA(1)=='\u18A9'||(input.LA(1)>='\u1920' && input.LA(1)<='\u192B')||(input.LA(1)>='\u1930' && input.LA(1)<='\u193B')||(input.LA(1)>='\u1A17' && input.LA(1)<='\u1A1B')||(input.LA(1)>='\u1A55' && input.LA(1)<='\u1A5E')||(input.LA(1)>='\u1A60' && input.LA(1)<='\u1A7C')||input.LA(1)=='\u1A7F'||(input.LA(1)>='\u1AB0' && input.LA(1)<='\u1ABD')||(input.LA(1)>='\u1B00' && input.LA(1)<='\u1B04')||(input.LA(1)>='\u1B34' && input.LA(1)<='\u1B44')||(input.LA(1)>='\u1B6B' && input.LA(1)<='\u1B73')||(input.LA(1)>='\u1B80' && input.LA(1)<='\u1B82')||(input.LA(1)>='\u1BA1' && input.LA(1)<='\u1BAD')||(input.LA(1)>='\u1BE6' && input.LA(1)<='\u1BF3')||(input.LA(1)>='\u1C24' && input.LA(1)<='\u1C37')||(input.LA(1)>='\u1CD0' && input.LA(1)<='\u1CD2')||(input.LA(1)>='\u1CD4' && input.LA(1)<='\u1CE8')||input.LA(1)=='\u1CED'||(input.LA(1)>='\u1CF2' && input.LA(1)<='\u1CF4')||(input.LA(1)>='\u1CF8' && input.LA(1)<='\u1CF9')||(input.LA(1)>='\u1DC0' && input.LA(1)<='\u1DF5')||(input.LA(1)>='\u1DFC' && input.LA(1)<='\u1DFF')||(input.LA(1)>='\u20D0' && input.LA(1)<='\u20DC')||input.LA(1)=='\u20E1'||(input.LA(1)>='\u20E5' && input.LA(1)<='\u20F0')||(input.LA(1)>='\u2CEF' && input.LA(1)<='\u2CF1')||input.LA(1)=='\u2D7F'||(input.LA(1)>='\u2DE0' && input.LA(1)<='\u2DFF')||(input.LA(1)>='\u302A' && input.LA(1)<='\u302F')||(input.LA(1)>='\u3099' && input.LA(1)<='\u309A')||input.LA(1)=='\uA66F'||(input.LA(1)>='\uA674' && input.LA(1)<='\uA67D')||(input.LA(1)>='\uA69E' && input.LA(1)<='\uA69F')||(input.LA(1)>='\uA6F0' && input.LA(1)<='\uA6F1')||input.LA(1)=='\uA802'||input.LA(1)=='\uA806'||input.LA(1)=='\uA80B'||(input.LA(1)>='\uA823' && input.LA(1)<='\uA827')||(input.LA(1)>='\uA880' && input.LA(1)<='\uA881')||(input.LA(1)>='\uA8B4' && input.LA(1)<='\uA8C4')||(input.LA(1)>='\uA8E0' && input.LA(1)<='\uA8F1')||(input.LA(1)>='\uA926' && input.LA(1)<='\uA92D')||(input.LA(1)>='\uA947' && input.LA(1)<='\uA953')||(input.LA(1)>='\uA980' && input.LA(1)<='\uA983')||(input.LA(1)>='\uA9B3' && input.LA(1)<='\uA9C0')||input.LA(1)=='\uA9E5'||(input.LA(1)>='\uAA29' && input.LA(1)<='\uAA36')||input.LA(1)=='\uAA43'||(input.LA(1)>='\uAA4C' && input.LA(1)<='\uAA4D')||(input.LA(1)>='\uAA7B' && input.LA(1)<='\uAA7D')||input.LA(1)=='\uAAB0'||(input.LA(1)>='\uAAB2' && input.LA(1)<='\uAAB4')||(input.LA(1)>='\uAAB7' && input.LA(1)<='\uAAB8')||(input.LA(1)>='\uAABE' && input.LA(1)<='\uAABF')||input.LA(1)=='\uAAC1'||(input.LA(1)>='\uAAEB' && input.LA(1)<='\uAAEF')||(input.LA(1)>='\uAAF5' && input.LA(1)<='\uAAF6')||(input.LA(1)>='\uABE3' && input.LA(1)<='\uABEA')||(input.LA(1)>='\uABEC' && input.LA(1)<='\uABED')||input.LA(1)=='\uFB1E'||(input.LA(1)>='\uFE00' && input.LA(1)<='\uFE0F')||(input.LA(1)>='\uFE20' && input.LA(1)<='\uFE2F') ) { input.consume(); @@ -1253,8 +1427,8 @@ public final void mRULE_UNICODE_COMBINING_MARK_FRAGMENT() throws RecognitionExce // $ANTLR start "RULE_UNICODE_DIGIT_FRAGMENT" public final void mRULE_UNICODE_DIGIT_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:4741:38: ( ( '0' .. '9' | '\\u0660' .. '\\u0669' | '\\u06F0' .. '\\u06F9' | '\\u07C0' .. '\\u07C9' | '\\u0966' .. '\\u096F' | '\\u09E6' .. '\\u09EF' | '\\u0A66' .. '\\u0A6F' | '\\u0AE6' .. '\\u0AEF' | '\\u0B66' .. '\\u0B6F' | '\\u0BE6' .. '\\u0BEF' | '\\u0C66' .. '\\u0C6F' | '\\u0CE6' .. '\\u0CEF' | '\\u0D66' .. '\\u0D6F' | '\\u0DE6' .. '\\u0DEF' | '\\u0E50' .. '\\u0E59' | '\\u0ED0' .. '\\u0ED9' | '\\u0F20' .. '\\u0F29' | '\\u1040' .. '\\u1049' | '\\u1090' .. '\\u1099' | '\\u17E0' .. '\\u17E9' | '\\u1810' .. '\\u1819' | '\\u1946' .. '\\u194F' | '\\u19D0' .. '\\u19D9' | '\\u1A80' .. '\\u1A89' | '\\u1A90' .. '\\u1A99' | '\\u1B50' .. '\\u1B59' | '\\u1BB0' .. '\\u1BB9' | '\\u1C40' .. '\\u1C49' | '\\u1C50' .. '\\u1C59' | '\\uA620' .. '\\uA629' | '\\uA8D0' .. '\\uA8D9' | '\\uA900' .. '\\uA909' | '\\uA9D0' .. '\\uA9D9' | '\\uA9F0' .. '\\uA9F9' | '\\uAA50' .. '\\uAA59' | '\\uABF0' .. '\\uABF9' | '\\uFF10' .. '\\uFF19' ) ) - // InternalSemver.g:4741:40: ( '0' .. '9' | '\\u0660' .. '\\u0669' | '\\u06F0' .. '\\u06F9' | '\\u07C0' .. '\\u07C9' | '\\u0966' .. '\\u096F' | '\\u09E6' .. '\\u09EF' | '\\u0A66' .. '\\u0A6F' | '\\u0AE6' .. '\\u0AEF' | '\\u0B66' .. '\\u0B6F' | '\\u0BE6' .. '\\u0BEF' | '\\u0C66' .. '\\u0C6F' | '\\u0CE6' .. '\\u0CEF' | '\\u0D66' .. '\\u0D6F' | '\\u0DE6' .. '\\u0DEF' | '\\u0E50' .. '\\u0E59' | '\\u0ED0' .. '\\u0ED9' | '\\u0F20' .. '\\u0F29' | '\\u1040' .. '\\u1049' | '\\u1090' .. '\\u1099' | '\\u17E0' .. '\\u17E9' | '\\u1810' .. '\\u1819' | '\\u1946' .. '\\u194F' | '\\u19D0' .. '\\u19D9' | '\\u1A80' .. '\\u1A89' | '\\u1A90' .. '\\u1A99' | '\\u1B50' .. '\\u1B59' | '\\u1BB0' .. '\\u1BB9' | '\\u1C40' .. '\\u1C49' | '\\u1C50' .. '\\u1C59' | '\\uA620' .. '\\uA629' | '\\uA8D0' .. '\\uA8D9' | '\\uA900' .. '\\uA909' | '\\uA9D0' .. '\\uA9D9' | '\\uA9F0' .. '\\uA9F9' | '\\uAA50' .. '\\uAA59' | '\\uABF0' .. '\\uABF9' | '\\uFF10' .. '\\uFF19' ) + // InternalSemver.g:5257:38: ( ( '0' .. '9' | '\\u0660' .. '\\u0669' | '\\u06F0' .. '\\u06F9' | '\\u07C0' .. '\\u07C9' | '\\u0966' .. '\\u096F' | '\\u09E6' .. '\\u09EF' | '\\u0A66' .. '\\u0A6F' | '\\u0AE6' .. '\\u0AEF' | '\\u0B66' .. '\\u0B6F' | '\\u0BE6' .. '\\u0BEF' | '\\u0C66' .. '\\u0C6F' | '\\u0CE6' .. '\\u0CEF' | '\\u0D66' .. '\\u0D6F' | '\\u0DE6' .. '\\u0DEF' | '\\u0E50' .. '\\u0E59' | '\\u0ED0' .. '\\u0ED9' | '\\u0F20' .. '\\u0F29' | '\\u1040' .. '\\u1049' | '\\u1090' .. '\\u1099' | '\\u17E0' .. '\\u17E9' | '\\u1810' .. '\\u1819' | '\\u1946' .. '\\u194F' | '\\u19D0' .. '\\u19D9' | '\\u1A80' .. '\\u1A89' | '\\u1A90' .. '\\u1A99' | '\\u1B50' .. '\\u1B59' | '\\u1BB0' .. '\\u1BB9' | '\\u1C40' .. '\\u1C49' | '\\u1C50' .. '\\u1C59' | '\\uA620' .. '\\uA629' | '\\uA8D0' .. '\\uA8D9' | '\\uA900' .. '\\uA909' | '\\uA9D0' .. '\\uA9D9' | '\\uA9F0' .. '\\uA9F9' | '\\uAA50' .. '\\uAA59' | '\\uABF0' .. '\\uABF9' | '\\uFF10' .. '\\uFF19' ) ) + // InternalSemver.g:5257:40: ( '0' .. '9' | '\\u0660' .. '\\u0669' | '\\u06F0' .. '\\u06F9' | '\\u07C0' .. '\\u07C9' | '\\u0966' .. '\\u096F' | '\\u09E6' .. '\\u09EF' | '\\u0A66' .. '\\u0A6F' | '\\u0AE6' .. '\\u0AEF' | '\\u0B66' .. '\\u0B6F' | '\\u0BE6' .. '\\u0BEF' | '\\u0C66' .. '\\u0C6F' | '\\u0CE6' .. '\\u0CEF' | '\\u0D66' .. '\\u0D6F' | '\\u0DE6' .. '\\u0DEF' | '\\u0E50' .. '\\u0E59' | '\\u0ED0' .. '\\u0ED9' | '\\u0F20' .. '\\u0F29' | '\\u1040' .. '\\u1049' | '\\u1090' .. '\\u1099' | '\\u17E0' .. '\\u17E9' | '\\u1810' .. '\\u1819' | '\\u1946' .. '\\u194F' | '\\u19D0' .. '\\u19D9' | '\\u1A80' .. '\\u1A89' | '\\u1A90' .. '\\u1A99' | '\\u1B50' .. '\\u1B59' | '\\u1BB0' .. '\\u1BB9' | '\\u1C40' .. '\\u1C49' | '\\u1C50' .. '\\u1C59' | '\\uA620' .. '\\uA629' | '\\uA8D0' .. '\\uA8D9' | '\\uA900' .. '\\uA909' | '\\uA9D0' .. '\\uA9D9' | '\\uA9F0' .. '\\uA9F9' | '\\uAA50' .. '\\uAA59' | '\\uABF0' .. '\\uABF9' | '\\uFF10' .. '\\uFF19' ) { if ( (input.LA(1)>='0' && input.LA(1)<='9')||(input.LA(1)>='\u0660' && input.LA(1)<='\u0669')||(input.LA(1)>='\u06F0' && input.LA(1)<='\u06F9')||(input.LA(1)>='\u07C0' && input.LA(1)<='\u07C9')||(input.LA(1)>='\u0966' && input.LA(1)<='\u096F')||(input.LA(1)>='\u09E6' && input.LA(1)<='\u09EF')||(input.LA(1)>='\u0A66' && input.LA(1)<='\u0A6F')||(input.LA(1)>='\u0AE6' && input.LA(1)<='\u0AEF')||(input.LA(1)>='\u0B66' && input.LA(1)<='\u0B6F')||(input.LA(1)>='\u0BE6' && input.LA(1)<='\u0BEF')||(input.LA(1)>='\u0C66' && input.LA(1)<='\u0C6F')||(input.LA(1)>='\u0CE6' && input.LA(1)<='\u0CEF')||(input.LA(1)>='\u0D66' && input.LA(1)<='\u0D6F')||(input.LA(1)>='\u0DE6' && input.LA(1)<='\u0DEF')||(input.LA(1)>='\u0E50' && input.LA(1)<='\u0E59')||(input.LA(1)>='\u0ED0' && input.LA(1)<='\u0ED9')||(input.LA(1)>='\u0F20' && input.LA(1)<='\u0F29')||(input.LA(1)>='\u1040' && input.LA(1)<='\u1049')||(input.LA(1)>='\u1090' && input.LA(1)<='\u1099')||(input.LA(1)>='\u17E0' && input.LA(1)<='\u17E9')||(input.LA(1)>='\u1810' && input.LA(1)<='\u1819')||(input.LA(1)>='\u1946' && input.LA(1)<='\u194F')||(input.LA(1)>='\u19D0' && input.LA(1)<='\u19D9')||(input.LA(1)>='\u1A80' && input.LA(1)<='\u1A89')||(input.LA(1)>='\u1A90' && input.LA(1)<='\u1A99')||(input.LA(1)>='\u1B50' && input.LA(1)<='\u1B59')||(input.LA(1)>='\u1BB0' && input.LA(1)<='\u1BB9')||(input.LA(1)>='\u1C40' && input.LA(1)<='\u1C49')||(input.LA(1)>='\u1C50' && input.LA(1)<='\u1C59')||(input.LA(1)>='\uA620' && input.LA(1)<='\uA629')||(input.LA(1)>='\uA8D0' && input.LA(1)<='\uA8D9')||(input.LA(1)>='\uA900' && input.LA(1)<='\uA909')||(input.LA(1)>='\uA9D0' && input.LA(1)<='\uA9D9')||(input.LA(1)>='\uA9F0' && input.LA(1)<='\uA9F9')||(input.LA(1)>='\uAA50' && input.LA(1)<='\uAA59')||(input.LA(1)>='\uABF0' && input.LA(1)<='\uABF9')||(input.LA(1)>='\uFF10' && input.LA(1)<='\uFF19') ) { input.consume(); @@ -1277,8 +1451,8 @@ public final void mRULE_UNICODE_DIGIT_FRAGMENT() throws RecognitionException { // $ANTLR start "RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT" public final void mRULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:4743:54: ( ( '_' | '\\u203F' .. '\\u2040' | '\\u2054' | '\\uFE33' .. '\\uFE34' | '\\uFE4D' .. '\\uFE4F' | '\\uFF3F' ) ) - // InternalSemver.g:4743:56: ( '_' | '\\u203F' .. '\\u2040' | '\\u2054' | '\\uFE33' .. '\\uFE34' | '\\uFE4D' .. '\\uFE4F' | '\\uFF3F' ) + // InternalSemver.g:5259:54: ( ( '_' | '\\u203F' .. '\\u2040' | '\\u2054' | '\\uFE33' .. '\\uFE34' | '\\uFE4D' .. '\\uFE4F' | '\\uFF3F' ) ) + // InternalSemver.g:5259:56: ( '_' | '\\u203F' .. '\\u2040' | '\\u2054' | '\\uFE33' .. '\\uFE34' | '\\uFE4D' .. '\\uFE4F' | '\\uFF3F' ) { if ( input.LA(1)=='_'||(input.LA(1)>='\u203F' && input.LA(1)<='\u2040')||input.LA(1)=='\u2054'||(input.LA(1)>='\uFE33' && input.LA(1)<='\uFE34')||(input.LA(1)>='\uFE4D' && input.LA(1)<='\uFE4F')||input.LA(1)=='\uFF3F' ) { input.consume(); @@ -1301,8 +1475,8 @@ public final void mRULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT() throws Recognit // $ANTLR start "RULE_UNICODE_LETTER_FRAGMENT" public final void mRULE_UNICODE_LETTER_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:4745:39: ( ( 'A' .. 'Z' | 'a' .. 'z' | '\\u00AA' | '\\u00B5' | '\\u00BA' | '\\u00C0' .. '\\u00D6' | '\\u00D8' .. '\\u00F6' | '\\u00F8' .. '\\u02C1' | '\\u02C6' .. '\\u02D1' | '\\u02E0' .. '\\u02E4' | '\\u02EC' | '\\u02EE' | '\\u0370' .. '\\u0374' | '\\u0376' .. '\\u0377' | '\\u037A' .. '\\u037D' | '\\u037F' | '\\u0386' | '\\u0388' .. '\\u038A' | '\\u038C' | '\\u038E' .. '\\u03A1' | '\\u03A3' .. '\\u03F5' | '\\u03F7' .. '\\u0481' | '\\u048A' .. '\\u052F' | '\\u0531' .. '\\u0556' | '\\u0559' | '\\u0561' .. '\\u0587' | '\\u05D0' .. '\\u05EA' | '\\u05F0' .. '\\u05F2' | '\\u0620' .. '\\u064A' | '\\u066E' .. '\\u066F' | '\\u0671' .. '\\u06D3' | '\\u06D5' | '\\u06E5' .. '\\u06E6' | '\\u06EE' .. '\\u06EF' | '\\u06FA' .. '\\u06FC' | '\\u06FF' | '\\u0710' | '\\u0712' .. '\\u072F' | '\\u074D' .. '\\u07A5' | '\\u07B1' | '\\u07CA' .. '\\u07EA' | '\\u07F4' .. '\\u07F5' | '\\u07FA' | '\\u0800' .. '\\u0815' | '\\u081A' | '\\u0824' | '\\u0828' | '\\u0840' .. '\\u0858' | '\\u08A0' .. '\\u08B4' | '\\u0904' .. '\\u0939' | '\\u093D' | '\\u0950' | '\\u0958' .. '\\u0961' | '\\u0971' .. '\\u0980' | '\\u0985' .. '\\u098C' | '\\u098F' .. '\\u0990' | '\\u0993' .. '\\u09A8' | '\\u09AA' .. '\\u09B0' | '\\u09B2' | '\\u09B6' .. '\\u09B9' | '\\u09BD' | '\\u09CE' | '\\u09DC' .. '\\u09DD' | '\\u09DF' .. '\\u09E1' | '\\u09F0' .. '\\u09F1' | '\\u0A05' .. '\\u0A0A' | '\\u0A0F' .. '\\u0A10' | '\\u0A13' .. '\\u0A28' | '\\u0A2A' .. '\\u0A30' | '\\u0A32' .. '\\u0A33' | '\\u0A35' .. '\\u0A36' | '\\u0A38' .. '\\u0A39' | '\\u0A59' .. '\\u0A5C' | '\\u0A5E' | '\\u0A72' .. '\\u0A74' | '\\u0A85' .. '\\u0A8D' | '\\u0A8F' .. '\\u0A91' | '\\u0A93' .. '\\u0AA8' | '\\u0AAA' .. '\\u0AB0' | '\\u0AB2' .. '\\u0AB3' | '\\u0AB5' .. '\\u0AB9' | '\\u0ABD' | '\\u0AD0' | '\\u0AE0' .. '\\u0AE1' | '\\u0AF9' | '\\u0B05' .. '\\u0B0C' | '\\u0B0F' .. '\\u0B10' | '\\u0B13' .. '\\u0B28' | '\\u0B2A' .. '\\u0B30' | '\\u0B32' .. '\\u0B33' | '\\u0B35' .. '\\u0B39' | '\\u0B3D' | '\\u0B5C' .. '\\u0B5D' | '\\u0B5F' .. '\\u0B61' | '\\u0B71' | '\\u0B83' | '\\u0B85' .. '\\u0B8A' | '\\u0B8E' .. '\\u0B90' | '\\u0B92' .. '\\u0B95' | '\\u0B99' .. '\\u0B9A' | '\\u0B9C' | '\\u0B9E' .. '\\u0B9F' | '\\u0BA3' .. '\\u0BA4' | '\\u0BA8' .. '\\u0BAA' | '\\u0BAE' .. '\\u0BB9' | '\\u0BD0' | '\\u0C05' .. '\\u0C0C' | '\\u0C0E' .. '\\u0C10' | '\\u0C12' .. '\\u0C28' | '\\u0C2A' .. '\\u0C39' | '\\u0C3D' | '\\u0C58' .. '\\u0C5A' | '\\u0C60' .. '\\u0C61' | '\\u0C85' .. '\\u0C8C' | '\\u0C8E' .. '\\u0C90' | '\\u0C92' .. '\\u0CA8' | '\\u0CAA' .. '\\u0CB3' | '\\u0CB5' .. '\\u0CB9' | '\\u0CBD' | '\\u0CDE' | '\\u0CE0' .. '\\u0CE1' | '\\u0CF1' .. '\\u0CF2' | '\\u0D05' .. '\\u0D0C' | '\\u0D0E' .. '\\u0D10' | '\\u0D12' .. '\\u0D3A' | '\\u0D3D' | '\\u0D4E' | '\\u0D5F' .. '\\u0D61' | '\\u0D7A' .. '\\u0D7F' | '\\u0D85' .. '\\u0D96' | '\\u0D9A' .. '\\u0DB1' | '\\u0DB3' .. '\\u0DBB' | '\\u0DBD' | '\\u0DC0' .. '\\u0DC6' | '\\u0E01' .. '\\u0E30' | '\\u0E32' .. '\\u0E33' | '\\u0E40' .. '\\u0E46' | '\\u0E81' .. '\\u0E82' | '\\u0E84' | '\\u0E87' .. '\\u0E88' | '\\u0E8A' | '\\u0E8D' | '\\u0E94' .. '\\u0E97' | '\\u0E99' .. '\\u0E9F' | '\\u0EA1' .. '\\u0EA3' | '\\u0EA5' | '\\u0EA7' | '\\u0EAA' .. '\\u0EAB' | '\\u0EAD' .. '\\u0EB0' | '\\u0EB2' .. '\\u0EB3' | '\\u0EBD' | '\\u0EC0' .. '\\u0EC4' | '\\u0EC6' | '\\u0EDC' .. '\\u0EDF' | '\\u0F00' | '\\u0F40' .. '\\u0F47' | '\\u0F49' .. '\\u0F6C' | '\\u0F88' .. '\\u0F8C' | '\\u1000' .. '\\u102A' | '\\u103F' | '\\u1050' .. '\\u1055' | '\\u105A' .. '\\u105D' | '\\u1061' | '\\u1065' .. '\\u1066' | '\\u106E' .. '\\u1070' | '\\u1075' .. '\\u1081' | '\\u108E' | '\\u10A0' .. '\\u10C5' | '\\u10C7' | '\\u10CD' | '\\u10D0' .. '\\u10FA' | '\\u10FC' .. '\\u1248' | '\\u124A' .. '\\u124D' | '\\u1250' .. '\\u1256' | '\\u1258' | '\\u125A' .. '\\u125D' | '\\u1260' .. '\\u1288' | '\\u128A' .. '\\u128D' | '\\u1290' .. '\\u12B0' | '\\u12B2' .. '\\u12B5' | '\\u12B8' .. '\\u12BE' | '\\u12C0' | '\\u12C2' .. '\\u12C5' | '\\u12C8' .. '\\u12D6' | '\\u12D8' .. '\\u1310' | '\\u1312' .. '\\u1315' | '\\u1318' .. '\\u135A' | '\\u1380' .. '\\u138F' | '\\u13A0' .. '\\u13F5' | '\\u13F8' .. '\\u13FD' | '\\u1401' .. '\\u166C' | '\\u166F' .. '\\u167F' | '\\u1681' .. '\\u169A' | '\\u16A0' .. '\\u16EA' | '\\u16EE' .. '\\u16F8' | '\\u1700' .. '\\u170C' | '\\u170E' .. '\\u1711' | '\\u1720' .. '\\u1731' | '\\u1740' .. '\\u1751' | '\\u1760' .. '\\u176C' | '\\u176E' .. '\\u1770' | '\\u1780' .. '\\u17B3' | '\\u17D7' | '\\u17DC' | '\\u1820' .. '\\u1877' | '\\u1880' .. '\\u18A8' | '\\u18AA' | '\\u18B0' .. '\\u18F5' | '\\u1900' .. '\\u191E' | '\\u1950' .. '\\u196D' | '\\u1970' .. '\\u1974' | '\\u1980' .. '\\u19AB' | '\\u19B0' .. '\\u19C9' | '\\u1A00' .. '\\u1A16' | '\\u1A20' .. '\\u1A54' | '\\u1AA7' | '\\u1B05' .. '\\u1B33' | '\\u1B45' .. '\\u1B4B' | '\\u1B83' .. '\\u1BA0' | '\\u1BAE' .. '\\u1BAF' | '\\u1BBA' .. '\\u1BE5' | '\\u1C00' .. '\\u1C23' | '\\u1C4D' .. '\\u1C4F' | '\\u1C5A' .. '\\u1C7D' | '\\u1CE9' .. '\\u1CEC' | '\\u1CEE' .. '\\u1CF1' | '\\u1CF5' .. '\\u1CF6' | '\\u1D00' .. '\\u1DBF' | '\\u1E00' .. '\\u1F15' | '\\u1F18' .. '\\u1F1D' | '\\u1F20' .. '\\u1F45' | '\\u1F48' .. '\\u1F4D' | '\\u1F50' .. '\\u1F57' | '\\u1F59' | '\\u1F5B' | '\\u1F5D' | '\\u1F5F' .. '\\u1F7D' | '\\u1F80' .. '\\u1FB4' | '\\u1FB6' .. '\\u1FBC' | '\\u1FBE' | '\\u1FC2' .. '\\u1FC4' | '\\u1FC6' .. '\\u1FCC' | '\\u1FD0' .. '\\u1FD3' | '\\u1FD6' .. '\\u1FDB' | '\\u1FE0' .. '\\u1FEC' | '\\u1FF2' .. '\\u1FF4' | '\\u1FF6' .. '\\u1FFC' | '\\u2071' | '\\u207F' | '\\u2090' .. '\\u209C' | '\\u2102' | '\\u2107' | '\\u210A' .. '\\u2113' | '\\u2115' | '\\u2119' .. '\\u211D' | '\\u2124' | '\\u2126' | '\\u2128' | '\\u212A' .. '\\u212D' | '\\u212F' .. '\\u2139' | '\\u213C' .. '\\u213F' | '\\u2145' .. '\\u2149' | '\\u214E' | '\\u2160' .. '\\u2188' | '\\u2C00' .. '\\u2C2E' | '\\u2C30' .. '\\u2C5E' | '\\u2C60' .. '\\u2CE4' | '\\u2CEB' .. '\\u2CEE' | '\\u2CF2' .. '\\u2CF3' | '\\u2D00' .. '\\u2D25' | '\\u2D27' | '\\u2D2D' | '\\u2D30' .. '\\u2D67' | '\\u2D6F' | '\\u2D80' .. '\\u2D96' | '\\u2DA0' .. '\\u2DA6' | '\\u2DA8' .. '\\u2DAE' | '\\u2DB0' .. '\\u2DB6' | '\\u2DB8' .. '\\u2DBE' | '\\u2DC0' .. '\\u2DC6' | '\\u2DC8' .. '\\u2DCE' | '\\u2DD0' .. '\\u2DD6' | '\\u2DD8' .. '\\u2DDE' | '\\u2E2F' | '\\u3005' .. '\\u3007' | '\\u3021' .. '\\u3029' | '\\u3031' .. '\\u3035' | '\\u3038' .. '\\u303C' | '\\u3041' .. '\\u3096' | '\\u309D' .. '\\u309F' | '\\u30A1' .. '\\u30FA' | '\\u30FC' .. '\\u30FF' | '\\u3105' .. '\\u312D' | '\\u3131' .. '\\u318E' | '\\u31A0' .. '\\u31BA' | '\\u31F0' .. '\\u31FF' | '\\u3400' .. '\\u4DB5' | '\\u4E00' .. '\\u9FD5' | '\\uA000' .. '\\uA48C' | '\\uA4D0' .. '\\uA4FD' | '\\uA500' .. '\\uA60C' | '\\uA610' .. '\\uA61F' | '\\uA62A' .. '\\uA62B' | '\\uA640' .. '\\uA66E' | '\\uA67F' .. '\\uA69D' | '\\uA6A0' .. '\\uA6EF' | '\\uA717' .. '\\uA71F' | '\\uA722' .. '\\uA788' | '\\uA78B' .. '\\uA7AD' | '\\uA7B0' .. '\\uA7B7' | '\\uA7F7' .. '\\uA801' | '\\uA803' .. '\\uA805' | '\\uA807' .. '\\uA80A' | '\\uA80C' .. '\\uA822' | '\\uA840' .. '\\uA873' | '\\uA882' .. '\\uA8B3' | '\\uA8F2' .. '\\uA8F7' | '\\uA8FB' | '\\uA8FD' | '\\uA90A' .. '\\uA925' | '\\uA930' .. '\\uA946' | '\\uA960' .. '\\uA97C' | '\\uA984' .. '\\uA9B2' | '\\uA9CF' | '\\uA9E0' .. '\\uA9E4' | '\\uA9E6' .. '\\uA9EF' | '\\uA9FA' .. '\\uA9FE' | '\\uAA00' .. '\\uAA28' | '\\uAA40' .. '\\uAA42' | '\\uAA44' .. '\\uAA4B' | '\\uAA60' .. '\\uAA76' | '\\uAA7A' | '\\uAA7E' .. '\\uAAAF' | '\\uAAB1' | '\\uAAB5' .. '\\uAAB6' | '\\uAAB9' .. '\\uAABD' | '\\uAAC0' | '\\uAAC2' | '\\uAADB' .. '\\uAADD' | '\\uAAE0' .. '\\uAAEA' | '\\uAAF2' .. '\\uAAF4' | '\\uAB01' .. '\\uAB06' | '\\uAB09' .. '\\uAB0E' | '\\uAB11' .. '\\uAB16' | '\\uAB20' .. '\\uAB26' | '\\uAB28' .. '\\uAB2E' | '\\uAB30' .. '\\uAB5A' | '\\uAB5C' .. '\\uAB65' | '\\uAB70' .. '\\uABE2' | '\\uAC00' .. '\\uD7A3' | '\\uD7B0' .. '\\uD7C6' | '\\uD7CB' .. '\\uD7FB' | '\\uF900' .. '\\uFA6D' | '\\uFA70' .. '\\uFAD9' | '\\uFB00' .. '\\uFB06' | '\\uFB13' .. '\\uFB17' | '\\uFB1D' | '\\uFB1F' .. '\\uFB28' | '\\uFB2A' .. '\\uFB36' | '\\uFB38' .. '\\uFB3C' | '\\uFB3E' | '\\uFB40' .. '\\uFB41' | '\\uFB43' .. '\\uFB44' | '\\uFB46' .. '\\uFBB1' | '\\uFBD3' .. '\\uFD3D' | '\\uFD50' .. '\\uFD8F' | '\\uFD92' .. '\\uFDC7' | '\\uFDF0' .. '\\uFDFB' | '\\uFE70' .. '\\uFE74' | '\\uFE76' .. '\\uFEFC' | '\\uFF21' .. '\\uFF3A' | '\\uFF41' .. '\\uFF5A' | '\\uFF66' .. '\\uFFBE' | '\\uFFC2' .. '\\uFFC7' | '\\uFFCA' .. '\\uFFCF' | '\\uFFD2' .. '\\uFFD7' | '\\uFFDA' .. '\\uFFDC' ) ) - // InternalSemver.g:4745:41: ( 'A' .. 'Z' | 'a' .. 'z' | '\\u00AA' | '\\u00B5' | '\\u00BA' | '\\u00C0' .. '\\u00D6' | '\\u00D8' .. '\\u00F6' | '\\u00F8' .. '\\u02C1' | '\\u02C6' .. '\\u02D1' | '\\u02E0' .. '\\u02E4' | '\\u02EC' | '\\u02EE' | '\\u0370' .. '\\u0374' | '\\u0376' .. '\\u0377' | '\\u037A' .. '\\u037D' | '\\u037F' | '\\u0386' | '\\u0388' .. '\\u038A' | '\\u038C' | '\\u038E' .. '\\u03A1' | '\\u03A3' .. '\\u03F5' | '\\u03F7' .. '\\u0481' | '\\u048A' .. '\\u052F' | '\\u0531' .. '\\u0556' | '\\u0559' | '\\u0561' .. '\\u0587' | '\\u05D0' .. '\\u05EA' | '\\u05F0' .. '\\u05F2' | '\\u0620' .. '\\u064A' | '\\u066E' .. '\\u066F' | '\\u0671' .. '\\u06D3' | '\\u06D5' | '\\u06E5' .. '\\u06E6' | '\\u06EE' .. '\\u06EF' | '\\u06FA' .. '\\u06FC' | '\\u06FF' | '\\u0710' | '\\u0712' .. '\\u072F' | '\\u074D' .. '\\u07A5' | '\\u07B1' | '\\u07CA' .. '\\u07EA' | '\\u07F4' .. '\\u07F5' | '\\u07FA' | '\\u0800' .. '\\u0815' | '\\u081A' | '\\u0824' | '\\u0828' | '\\u0840' .. '\\u0858' | '\\u08A0' .. '\\u08B4' | '\\u0904' .. '\\u0939' | '\\u093D' | '\\u0950' | '\\u0958' .. '\\u0961' | '\\u0971' .. '\\u0980' | '\\u0985' .. '\\u098C' | '\\u098F' .. '\\u0990' | '\\u0993' .. '\\u09A8' | '\\u09AA' .. '\\u09B0' | '\\u09B2' | '\\u09B6' .. '\\u09B9' | '\\u09BD' | '\\u09CE' | '\\u09DC' .. '\\u09DD' | '\\u09DF' .. '\\u09E1' | '\\u09F0' .. '\\u09F1' | '\\u0A05' .. '\\u0A0A' | '\\u0A0F' .. '\\u0A10' | '\\u0A13' .. '\\u0A28' | '\\u0A2A' .. '\\u0A30' | '\\u0A32' .. '\\u0A33' | '\\u0A35' .. '\\u0A36' | '\\u0A38' .. '\\u0A39' | '\\u0A59' .. '\\u0A5C' | '\\u0A5E' | '\\u0A72' .. '\\u0A74' | '\\u0A85' .. '\\u0A8D' | '\\u0A8F' .. '\\u0A91' | '\\u0A93' .. '\\u0AA8' | '\\u0AAA' .. '\\u0AB0' | '\\u0AB2' .. '\\u0AB3' | '\\u0AB5' .. '\\u0AB9' | '\\u0ABD' | '\\u0AD0' | '\\u0AE0' .. '\\u0AE1' | '\\u0AF9' | '\\u0B05' .. '\\u0B0C' | '\\u0B0F' .. '\\u0B10' | '\\u0B13' .. '\\u0B28' | '\\u0B2A' .. '\\u0B30' | '\\u0B32' .. '\\u0B33' | '\\u0B35' .. '\\u0B39' | '\\u0B3D' | '\\u0B5C' .. '\\u0B5D' | '\\u0B5F' .. '\\u0B61' | '\\u0B71' | '\\u0B83' | '\\u0B85' .. '\\u0B8A' | '\\u0B8E' .. '\\u0B90' | '\\u0B92' .. '\\u0B95' | '\\u0B99' .. '\\u0B9A' | '\\u0B9C' | '\\u0B9E' .. '\\u0B9F' | '\\u0BA3' .. '\\u0BA4' | '\\u0BA8' .. '\\u0BAA' | '\\u0BAE' .. '\\u0BB9' | '\\u0BD0' | '\\u0C05' .. '\\u0C0C' | '\\u0C0E' .. '\\u0C10' | '\\u0C12' .. '\\u0C28' | '\\u0C2A' .. '\\u0C39' | '\\u0C3D' | '\\u0C58' .. '\\u0C5A' | '\\u0C60' .. '\\u0C61' | '\\u0C85' .. '\\u0C8C' | '\\u0C8E' .. '\\u0C90' | '\\u0C92' .. '\\u0CA8' | '\\u0CAA' .. '\\u0CB3' | '\\u0CB5' .. '\\u0CB9' | '\\u0CBD' | '\\u0CDE' | '\\u0CE0' .. '\\u0CE1' | '\\u0CF1' .. '\\u0CF2' | '\\u0D05' .. '\\u0D0C' | '\\u0D0E' .. '\\u0D10' | '\\u0D12' .. '\\u0D3A' | '\\u0D3D' | '\\u0D4E' | '\\u0D5F' .. '\\u0D61' | '\\u0D7A' .. '\\u0D7F' | '\\u0D85' .. '\\u0D96' | '\\u0D9A' .. '\\u0DB1' | '\\u0DB3' .. '\\u0DBB' | '\\u0DBD' | '\\u0DC0' .. '\\u0DC6' | '\\u0E01' .. '\\u0E30' | '\\u0E32' .. '\\u0E33' | '\\u0E40' .. '\\u0E46' | '\\u0E81' .. '\\u0E82' | '\\u0E84' | '\\u0E87' .. '\\u0E88' | '\\u0E8A' | '\\u0E8D' | '\\u0E94' .. '\\u0E97' | '\\u0E99' .. '\\u0E9F' | '\\u0EA1' .. '\\u0EA3' | '\\u0EA5' | '\\u0EA7' | '\\u0EAA' .. '\\u0EAB' | '\\u0EAD' .. '\\u0EB0' | '\\u0EB2' .. '\\u0EB3' | '\\u0EBD' | '\\u0EC0' .. '\\u0EC4' | '\\u0EC6' | '\\u0EDC' .. '\\u0EDF' | '\\u0F00' | '\\u0F40' .. '\\u0F47' | '\\u0F49' .. '\\u0F6C' | '\\u0F88' .. '\\u0F8C' | '\\u1000' .. '\\u102A' | '\\u103F' | '\\u1050' .. '\\u1055' | '\\u105A' .. '\\u105D' | '\\u1061' | '\\u1065' .. '\\u1066' | '\\u106E' .. '\\u1070' | '\\u1075' .. '\\u1081' | '\\u108E' | '\\u10A0' .. '\\u10C5' | '\\u10C7' | '\\u10CD' | '\\u10D0' .. '\\u10FA' | '\\u10FC' .. '\\u1248' | '\\u124A' .. '\\u124D' | '\\u1250' .. '\\u1256' | '\\u1258' | '\\u125A' .. '\\u125D' | '\\u1260' .. '\\u1288' | '\\u128A' .. '\\u128D' | '\\u1290' .. '\\u12B0' | '\\u12B2' .. '\\u12B5' | '\\u12B8' .. '\\u12BE' | '\\u12C0' | '\\u12C2' .. '\\u12C5' | '\\u12C8' .. '\\u12D6' | '\\u12D8' .. '\\u1310' | '\\u1312' .. '\\u1315' | '\\u1318' .. '\\u135A' | '\\u1380' .. '\\u138F' | '\\u13A0' .. '\\u13F5' | '\\u13F8' .. '\\u13FD' | '\\u1401' .. '\\u166C' | '\\u166F' .. '\\u167F' | '\\u1681' .. '\\u169A' | '\\u16A0' .. '\\u16EA' | '\\u16EE' .. '\\u16F8' | '\\u1700' .. '\\u170C' | '\\u170E' .. '\\u1711' | '\\u1720' .. '\\u1731' | '\\u1740' .. '\\u1751' | '\\u1760' .. '\\u176C' | '\\u176E' .. '\\u1770' | '\\u1780' .. '\\u17B3' | '\\u17D7' | '\\u17DC' | '\\u1820' .. '\\u1877' | '\\u1880' .. '\\u18A8' | '\\u18AA' | '\\u18B0' .. '\\u18F5' | '\\u1900' .. '\\u191E' | '\\u1950' .. '\\u196D' | '\\u1970' .. '\\u1974' | '\\u1980' .. '\\u19AB' | '\\u19B0' .. '\\u19C9' | '\\u1A00' .. '\\u1A16' | '\\u1A20' .. '\\u1A54' | '\\u1AA7' | '\\u1B05' .. '\\u1B33' | '\\u1B45' .. '\\u1B4B' | '\\u1B83' .. '\\u1BA0' | '\\u1BAE' .. '\\u1BAF' | '\\u1BBA' .. '\\u1BE5' | '\\u1C00' .. '\\u1C23' | '\\u1C4D' .. '\\u1C4F' | '\\u1C5A' .. '\\u1C7D' | '\\u1CE9' .. '\\u1CEC' | '\\u1CEE' .. '\\u1CF1' | '\\u1CF5' .. '\\u1CF6' | '\\u1D00' .. '\\u1DBF' | '\\u1E00' .. '\\u1F15' | '\\u1F18' .. '\\u1F1D' | '\\u1F20' .. '\\u1F45' | '\\u1F48' .. '\\u1F4D' | '\\u1F50' .. '\\u1F57' | '\\u1F59' | '\\u1F5B' | '\\u1F5D' | '\\u1F5F' .. '\\u1F7D' | '\\u1F80' .. '\\u1FB4' | '\\u1FB6' .. '\\u1FBC' | '\\u1FBE' | '\\u1FC2' .. '\\u1FC4' | '\\u1FC6' .. '\\u1FCC' | '\\u1FD0' .. '\\u1FD3' | '\\u1FD6' .. '\\u1FDB' | '\\u1FE0' .. '\\u1FEC' | '\\u1FF2' .. '\\u1FF4' | '\\u1FF6' .. '\\u1FFC' | '\\u2071' | '\\u207F' | '\\u2090' .. '\\u209C' | '\\u2102' | '\\u2107' | '\\u210A' .. '\\u2113' | '\\u2115' | '\\u2119' .. '\\u211D' | '\\u2124' | '\\u2126' | '\\u2128' | '\\u212A' .. '\\u212D' | '\\u212F' .. '\\u2139' | '\\u213C' .. '\\u213F' | '\\u2145' .. '\\u2149' | '\\u214E' | '\\u2160' .. '\\u2188' | '\\u2C00' .. '\\u2C2E' | '\\u2C30' .. '\\u2C5E' | '\\u2C60' .. '\\u2CE4' | '\\u2CEB' .. '\\u2CEE' | '\\u2CF2' .. '\\u2CF3' | '\\u2D00' .. '\\u2D25' | '\\u2D27' | '\\u2D2D' | '\\u2D30' .. '\\u2D67' | '\\u2D6F' | '\\u2D80' .. '\\u2D96' | '\\u2DA0' .. '\\u2DA6' | '\\u2DA8' .. '\\u2DAE' | '\\u2DB0' .. '\\u2DB6' | '\\u2DB8' .. '\\u2DBE' | '\\u2DC0' .. '\\u2DC6' | '\\u2DC8' .. '\\u2DCE' | '\\u2DD0' .. '\\u2DD6' | '\\u2DD8' .. '\\u2DDE' | '\\u2E2F' | '\\u3005' .. '\\u3007' | '\\u3021' .. '\\u3029' | '\\u3031' .. '\\u3035' | '\\u3038' .. '\\u303C' | '\\u3041' .. '\\u3096' | '\\u309D' .. '\\u309F' | '\\u30A1' .. '\\u30FA' | '\\u30FC' .. '\\u30FF' | '\\u3105' .. '\\u312D' | '\\u3131' .. '\\u318E' | '\\u31A0' .. '\\u31BA' | '\\u31F0' .. '\\u31FF' | '\\u3400' .. '\\u4DB5' | '\\u4E00' .. '\\u9FD5' | '\\uA000' .. '\\uA48C' | '\\uA4D0' .. '\\uA4FD' | '\\uA500' .. '\\uA60C' | '\\uA610' .. '\\uA61F' | '\\uA62A' .. '\\uA62B' | '\\uA640' .. '\\uA66E' | '\\uA67F' .. '\\uA69D' | '\\uA6A0' .. '\\uA6EF' | '\\uA717' .. '\\uA71F' | '\\uA722' .. '\\uA788' | '\\uA78B' .. '\\uA7AD' | '\\uA7B0' .. '\\uA7B7' | '\\uA7F7' .. '\\uA801' | '\\uA803' .. '\\uA805' | '\\uA807' .. '\\uA80A' | '\\uA80C' .. '\\uA822' | '\\uA840' .. '\\uA873' | '\\uA882' .. '\\uA8B3' | '\\uA8F2' .. '\\uA8F7' | '\\uA8FB' | '\\uA8FD' | '\\uA90A' .. '\\uA925' | '\\uA930' .. '\\uA946' | '\\uA960' .. '\\uA97C' | '\\uA984' .. '\\uA9B2' | '\\uA9CF' | '\\uA9E0' .. '\\uA9E4' | '\\uA9E6' .. '\\uA9EF' | '\\uA9FA' .. '\\uA9FE' | '\\uAA00' .. '\\uAA28' | '\\uAA40' .. '\\uAA42' | '\\uAA44' .. '\\uAA4B' | '\\uAA60' .. '\\uAA76' | '\\uAA7A' | '\\uAA7E' .. '\\uAAAF' | '\\uAAB1' | '\\uAAB5' .. '\\uAAB6' | '\\uAAB9' .. '\\uAABD' | '\\uAAC0' | '\\uAAC2' | '\\uAADB' .. '\\uAADD' | '\\uAAE0' .. '\\uAAEA' | '\\uAAF2' .. '\\uAAF4' | '\\uAB01' .. '\\uAB06' | '\\uAB09' .. '\\uAB0E' | '\\uAB11' .. '\\uAB16' | '\\uAB20' .. '\\uAB26' | '\\uAB28' .. '\\uAB2E' | '\\uAB30' .. '\\uAB5A' | '\\uAB5C' .. '\\uAB65' | '\\uAB70' .. '\\uABE2' | '\\uAC00' .. '\\uD7A3' | '\\uD7B0' .. '\\uD7C6' | '\\uD7CB' .. '\\uD7FB' | '\\uF900' .. '\\uFA6D' | '\\uFA70' .. '\\uFAD9' | '\\uFB00' .. '\\uFB06' | '\\uFB13' .. '\\uFB17' | '\\uFB1D' | '\\uFB1F' .. '\\uFB28' | '\\uFB2A' .. '\\uFB36' | '\\uFB38' .. '\\uFB3C' | '\\uFB3E' | '\\uFB40' .. '\\uFB41' | '\\uFB43' .. '\\uFB44' | '\\uFB46' .. '\\uFBB1' | '\\uFBD3' .. '\\uFD3D' | '\\uFD50' .. '\\uFD8F' | '\\uFD92' .. '\\uFDC7' | '\\uFDF0' .. '\\uFDFB' | '\\uFE70' .. '\\uFE74' | '\\uFE76' .. '\\uFEFC' | '\\uFF21' .. '\\uFF3A' | '\\uFF41' .. '\\uFF5A' | '\\uFF66' .. '\\uFFBE' | '\\uFFC2' .. '\\uFFC7' | '\\uFFCA' .. '\\uFFCF' | '\\uFFD2' .. '\\uFFD7' | '\\uFFDA' .. '\\uFFDC' ) + // InternalSemver.g:5261:39: ( ( 'A' .. 'Z' | 'a' .. 'z' | '\\u00AA' | '\\u00B5' | '\\u00BA' | '\\u00C0' .. '\\u00D6' | '\\u00D8' .. '\\u00F6' | '\\u00F8' .. '\\u02C1' | '\\u02C6' .. '\\u02D1' | '\\u02E0' .. '\\u02E4' | '\\u02EC' | '\\u02EE' | '\\u0370' .. '\\u0374' | '\\u0376' .. '\\u0377' | '\\u037A' .. '\\u037D' | '\\u037F' | '\\u0386' | '\\u0388' .. '\\u038A' | '\\u038C' | '\\u038E' .. '\\u03A1' | '\\u03A3' .. '\\u03F5' | '\\u03F7' .. '\\u0481' | '\\u048A' .. '\\u052F' | '\\u0531' .. '\\u0556' | '\\u0559' | '\\u0561' .. '\\u0587' | '\\u05D0' .. '\\u05EA' | '\\u05F0' .. '\\u05F2' | '\\u0620' .. '\\u064A' | '\\u066E' .. '\\u066F' | '\\u0671' .. '\\u06D3' | '\\u06D5' | '\\u06E5' .. '\\u06E6' | '\\u06EE' .. '\\u06EF' | '\\u06FA' .. '\\u06FC' | '\\u06FF' | '\\u0710' | '\\u0712' .. '\\u072F' | '\\u074D' .. '\\u07A5' | '\\u07B1' | '\\u07CA' .. '\\u07EA' | '\\u07F4' .. '\\u07F5' | '\\u07FA' | '\\u0800' .. '\\u0815' | '\\u081A' | '\\u0824' | '\\u0828' | '\\u0840' .. '\\u0858' | '\\u08A0' .. '\\u08B4' | '\\u0904' .. '\\u0939' | '\\u093D' | '\\u0950' | '\\u0958' .. '\\u0961' | '\\u0971' .. '\\u0980' | '\\u0985' .. '\\u098C' | '\\u098F' .. '\\u0990' | '\\u0993' .. '\\u09A8' | '\\u09AA' .. '\\u09B0' | '\\u09B2' | '\\u09B6' .. '\\u09B9' | '\\u09BD' | '\\u09CE' | '\\u09DC' .. '\\u09DD' | '\\u09DF' .. '\\u09E1' | '\\u09F0' .. '\\u09F1' | '\\u0A05' .. '\\u0A0A' | '\\u0A0F' .. '\\u0A10' | '\\u0A13' .. '\\u0A28' | '\\u0A2A' .. '\\u0A30' | '\\u0A32' .. '\\u0A33' | '\\u0A35' .. '\\u0A36' | '\\u0A38' .. '\\u0A39' | '\\u0A59' .. '\\u0A5C' | '\\u0A5E' | '\\u0A72' .. '\\u0A74' | '\\u0A85' .. '\\u0A8D' | '\\u0A8F' .. '\\u0A91' | '\\u0A93' .. '\\u0AA8' | '\\u0AAA' .. '\\u0AB0' | '\\u0AB2' .. '\\u0AB3' | '\\u0AB5' .. '\\u0AB9' | '\\u0ABD' | '\\u0AD0' | '\\u0AE0' .. '\\u0AE1' | '\\u0AF9' | '\\u0B05' .. '\\u0B0C' | '\\u0B0F' .. '\\u0B10' | '\\u0B13' .. '\\u0B28' | '\\u0B2A' .. '\\u0B30' | '\\u0B32' .. '\\u0B33' | '\\u0B35' .. '\\u0B39' | '\\u0B3D' | '\\u0B5C' .. '\\u0B5D' | '\\u0B5F' .. '\\u0B61' | '\\u0B71' | '\\u0B83' | '\\u0B85' .. '\\u0B8A' | '\\u0B8E' .. '\\u0B90' | '\\u0B92' .. '\\u0B95' | '\\u0B99' .. '\\u0B9A' | '\\u0B9C' | '\\u0B9E' .. '\\u0B9F' | '\\u0BA3' .. '\\u0BA4' | '\\u0BA8' .. '\\u0BAA' | '\\u0BAE' .. '\\u0BB9' | '\\u0BD0' | '\\u0C05' .. '\\u0C0C' | '\\u0C0E' .. '\\u0C10' | '\\u0C12' .. '\\u0C28' | '\\u0C2A' .. '\\u0C39' | '\\u0C3D' | '\\u0C58' .. '\\u0C5A' | '\\u0C60' .. '\\u0C61' | '\\u0C85' .. '\\u0C8C' | '\\u0C8E' .. '\\u0C90' | '\\u0C92' .. '\\u0CA8' | '\\u0CAA' .. '\\u0CB3' | '\\u0CB5' .. '\\u0CB9' | '\\u0CBD' | '\\u0CDE' | '\\u0CE0' .. '\\u0CE1' | '\\u0CF1' .. '\\u0CF2' | '\\u0D05' .. '\\u0D0C' | '\\u0D0E' .. '\\u0D10' | '\\u0D12' .. '\\u0D3A' | '\\u0D3D' | '\\u0D4E' | '\\u0D5F' .. '\\u0D61' | '\\u0D7A' .. '\\u0D7F' | '\\u0D85' .. '\\u0D96' | '\\u0D9A' .. '\\u0DB1' | '\\u0DB3' .. '\\u0DBB' | '\\u0DBD' | '\\u0DC0' .. '\\u0DC6' | '\\u0E01' .. '\\u0E30' | '\\u0E32' .. '\\u0E33' | '\\u0E40' .. '\\u0E46' | '\\u0E81' .. '\\u0E82' | '\\u0E84' | '\\u0E87' .. '\\u0E88' | '\\u0E8A' | '\\u0E8D' | '\\u0E94' .. '\\u0E97' | '\\u0E99' .. '\\u0E9F' | '\\u0EA1' .. '\\u0EA3' | '\\u0EA5' | '\\u0EA7' | '\\u0EAA' .. '\\u0EAB' | '\\u0EAD' .. '\\u0EB0' | '\\u0EB2' .. '\\u0EB3' | '\\u0EBD' | '\\u0EC0' .. '\\u0EC4' | '\\u0EC6' | '\\u0EDC' .. '\\u0EDF' | '\\u0F00' | '\\u0F40' .. '\\u0F47' | '\\u0F49' .. '\\u0F6C' | '\\u0F88' .. '\\u0F8C' | '\\u1000' .. '\\u102A' | '\\u103F' | '\\u1050' .. '\\u1055' | '\\u105A' .. '\\u105D' | '\\u1061' | '\\u1065' .. '\\u1066' | '\\u106E' .. '\\u1070' | '\\u1075' .. '\\u1081' | '\\u108E' | '\\u10A0' .. '\\u10C5' | '\\u10C7' | '\\u10CD' | '\\u10D0' .. '\\u10FA' | '\\u10FC' .. '\\u1248' | '\\u124A' .. '\\u124D' | '\\u1250' .. '\\u1256' | '\\u1258' | '\\u125A' .. '\\u125D' | '\\u1260' .. '\\u1288' | '\\u128A' .. '\\u128D' | '\\u1290' .. '\\u12B0' | '\\u12B2' .. '\\u12B5' | '\\u12B8' .. '\\u12BE' | '\\u12C0' | '\\u12C2' .. '\\u12C5' | '\\u12C8' .. '\\u12D6' | '\\u12D8' .. '\\u1310' | '\\u1312' .. '\\u1315' | '\\u1318' .. '\\u135A' | '\\u1380' .. '\\u138F' | '\\u13A0' .. '\\u13F5' | '\\u13F8' .. '\\u13FD' | '\\u1401' .. '\\u166C' | '\\u166F' .. '\\u167F' | '\\u1681' .. '\\u169A' | '\\u16A0' .. '\\u16EA' | '\\u16EE' .. '\\u16F8' | '\\u1700' .. '\\u170C' | '\\u170E' .. '\\u1711' | '\\u1720' .. '\\u1731' | '\\u1740' .. '\\u1751' | '\\u1760' .. '\\u176C' | '\\u176E' .. '\\u1770' | '\\u1780' .. '\\u17B3' | '\\u17D7' | '\\u17DC' | '\\u1820' .. '\\u1877' | '\\u1880' .. '\\u18A8' | '\\u18AA' | '\\u18B0' .. '\\u18F5' | '\\u1900' .. '\\u191E' | '\\u1950' .. '\\u196D' | '\\u1970' .. '\\u1974' | '\\u1980' .. '\\u19AB' | '\\u19B0' .. '\\u19C9' | '\\u1A00' .. '\\u1A16' | '\\u1A20' .. '\\u1A54' | '\\u1AA7' | '\\u1B05' .. '\\u1B33' | '\\u1B45' .. '\\u1B4B' | '\\u1B83' .. '\\u1BA0' | '\\u1BAE' .. '\\u1BAF' | '\\u1BBA' .. '\\u1BE5' | '\\u1C00' .. '\\u1C23' | '\\u1C4D' .. '\\u1C4F' | '\\u1C5A' .. '\\u1C7D' | '\\u1CE9' .. '\\u1CEC' | '\\u1CEE' .. '\\u1CF1' | '\\u1CF5' .. '\\u1CF6' | '\\u1D00' .. '\\u1DBF' | '\\u1E00' .. '\\u1F15' | '\\u1F18' .. '\\u1F1D' | '\\u1F20' .. '\\u1F45' | '\\u1F48' .. '\\u1F4D' | '\\u1F50' .. '\\u1F57' | '\\u1F59' | '\\u1F5B' | '\\u1F5D' | '\\u1F5F' .. '\\u1F7D' | '\\u1F80' .. '\\u1FB4' | '\\u1FB6' .. '\\u1FBC' | '\\u1FBE' | '\\u1FC2' .. '\\u1FC4' | '\\u1FC6' .. '\\u1FCC' | '\\u1FD0' .. '\\u1FD3' | '\\u1FD6' .. '\\u1FDB' | '\\u1FE0' .. '\\u1FEC' | '\\u1FF2' .. '\\u1FF4' | '\\u1FF6' .. '\\u1FFC' | '\\u2071' | '\\u207F' | '\\u2090' .. '\\u209C' | '\\u2102' | '\\u2107' | '\\u210A' .. '\\u2113' | '\\u2115' | '\\u2119' .. '\\u211D' | '\\u2124' | '\\u2126' | '\\u2128' | '\\u212A' .. '\\u212D' | '\\u212F' .. '\\u2139' | '\\u213C' .. '\\u213F' | '\\u2145' .. '\\u2149' | '\\u214E' | '\\u2160' .. '\\u2188' | '\\u2C00' .. '\\u2C2E' | '\\u2C30' .. '\\u2C5E' | '\\u2C60' .. '\\u2CE4' | '\\u2CEB' .. '\\u2CEE' | '\\u2CF2' .. '\\u2CF3' | '\\u2D00' .. '\\u2D25' | '\\u2D27' | '\\u2D2D' | '\\u2D30' .. '\\u2D67' | '\\u2D6F' | '\\u2D80' .. '\\u2D96' | '\\u2DA0' .. '\\u2DA6' | '\\u2DA8' .. '\\u2DAE' | '\\u2DB0' .. '\\u2DB6' | '\\u2DB8' .. '\\u2DBE' | '\\u2DC0' .. '\\u2DC6' | '\\u2DC8' .. '\\u2DCE' | '\\u2DD0' .. '\\u2DD6' | '\\u2DD8' .. '\\u2DDE' | '\\u2E2F' | '\\u3005' .. '\\u3007' | '\\u3021' .. '\\u3029' | '\\u3031' .. '\\u3035' | '\\u3038' .. '\\u303C' | '\\u3041' .. '\\u3096' | '\\u309D' .. '\\u309F' | '\\u30A1' .. '\\u30FA' | '\\u30FC' .. '\\u30FF' | '\\u3105' .. '\\u312D' | '\\u3131' .. '\\u318E' | '\\u31A0' .. '\\u31BA' | '\\u31F0' .. '\\u31FF' | '\\u3400' .. '\\u4DB5' | '\\u4E00' .. '\\u9FD5' | '\\uA000' .. '\\uA48C' | '\\uA4D0' .. '\\uA4FD' | '\\uA500' .. '\\uA60C' | '\\uA610' .. '\\uA61F' | '\\uA62A' .. '\\uA62B' | '\\uA640' .. '\\uA66E' | '\\uA67F' .. '\\uA69D' | '\\uA6A0' .. '\\uA6EF' | '\\uA717' .. '\\uA71F' | '\\uA722' .. '\\uA788' | '\\uA78B' .. '\\uA7AD' | '\\uA7B0' .. '\\uA7B7' | '\\uA7F7' .. '\\uA801' | '\\uA803' .. '\\uA805' | '\\uA807' .. '\\uA80A' | '\\uA80C' .. '\\uA822' | '\\uA840' .. '\\uA873' | '\\uA882' .. '\\uA8B3' | '\\uA8F2' .. '\\uA8F7' | '\\uA8FB' | '\\uA8FD' | '\\uA90A' .. '\\uA925' | '\\uA930' .. '\\uA946' | '\\uA960' .. '\\uA97C' | '\\uA984' .. '\\uA9B2' | '\\uA9CF' | '\\uA9E0' .. '\\uA9E4' | '\\uA9E6' .. '\\uA9EF' | '\\uA9FA' .. '\\uA9FE' | '\\uAA00' .. '\\uAA28' | '\\uAA40' .. '\\uAA42' | '\\uAA44' .. '\\uAA4B' | '\\uAA60' .. '\\uAA76' | '\\uAA7A' | '\\uAA7E' .. '\\uAAAF' | '\\uAAB1' | '\\uAAB5' .. '\\uAAB6' | '\\uAAB9' .. '\\uAABD' | '\\uAAC0' | '\\uAAC2' | '\\uAADB' .. '\\uAADD' | '\\uAAE0' .. '\\uAAEA' | '\\uAAF2' .. '\\uAAF4' | '\\uAB01' .. '\\uAB06' | '\\uAB09' .. '\\uAB0E' | '\\uAB11' .. '\\uAB16' | '\\uAB20' .. '\\uAB26' | '\\uAB28' .. '\\uAB2E' | '\\uAB30' .. '\\uAB5A' | '\\uAB5C' .. '\\uAB65' | '\\uAB70' .. '\\uABE2' | '\\uAC00' .. '\\uD7A3' | '\\uD7B0' .. '\\uD7C6' | '\\uD7CB' .. '\\uD7FB' | '\\uF900' .. '\\uFA6D' | '\\uFA70' .. '\\uFAD9' | '\\uFB00' .. '\\uFB06' | '\\uFB13' .. '\\uFB17' | '\\uFB1D' | '\\uFB1F' .. '\\uFB28' | '\\uFB2A' .. '\\uFB36' | '\\uFB38' .. '\\uFB3C' | '\\uFB3E' | '\\uFB40' .. '\\uFB41' | '\\uFB43' .. '\\uFB44' | '\\uFB46' .. '\\uFBB1' | '\\uFBD3' .. '\\uFD3D' | '\\uFD50' .. '\\uFD8F' | '\\uFD92' .. '\\uFDC7' | '\\uFDF0' .. '\\uFDFB' | '\\uFE70' .. '\\uFE74' | '\\uFE76' .. '\\uFEFC' | '\\uFF21' .. '\\uFF3A' | '\\uFF41' .. '\\uFF5A' | '\\uFF66' .. '\\uFFBE' | '\\uFFC2' .. '\\uFFC7' | '\\uFFCA' .. '\\uFFCF' | '\\uFFD2' .. '\\uFFD7' | '\\uFFDA' .. '\\uFFDC' ) ) + // InternalSemver.g:5261:41: ( 'A' .. 'Z' | 'a' .. 'z' | '\\u00AA' | '\\u00B5' | '\\u00BA' | '\\u00C0' .. '\\u00D6' | '\\u00D8' .. '\\u00F6' | '\\u00F8' .. '\\u02C1' | '\\u02C6' .. '\\u02D1' | '\\u02E0' .. '\\u02E4' | '\\u02EC' | '\\u02EE' | '\\u0370' .. '\\u0374' | '\\u0376' .. '\\u0377' | '\\u037A' .. '\\u037D' | '\\u037F' | '\\u0386' | '\\u0388' .. '\\u038A' | '\\u038C' | '\\u038E' .. '\\u03A1' | '\\u03A3' .. '\\u03F5' | '\\u03F7' .. '\\u0481' | '\\u048A' .. '\\u052F' | '\\u0531' .. '\\u0556' | '\\u0559' | '\\u0561' .. '\\u0587' | '\\u05D0' .. '\\u05EA' | '\\u05F0' .. '\\u05F2' | '\\u0620' .. '\\u064A' | '\\u066E' .. '\\u066F' | '\\u0671' .. '\\u06D3' | '\\u06D5' | '\\u06E5' .. '\\u06E6' | '\\u06EE' .. '\\u06EF' | '\\u06FA' .. '\\u06FC' | '\\u06FF' | '\\u0710' | '\\u0712' .. '\\u072F' | '\\u074D' .. '\\u07A5' | '\\u07B1' | '\\u07CA' .. '\\u07EA' | '\\u07F4' .. '\\u07F5' | '\\u07FA' | '\\u0800' .. '\\u0815' | '\\u081A' | '\\u0824' | '\\u0828' | '\\u0840' .. '\\u0858' | '\\u08A0' .. '\\u08B4' | '\\u0904' .. '\\u0939' | '\\u093D' | '\\u0950' | '\\u0958' .. '\\u0961' | '\\u0971' .. '\\u0980' | '\\u0985' .. '\\u098C' | '\\u098F' .. '\\u0990' | '\\u0993' .. '\\u09A8' | '\\u09AA' .. '\\u09B0' | '\\u09B2' | '\\u09B6' .. '\\u09B9' | '\\u09BD' | '\\u09CE' | '\\u09DC' .. '\\u09DD' | '\\u09DF' .. '\\u09E1' | '\\u09F0' .. '\\u09F1' | '\\u0A05' .. '\\u0A0A' | '\\u0A0F' .. '\\u0A10' | '\\u0A13' .. '\\u0A28' | '\\u0A2A' .. '\\u0A30' | '\\u0A32' .. '\\u0A33' | '\\u0A35' .. '\\u0A36' | '\\u0A38' .. '\\u0A39' | '\\u0A59' .. '\\u0A5C' | '\\u0A5E' | '\\u0A72' .. '\\u0A74' | '\\u0A85' .. '\\u0A8D' | '\\u0A8F' .. '\\u0A91' | '\\u0A93' .. '\\u0AA8' | '\\u0AAA' .. '\\u0AB0' | '\\u0AB2' .. '\\u0AB3' | '\\u0AB5' .. '\\u0AB9' | '\\u0ABD' | '\\u0AD0' | '\\u0AE0' .. '\\u0AE1' | '\\u0AF9' | '\\u0B05' .. '\\u0B0C' | '\\u0B0F' .. '\\u0B10' | '\\u0B13' .. '\\u0B28' | '\\u0B2A' .. '\\u0B30' | '\\u0B32' .. '\\u0B33' | '\\u0B35' .. '\\u0B39' | '\\u0B3D' | '\\u0B5C' .. '\\u0B5D' | '\\u0B5F' .. '\\u0B61' | '\\u0B71' | '\\u0B83' | '\\u0B85' .. '\\u0B8A' | '\\u0B8E' .. '\\u0B90' | '\\u0B92' .. '\\u0B95' | '\\u0B99' .. '\\u0B9A' | '\\u0B9C' | '\\u0B9E' .. '\\u0B9F' | '\\u0BA3' .. '\\u0BA4' | '\\u0BA8' .. '\\u0BAA' | '\\u0BAE' .. '\\u0BB9' | '\\u0BD0' | '\\u0C05' .. '\\u0C0C' | '\\u0C0E' .. '\\u0C10' | '\\u0C12' .. '\\u0C28' | '\\u0C2A' .. '\\u0C39' | '\\u0C3D' | '\\u0C58' .. '\\u0C5A' | '\\u0C60' .. '\\u0C61' | '\\u0C85' .. '\\u0C8C' | '\\u0C8E' .. '\\u0C90' | '\\u0C92' .. '\\u0CA8' | '\\u0CAA' .. '\\u0CB3' | '\\u0CB5' .. '\\u0CB9' | '\\u0CBD' | '\\u0CDE' | '\\u0CE0' .. '\\u0CE1' | '\\u0CF1' .. '\\u0CF2' | '\\u0D05' .. '\\u0D0C' | '\\u0D0E' .. '\\u0D10' | '\\u0D12' .. '\\u0D3A' | '\\u0D3D' | '\\u0D4E' | '\\u0D5F' .. '\\u0D61' | '\\u0D7A' .. '\\u0D7F' | '\\u0D85' .. '\\u0D96' | '\\u0D9A' .. '\\u0DB1' | '\\u0DB3' .. '\\u0DBB' | '\\u0DBD' | '\\u0DC0' .. '\\u0DC6' | '\\u0E01' .. '\\u0E30' | '\\u0E32' .. '\\u0E33' | '\\u0E40' .. '\\u0E46' | '\\u0E81' .. '\\u0E82' | '\\u0E84' | '\\u0E87' .. '\\u0E88' | '\\u0E8A' | '\\u0E8D' | '\\u0E94' .. '\\u0E97' | '\\u0E99' .. '\\u0E9F' | '\\u0EA1' .. '\\u0EA3' | '\\u0EA5' | '\\u0EA7' | '\\u0EAA' .. '\\u0EAB' | '\\u0EAD' .. '\\u0EB0' | '\\u0EB2' .. '\\u0EB3' | '\\u0EBD' | '\\u0EC0' .. '\\u0EC4' | '\\u0EC6' | '\\u0EDC' .. '\\u0EDF' | '\\u0F00' | '\\u0F40' .. '\\u0F47' | '\\u0F49' .. '\\u0F6C' | '\\u0F88' .. '\\u0F8C' | '\\u1000' .. '\\u102A' | '\\u103F' | '\\u1050' .. '\\u1055' | '\\u105A' .. '\\u105D' | '\\u1061' | '\\u1065' .. '\\u1066' | '\\u106E' .. '\\u1070' | '\\u1075' .. '\\u1081' | '\\u108E' | '\\u10A0' .. '\\u10C5' | '\\u10C7' | '\\u10CD' | '\\u10D0' .. '\\u10FA' | '\\u10FC' .. '\\u1248' | '\\u124A' .. '\\u124D' | '\\u1250' .. '\\u1256' | '\\u1258' | '\\u125A' .. '\\u125D' | '\\u1260' .. '\\u1288' | '\\u128A' .. '\\u128D' | '\\u1290' .. '\\u12B0' | '\\u12B2' .. '\\u12B5' | '\\u12B8' .. '\\u12BE' | '\\u12C0' | '\\u12C2' .. '\\u12C5' | '\\u12C8' .. '\\u12D6' | '\\u12D8' .. '\\u1310' | '\\u1312' .. '\\u1315' | '\\u1318' .. '\\u135A' | '\\u1380' .. '\\u138F' | '\\u13A0' .. '\\u13F5' | '\\u13F8' .. '\\u13FD' | '\\u1401' .. '\\u166C' | '\\u166F' .. '\\u167F' | '\\u1681' .. '\\u169A' | '\\u16A0' .. '\\u16EA' | '\\u16EE' .. '\\u16F8' | '\\u1700' .. '\\u170C' | '\\u170E' .. '\\u1711' | '\\u1720' .. '\\u1731' | '\\u1740' .. '\\u1751' | '\\u1760' .. '\\u176C' | '\\u176E' .. '\\u1770' | '\\u1780' .. '\\u17B3' | '\\u17D7' | '\\u17DC' | '\\u1820' .. '\\u1877' | '\\u1880' .. '\\u18A8' | '\\u18AA' | '\\u18B0' .. '\\u18F5' | '\\u1900' .. '\\u191E' | '\\u1950' .. '\\u196D' | '\\u1970' .. '\\u1974' | '\\u1980' .. '\\u19AB' | '\\u19B0' .. '\\u19C9' | '\\u1A00' .. '\\u1A16' | '\\u1A20' .. '\\u1A54' | '\\u1AA7' | '\\u1B05' .. '\\u1B33' | '\\u1B45' .. '\\u1B4B' | '\\u1B83' .. '\\u1BA0' | '\\u1BAE' .. '\\u1BAF' | '\\u1BBA' .. '\\u1BE5' | '\\u1C00' .. '\\u1C23' | '\\u1C4D' .. '\\u1C4F' | '\\u1C5A' .. '\\u1C7D' | '\\u1CE9' .. '\\u1CEC' | '\\u1CEE' .. '\\u1CF1' | '\\u1CF5' .. '\\u1CF6' | '\\u1D00' .. '\\u1DBF' | '\\u1E00' .. '\\u1F15' | '\\u1F18' .. '\\u1F1D' | '\\u1F20' .. '\\u1F45' | '\\u1F48' .. '\\u1F4D' | '\\u1F50' .. '\\u1F57' | '\\u1F59' | '\\u1F5B' | '\\u1F5D' | '\\u1F5F' .. '\\u1F7D' | '\\u1F80' .. '\\u1FB4' | '\\u1FB6' .. '\\u1FBC' | '\\u1FBE' | '\\u1FC2' .. '\\u1FC4' | '\\u1FC6' .. '\\u1FCC' | '\\u1FD0' .. '\\u1FD3' | '\\u1FD6' .. '\\u1FDB' | '\\u1FE0' .. '\\u1FEC' | '\\u1FF2' .. '\\u1FF4' | '\\u1FF6' .. '\\u1FFC' | '\\u2071' | '\\u207F' | '\\u2090' .. '\\u209C' | '\\u2102' | '\\u2107' | '\\u210A' .. '\\u2113' | '\\u2115' | '\\u2119' .. '\\u211D' | '\\u2124' | '\\u2126' | '\\u2128' | '\\u212A' .. '\\u212D' | '\\u212F' .. '\\u2139' | '\\u213C' .. '\\u213F' | '\\u2145' .. '\\u2149' | '\\u214E' | '\\u2160' .. '\\u2188' | '\\u2C00' .. '\\u2C2E' | '\\u2C30' .. '\\u2C5E' | '\\u2C60' .. '\\u2CE4' | '\\u2CEB' .. '\\u2CEE' | '\\u2CF2' .. '\\u2CF3' | '\\u2D00' .. '\\u2D25' | '\\u2D27' | '\\u2D2D' | '\\u2D30' .. '\\u2D67' | '\\u2D6F' | '\\u2D80' .. '\\u2D96' | '\\u2DA0' .. '\\u2DA6' | '\\u2DA8' .. '\\u2DAE' | '\\u2DB0' .. '\\u2DB6' | '\\u2DB8' .. '\\u2DBE' | '\\u2DC0' .. '\\u2DC6' | '\\u2DC8' .. '\\u2DCE' | '\\u2DD0' .. '\\u2DD6' | '\\u2DD8' .. '\\u2DDE' | '\\u2E2F' | '\\u3005' .. '\\u3007' | '\\u3021' .. '\\u3029' | '\\u3031' .. '\\u3035' | '\\u3038' .. '\\u303C' | '\\u3041' .. '\\u3096' | '\\u309D' .. '\\u309F' | '\\u30A1' .. '\\u30FA' | '\\u30FC' .. '\\u30FF' | '\\u3105' .. '\\u312D' | '\\u3131' .. '\\u318E' | '\\u31A0' .. '\\u31BA' | '\\u31F0' .. '\\u31FF' | '\\u3400' .. '\\u4DB5' | '\\u4E00' .. '\\u9FD5' | '\\uA000' .. '\\uA48C' | '\\uA4D0' .. '\\uA4FD' | '\\uA500' .. '\\uA60C' | '\\uA610' .. '\\uA61F' | '\\uA62A' .. '\\uA62B' | '\\uA640' .. '\\uA66E' | '\\uA67F' .. '\\uA69D' | '\\uA6A0' .. '\\uA6EF' | '\\uA717' .. '\\uA71F' | '\\uA722' .. '\\uA788' | '\\uA78B' .. '\\uA7AD' | '\\uA7B0' .. '\\uA7B7' | '\\uA7F7' .. '\\uA801' | '\\uA803' .. '\\uA805' | '\\uA807' .. '\\uA80A' | '\\uA80C' .. '\\uA822' | '\\uA840' .. '\\uA873' | '\\uA882' .. '\\uA8B3' | '\\uA8F2' .. '\\uA8F7' | '\\uA8FB' | '\\uA8FD' | '\\uA90A' .. '\\uA925' | '\\uA930' .. '\\uA946' | '\\uA960' .. '\\uA97C' | '\\uA984' .. '\\uA9B2' | '\\uA9CF' | '\\uA9E0' .. '\\uA9E4' | '\\uA9E6' .. '\\uA9EF' | '\\uA9FA' .. '\\uA9FE' | '\\uAA00' .. '\\uAA28' | '\\uAA40' .. '\\uAA42' | '\\uAA44' .. '\\uAA4B' | '\\uAA60' .. '\\uAA76' | '\\uAA7A' | '\\uAA7E' .. '\\uAAAF' | '\\uAAB1' | '\\uAAB5' .. '\\uAAB6' | '\\uAAB9' .. '\\uAABD' | '\\uAAC0' | '\\uAAC2' | '\\uAADB' .. '\\uAADD' | '\\uAAE0' .. '\\uAAEA' | '\\uAAF2' .. '\\uAAF4' | '\\uAB01' .. '\\uAB06' | '\\uAB09' .. '\\uAB0E' | '\\uAB11' .. '\\uAB16' | '\\uAB20' .. '\\uAB26' | '\\uAB28' .. '\\uAB2E' | '\\uAB30' .. '\\uAB5A' | '\\uAB5C' .. '\\uAB65' | '\\uAB70' .. '\\uABE2' | '\\uAC00' .. '\\uD7A3' | '\\uD7B0' .. '\\uD7C6' | '\\uD7CB' .. '\\uD7FB' | '\\uF900' .. '\\uFA6D' | '\\uFA70' .. '\\uFAD9' | '\\uFB00' .. '\\uFB06' | '\\uFB13' .. '\\uFB17' | '\\uFB1D' | '\\uFB1F' .. '\\uFB28' | '\\uFB2A' .. '\\uFB36' | '\\uFB38' .. '\\uFB3C' | '\\uFB3E' | '\\uFB40' .. '\\uFB41' | '\\uFB43' .. '\\uFB44' | '\\uFB46' .. '\\uFBB1' | '\\uFBD3' .. '\\uFD3D' | '\\uFD50' .. '\\uFD8F' | '\\uFD92' .. '\\uFDC7' | '\\uFDF0' .. '\\uFDFB' | '\\uFE70' .. '\\uFE74' | '\\uFE76' .. '\\uFEFC' | '\\uFF21' .. '\\uFF3A' | '\\uFF41' .. '\\uFF5A' | '\\uFF66' .. '\\uFFBE' | '\\uFFC2' .. '\\uFFC7' | '\\uFFCA' .. '\\uFFCF' | '\\uFFD2' .. '\\uFFD7' | '\\uFFDA' .. '\\uFFDC' ) { if ( (input.LA(1)>='A' && input.LA(1)<='Z')||(input.LA(1)>='a' && input.LA(1)<='z')||input.LA(1)=='\u00AA'||input.LA(1)=='\u00B5'||input.LA(1)=='\u00BA'||(input.LA(1)>='\u00C0' && input.LA(1)<='\u00D6')||(input.LA(1)>='\u00D8' && input.LA(1)<='\u00F6')||(input.LA(1)>='\u00F8' && input.LA(1)<='\u02C1')||(input.LA(1)>='\u02C6' && input.LA(1)<='\u02D1')||(input.LA(1)>='\u02E0' && input.LA(1)<='\u02E4')||input.LA(1)=='\u02EC'||input.LA(1)=='\u02EE'||(input.LA(1)>='\u0370' && input.LA(1)<='\u0374')||(input.LA(1)>='\u0376' && input.LA(1)<='\u0377')||(input.LA(1)>='\u037A' && input.LA(1)<='\u037D')||input.LA(1)=='\u037F'||input.LA(1)=='\u0386'||(input.LA(1)>='\u0388' && input.LA(1)<='\u038A')||input.LA(1)=='\u038C'||(input.LA(1)>='\u038E' && input.LA(1)<='\u03A1')||(input.LA(1)>='\u03A3' && input.LA(1)<='\u03F5')||(input.LA(1)>='\u03F7' && input.LA(1)<='\u0481')||(input.LA(1)>='\u048A' && input.LA(1)<='\u052F')||(input.LA(1)>='\u0531' && input.LA(1)<='\u0556')||input.LA(1)=='\u0559'||(input.LA(1)>='\u0561' && input.LA(1)<='\u0587')||(input.LA(1)>='\u05D0' && input.LA(1)<='\u05EA')||(input.LA(1)>='\u05F0' && input.LA(1)<='\u05F2')||(input.LA(1)>='\u0620' && input.LA(1)<='\u064A')||(input.LA(1)>='\u066E' && input.LA(1)<='\u066F')||(input.LA(1)>='\u0671' && input.LA(1)<='\u06D3')||input.LA(1)=='\u06D5'||(input.LA(1)>='\u06E5' && input.LA(1)<='\u06E6')||(input.LA(1)>='\u06EE' && input.LA(1)<='\u06EF')||(input.LA(1)>='\u06FA' && input.LA(1)<='\u06FC')||input.LA(1)=='\u06FF'||input.LA(1)=='\u0710'||(input.LA(1)>='\u0712' && input.LA(1)<='\u072F')||(input.LA(1)>='\u074D' && input.LA(1)<='\u07A5')||input.LA(1)=='\u07B1'||(input.LA(1)>='\u07CA' && input.LA(1)<='\u07EA')||(input.LA(1)>='\u07F4' && input.LA(1)<='\u07F5')||input.LA(1)=='\u07FA'||(input.LA(1)>='\u0800' && input.LA(1)<='\u0815')||input.LA(1)=='\u081A'||input.LA(1)=='\u0824'||input.LA(1)=='\u0828'||(input.LA(1)>='\u0840' && input.LA(1)<='\u0858')||(input.LA(1)>='\u08A0' && input.LA(1)<='\u08B4')||(input.LA(1)>='\u0904' && input.LA(1)<='\u0939')||input.LA(1)=='\u093D'||input.LA(1)=='\u0950'||(input.LA(1)>='\u0958' && input.LA(1)<='\u0961')||(input.LA(1)>='\u0971' && input.LA(1)<='\u0980')||(input.LA(1)>='\u0985' && input.LA(1)<='\u098C')||(input.LA(1)>='\u098F' && input.LA(1)<='\u0990')||(input.LA(1)>='\u0993' && input.LA(1)<='\u09A8')||(input.LA(1)>='\u09AA' && input.LA(1)<='\u09B0')||input.LA(1)=='\u09B2'||(input.LA(1)>='\u09B6' && input.LA(1)<='\u09B9')||input.LA(1)=='\u09BD'||input.LA(1)=='\u09CE'||(input.LA(1)>='\u09DC' && input.LA(1)<='\u09DD')||(input.LA(1)>='\u09DF' && input.LA(1)<='\u09E1')||(input.LA(1)>='\u09F0' && input.LA(1)<='\u09F1')||(input.LA(1)>='\u0A05' && input.LA(1)<='\u0A0A')||(input.LA(1)>='\u0A0F' && input.LA(1)<='\u0A10')||(input.LA(1)>='\u0A13' && input.LA(1)<='\u0A28')||(input.LA(1)>='\u0A2A' && input.LA(1)<='\u0A30')||(input.LA(1)>='\u0A32' && input.LA(1)<='\u0A33')||(input.LA(1)>='\u0A35' && input.LA(1)<='\u0A36')||(input.LA(1)>='\u0A38' && input.LA(1)<='\u0A39')||(input.LA(1)>='\u0A59' && input.LA(1)<='\u0A5C')||input.LA(1)=='\u0A5E'||(input.LA(1)>='\u0A72' && input.LA(1)<='\u0A74')||(input.LA(1)>='\u0A85' && input.LA(1)<='\u0A8D')||(input.LA(1)>='\u0A8F' && input.LA(1)<='\u0A91')||(input.LA(1)>='\u0A93' && input.LA(1)<='\u0AA8')||(input.LA(1)>='\u0AAA' && input.LA(1)<='\u0AB0')||(input.LA(1)>='\u0AB2' && input.LA(1)<='\u0AB3')||(input.LA(1)>='\u0AB5' && input.LA(1)<='\u0AB9')||input.LA(1)=='\u0ABD'||input.LA(1)=='\u0AD0'||(input.LA(1)>='\u0AE0' && input.LA(1)<='\u0AE1')||input.LA(1)=='\u0AF9'||(input.LA(1)>='\u0B05' && input.LA(1)<='\u0B0C')||(input.LA(1)>='\u0B0F' && input.LA(1)<='\u0B10')||(input.LA(1)>='\u0B13' && input.LA(1)<='\u0B28')||(input.LA(1)>='\u0B2A' && input.LA(1)<='\u0B30')||(input.LA(1)>='\u0B32' && input.LA(1)<='\u0B33')||(input.LA(1)>='\u0B35' && input.LA(1)<='\u0B39')||input.LA(1)=='\u0B3D'||(input.LA(1)>='\u0B5C' && input.LA(1)<='\u0B5D')||(input.LA(1)>='\u0B5F' && input.LA(1)<='\u0B61')||input.LA(1)=='\u0B71'||input.LA(1)=='\u0B83'||(input.LA(1)>='\u0B85' && input.LA(1)<='\u0B8A')||(input.LA(1)>='\u0B8E' && input.LA(1)<='\u0B90')||(input.LA(1)>='\u0B92' && input.LA(1)<='\u0B95')||(input.LA(1)>='\u0B99' && input.LA(1)<='\u0B9A')||input.LA(1)=='\u0B9C'||(input.LA(1)>='\u0B9E' && input.LA(1)<='\u0B9F')||(input.LA(1)>='\u0BA3' && input.LA(1)<='\u0BA4')||(input.LA(1)>='\u0BA8' && input.LA(1)<='\u0BAA')||(input.LA(1)>='\u0BAE' && input.LA(1)<='\u0BB9')||input.LA(1)=='\u0BD0'||(input.LA(1)>='\u0C05' && input.LA(1)<='\u0C0C')||(input.LA(1)>='\u0C0E' && input.LA(1)<='\u0C10')||(input.LA(1)>='\u0C12' && input.LA(1)<='\u0C28')||(input.LA(1)>='\u0C2A' && input.LA(1)<='\u0C39')||input.LA(1)=='\u0C3D'||(input.LA(1)>='\u0C58' && input.LA(1)<='\u0C5A')||(input.LA(1)>='\u0C60' && input.LA(1)<='\u0C61')||(input.LA(1)>='\u0C85' && input.LA(1)<='\u0C8C')||(input.LA(1)>='\u0C8E' && input.LA(1)<='\u0C90')||(input.LA(1)>='\u0C92' && input.LA(1)<='\u0CA8')||(input.LA(1)>='\u0CAA' && input.LA(1)<='\u0CB3')||(input.LA(1)>='\u0CB5' && input.LA(1)<='\u0CB9')||input.LA(1)=='\u0CBD'||input.LA(1)=='\u0CDE'||(input.LA(1)>='\u0CE0' && input.LA(1)<='\u0CE1')||(input.LA(1)>='\u0CF1' && input.LA(1)<='\u0CF2')||(input.LA(1)>='\u0D05' && input.LA(1)<='\u0D0C')||(input.LA(1)>='\u0D0E' && input.LA(1)<='\u0D10')||(input.LA(1)>='\u0D12' && input.LA(1)<='\u0D3A')||input.LA(1)=='\u0D3D'||input.LA(1)=='\u0D4E'||(input.LA(1)>='\u0D5F' && input.LA(1)<='\u0D61')||(input.LA(1)>='\u0D7A' && input.LA(1)<='\u0D7F')||(input.LA(1)>='\u0D85' && input.LA(1)<='\u0D96')||(input.LA(1)>='\u0D9A' && input.LA(1)<='\u0DB1')||(input.LA(1)>='\u0DB3' && input.LA(1)<='\u0DBB')||input.LA(1)=='\u0DBD'||(input.LA(1)>='\u0DC0' && input.LA(1)<='\u0DC6')||(input.LA(1)>='\u0E01' && input.LA(1)<='\u0E30')||(input.LA(1)>='\u0E32' && input.LA(1)<='\u0E33')||(input.LA(1)>='\u0E40' && input.LA(1)<='\u0E46')||(input.LA(1)>='\u0E81' && input.LA(1)<='\u0E82')||input.LA(1)=='\u0E84'||(input.LA(1)>='\u0E87' && input.LA(1)<='\u0E88')||input.LA(1)=='\u0E8A'||input.LA(1)=='\u0E8D'||(input.LA(1)>='\u0E94' && input.LA(1)<='\u0E97')||(input.LA(1)>='\u0E99' && input.LA(1)<='\u0E9F')||(input.LA(1)>='\u0EA1' && input.LA(1)<='\u0EA3')||input.LA(1)=='\u0EA5'||input.LA(1)=='\u0EA7'||(input.LA(1)>='\u0EAA' && input.LA(1)<='\u0EAB')||(input.LA(1)>='\u0EAD' && input.LA(1)<='\u0EB0')||(input.LA(1)>='\u0EB2' && input.LA(1)<='\u0EB3')||input.LA(1)=='\u0EBD'||(input.LA(1)>='\u0EC0' && input.LA(1)<='\u0EC4')||input.LA(1)=='\u0EC6'||(input.LA(1)>='\u0EDC' && input.LA(1)<='\u0EDF')||input.LA(1)=='\u0F00'||(input.LA(1)>='\u0F40' && input.LA(1)<='\u0F47')||(input.LA(1)>='\u0F49' && input.LA(1)<='\u0F6C')||(input.LA(1)>='\u0F88' && input.LA(1)<='\u0F8C')||(input.LA(1)>='\u1000' && input.LA(1)<='\u102A')||input.LA(1)=='\u103F'||(input.LA(1)>='\u1050' && input.LA(1)<='\u1055')||(input.LA(1)>='\u105A' && input.LA(1)<='\u105D')||input.LA(1)=='\u1061'||(input.LA(1)>='\u1065' && input.LA(1)<='\u1066')||(input.LA(1)>='\u106E' && input.LA(1)<='\u1070')||(input.LA(1)>='\u1075' && input.LA(1)<='\u1081')||input.LA(1)=='\u108E'||(input.LA(1)>='\u10A0' && input.LA(1)<='\u10C5')||input.LA(1)=='\u10C7'||input.LA(1)=='\u10CD'||(input.LA(1)>='\u10D0' && input.LA(1)<='\u10FA')||(input.LA(1)>='\u10FC' && input.LA(1)<='\u1248')||(input.LA(1)>='\u124A' && input.LA(1)<='\u124D')||(input.LA(1)>='\u1250' && input.LA(1)<='\u1256')||input.LA(1)=='\u1258'||(input.LA(1)>='\u125A' && input.LA(1)<='\u125D')||(input.LA(1)>='\u1260' && input.LA(1)<='\u1288')||(input.LA(1)>='\u128A' && input.LA(1)<='\u128D')||(input.LA(1)>='\u1290' && input.LA(1)<='\u12B0')||(input.LA(1)>='\u12B2' && input.LA(1)<='\u12B5')||(input.LA(1)>='\u12B8' && input.LA(1)<='\u12BE')||input.LA(1)=='\u12C0'||(input.LA(1)>='\u12C2' && input.LA(1)<='\u12C5')||(input.LA(1)>='\u12C8' && input.LA(1)<='\u12D6')||(input.LA(1)>='\u12D8' && input.LA(1)<='\u1310')||(input.LA(1)>='\u1312' && input.LA(1)<='\u1315')||(input.LA(1)>='\u1318' && input.LA(1)<='\u135A')||(input.LA(1)>='\u1380' && input.LA(1)<='\u138F')||(input.LA(1)>='\u13A0' && input.LA(1)<='\u13F5')||(input.LA(1)>='\u13F8' && input.LA(1)<='\u13FD')||(input.LA(1)>='\u1401' && input.LA(1)<='\u166C')||(input.LA(1)>='\u166F' && input.LA(1)<='\u167F')||(input.LA(1)>='\u1681' && input.LA(1)<='\u169A')||(input.LA(1)>='\u16A0' && input.LA(1)<='\u16EA')||(input.LA(1)>='\u16EE' && input.LA(1)<='\u16F8')||(input.LA(1)>='\u1700' && input.LA(1)<='\u170C')||(input.LA(1)>='\u170E' && input.LA(1)<='\u1711')||(input.LA(1)>='\u1720' && input.LA(1)<='\u1731')||(input.LA(1)>='\u1740' && input.LA(1)<='\u1751')||(input.LA(1)>='\u1760' && input.LA(1)<='\u176C')||(input.LA(1)>='\u176E' && input.LA(1)<='\u1770')||(input.LA(1)>='\u1780' && input.LA(1)<='\u17B3')||input.LA(1)=='\u17D7'||input.LA(1)=='\u17DC'||(input.LA(1)>='\u1820' && input.LA(1)<='\u1877')||(input.LA(1)>='\u1880' && input.LA(1)<='\u18A8')||input.LA(1)=='\u18AA'||(input.LA(1)>='\u18B0' && input.LA(1)<='\u18F5')||(input.LA(1)>='\u1900' && input.LA(1)<='\u191E')||(input.LA(1)>='\u1950' && input.LA(1)<='\u196D')||(input.LA(1)>='\u1970' && input.LA(1)<='\u1974')||(input.LA(1)>='\u1980' && input.LA(1)<='\u19AB')||(input.LA(1)>='\u19B0' && input.LA(1)<='\u19C9')||(input.LA(1)>='\u1A00' && input.LA(1)<='\u1A16')||(input.LA(1)>='\u1A20' && input.LA(1)<='\u1A54')||input.LA(1)=='\u1AA7'||(input.LA(1)>='\u1B05' && input.LA(1)<='\u1B33')||(input.LA(1)>='\u1B45' && input.LA(1)<='\u1B4B')||(input.LA(1)>='\u1B83' && input.LA(1)<='\u1BA0')||(input.LA(1)>='\u1BAE' && input.LA(1)<='\u1BAF')||(input.LA(1)>='\u1BBA' && input.LA(1)<='\u1BE5')||(input.LA(1)>='\u1C00' && input.LA(1)<='\u1C23')||(input.LA(1)>='\u1C4D' && input.LA(1)<='\u1C4F')||(input.LA(1)>='\u1C5A' && input.LA(1)<='\u1C7D')||(input.LA(1)>='\u1CE9' && input.LA(1)<='\u1CEC')||(input.LA(1)>='\u1CEE' && input.LA(1)<='\u1CF1')||(input.LA(1)>='\u1CF5' && input.LA(1)<='\u1CF6')||(input.LA(1)>='\u1D00' && input.LA(1)<='\u1DBF')||(input.LA(1)>='\u1E00' && input.LA(1)<='\u1F15')||(input.LA(1)>='\u1F18' && input.LA(1)<='\u1F1D')||(input.LA(1)>='\u1F20' && input.LA(1)<='\u1F45')||(input.LA(1)>='\u1F48' && input.LA(1)<='\u1F4D')||(input.LA(1)>='\u1F50' && input.LA(1)<='\u1F57')||input.LA(1)=='\u1F59'||input.LA(1)=='\u1F5B'||input.LA(1)=='\u1F5D'||(input.LA(1)>='\u1F5F' && input.LA(1)<='\u1F7D')||(input.LA(1)>='\u1F80' && input.LA(1)<='\u1FB4')||(input.LA(1)>='\u1FB6' && input.LA(1)<='\u1FBC')||input.LA(1)=='\u1FBE'||(input.LA(1)>='\u1FC2' && input.LA(1)<='\u1FC4')||(input.LA(1)>='\u1FC6' && input.LA(1)<='\u1FCC')||(input.LA(1)>='\u1FD0' && input.LA(1)<='\u1FD3')||(input.LA(1)>='\u1FD6' && input.LA(1)<='\u1FDB')||(input.LA(1)>='\u1FE0' && input.LA(1)<='\u1FEC')||(input.LA(1)>='\u1FF2' && input.LA(1)<='\u1FF4')||(input.LA(1)>='\u1FF6' && input.LA(1)<='\u1FFC')||input.LA(1)=='\u2071'||input.LA(1)=='\u207F'||(input.LA(1)>='\u2090' && input.LA(1)<='\u209C')||input.LA(1)=='\u2102'||input.LA(1)=='\u2107'||(input.LA(1)>='\u210A' && input.LA(1)<='\u2113')||input.LA(1)=='\u2115'||(input.LA(1)>='\u2119' && input.LA(1)<='\u211D')||input.LA(1)=='\u2124'||input.LA(1)=='\u2126'||input.LA(1)=='\u2128'||(input.LA(1)>='\u212A' && input.LA(1)<='\u212D')||(input.LA(1)>='\u212F' && input.LA(1)<='\u2139')||(input.LA(1)>='\u213C' && input.LA(1)<='\u213F')||(input.LA(1)>='\u2145' && input.LA(1)<='\u2149')||input.LA(1)=='\u214E'||(input.LA(1)>='\u2160' && input.LA(1)<='\u2188')||(input.LA(1)>='\u2C00' && input.LA(1)<='\u2C2E')||(input.LA(1)>='\u2C30' && input.LA(1)<='\u2C5E')||(input.LA(1)>='\u2C60' && input.LA(1)<='\u2CE4')||(input.LA(1)>='\u2CEB' && input.LA(1)<='\u2CEE')||(input.LA(1)>='\u2CF2' && input.LA(1)<='\u2CF3')||(input.LA(1)>='\u2D00' && input.LA(1)<='\u2D25')||input.LA(1)=='\u2D27'||input.LA(1)=='\u2D2D'||(input.LA(1)>='\u2D30' && input.LA(1)<='\u2D67')||input.LA(1)=='\u2D6F'||(input.LA(1)>='\u2D80' && input.LA(1)<='\u2D96')||(input.LA(1)>='\u2DA0' && input.LA(1)<='\u2DA6')||(input.LA(1)>='\u2DA8' && input.LA(1)<='\u2DAE')||(input.LA(1)>='\u2DB0' && input.LA(1)<='\u2DB6')||(input.LA(1)>='\u2DB8' && input.LA(1)<='\u2DBE')||(input.LA(1)>='\u2DC0' && input.LA(1)<='\u2DC6')||(input.LA(1)>='\u2DC8' && input.LA(1)<='\u2DCE')||(input.LA(1)>='\u2DD0' && input.LA(1)<='\u2DD6')||(input.LA(1)>='\u2DD8' && input.LA(1)<='\u2DDE')||input.LA(1)=='\u2E2F'||(input.LA(1)>='\u3005' && input.LA(1)<='\u3007')||(input.LA(1)>='\u3021' && input.LA(1)<='\u3029')||(input.LA(1)>='\u3031' && input.LA(1)<='\u3035')||(input.LA(1)>='\u3038' && input.LA(1)<='\u303C')||(input.LA(1)>='\u3041' && input.LA(1)<='\u3096')||(input.LA(1)>='\u309D' && input.LA(1)<='\u309F')||(input.LA(1)>='\u30A1' && input.LA(1)<='\u30FA')||(input.LA(1)>='\u30FC' && input.LA(1)<='\u30FF')||(input.LA(1)>='\u3105' && input.LA(1)<='\u312D')||(input.LA(1)>='\u3131' && input.LA(1)<='\u318E')||(input.LA(1)>='\u31A0' && input.LA(1)<='\u31BA')||(input.LA(1)>='\u31F0' && input.LA(1)<='\u31FF')||(input.LA(1)>='\u3400' && input.LA(1)<='\u4DB5')||(input.LA(1)>='\u4E00' && input.LA(1)<='\u9FD5')||(input.LA(1)>='\uA000' && input.LA(1)<='\uA48C')||(input.LA(1)>='\uA4D0' && input.LA(1)<='\uA4FD')||(input.LA(1)>='\uA500' && input.LA(1)<='\uA60C')||(input.LA(1)>='\uA610' && input.LA(1)<='\uA61F')||(input.LA(1)>='\uA62A' && input.LA(1)<='\uA62B')||(input.LA(1)>='\uA640' && input.LA(1)<='\uA66E')||(input.LA(1)>='\uA67F' && input.LA(1)<='\uA69D')||(input.LA(1)>='\uA6A0' && input.LA(1)<='\uA6EF')||(input.LA(1)>='\uA717' && input.LA(1)<='\uA71F')||(input.LA(1)>='\uA722' && input.LA(1)<='\uA788')||(input.LA(1)>='\uA78B' && input.LA(1)<='\uA7AD')||(input.LA(1)>='\uA7B0' && input.LA(1)<='\uA7B7')||(input.LA(1)>='\uA7F7' && input.LA(1)<='\uA801')||(input.LA(1)>='\uA803' && input.LA(1)<='\uA805')||(input.LA(1)>='\uA807' && input.LA(1)<='\uA80A')||(input.LA(1)>='\uA80C' && input.LA(1)<='\uA822')||(input.LA(1)>='\uA840' && input.LA(1)<='\uA873')||(input.LA(1)>='\uA882' && input.LA(1)<='\uA8B3')||(input.LA(1)>='\uA8F2' && input.LA(1)<='\uA8F7')||input.LA(1)=='\uA8FB'||input.LA(1)=='\uA8FD'||(input.LA(1)>='\uA90A' && input.LA(1)<='\uA925')||(input.LA(1)>='\uA930' && input.LA(1)<='\uA946')||(input.LA(1)>='\uA960' && input.LA(1)<='\uA97C')||(input.LA(1)>='\uA984' && input.LA(1)<='\uA9B2')||input.LA(1)=='\uA9CF'||(input.LA(1)>='\uA9E0' && input.LA(1)<='\uA9E4')||(input.LA(1)>='\uA9E6' && input.LA(1)<='\uA9EF')||(input.LA(1)>='\uA9FA' && input.LA(1)<='\uA9FE')||(input.LA(1)>='\uAA00' && input.LA(1)<='\uAA28')||(input.LA(1)>='\uAA40' && input.LA(1)<='\uAA42')||(input.LA(1)>='\uAA44' && input.LA(1)<='\uAA4B')||(input.LA(1)>='\uAA60' && input.LA(1)<='\uAA76')||input.LA(1)=='\uAA7A'||(input.LA(1)>='\uAA7E' && input.LA(1)<='\uAAAF')||input.LA(1)=='\uAAB1'||(input.LA(1)>='\uAAB5' && input.LA(1)<='\uAAB6')||(input.LA(1)>='\uAAB9' && input.LA(1)<='\uAABD')||input.LA(1)=='\uAAC0'||input.LA(1)=='\uAAC2'||(input.LA(1)>='\uAADB' && input.LA(1)<='\uAADD')||(input.LA(1)>='\uAAE0' && input.LA(1)<='\uAAEA')||(input.LA(1)>='\uAAF2' && input.LA(1)<='\uAAF4')||(input.LA(1)>='\uAB01' && input.LA(1)<='\uAB06')||(input.LA(1)>='\uAB09' && input.LA(1)<='\uAB0E')||(input.LA(1)>='\uAB11' && input.LA(1)<='\uAB16')||(input.LA(1)>='\uAB20' && input.LA(1)<='\uAB26')||(input.LA(1)>='\uAB28' && input.LA(1)<='\uAB2E')||(input.LA(1)>='\uAB30' && input.LA(1)<='\uAB5A')||(input.LA(1)>='\uAB5C' && input.LA(1)<='\uAB65')||(input.LA(1)>='\uAB70' && input.LA(1)<='\uABE2')||(input.LA(1)>='\uAC00' && input.LA(1)<='\uD7A3')||(input.LA(1)>='\uD7B0' && input.LA(1)<='\uD7C6')||(input.LA(1)>='\uD7CB' && input.LA(1)<='\uD7FB')||(input.LA(1)>='\uF900' && input.LA(1)<='\uFA6D')||(input.LA(1)>='\uFA70' && input.LA(1)<='\uFAD9')||(input.LA(1)>='\uFB00' && input.LA(1)<='\uFB06')||(input.LA(1)>='\uFB13' && input.LA(1)<='\uFB17')||input.LA(1)=='\uFB1D'||(input.LA(1)>='\uFB1F' && input.LA(1)<='\uFB28')||(input.LA(1)>='\uFB2A' && input.LA(1)<='\uFB36')||(input.LA(1)>='\uFB38' && input.LA(1)<='\uFB3C')||input.LA(1)=='\uFB3E'||(input.LA(1)>='\uFB40' && input.LA(1)<='\uFB41')||(input.LA(1)>='\uFB43' && input.LA(1)<='\uFB44')||(input.LA(1)>='\uFB46' && input.LA(1)<='\uFBB1')||(input.LA(1)>='\uFBD3' && input.LA(1)<='\uFD3D')||(input.LA(1)>='\uFD50' && input.LA(1)<='\uFD8F')||(input.LA(1)>='\uFD92' && input.LA(1)<='\uFDC7')||(input.LA(1)>='\uFDF0' && input.LA(1)<='\uFDFB')||(input.LA(1)>='\uFE70' && input.LA(1)<='\uFE74')||(input.LA(1)>='\uFE76' && input.LA(1)<='\uFEFC')||(input.LA(1)>='\uFF21' && input.LA(1)<='\uFF3A')||(input.LA(1)>='\uFF41' && input.LA(1)<='\uFF5A')||(input.LA(1)>='\uFF66' && input.LA(1)<='\uFFBE')||(input.LA(1)>='\uFFC2' && input.LA(1)<='\uFFC7')||(input.LA(1)>='\uFFCA' && input.LA(1)<='\uFFCF')||(input.LA(1)>='\uFFD2' && input.LA(1)<='\uFFD7')||(input.LA(1)>='\uFFDA' && input.LA(1)<='\uFFDC') ) { input.consume(); @@ -1325,8 +1499,8 @@ public final void mRULE_UNICODE_LETTER_FRAGMENT() throws RecognitionException { // $ANTLR start "RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT" public final void mRULE_UNICODE_SPACE_SEPARATOR_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:4747:48: ( ( ' ' | '\\u00A0' | '\\u1680' | '\\u2000' .. '\\u200A' | '\\u202F' | '\\u205F' | '\\u3000' ) ) - // InternalSemver.g:4747:50: ( ' ' | '\\u00A0' | '\\u1680' | '\\u2000' .. '\\u200A' | '\\u202F' | '\\u205F' | '\\u3000' ) + // InternalSemver.g:5263:48: ( ( ' ' | '\\u00A0' | '\\u1680' | '\\u2000' .. '\\u200A' | '\\u202F' | '\\u205F' | '\\u3000' ) ) + // InternalSemver.g:5263:50: ( ' ' | '\\u00A0' | '\\u1680' | '\\u2000' .. '\\u200A' | '\\u202F' | '\\u205F' | '\\u3000' ) { if ( input.LA(1)==' '||input.LA(1)=='\u00A0'||input.LA(1)=='\u1680'||(input.LA(1)>='\u2000' && input.LA(1)<='\u200A')||input.LA(1)=='\u202F'||input.LA(1)=='\u205F'||input.LA(1)=='\u3000' ) { input.consume(); @@ -1349,8 +1523,8 @@ public final void mRULE_UNICODE_SPACE_SEPARATOR_FRAGMENT() throws RecognitionExc // $ANTLR start "RULE_ANY_OTHER" public final void mRULE_ANY_OTHER() throws RecognitionException { try { - // InternalSemver.g:4749:25: ( . ) - // InternalSemver.g:4749:27: . + // InternalSemver.g:5265:25: ( . ) + // InternalSemver.g:5265:27: . { matchAny(); @@ -1363,140 +1537,140 @@ public final void mRULE_ANY_OTHER() throws RecognitionException { // $ANTLR end "RULE_ANY_OTHER" public void mTokens() throws RecognitionException { - // InternalSemver.g:1:8: ( T__35 | T__36 | T__37 | T__38 | T__39 | T__40 | T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | RULE_LETTER_S | RULE_LETTER_M | RULE_LETTER_R | RULE_LETTER_F | RULE_LETTER_I | RULE_LETTER_L | RULE_LETTER_E | RULE_LETTER_V | RULE_LETTER_X | RULE_LETTER_OTHER | RULE_ASTERIX | RULE_DIGITS | RULE_WS | RULE_EOL ) - int alt9=30; + // InternalSemver.g:1:8: ( T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | T__51 | T__52 | T__53 | T__54 | T__55 | T__56 | RULE_LETTER_A | RULE_LETTER_C | RULE_LETTER_E | RULE_LETTER_F | RULE_LETTER_I | RULE_LETTER_K | RULE_LETTER_L | RULE_LETTER_M | RULE_LETTER_O | RULE_LETTER_P | RULE_LETTER_R | RULE_LETTER_S | RULE_LETTER_V | RULE_LETTER_W | RULE_LETTER_X | RULE_LETTER_OTHER | RULE_ASTERIX | RULE_DIGITS | RULE_WS | RULE_EOL ) + int alt9=36; alt9 = dfa9.predict(input); switch (alt9) { case 1 : - // InternalSemver.g:1:10: T__35 + // InternalSemver.g:1:10: T__41 { - mT__35(); + mT__41(); } break; case 2 : - // InternalSemver.g:1:16: T__36 + // InternalSemver.g:1:16: T__42 { - mT__36(); + mT__42(); } break; case 3 : - // InternalSemver.g:1:22: T__37 + // InternalSemver.g:1:22: T__43 { - mT__37(); + mT__43(); } break; case 4 : - // InternalSemver.g:1:28: T__38 + // InternalSemver.g:1:28: T__44 { - mT__38(); + mT__44(); } break; case 5 : - // InternalSemver.g:1:34: T__39 + // InternalSemver.g:1:34: T__45 { - mT__39(); + mT__45(); } break; case 6 : - // InternalSemver.g:1:40: T__40 + // InternalSemver.g:1:40: T__46 { - mT__40(); + mT__46(); } break; case 7 : - // InternalSemver.g:1:46: T__41 + // InternalSemver.g:1:46: T__47 { - mT__41(); + mT__47(); } break; case 8 : - // InternalSemver.g:1:52: T__42 + // InternalSemver.g:1:52: T__48 { - mT__42(); + mT__48(); } break; case 9 : - // InternalSemver.g:1:58: T__43 + // InternalSemver.g:1:58: T__49 { - mT__43(); + mT__49(); } break; case 10 : - // InternalSemver.g:1:64: T__44 + // InternalSemver.g:1:64: T__50 { - mT__44(); + mT__50(); } break; case 11 : - // InternalSemver.g:1:70: T__45 + // InternalSemver.g:1:70: T__51 { - mT__45(); + mT__51(); } break; case 12 : - // InternalSemver.g:1:76: T__46 + // InternalSemver.g:1:76: T__52 { - mT__46(); + mT__52(); } break; case 13 : - // InternalSemver.g:1:82: T__47 + // InternalSemver.g:1:82: T__53 { - mT__47(); + mT__53(); } break; case 14 : - // InternalSemver.g:1:88: T__48 + // InternalSemver.g:1:88: T__54 { - mT__48(); + mT__54(); } break; case 15 : - // InternalSemver.g:1:94: T__49 + // InternalSemver.g:1:94: T__55 { - mT__49(); + mT__55(); } break; case 16 : - // InternalSemver.g:1:100: T__50 + // InternalSemver.g:1:100: T__56 { - mT__50(); + mT__56(); } break; case 17 : - // InternalSemver.g:1:106: RULE_LETTER_S + // InternalSemver.g:1:106: RULE_LETTER_A { - mRULE_LETTER_S(); + mRULE_LETTER_A(); } break; case 18 : - // InternalSemver.g:1:120: RULE_LETTER_M + // InternalSemver.g:1:120: RULE_LETTER_C { - mRULE_LETTER_M(); + mRULE_LETTER_C(); } break; case 19 : - // InternalSemver.g:1:134: RULE_LETTER_R + // InternalSemver.g:1:134: RULE_LETTER_E { - mRULE_LETTER_R(); + mRULE_LETTER_E(); } break; @@ -1515,63 +1689,105 @@ public void mTokens() throws RecognitionException { } break; case 22 : - // InternalSemver.g:1:176: RULE_LETTER_L + // InternalSemver.g:1:176: RULE_LETTER_K { - mRULE_LETTER_L(); + mRULE_LETTER_K(); } break; case 23 : - // InternalSemver.g:1:190: RULE_LETTER_E + // InternalSemver.g:1:190: RULE_LETTER_L { - mRULE_LETTER_E(); + mRULE_LETTER_L(); } break; case 24 : - // InternalSemver.g:1:204: RULE_LETTER_V + // InternalSemver.g:1:204: RULE_LETTER_M { - mRULE_LETTER_V(); + mRULE_LETTER_M(); } break; case 25 : - // InternalSemver.g:1:218: RULE_LETTER_X + // InternalSemver.g:1:218: RULE_LETTER_O { - mRULE_LETTER_X(); + mRULE_LETTER_O(); } break; case 26 : - // InternalSemver.g:1:232: RULE_LETTER_OTHER + // InternalSemver.g:1:232: RULE_LETTER_P { - mRULE_LETTER_OTHER(); + mRULE_LETTER_P(); } break; case 27 : - // InternalSemver.g:1:250: RULE_ASTERIX + // InternalSemver.g:1:246: RULE_LETTER_R { - mRULE_ASTERIX(); + mRULE_LETTER_R(); } break; case 28 : - // InternalSemver.g:1:263: RULE_DIGITS + // InternalSemver.g:1:260: RULE_LETTER_S { - mRULE_DIGITS(); + mRULE_LETTER_S(); } break; case 29 : - // InternalSemver.g:1:275: RULE_WS + // InternalSemver.g:1:274: RULE_LETTER_V { - mRULE_WS(); + mRULE_LETTER_V(); } break; case 30 : - // InternalSemver.g:1:283: RULE_EOL + // InternalSemver.g:1:288: RULE_LETTER_W + { + mRULE_LETTER_W(); + + } + break; + case 31 : + // InternalSemver.g:1:302: RULE_LETTER_X + { + mRULE_LETTER_X(); + + } + break; + case 32 : + // InternalSemver.g:1:316: RULE_LETTER_OTHER + { + mRULE_LETTER_OTHER(); + + } + break; + case 33 : + // InternalSemver.g:1:334: RULE_ASTERIX + { + mRULE_ASTERIX(); + + } + break; + case 34 : + // InternalSemver.g:1:347: RULE_DIGITS + { + mRULE_DIGITS(); + + } + break; + case 35 : + // InternalSemver.g:1:359: RULE_WS + { + mRULE_WS(); + + } + break; + case 36 : + // InternalSemver.g:1:367: RULE_EOL { mRULE_EOL(); @@ -1585,31 +1801,37 @@ public void mTokens() throws RecognitionException { protected DFA9 dfa9 = new DFA9(this); static final String DFA9_eotS = - "\11\uffff\1\36\2\uffff\1\40\24\uffff"; + "\13\uffff\1\44\1\46\32\uffff"; static final String DFA9_eofS = - "\41\uffff"; + "\47\uffff"; static final String DFA9_minS = - "\1\11\10\uffff\1\75\2\uffff\1\75\24\uffff"; + "\1\11\12\uffff\2\75\32\uffff"; static final String DFA9_maxS = - "\1\ufeff\10\uffff\1\75\2\uffff\1\75\24\uffff"; + "\1\ufeff\12\uffff\2\75\32\uffff"; static final String DFA9_acceptS = - "\1\uffff\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\uffff\1\12\1\13\1\uffff\1\17\1\20\1\21\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\14\1\11\1\16\1\15"; + "\1\uffff\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\11\1\12\2\uffff\1\17\1\20\1\21\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\1\44\1\15\1\13\1\16\1\14"; static final String DFA9_specialS = - "\41\uffff}>"; + "\47\uffff}>"; static final String[] DFA9_transitionS = { - "\1\33\1\34\2\33\1\34\22\uffff\1\33\2\uffff\1\15\6\uffff\1\31\1\6\1\uffff\1\4\1\2\1\1\12\32\1\7\1\uffff\1\11\1\10\1\14\1\uffff\1\3\4\30\1\25\1\22\2\30\1\23\2\30\1\24\1\20\4\30\1\21\1\17\2\30\1\26\1\30\1\27\2\30\3\uffff\1\13\1\5\1\uffff\4\30\1\25\1\22\2\30\1\23\2\30\1\24\1\20\4\30\1\21\1\17\2\30\1\26\1\30\1\27\2\30\1\uffff\1\16\1\uffff\1\12\41\uffff\1\33\u15df\uffff\1\33\u097f\uffff\13\33\35\uffff\2\34\5\uffff\1\33\57\uffff\1\33\u0fa0\uffff\1\33\ucefe\uffff\1\33", + "\1\41\1\42\2\41\1\42\22\uffff\1\41\2\uffff\1\15\6\uffff\1\37\1\5\1\uffff\1\7\1\2\1\1\12\40\1\6\1\uffff\1\13\1\10\1\14\1\uffff\1\3\1\17\1\36\1\20\1\36\1\21\1\22\2\36\1\23\1\36\1\24\1\25\1\26\1\36\1\27\1\30\1\36\1\31\1\32\2\36\1\33\1\34\1\35\2\36\3\uffff\1\12\1\4\1\uffff\1\17\1\36\1\20\1\36\1\21\1\22\2\36\1\23\1\36\1\24\1\25\1\26\1\36\1\27\1\30\1\36\1\31\1\32\2\36\1\33\1\34\1\35\2\36\1\uffff\1\16\1\uffff\1\11\41\uffff\1\41\u15df\uffff\1\41\u097f\uffff\13\41\35\uffff\2\42\5\uffff\1\41\57\uffff\1\41\u0fa0\uffff\1\41\ucefe\uffff\1\41", + "", + "", + "", + "", + "", + "", "", "", "", "", + "\1\43", + "\1\45", "", "", "", "", - "\1\35", "", "", - "\1\37", "", "", "", @@ -1662,7 +1884,7 @@ public DFA9(BaseRecognizer recognizer) { this.transition = DFA9_transition; } public String getDescription() { - return "1:1: Tokens : ( T__35 | T__36 | T__37 | T__38 | T__39 | T__40 | T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | RULE_LETTER_S | RULE_LETTER_M | RULE_LETTER_R | RULE_LETTER_F | RULE_LETTER_I | RULE_LETTER_L | RULE_LETTER_E | RULE_LETTER_V | RULE_LETTER_X | RULE_LETTER_OTHER | RULE_ASTERIX | RULE_DIGITS | RULE_WS | RULE_EOL );"; + return "1:1: Tokens : ( T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | T__51 | T__52 | T__53 | T__54 | T__55 | T__56 | RULE_LETTER_A | RULE_LETTER_C | RULE_LETTER_E | RULE_LETTER_F | RULE_LETTER_I | RULE_LETTER_K | RULE_LETTER_L | RULE_LETTER_M | RULE_LETTER_O | RULE_LETTER_P | RULE_LETTER_R | RULE_LETTER_S | RULE_LETTER_V | RULE_LETTER_W | RULE_LETTER_X | RULE_LETTER_OTHER | RULE_ASTERIX | RULE_DIGITS | RULE_WS | RULE_EOL );"; } } diff --git a/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemverParser.java b/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemverParser.java index 9fe439cb1b..0e03239656 100644 --- a/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemverParser.java +++ b/plugins/org.eclipse.n4js.semver.ide/src-gen/org/eclipse/n4js/semver/ide/contentassist/antlr/internal/InternalSemverParser.java @@ -33,53 +33,59 @@ @SuppressWarnings("all") public class InternalSemverParser extends AbstractInternalContentAssistParser { public static final String[] tokenNames = new String[] { - "", "", "", "", "RULE_DIGITS", "RULE_LETTER_X", "RULE_ASTERIX", "RULE_LETTER_V", "RULE_LETTER_S", "RULE_LETTER_M", "RULE_LETTER_R", "RULE_LETTER_F", "RULE_LETTER_I", "RULE_LETTER_L", "RULE_LETTER_E", "RULE_LETTER_OTHER", "RULE_WS", "RULE_WHITESPACE_FRAGMENT", "RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT", "RULE_EOL", "RULE_DECIMAL_DIGIT_FRAGMENT", "RULE_HEX_DIGIT", "RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT", "RULE_ZWJ", "RULE_ZWNJ", "RULE_BOM", "RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT", "RULE_LINE_TERMINATOR_FRAGMENT", "RULE_SL_COMMENT_FRAGMENT", "RULE_ML_COMMENT_FRAGMENT", "RULE_UNICODE_COMBINING_MARK_FRAGMENT", "RULE_UNICODE_DIGIT_FRAGMENT", "RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT", "RULE_UNICODE_LETTER_FRAGMENT", "RULE_ANY_OTHER", "'/'", "'.'", "'@'", "'-'", "'_'", "'+'", "':'", "'='", "'<'", "'~'", "'^'", "'<='", "'>'", "'>='", "'#'", "'||'" + "", "", "", "", "RULE_ASTERIX", "RULE_DIGITS", "RULE_LETTER_X", "RULE_LETTER_V", "RULE_LETTER_A", "RULE_LETTER_C", "RULE_LETTER_E", "RULE_LETTER_F", "RULE_LETTER_I", "RULE_LETTER_K", "RULE_LETTER_L", "RULE_LETTER_M", "RULE_LETTER_O", "RULE_LETTER_P", "RULE_LETTER_R", "RULE_LETTER_S", "RULE_LETTER_W", "RULE_LETTER_OTHER", "RULE_WS", "RULE_WHITESPACE_FRAGMENT", "RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT", "RULE_EOL", "RULE_DECIMAL_DIGIT_FRAGMENT", "RULE_HEX_DIGIT", "RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT", "RULE_ZWJ", "RULE_ZWNJ", "RULE_BOM", "RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT", "RULE_LINE_TERMINATOR_FRAGMENT", "RULE_SL_COMMENT_FRAGMENT", "RULE_ML_COMMENT_FRAGMENT", "RULE_UNICODE_COMBINING_MARK_FRAGMENT", "RULE_UNICODE_DIGIT_FRAGMENT", "RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT", "RULE_UNICODE_LETTER_FRAGMENT", "RULE_ANY_OTHER", "'/'", "'.'", "'@'", "'_'", "'+'", "':'", "'-'", "'='", "'~'", "'^'", "'<'", "'>'", "'<='", "'>='", "'#'", "'||'" }; public static final int T__50=50; - public static final int RULE_WHITESPACE_FRAGMENT=17; - public static final int RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT=18; - public static final int RULE_EOL=19; - public static final int RULE_LETTER_OTHER=15; - public static final int RULE_UNICODE_COMBINING_MARK_FRAGMENT=30; - public static final int RULE_ZWNJ=24; - public static final int RULE_ASTERIX=6; - public static final int RULE_LETTER_E=14; - public static final int RULE_ML_COMMENT_FRAGMENT=29; - public static final int RULE_DIGITS=4; - public static final int RULE_ZWJ=23; - public static final int RULE_SL_COMMENT_FRAGMENT=28; - public static final int RULE_UNICODE_DIGIT_FRAGMENT=31; - public static final int T__37=37; - public static final int RULE_LETTER_R=10; - public static final int T__38=38; - public static final int RULE_LETTER_S=8; - public static final int T__39=39; + public static final int RULE_WHITESPACE_FRAGMENT=23; + public static final int T__55=55; + public static final int T__56=56; + public static final int T__51=51; + public static final int T__52=52; + public static final int T__53=53; + public static final int T__54=54; + public static final int RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT=24; + public static final int RULE_EOL=25; + public static final int RULE_LETTER_OTHER=21; + public static final int RULE_UNICODE_COMBINING_MARK_FRAGMENT=36; + public static final int RULE_ZWNJ=30; + public static final int RULE_LETTER_A=8; + public static final int RULE_LETTER_C=9; + public static final int RULE_ASTERIX=4; + public static final int RULE_LETTER_E=10; + public static final int RULE_ML_COMMENT_FRAGMENT=35; + public static final int RULE_DIGITS=5; + public static final int RULE_LETTER_O=16; + public static final int RULE_ZWJ=29; + public static final int RULE_SL_COMMENT_FRAGMENT=34; + public static final int RULE_LETTER_P=17; + public static final int RULE_UNICODE_DIGIT_FRAGMENT=37; + public static final int RULE_LETTER_R=18; + public static final int RULE_LETTER_S=19; public static final int RULE_LETTER_F=11; - public static final int RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT=26; - public static final int T__35=35; - public static final int T__36=36; + public static final int RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT=32; public static final int RULE_LETTER_I=12; public static final int EOF=-1; - public static final int RULE_LETTER_L=13; - public static final int RULE_LETTER_M=9; - public static final int RULE_WS=16; - public static final int RULE_BOM=25; + public static final int RULE_LETTER_K=13; + public static final int RULE_LETTER_L=14; + public static final int RULE_LETTER_M=15; + public static final int RULE_WS=22; + public static final int RULE_BOM=31; public static final int RULE_LETTER_V=7; - public static final int RULE_LETTER_X=5; - public static final int RULE_ANY_OTHER=34; - public static final int RULE_LINE_TERMINATOR_FRAGMENT=27; - public static final int RULE_UNICODE_LETTER_FRAGMENT=33; - public static final int RULE_DECIMAL_DIGIT_FRAGMENT=20; + public static final int RULE_LETTER_W=20; + public static final int RULE_LETTER_X=6; + public static final int RULE_ANY_OTHER=40; + public static final int RULE_LINE_TERMINATOR_FRAGMENT=33; + public static final int RULE_UNICODE_LETTER_FRAGMENT=39; + public static final int RULE_DECIMAL_DIGIT_FRAGMENT=26; public static final int T__48=48; public static final int T__49=49; public static final int T__44=44; public static final int T__45=45; - public static final int RULE_HEX_DIGIT=21; - public static final int RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT=22; - public static final int RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT=32; + public static final int RULE_HEX_DIGIT=27; + public static final int RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT=28; + public static final int RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT=38; public static final int T__46=46; public static final int T__47=47; - public static final int T__40=40; public static final int T__41=41; public static final int T__42=42; public static final int T__43=43; @@ -544,23 +550,23 @@ public final void ruleURLSemver() throws RecognitionException { // $ANTLR end "ruleURLSemver" - // $ANTLR start "entryRuleTagVersionRequirement" - // InternalSemver.g:186:1: entryRuleTagVersionRequirement : ruleTagVersionRequirement EOF ; - public final void entryRuleTagVersionRequirement() throws RecognitionException { + // $ANTLR start "entryRuleWorkspaceVersionRequirement" + // InternalSemver.g:186:1: entryRuleWorkspaceVersionRequirement : ruleWorkspaceVersionRequirement EOF ; + public final void entryRuleWorkspaceVersionRequirement() throws RecognitionException { try { - // InternalSemver.g:187:1: ( ruleTagVersionRequirement EOF ) - // InternalSemver.g:188:1: ruleTagVersionRequirement EOF + // InternalSemver.g:187:1: ( ruleWorkspaceVersionRequirement EOF ) + // InternalSemver.g:188:1: ruleWorkspaceVersionRequirement EOF { if ( state.backtracking==0 ) { - before(grammarAccess.getTagVersionRequirementRule()); + before(grammarAccess.getWorkspaceVersionRequirementRule()); } pushFollow(FOLLOW_1); - ruleTagVersionRequirement(); + ruleWorkspaceVersionRequirement(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getTagVersionRequirementRule()); + after(grammarAccess.getWorkspaceVersionRequirementRule()); } match(input,EOF,FOLLOW_2); if (state.failed) return ; @@ -575,30 +581,30 @@ public final void entryRuleTagVersionRequirement() throws RecognitionException { } return ; } - // $ANTLR end "entryRuleTagVersionRequirement" + // $ANTLR end "entryRuleWorkspaceVersionRequirement" - // $ANTLR start "ruleTagVersionRequirement" - // InternalSemver.g:195:1: ruleTagVersionRequirement : ( ( rule__TagVersionRequirement__TagNameAssignment ) ) ; - public final void ruleTagVersionRequirement() throws RecognitionException { + // $ANTLR start "ruleWorkspaceVersionRequirement" + // InternalSemver.g:195:1: ruleWorkspaceVersionRequirement : ( ( rule__WorkspaceVersionRequirement__Group__0 ) ) ; + public final void ruleWorkspaceVersionRequirement() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:199:2: ( ( ( rule__TagVersionRequirement__TagNameAssignment ) ) ) - // InternalSemver.g:200:2: ( ( rule__TagVersionRequirement__TagNameAssignment ) ) + // InternalSemver.g:199:2: ( ( ( rule__WorkspaceVersionRequirement__Group__0 ) ) ) + // InternalSemver.g:200:2: ( ( rule__WorkspaceVersionRequirement__Group__0 ) ) { - // InternalSemver.g:200:2: ( ( rule__TagVersionRequirement__TagNameAssignment ) ) - // InternalSemver.g:201:3: ( rule__TagVersionRequirement__TagNameAssignment ) + // InternalSemver.g:200:2: ( ( rule__WorkspaceVersionRequirement__Group__0 ) ) + // InternalSemver.g:201:3: ( rule__WorkspaceVersionRequirement__Group__0 ) { if ( state.backtracking==0 ) { - before(grammarAccess.getTagVersionRequirementAccess().getTagNameAssignment()); + before(grammarAccess.getWorkspaceVersionRequirementAccess().getGroup()); } - // InternalSemver.g:202:3: ( rule__TagVersionRequirement__TagNameAssignment ) - // InternalSemver.g:202:4: rule__TagVersionRequirement__TagNameAssignment + // InternalSemver.g:202:3: ( rule__WorkspaceVersionRequirement__Group__0 ) + // InternalSemver.g:202:4: rule__WorkspaceVersionRequirement__Group__0 { pushFollow(FOLLOW_2); - rule__TagVersionRequirement__TagNameAssignment(); + rule__WorkspaceVersionRequirement__Group__0(); state._fsp--; if (state.failed) return ; @@ -606,7 +612,7 @@ public final void ruleTagVersionRequirement() throws RecognitionException { } if ( state.backtracking==0 ) { - after(grammarAccess.getTagVersionRequirementAccess().getTagNameAssignment()); + after(grammarAccess.getWorkspaceVersionRequirementAccess().getGroup()); } } @@ -626,7 +632,7 @@ public final void ruleTagVersionRequirement() throws RecognitionException { } return ; } - // $ANTLR end "ruleTagVersionRequirement" + // $ANTLR end "ruleWorkspaceVersionRequirement" // $ANTLR start "entryRuleGitHubVersionRequirement" @@ -714,12 +720,97 @@ public final void ruleGitHubVersionRequirement() throws RecognitionException { // $ANTLR end "ruleGitHubVersionRequirement" + // $ANTLR start "entryRuleTagVersionRequirement" + // InternalSemver.g:236:1: entryRuleTagVersionRequirement : ruleTagVersionRequirement EOF ; + public final void entryRuleTagVersionRequirement() throws RecognitionException { + try { + // InternalSemver.g:237:1: ( ruleTagVersionRequirement EOF ) + // InternalSemver.g:238:1: ruleTagVersionRequirement EOF + { + if ( state.backtracking==0 ) { + before(grammarAccess.getTagVersionRequirementRule()); + } + pushFollow(FOLLOW_1); + ruleTagVersionRequirement(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getTagVersionRequirementRule()); + } + match(input,EOF,FOLLOW_2); if (state.failed) return ; + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return ; + } + // $ANTLR end "entryRuleTagVersionRequirement" + + + // $ANTLR start "ruleTagVersionRequirement" + // InternalSemver.g:245:1: ruleTagVersionRequirement : ( ( rule__TagVersionRequirement__TagNameAssignment ) ) ; + public final void ruleTagVersionRequirement() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:249:2: ( ( ( rule__TagVersionRequirement__TagNameAssignment ) ) ) + // InternalSemver.g:250:2: ( ( rule__TagVersionRequirement__TagNameAssignment ) ) + { + // InternalSemver.g:250:2: ( ( rule__TagVersionRequirement__TagNameAssignment ) ) + // InternalSemver.g:251:3: ( rule__TagVersionRequirement__TagNameAssignment ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getTagVersionRequirementAccess().getTagNameAssignment()); + } + // InternalSemver.g:252:3: ( rule__TagVersionRequirement__TagNameAssignment ) + // InternalSemver.g:252:4: rule__TagVersionRequirement__TagNameAssignment + { + pushFollow(FOLLOW_2); + rule__TagVersionRequirement__TagNameAssignment(); + + state._fsp--; + if (state.failed) return ; + + } + + if ( state.backtracking==0 ) { + after(grammarAccess.getTagVersionRequirementAccess().getTagNameAssignment()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "ruleTagVersionRequirement" + + // $ANTLR start "entryRuleVersionRangeSetRequirement" - // InternalSemver.g:236:1: entryRuleVersionRangeSetRequirement : ruleVersionRangeSetRequirement EOF ; + // InternalSemver.g:261:1: entryRuleVersionRangeSetRequirement : ruleVersionRangeSetRequirement EOF ; public final void entryRuleVersionRangeSetRequirement() throws RecognitionException { try { - // InternalSemver.g:237:1: ( ruleVersionRangeSetRequirement EOF ) - // InternalSemver.g:238:1: ruleVersionRangeSetRequirement EOF + // InternalSemver.g:262:1: ( ruleVersionRangeSetRequirement EOF ) + // InternalSemver.g:263:1: ruleVersionRangeSetRequirement EOF { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeSetRequirementRule()); @@ -749,23 +840,23 @@ public final void entryRuleVersionRangeSetRequirement() throws RecognitionExcept // $ANTLR start "ruleVersionRangeSetRequirement" - // InternalSemver.g:245:1: ruleVersionRangeSetRequirement : ( ( rule__VersionRangeSetRequirement__Group__0 ) ) ; + // InternalSemver.g:270:1: ruleVersionRangeSetRequirement : ( ( rule__VersionRangeSetRequirement__Group__0 ) ) ; public final void ruleVersionRangeSetRequirement() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:249:2: ( ( ( rule__VersionRangeSetRequirement__Group__0 ) ) ) - // InternalSemver.g:250:2: ( ( rule__VersionRangeSetRequirement__Group__0 ) ) + // InternalSemver.g:274:2: ( ( ( rule__VersionRangeSetRequirement__Group__0 ) ) ) + // InternalSemver.g:275:2: ( ( rule__VersionRangeSetRequirement__Group__0 ) ) { - // InternalSemver.g:250:2: ( ( rule__VersionRangeSetRequirement__Group__0 ) ) - // InternalSemver.g:251:3: ( rule__VersionRangeSetRequirement__Group__0 ) + // InternalSemver.g:275:2: ( ( rule__VersionRangeSetRequirement__Group__0 ) ) + // InternalSemver.g:276:3: ( rule__VersionRangeSetRequirement__Group__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeSetRequirementAccess().getGroup()); } - // InternalSemver.g:252:3: ( rule__VersionRangeSetRequirement__Group__0 ) - // InternalSemver.g:252:4: rule__VersionRangeSetRequirement__Group__0 + // InternalSemver.g:277:3: ( rule__VersionRangeSetRequirement__Group__0 ) + // InternalSemver.g:277:4: rule__VersionRangeSetRequirement__Group__0 { pushFollow(FOLLOW_2); rule__VersionRangeSetRequirement__Group__0(); @@ -800,11 +891,11 @@ public final void ruleVersionRangeSetRequirement() throws RecognitionException { // $ANTLR start "entryRuleVersionRange" - // InternalSemver.g:261:1: entryRuleVersionRange : ruleVersionRange EOF ; + // InternalSemver.g:286:1: entryRuleVersionRange : ruleVersionRange EOF ; public final void entryRuleVersionRange() throws RecognitionException { try { - // InternalSemver.g:262:1: ( ruleVersionRange EOF ) - // InternalSemver.g:263:1: ruleVersionRange EOF + // InternalSemver.g:287:1: ( ruleVersionRange EOF ) + // InternalSemver.g:288:1: ruleVersionRange EOF { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeRule()); @@ -834,23 +925,23 @@ public final void entryRuleVersionRange() throws RecognitionException { // $ANTLR start "ruleVersionRange" - // InternalSemver.g:270:1: ruleVersionRange : ( ( rule__VersionRange__Alternatives ) ) ; + // InternalSemver.g:295:1: ruleVersionRange : ( ( rule__VersionRange__Alternatives ) ) ; public final void ruleVersionRange() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:274:2: ( ( ( rule__VersionRange__Alternatives ) ) ) - // InternalSemver.g:275:2: ( ( rule__VersionRange__Alternatives ) ) + // InternalSemver.g:299:2: ( ( ( rule__VersionRange__Alternatives ) ) ) + // InternalSemver.g:300:2: ( ( rule__VersionRange__Alternatives ) ) { - // InternalSemver.g:275:2: ( ( rule__VersionRange__Alternatives ) ) - // InternalSemver.g:276:3: ( rule__VersionRange__Alternatives ) + // InternalSemver.g:300:2: ( ( rule__VersionRange__Alternatives ) ) + // InternalSemver.g:301:3: ( rule__VersionRange__Alternatives ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeAccess().getAlternatives()); } - // InternalSemver.g:277:3: ( rule__VersionRange__Alternatives ) - // InternalSemver.g:277:4: rule__VersionRange__Alternatives + // InternalSemver.g:302:3: ( rule__VersionRange__Alternatives ) + // InternalSemver.g:302:4: rule__VersionRange__Alternatives { pushFollow(FOLLOW_2); rule__VersionRange__Alternatives(); @@ -885,11 +976,11 @@ public final void ruleVersionRange() throws RecognitionException { // $ANTLR start "entryRuleHyphenVersionRange" - // InternalSemver.g:286:1: entryRuleHyphenVersionRange : ruleHyphenVersionRange EOF ; + // InternalSemver.g:311:1: entryRuleHyphenVersionRange : ruleHyphenVersionRange EOF ; public final void entryRuleHyphenVersionRange() throws RecognitionException { try { - // InternalSemver.g:287:1: ( ruleHyphenVersionRange EOF ) - // InternalSemver.g:288:1: ruleHyphenVersionRange EOF + // InternalSemver.g:312:1: ( ruleHyphenVersionRange EOF ) + // InternalSemver.g:313:1: ruleHyphenVersionRange EOF { if ( state.backtracking==0 ) { before(grammarAccess.getHyphenVersionRangeRule()); @@ -919,23 +1010,23 @@ public final void entryRuleHyphenVersionRange() throws RecognitionException { // $ANTLR start "ruleHyphenVersionRange" - // InternalSemver.g:295:1: ruleHyphenVersionRange : ( ( rule__HyphenVersionRange__Group__0 ) ) ; + // InternalSemver.g:320:1: ruleHyphenVersionRange : ( ( rule__HyphenVersionRange__Group__0 ) ) ; public final void ruleHyphenVersionRange() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:299:2: ( ( ( rule__HyphenVersionRange__Group__0 ) ) ) - // InternalSemver.g:300:2: ( ( rule__HyphenVersionRange__Group__0 ) ) + // InternalSemver.g:324:2: ( ( ( rule__HyphenVersionRange__Group__0 ) ) ) + // InternalSemver.g:325:2: ( ( rule__HyphenVersionRange__Group__0 ) ) { - // InternalSemver.g:300:2: ( ( rule__HyphenVersionRange__Group__0 ) ) - // InternalSemver.g:301:3: ( rule__HyphenVersionRange__Group__0 ) + // InternalSemver.g:325:2: ( ( rule__HyphenVersionRange__Group__0 ) ) + // InternalSemver.g:326:3: ( rule__HyphenVersionRange__Group__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getHyphenVersionRangeAccess().getGroup()); } - // InternalSemver.g:302:3: ( rule__HyphenVersionRange__Group__0 ) - // InternalSemver.g:302:4: rule__HyphenVersionRange__Group__0 + // InternalSemver.g:327:3: ( rule__HyphenVersionRange__Group__0 ) + // InternalSemver.g:327:4: rule__HyphenVersionRange__Group__0 { pushFollow(FOLLOW_2); rule__HyphenVersionRange__Group__0(); @@ -970,11 +1061,11 @@ public final void ruleHyphenVersionRange() throws RecognitionException { // $ANTLR start "entryRuleVersionRangeContraint" - // InternalSemver.g:311:1: entryRuleVersionRangeContraint : ruleVersionRangeContraint EOF ; + // InternalSemver.g:336:1: entryRuleVersionRangeContraint : ruleVersionRangeContraint EOF ; public final void entryRuleVersionRangeContraint() throws RecognitionException { try { - // InternalSemver.g:312:1: ( ruleVersionRangeContraint EOF ) - // InternalSemver.g:313:1: ruleVersionRangeContraint EOF + // InternalSemver.g:337:1: ( ruleVersionRangeContraint EOF ) + // InternalSemver.g:338:1: ruleVersionRangeContraint EOF { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeContraintRule()); @@ -1004,23 +1095,23 @@ public final void entryRuleVersionRangeContraint() throws RecognitionException { // $ANTLR start "ruleVersionRangeContraint" - // InternalSemver.g:320:1: ruleVersionRangeContraint : ( ( rule__VersionRangeContraint__Group__0 ) ) ; + // InternalSemver.g:345:1: ruleVersionRangeContraint : ( ( rule__VersionRangeContraint__Group__0 ) ) ; public final void ruleVersionRangeContraint() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:324:2: ( ( ( rule__VersionRangeContraint__Group__0 ) ) ) - // InternalSemver.g:325:2: ( ( rule__VersionRangeContraint__Group__0 ) ) + // InternalSemver.g:349:2: ( ( ( rule__VersionRangeContraint__Group__0 ) ) ) + // InternalSemver.g:350:2: ( ( rule__VersionRangeContraint__Group__0 ) ) { - // InternalSemver.g:325:2: ( ( rule__VersionRangeContraint__Group__0 ) ) - // InternalSemver.g:326:3: ( rule__VersionRangeContraint__Group__0 ) + // InternalSemver.g:350:2: ( ( rule__VersionRangeContraint__Group__0 ) ) + // InternalSemver.g:351:3: ( rule__VersionRangeContraint__Group__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeContraintAccess().getGroup()); } - // InternalSemver.g:327:3: ( rule__VersionRangeContraint__Group__0 ) - // InternalSemver.g:327:4: rule__VersionRangeContraint__Group__0 + // InternalSemver.g:352:3: ( rule__VersionRangeContraint__Group__0 ) + // InternalSemver.g:352:4: rule__VersionRangeContraint__Group__0 { pushFollow(FOLLOW_2); rule__VersionRangeContraint__Group__0(); @@ -1055,11 +1146,11 @@ public final void ruleVersionRangeContraint() throws RecognitionException { // $ANTLR start "entryRuleSimpleVersion" - // InternalSemver.g:336:1: entryRuleSimpleVersion : ruleSimpleVersion EOF ; + // InternalSemver.g:361:1: entryRuleSimpleVersion : ruleSimpleVersion EOF ; public final void entryRuleSimpleVersion() throws RecognitionException { try { - // InternalSemver.g:337:1: ( ruleSimpleVersion EOF ) - // InternalSemver.g:338:1: ruleSimpleVersion EOF + // InternalSemver.g:362:1: ( ruleSimpleVersion EOF ) + // InternalSemver.g:363:1: ruleSimpleVersion EOF { if ( state.backtracking==0 ) { before(grammarAccess.getSimpleVersionRule()); @@ -1089,23 +1180,23 @@ public final void entryRuleSimpleVersion() throws RecognitionException { // $ANTLR start "ruleSimpleVersion" - // InternalSemver.g:345:1: ruleSimpleVersion : ( ( rule__SimpleVersion__Group__0 ) ) ; + // InternalSemver.g:370:1: ruleSimpleVersion : ( ( rule__SimpleVersion__Group__0 ) ) ; public final void ruleSimpleVersion() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:349:2: ( ( ( rule__SimpleVersion__Group__0 ) ) ) - // InternalSemver.g:350:2: ( ( rule__SimpleVersion__Group__0 ) ) + // InternalSemver.g:374:2: ( ( ( rule__SimpleVersion__Group__0 ) ) ) + // InternalSemver.g:375:2: ( ( rule__SimpleVersion__Group__0 ) ) { - // InternalSemver.g:350:2: ( ( rule__SimpleVersion__Group__0 ) ) - // InternalSemver.g:351:3: ( rule__SimpleVersion__Group__0 ) + // InternalSemver.g:375:2: ( ( rule__SimpleVersion__Group__0 ) ) + // InternalSemver.g:376:3: ( rule__SimpleVersion__Group__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getSimpleVersionAccess().getGroup()); } - // InternalSemver.g:352:3: ( rule__SimpleVersion__Group__0 ) - // InternalSemver.g:352:4: rule__SimpleVersion__Group__0 + // InternalSemver.g:377:3: ( rule__SimpleVersion__Group__0 ) + // InternalSemver.g:377:4: rule__SimpleVersion__Group__0 { pushFollow(FOLLOW_2); rule__SimpleVersion__Group__0(); @@ -1140,11 +1231,11 @@ public final void ruleSimpleVersion() throws RecognitionException { // $ANTLR start "entryRuleVersionNumber" - // InternalSemver.g:361:1: entryRuleVersionNumber : ruleVersionNumber EOF ; + // InternalSemver.g:386:1: entryRuleVersionNumber : ruleVersionNumber EOF ; public final void entryRuleVersionNumber() throws RecognitionException { try { - // InternalSemver.g:362:1: ( ruleVersionNumber EOF ) - // InternalSemver.g:363:1: ruleVersionNumber EOF + // InternalSemver.g:387:1: ( ruleVersionNumber EOF ) + // InternalSemver.g:388:1: ruleVersionNumber EOF { if ( state.backtracking==0 ) { before(grammarAccess.getVersionNumberRule()); @@ -1174,23 +1265,23 @@ public final void entryRuleVersionNumber() throws RecognitionException { // $ANTLR start "ruleVersionNumber" - // InternalSemver.g:370:1: ruleVersionNumber : ( ( rule__VersionNumber__Group__0 ) ) ; + // InternalSemver.g:395:1: ruleVersionNumber : ( ( rule__VersionNumber__Group__0 ) ) ; public final void ruleVersionNumber() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:374:2: ( ( ( rule__VersionNumber__Group__0 ) ) ) - // InternalSemver.g:375:2: ( ( rule__VersionNumber__Group__0 ) ) + // InternalSemver.g:399:2: ( ( ( rule__VersionNumber__Group__0 ) ) ) + // InternalSemver.g:400:2: ( ( rule__VersionNumber__Group__0 ) ) { - // InternalSemver.g:375:2: ( ( rule__VersionNumber__Group__0 ) ) - // InternalSemver.g:376:3: ( rule__VersionNumber__Group__0 ) + // InternalSemver.g:400:2: ( ( rule__VersionNumber__Group__0 ) ) + // InternalSemver.g:401:3: ( rule__VersionNumber__Group__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionNumberAccess().getGroup()); } - // InternalSemver.g:377:3: ( rule__VersionNumber__Group__0 ) - // InternalSemver.g:377:4: rule__VersionNumber__Group__0 + // InternalSemver.g:402:3: ( rule__VersionNumber__Group__0 ) + // InternalSemver.g:402:4: rule__VersionNumber__Group__0 { pushFollow(FOLLOW_2); rule__VersionNumber__Group__0(); @@ -1225,11 +1316,11 @@ public final void ruleVersionNumber() throws RecognitionException { // $ANTLR start "entryRuleVersionPart" - // InternalSemver.g:386:1: entryRuleVersionPart : ruleVersionPart EOF ; + // InternalSemver.g:411:1: entryRuleVersionPart : ruleVersionPart EOF ; public final void entryRuleVersionPart() throws RecognitionException { try { - // InternalSemver.g:387:1: ( ruleVersionPart EOF ) - // InternalSemver.g:388:1: ruleVersionPart EOF + // InternalSemver.g:412:1: ( ruleVersionPart EOF ) + // InternalSemver.g:413:1: ruleVersionPart EOF { if ( state.backtracking==0 ) { before(grammarAccess.getVersionPartRule()); @@ -1259,23 +1350,23 @@ public final void entryRuleVersionPart() throws RecognitionException { // $ANTLR start "ruleVersionPart" - // InternalSemver.g:395:1: ruleVersionPart : ( ( rule__VersionPart__Alternatives ) ) ; + // InternalSemver.g:420:1: ruleVersionPart : ( ( rule__VersionPart__Alternatives ) ) ; public final void ruleVersionPart() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:399:2: ( ( ( rule__VersionPart__Alternatives ) ) ) - // InternalSemver.g:400:2: ( ( rule__VersionPart__Alternatives ) ) + // InternalSemver.g:424:2: ( ( ( rule__VersionPart__Alternatives ) ) ) + // InternalSemver.g:425:2: ( ( rule__VersionPart__Alternatives ) ) { - // InternalSemver.g:400:2: ( ( rule__VersionPart__Alternatives ) ) - // InternalSemver.g:401:3: ( rule__VersionPart__Alternatives ) + // InternalSemver.g:425:2: ( ( rule__VersionPart__Alternatives ) ) + // InternalSemver.g:426:3: ( rule__VersionPart__Alternatives ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionPartAccess().getAlternatives()); } - // InternalSemver.g:402:3: ( rule__VersionPart__Alternatives ) - // InternalSemver.g:402:4: rule__VersionPart__Alternatives + // InternalSemver.g:427:3: ( rule__VersionPart__Alternatives ) + // InternalSemver.g:427:4: rule__VersionPart__Alternatives { pushFollow(FOLLOW_2); rule__VersionPart__Alternatives(); @@ -1310,11 +1401,11 @@ public final void ruleVersionPart() throws RecognitionException { // $ANTLR start "entryRuleQualifier" - // InternalSemver.g:411:1: entryRuleQualifier : ruleQualifier EOF ; + // InternalSemver.g:436:1: entryRuleQualifier : ruleQualifier EOF ; public final void entryRuleQualifier() throws RecognitionException { try { - // InternalSemver.g:412:1: ( ruleQualifier EOF ) - // InternalSemver.g:413:1: ruleQualifier EOF + // InternalSemver.g:437:1: ( ruleQualifier EOF ) + // InternalSemver.g:438:1: ruleQualifier EOF { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierRule()); @@ -1344,23 +1435,23 @@ public final void entryRuleQualifier() throws RecognitionException { // $ANTLR start "ruleQualifier" - // InternalSemver.g:420:1: ruleQualifier : ( ( rule__Qualifier__Alternatives ) ) ; + // InternalSemver.g:445:1: ruleQualifier : ( ( rule__Qualifier__Alternatives ) ) ; public final void ruleQualifier() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:424:2: ( ( ( rule__Qualifier__Alternatives ) ) ) - // InternalSemver.g:425:2: ( ( rule__Qualifier__Alternatives ) ) + // InternalSemver.g:449:2: ( ( ( rule__Qualifier__Alternatives ) ) ) + // InternalSemver.g:450:2: ( ( rule__Qualifier__Alternatives ) ) { - // InternalSemver.g:425:2: ( ( rule__Qualifier__Alternatives ) ) - // InternalSemver.g:426:3: ( rule__Qualifier__Alternatives ) + // InternalSemver.g:450:2: ( ( rule__Qualifier__Alternatives ) ) + // InternalSemver.g:451:3: ( rule__Qualifier__Alternatives ) { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierAccess().getAlternatives()); } - // InternalSemver.g:427:3: ( rule__Qualifier__Alternatives ) - // InternalSemver.g:427:4: rule__Qualifier__Alternatives + // InternalSemver.g:452:3: ( rule__Qualifier__Alternatives ) + // InternalSemver.g:452:4: rule__Qualifier__Alternatives { pushFollow(FOLLOW_2); rule__Qualifier__Alternatives(); @@ -1395,11 +1486,11 @@ public final void ruleQualifier() throws RecognitionException { // $ANTLR start "entryRuleQualifierTag" - // InternalSemver.g:436:1: entryRuleQualifierTag : ruleQualifierTag EOF ; + // InternalSemver.g:461:1: entryRuleQualifierTag : ruleQualifierTag EOF ; public final void entryRuleQualifierTag() throws RecognitionException { try { - // InternalSemver.g:437:1: ( ruleQualifierTag EOF ) - // InternalSemver.g:438:1: ruleQualifierTag EOF + // InternalSemver.g:462:1: ( ruleQualifierTag EOF ) + // InternalSemver.g:463:1: ruleQualifierTag EOF { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierTagRule()); @@ -1429,23 +1520,23 @@ public final void entryRuleQualifierTag() throws RecognitionException { // $ANTLR start "ruleQualifierTag" - // InternalSemver.g:445:1: ruleQualifierTag : ( ( rule__QualifierTag__Group__0 ) ) ; + // InternalSemver.g:470:1: ruleQualifierTag : ( ( rule__QualifierTag__Group__0 ) ) ; public final void ruleQualifierTag() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:449:2: ( ( ( rule__QualifierTag__Group__0 ) ) ) - // InternalSemver.g:450:2: ( ( rule__QualifierTag__Group__0 ) ) + // InternalSemver.g:474:2: ( ( ( rule__QualifierTag__Group__0 ) ) ) + // InternalSemver.g:475:2: ( ( rule__QualifierTag__Group__0 ) ) { - // InternalSemver.g:450:2: ( ( rule__QualifierTag__Group__0 ) ) - // InternalSemver.g:451:3: ( rule__QualifierTag__Group__0 ) + // InternalSemver.g:475:2: ( ( rule__QualifierTag__Group__0 ) ) + // InternalSemver.g:476:3: ( rule__QualifierTag__Group__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierTagAccess().getGroup()); } - // InternalSemver.g:452:3: ( rule__QualifierTag__Group__0 ) - // InternalSemver.g:452:4: rule__QualifierTag__Group__0 + // InternalSemver.g:477:3: ( rule__QualifierTag__Group__0 ) + // InternalSemver.g:477:4: rule__QualifierTag__Group__0 { pushFollow(FOLLOW_2); rule__QualifierTag__Group__0(); @@ -1480,11 +1571,11 @@ public final void ruleQualifierTag() throws RecognitionException { // $ANTLR start "entryRuleFILE_TAG" - // InternalSemver.g:461:1: entryRuleFILE_TAG : ruleFILE_TAG EOF ; + // InternalSemver.g:486:1: entryRuleFILE_TAG : ruleFILE_TAG EOF ; public final void entryRuleFILE_TAG() throws RecognitionException { try { - // InternalSemver.g:462:1: ( ruleFILE_TAG EOF ) - // InternalSemver.g:463:1: ruleFILE_TAG EOF + // InternalSemver.g:487:1: ( ruleFILE_TAG EOF ) + // InternalSemver.g:488:1: ruleFILE_TAG EOF { if ( state.backtracking==0 ) { before(grammarAccess.getFILE_TAGRule()); @@ -1514,23 +1605,23 @@ public final void entryRuleFILE_TAG() throws RecognitionException { // $ANTLR start "ruleFILE_TAG" - // InternalSemver.g:470:1: ruleFILE_TAG : ( ( rule__FILE_TAG__Group__0 ) ) ; + // InternalSemver.g:495:1: ruleFILE_TAG : ( ( rule__FILE_TAG__Group__0 ) ) ; public final void ruleFILE_TAG() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:474:2: ( ( ( rule__FILE_TAG__Group__0 ) ) ) - // InternalSemver.g:475:2: ( ( rule__FILE_TAG__Group__0 ) ) + // InternalSemver.g:499:2: ( ( ( rule__FILE_TAG__Group__0 ) ) ) + // InternalSemver.g:500:2: ( ( rule__FILE_TAG__Group__0 ) ) { - // InternalSemver.g:475:2: ( ( rule__FILE_TAG__Group__0 ) ) - // InternalSemver.g:476:3: ( rule__FILE_TAG__Group__0 ) + // InternalSemver.g:500:2: ( ( rule__FILE_TAG__Group__0 ) ) + // InternalSemver.g:501:3: ( rule__FILE_TAG__Group__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getFILE_TAGAccess().getGroup()); } - // InternalSemver.g:477:3: ( rule__FILE_TAG__Group__0 ) - // InternalSemver.g:477:4: rule__FILE_TAG__Group__0 + // InternalSemver.g:502:3: ( rule__FILE_TAG__Group__0 ) + // InternalSemver.g:502:4: rule__FILE_TAG__Group__0 { pushFollow(FOLLOW_2); rule__FILE_TAG__Group__0(); @@ -1565,11 +1656,11 @@ public final void ruleFILE_TAG() throws RecognitionException { // $ANTLR start "entryRuleSEMVER_TAG" - // InternalSemver.g:486:1: entryRuleSEMVER_TAG : ruleSEMVER_TAG EOF ; + // InternalSemver.g:511:1: entryRuleSEMVER_TAG : ruleSEMVER_TAG EOF ; public final void entryRuleSEMVER_TAG() throws RecognitionException { try { - // InternalSemver.g:487:1: ( ruleSEMVER_TAG EOF ) - // InternalSemver.g:488:1: ruleSEMVER_TAG EOF + // InternalSemver.g:512:1: ( ruleSEMVER_TAG EOF ) + // InternalSemver.g:513:1: ruleSEMVER_TAG EOF { if ( state.backtracking==0 ) { before(grammarAccess.getSEMVER_TAGRule()); @@ -1599,23 +1690,23 @@ public final void entryRuleSEMVER_TAG() throws RecognitionException { // $ANTLR start "ruleSEMVER_TAG" - // InternalSemver.g:495:1: ruleSEMVER_TAG : ( ( rule__SEMVER_TAG__Group__0 ) ) ; + // InternalSemver.g:520:1: ruleSEMVER_TAG : ( ( rule__SEMVER_TAG__Group__0 ) ) ; public final void ruleSEMVER_TAG() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:499:2: ( ( ( rule__SEMVER_TAG__Group__0 ) ) ) - // InternalSemver.g:500:2: ( ( rule__SEMVER_TAG__Group__0 ) ) + // InternalSemver.g:524:2: ( ( ( rule__SEMVER_TAG__Group__0 ) ) ) + // InternalSemver.g:525:2: ( ( rule__SEMVER_TAG__Group__0 ) ) { - // InternalSemver.g:500:2: ( ( rule__SEMVER_TAG__Group__0 ) ) - // InternalSemver.g:501:3: ( rule__SEMVER_TAG__Group__0 ) + // InternalSemver.g:525:2: ( ( rule__SEMVER_TAG__Group__0 ) ) + // InternalSemver.g:526:3: ( rule__SEMVER_TAG__Group__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getSEMVER_TAGAccess().getGroup()); } - // InternalSemver.g:502:3: ( rule__SEMVER_TAG__Group__0 ) - // InternalSemver.g:502:4: rule__SEMVER_TAG__Group__0 + // InternalSemver.g:527:3: ( rule__SEMVER_TAG__Group__0 ) + // InternalSemver.g:527:4: rule__SEMVER_TAG__Group__0 { pushFollow(FOLLOW_2); rule__SEMVER_TAG__Group__0(); @@ -1649,12 +1740,97 @@ public final void ruleSEMVER_TAG() throws RecognitionException { // $ANTLR end "ruleSEMVER_TAG" + // $ANTLR start "entryRuleWORKSPACE_TAG" + // InternalSemver.g:536:1: entryRuleWORKSPACE_TAG : ruleWORKSPACE_TAG EOF ; + public final void entryRuleWORKSPACE_TAG() throws RecognitionException { + try { + // InternalSemver.g:537:1: ( ruleWORKSPACE_TAG EOF ) + // InternalSemver.g:538:1: ruleWORKSPACE_TAG EOF + { + if ( state.backtracking==0 ) { + before(grammarAccess.getWORKSPACE_TAGRule()); + } + pushFollow(FOLLOW_1); + ruleWORKSPACE_TAG(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_TAGRule()); + } + match(input,EOF,FOLLOW_2); if (state.failed) return ; + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return ; + } + // $ANTLR end "entryRuleWORKSPACE_TAG" + + + // $ANTLR start "ruleWORKSPACE_TAG" + // InternalSemver.g:545:1: ruleWORKSPACE_TAG : ( ( rule__WORKSPACE_TAG__Group__0 ) ) ; + public final void ruleWORKSPACE_TAG() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:549:2: ( ( ( rule__WORKSPACE_TAG__Group__0 ) ) ) + // InternalSemver.g:550:2: ( ( rule__WORKSPACE_TAG__Group__0 ) ) + { + // InternalSemver.g:550:2: ( ( rule__WORKSPACE_TAG__Group__0 ) ) + // InternalSemver.g:551:3: ( rule__WORKSPACE_TAG__Group__0 ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getWORKSPACE_TAGAccess().getGroup()); + } + // InternalSemver.g:552:3: ( rule__WORKSPACE_TAG__Group__0 ) + // InternalSemver.g:552:4: rule__WORKSPACE_TAG__Group__0 + { + pushFollow(FOLLOW_2); + rule__WORKSPACE_TAG__Group__0(); + + state._fsp--; + if (state.failed) return ; + + } + + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_TAGAccess().getGroup()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "ruleWORKSPACE_TAG" + + // $ANTLR start "entryRulePATH" - // InternalSemver.g:511:1: entryRulePATH : rulePATH EOF ; + // InternalSemver.g:561:1: entryRulePATH : rulePATH EOF ; public final void entryRulePATH() throws RecognitionException { try { - // InternalSemver.g:512:1: ( rulePATH EOF ) - // InternalSemver.g:513:1: rulePATH EOF + // InternalSemver.g:562:1: ( rulePATH EOF ) + // InternalSemver.g:563:1: rulePATH EOF { if ( state.backtracking==0 ) { before(grammarAccess.getPATHRule()); @@ -1684,26 +1860,26 @@ public final void entryRulePATH() throws RecognitionException { // $ANTLR start "rulePATH" - // InternalSemver.g:520:1: rulePATH : ( ( ( rule__PATH__Alternatives ) ) ( ( rule__PATH__Alternatives )* ) ) ; + // InternalSemver.g:570:1: rulePATH : ( ( ( rule__PATH__Alternatives ) ) ( ( rule__PATH__Alternatives )* ) ) ; public final void rulePATH() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:524:2: ( ( ( ( rule__PATH__Alternatives ) ) ( ( rule__PATH__Alternatives )* ) ) ) - // InternalSemver.g:525:2: ( ( ( rule__PATH__Alternatives ) ) ( ( rule__PATH__Alternatives )* ) ) + // InternalSemver.g:574:2: ( ( ( ( rule__PATH__Alternatives ) ) ( ( rule__PATH__Alternatives )* ) ) ) + // InternalSemver.g:575:2: ( ( ( rule__PATH__Alternatives ) ) ( ( rule__PATH__Alternatives )* ) ) { - // InternalSemver.g:525:2: ( ( ( rule__PATH__Alternatives ) ) ( ( rule__PATH__Alternatives )* ) ) - // InternalSemver.g:526:3: ( ( rule__PATH__Alternatives ) ) ( ( rule__PATH__Alternatives )* ) + // InternalSemver.g:575:2: ( ( ( rule__PATH__Alternatives ) ) ( ( rule__PATH__Alternatives )* ) ) + // InternalSemver.g:576:3: ( ( rule__PATH__Alternatives ) ) ( ( rule__PATH__Alternatives )* ) { - // InternalSemver.g:526:3: ( ( rule__PATH__Alternatives ) ) - // InternalSemver.g:527:4: ( rule__PATH__Alternatives ) + // InternalSemver.g:576:3: ( ( rule__PATH__Alternatives ) ) + // InternalSemver.g:577:4: ( rule__PATH__Alternatives ) { if ( state.backtracking==0 ) { before(grammarAccess.getPATHAccess().getAlternatives()); } - // InternalSemver.g:528:4: ( rule__PATH__Alternatives ) - // InternalSemver.g:528:5: rule__PATH__Alternatives + // InternalSemver.g:578:4: ( rule__PATH__Alternatives ) + // InternalSemver.g:578:5: rule__PATH__Alternatives { pushFollow(FOLLOW_3); rule__PATH__Alternatives(); @@ -1719,26 +1895,26 @@ public final void rulePATH() throws RecognitionException { } - // InternalSemver.g:531:3: ( ( rule__PATH__Alternatives )* ) - // InternalSemver.g:532:4: ( rule__PATH__Alternatives )* + // InternalSemver.g:581:3: ( ( rule__PATH__Alternatives )* ) + // InternalSemver.g:582:4: ( rule__PATH__Alternatives )* { if ( state.backtracking==0 ) { before(grammarAccess.getPATHAccess().getAlternatives()); } - // InternalSemver.g:533:4: ( rule__PATH__Alternatives )* + // InternalSemver.g:583:4: ( rule__PATH__Alternatives )* loop1: do { int alt1=2; int LA1_0 = input.LA(1); - if ( ((LA1_0>=RULE_DIGITS && LA1_0<=RULE_LETTER_X)||(LA1_0>=RULE_LETTER_V && LA1_0<=RULE_LETTER_OTHER)||(LA1_0>=35 && LA1_0<=39)) ) { + if ( ((LA1_0>=RULE_DIGITS && LA1_0<=RULE_LETTER_OTHER)||(LA1_0>=41 && LA1_0<=44)||LA1_0==47) ) { alt1=1; } switch (alt1) { case 1 : - // InternalSemver.g:533:5: rule__PATH__Alternatives + // InternalSemver.g:583:5: rule__PATH__Alternatives { pushFollow(FOLLOW_3); rule__PATH__Alternatives(); @@ -1782,11 +1958,11 @@ public final void rulePATH() throws RecognitionException { // $ANTLR start "entryRuleURL_PROTOCOL" - // InternalSemver.g:543:1: entryRuleURL_PROTOCOL : ruleURL_PROTOCOL EOF ; + // InternalSemver.g:593:1: entryRuleURL_PROTOCOL : ruleURL_PROTOCOL EOF ; public final void entryRuleURL_PROTOCOL() throws RecognitionException { try { - // InternalSemver.g:544:1: ( ruleURL_PROTOCOL EOF ) - // InternalSemver.g:545:1: ruleURL_PROTOCOL EOF + // InternalSemver.g:594:1: ( ruleURL_PROTOCOL EOF ) + // InternalSemver.g:595:1: ruleURL_PROTOCOL EOF { if ( state.backtracking==0 ) { before(grammarAccess.getURL_PROTOCOLRule()); @@ -1816,23 +1992,23 @@ public final void entryRuleURL_PROTOCOL() throws RecognitionException { // $ANTLR start "ruleURL_PROTOCOL" - // InternalSemver.g:552:1: ruleURL_PROTOCOL : ( ( rule__URL_PROTOCOL__Group__0 ) ) ; + // InternalSemver.g:602:1: ruleURL_PROTOCOL : ( ( rule__URL_PROTOCOL__Group__0 ) ) ; public final void ruleURL_PROTOCOL() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:556:2: ( ( ( rule__URL_PROTOCOL__Group__0 ) ) ) - // InternalSemver.g:557:2: ( ( rule__URL_PROTOCOL__Group__0 ) ) + // InternalSemver.g:606:2: ( ( ( rule__URL_PROTOCOL__Group__0 ) ) ) + // InternalSemver.g:607:2: ( ( rule__URL_PROTOCOL__Group__0 ) ) { - // InternalSemver.g:557:2: ( ( rule__URL_PROTOCOL__Group__0 ) ) - // InternalSemver.g:558:3: ( rule__URL_PROTOCOL__Group__0 ) + // InternalSemver.g:607:2: ( ( rule__URL_PROTOCOL__Group__0 ) ) + // InternalSemver.g:608:3: ( rule__URL_PROTOCOL__Group__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getURL_PROTOCOLAccess().getGroup()); } - // InternalSemver.g:559:3: ( rule__URL_PROTOCOL__Group__0 ) - // InternalSemver.g:559:4: rule__URL_PROTOCOL__Group__0 + // InternalSemver.g:609:3: ( rule__URL_PROTOCOL__Group__0 ) + // InternalSemver.g:609:4: rule__URL_PROTOCOL__Group__0 { pushFollow(FOLLOW_2); rule__URL_PROTOCOL__Group__0(); @@ -1867,11 +2043,11 @@ public final void ruleURL_PROTOCOL() throws RecognitionException { // $ANTLR start "entryRuleURL" - // InternalSemver.g:568:1: entryRuleURL : ruleURL EOF ; + // InternalSemver.g:618:1: entryRuleURL : ruleURL EOF ; public final void entryRuleURL() throws RecognitionException { try { - // InternalSemver.g:569:1: ( ruleURL EOF ) - // InternalSemver.g:570:1: ruleURL EOF + // InternalSemver.g:619:1: ( ruleURL EOF ) + // InternalSemver.g:620:1: ruleURL EOF { if ( state.backtracking==0 ) { before(grammarAccess.getURLRule()); @@ -1901,23 +2077,23 @@ public final void entryRuleURL() throws RecognitionException { // $ANTLR start "ruleURL" - // InternalSemver.g:577:1: ruleURL : ( ( rule__URL__Group__0 ) ) ; + // InternalSemver.g:627:1: ruleURL : ( ( rule__URL__Group__0 ) ) ; public final void ruleURL() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:581:2: ( ( ( rule__URL__Group__0 ) ) ) - // InternalSemver.g:582:2: ( ( rule__URL__Group__0 ) ) + // InternalSemver.g:631:2: ( ( ( rule__URL__Group__0 ) ) ) + // InternalSemver.g:632:2: ( ( rule__URL__Group__0 ) ) { - // InternalSemver.g:582:2: ( ( rule__URL__Group__0 ) ) - // InternalSemver.g:583:3: ( rule__URL__Group__0 ) + // InternalSemver.g:632:2: ( ( rule__URL__Group__0 ) ) + // InternalSemver.g:633:3: ( rule__URL__Group__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getURLAccess().getGroup()); } - // InternalSemver.g:584:3: ( rule__URL__Group__0 ) - // InternalSemver.g:584:4: rule__URL__Group__0 + // InternalSemver.g:634:3: ( rule__URL__Group__0 ) + // InternalSemver.g:634:4: rule__URL__Group__0 { pushFollow(FOLLOW_2); rule__URL__Group__0(); @@ -1952,11 +2128,11 @@ public final void ruleURL() throws RecognitionException { // $ANTLR start "entryRuleURL_NO_VX" - // InternalSemver.g:593:1: entryRuleURL_NO_VX : ruleURL_NO_VX EOF ; + // InternalSemver.g:643:1: entryRuleURL_NO_VX : ruleURL_NO_VX EOF ; public final void entryRuleURL_NO_VX() throws RecognitionException { try { - // InternalSemver.g:594:1: ( ruleURL_NO_VX EOF ) - // InternalSemver.g:595:1: ruleURL_NO_VX EOF + // InternalSemver.g:644:1: ( ruleURL_NO_VX EOF ) + // InternalSemver.g:645:1: ruleURL_NO_VX EOF { if ( state.backtracking==0 ) { before(grammarAccess.getURL_NO_VXRule()); @@ -1986,23 +2162,23 @@ public final void entryRuleURL_NO_VX() throws RecognitionException { // $ANTLR start "ruleURL_NO_VX" - // InternalSemver.g:602:1: ruleURL_NO_VX : ( ( rule__URL_NO_VX__Group__0 ) ) ; + // InternalSemver.g:652:1: ruleURL_NO_VX : ( ( rule__URL_NO_VX__Group__0 ) ) ; public final void ruleURL_NO_VX() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:606:2: ( ( ( rule__URL_NO_VX__Group__0 ) ) ) - // InternalSemver.g:607:2: ( ( rule__URL_NO_VX__Group__0 ) ) + // InternalSemver.g:656:2: ( ( ( rule__URL_NO_VX__Group__0 ) ) ) + // InternalSemver.g:657:2: ( ( rule__URL_NO_VX__Group__0 ) ) { - // InternalSemver.g:607:2: ( ( rule__URL_NO_VX__Group__0 ) ) - // InternalSemver.g:608:3: ( rule__URL_NO_VX__Group__0 ) + // InternalSemver.g:657:2: ( ( rule__URL_NO_VX__Group__0 ) ) + // InternalSemver.g:658:3: ( rule__URL_NO_VX__Group__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getURL_NO_VXAccess().getGroup()); } - // InternalSemver.g:609:3: ( rule__URL_NO_VX__Group__0 ) - // InternalSemver.g:609:4: rule__URL_NO_VX__Group__0 + // InternalSemver.g:659:3: ( rule__URL_NO_VX__Group__0 ) + // InternalSemver.g:659:4: rule__URL_NO_VX__Group__0 { pushFollow(FOLLOW_2); rule__URL_NO_VX__Group__0(); @@ -2037,11 +2213,11 @@ public final void ruleURL_NO_VX() throws RecognitionException { // $ANTLR start "entryRuleTAG" - // InternalSemver.g:618:1: entryRuleTAG : ruleTAG EOF ; + // InternalSemver.g:668:1: entryRuleTAG : ruleTAG EOF ; public final void entryRuleTAG() throws RecognitionException { try { - // InternalSemver.g:619:1: ( ruleTAG EOF ) - // InternalSemver.g:620:1: ruleTAG EOF + // InternalSemver.g:669:1: ( ruleTAG EOF ) + // InternalSemver.g:670:1: ruleTAG EOF { if ( state.backtracking==0 ) { before(grammarAccess.getTAGRule()); @@ -2071,23 +2247,23 @@ public final void entryRuleTAG() throws RecognitionException { // $ANTLR start "ruleTAG" - // InternalSemver.g:627:1: ruleTAG : ( ( rule__TAG__Group__0 ) ) ; + // InternalSemver.g:677:1: ruleTAG : ( ( rule__TAG__Group__0 ) ) ; public final void ruleTAG() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:631:2: ( ( ( rule__TAG__Group__0 ) ) ) - // InternalSemver.g:632:2: ( ( rule__TAG__Group__0 ) ) + // InternalSemver.g:681:2: ( ( ( rule__TAG__Group__0 ) ) ) + // InternalSemver.g:682:2: ( ( rule__TAG__Group__0 ) ) { - // InternalSemver.g:632:2: ( ( rule__TAG__Group__0 ) ) - // InternalSemver.g:633:3: ( rule__TAG__Group__0 ) + // InternalSemver.g:682:2: ( ( rule__TAG__Group__0 ) ) + // InternalSemver.g:683:3: ( rule__TAG__Group__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getTAGAccess().getGroup()); } - // InternalSemver.g:634:3: ( rule__TAG__Group__0 ) - // InternalSemver.g:634:4: rule__TAG__Group__0 + // InternalSemver.g:684:3: ( rule__TAG__Group__0 ) + // InternalSemver.g:684:4: rule__TAG__Group__0 { pushFollow(FOLLOW_2); rule__TAG__Group__0(); @@ -2121,23 +2297,23 @@ public final void ruleTAG() throws RecognitionException { // $ANTLR end "ruleTAG" - // $ANTLR start "entryRuleALPHA_NUMERIC_CHARS" - // InternalSemver.g:643:1: entryRuleALPHA_NUMERIC_CHARS : ruleALPHA_NUMERIC_CHARS EOF ; - public final void entryRuleALPHA_NUMERIC_CHARS() throws RecognitionException { + // $ANTLR start "entryRuleWORKSPACE_VERSION" + // InternalSemver.g:693:1: entryRuleWORKSPACE_VERSION : ruleWORKSPACE_VERSION EOF ; + public final void entryRuleWORKSPACE_VERSION() throws RecognitionException { try { - // InternalSemver.g:644:1: ( ruleALPHA_NUMERIC_CHARS EOF ) - // InternalSemver.g:645:1: ruleALPHA_NUMERIC_CHARS EOF + // InternalSemver.g:694:1: ( ruleWORKSPACE_VERSION EOF ) + // InternalSemver.g:695:1: ruleWORKSPACE_VERSION EOF { if ( state.backtracking==0 ) { - before(grammarAccess.getALPHA_NUMERIC_CHARSRule()); + before(grammarAccess.getWORKSPACE_VERSIONRule()); } pushFollow(FOLLOW_1); - ruleALPHA_NUMERIC_CHARS(); + ruleWORKSPACE_VERSION(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getALPHA_NUMERIC_CHARSRule()); + after(grammarAccess.getWORKSPACE_VERSIONRule()); } match(input,EOF,FOLLOW_2); if (state.failed) return ; @@ -2152,33 +2328,33 @@ public final void entryRuleALPHA_NUMERIC_CHARS() throws RecognitionException { } return ; } - // $ANTLR end "entryRuleALPHA_NUMERIC_CHARS" + // $ANTLR end "entryRuleWORKSPACE_VERSION" - // $ANTLR start "ruleALPHA_NUMERIC_CHARS" - // InternalSemver.g:652:1: ruleALPHA_NUMERIC_CHARS : ( ( ( rule__ALPHA_NUMERIC_CHARS__Alternatives ) ) ( ( rule__ALPHA_NUMERIC_CHARS__Alternatives )* ) ) ; - public final void ruleALPHA_NUMERIC_CHARS() throws RecognitionException { + // $ANTLR start "ruleWORKSPACE_VERSION" + // InternalSemver.g:702:1: ruleWORKSPACE_VERSION : ( ( ( rule__WORKSPACE_VERSION__Alternatives ) ) ( ( rule__WORKSPACE_VERSION__Alternatives )* ) ) ; + public final void ruleWORKSPACE_VERSION() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:656:2: ( ( ( ( rule__ALPHA_NUMERIC_CHARS__Alternatives ) ) ( ( rule__ALPHA_NUMERIC_CHARS__Alternatives )* ) ) ) - // InternalSemver.g:657:2: ( ( ( rule__ALPHA_NUMERIC_CHARS__Alternatives ) ) ( ( rule__ALPHA_NUMERIC_CHARS__Alternatives )* ) ) + // InternalSemver.g:706:2: ( ( ( ( rule__WORKSPACE_VERSION__Alternatives ) ) ( ( rule__WORKSPACE_VERSION__Alternatives )* ) ) ) + // InternalSemver.g:707:2: ( ( ( rule__WORKSPACE_VERSION__Alternatives ) ) ( ( rule__WORKSPACE_VERSION__Alternatives )* ) ) { - // InternalSemver.g:657:2: ( ( ( rule__ALPHA_NUMERIC_CHARS__Alternatives ) ) ( ( rule__ALPHA_NUMERIC_CHARS__Alternatives )* ) ) - // InternalSemver.g:658:3: ( ( rule__ALPHA_NUMERIC_CHARS__Alternatives ) ) ( ( rule__ALPHA_NUMERIC_CHARS__Alternatives )* ) + // InternalSemver.g:707:2: ( ( ( rule__WORKSPACE_VERSION__Alternatives ) ) ( ( rule__WORKSPACE_VERSION__Alternatives )* ) ) + // InternalSemver.g:708:3: ( ( rule__WORKSPACE_VERSION__Alternatives ) ) ( ( rule__WORKSPACE_VERSION__Alternatives )* ) { - // InternalSemver.g:658:3: ( ( rule__ALPHA_NUMERIC_CHARS__Alternatives ) ) - // InternalSemver.g:659:4: ( rule__ALPHA_NUMERIC_CHARS__Alternatives ) + // InternalSemver.g:708:3: ( ( rule__WORKSPACE_VERSION__Alternatives ) ) + // InternalSemver.g:709:4: ( rule__WORKSPACE_VERSION__Alternatives ) { if ( state.backtracking==0 ) { - before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getAlternatives()); + before(grammarAccess.getWORKSPACE_VERSIONAccess().getAlternatives()); } - // InternalSemver.g:660:4: ( rule__ALPHA_NUMERIC_CHARS__Alternatives ) - // InternalSemver.g:660:5: rule__ALPHA_NUMERIC_CHARS__Alternatives + // InternalSemver.g:710:4: ( rule__WORKSPACE_VERSION__Alternatives ) + // InternalSemver.g:710:5: rule__WORKSPACE_VERSION__Alternatives { - pushFollow(FOLLOW_3); - rule__ALPHA_NUMERIC_CHARS__Alternatives(); + pushFollow(FOLLOW_4); + rule__WORKSPACE_VERSION__Alternatives(); state._fsp--; if (state.failed) return ; @@ -2186,34 +2362,34 @@ public final void ruleALPHA_NUMERIC_CHARS() throws RecognitionException { } if ( state.backtracking==0 ) { - after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getAlternatives()); + after(grammarAccess.getWORKSPACE_VERSIONAccess().getAlternatives()); } } - // InternalSemver.g:663:3: ( ( rule__ALPHA_NUMERIC_CHARS__Alternatives )* ) - // InternalSemver.g:664:4: ( rule__ALPHA_NUMERIC_CHARS__Alternatives )* + // InternalSemver.g:713:3: ( ( rule__WORKSPACE_VERSION__Alternatives )* ) + // InternalSemver.g:714:4: ( rule__WORKSPACE_VERSION__Alternatives )* { if ( state.backtracking==0 ) { - before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getAlternatives()); + before(grammarAccess.getWORKSPACE_VERSIONAccess().getAlternatives()); } - // InternalSemver.g:665:4: ( rule__ALPHA_NUMERIC_CHARS__Alternatives )* + // InternalSemver.g:715:4: ( rule__WORKSPACE_VERSION__Alternatives )* loop2: do { int alt2=2; int LA2_0 = input.LA(1); - if ( ((LA2_0>=RULE_DIGITS && LA2_0<=RULE_LETTER_X)||(LA2_0>=RULE_LETTER_V && LA2_0<=RULE_LETTER_OTHER)||LA2_0==38) ) { + if ( ((LA2_0>=RULE_ASTERIX && LA2_0<=RULE_LETTER_OTHER)||(LA2_0>=41 && LA2_0<=44)||(LA2_0>=46 && LA2_0<=54)) ) { alt2=1; } switch (alt2) { case 1 : - // InternalSemver.g:665:5: rule__ALPHA_NUMERIC_CHARS__Alternatives + // InternalSemver.g:715:5: rule__WORKSPACE_VERSION__Alternatives { - pushFollow(FOLLOW_3); - rule__ALPHA_NUMERIC_CHARS__Alternatives(); + pushFollow(FOLLOW_4); + rule__WORKSPACE_VERSION__Alternatives(); state._fsp--; if (state.failed) return ; @@ -2227,7 +2403,7 @@ public final void ruleALPHA_NUMERIC_CHARS() throws RecognitionException { } while (true); if ( state.backtracking==0 ) { - after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getAlternatives()); + after(grammarAccess.getWORKSPACE_VERSIONAccess().getAlternatives()); } } @@ -2250,15 +2426,15 @@ public final void ruleALPHA_NUMERIC_CHARS() throws RecognitionException { } return ; } - // $ANTLR end "ruleALPHA_NUMERIC_CHARS" + // $ANTLR end "ruleWORKSPACE_VERSION" // $ANTLR start "entryRuleALPHA_NUMERIC_CHARS_START_WITH_DIGITS" - // InternalSemver.g:675:1: entryRuleALPHA_NUMERIC_CHARS_START_WITH_DIGITS : ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS EOF ; + // InternalSemver.g:725:1: entryRuleALPHA_NUMERIC_CHARS_START_WITH_DIGITS : ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS EOF ; public final void entryRuleALPHA_NUMERIC_CHARS_START_WITH_DIGITS() throws RecognitionException { try { - // InternalSemver.g:676:1: ( ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS EOF ) - // InternalSemver.g:677:1: ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS EOF + // InternalSemver.g:726:1: ( ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS EOF ) + // InternalSemver.g:727:1: ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS EOF { if ( state.backtracking==0 ) { before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSRule()); @@ -2288,23 +2464,23 @@ public final void entryRuleALPHA_NUMERIC_CHARS_START_WITH_DIGITS() throws Recogn // $ANTLR start "ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS" - // InternalSemver.g:684:1: ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS : ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 ) ) ; + // InternalSemver.g:734:1: ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS : ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 ) ) ; public final void ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:688:2: ( ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 ) ) ) - // InternalSemver.g:689:2: ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 ) ) + // InternalSemver.g:738:2: ( ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 ) ) ) + // InternalSemver.g:739:2: ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 ) ) { - // InternalSemver.g:689:2: ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 ) ) - // InternalSemver.g:690:3: ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 ) + // InternalSemver.g:739:2: ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 ) ) + // InternalSemver.g:740:3: ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getGroup()); } - // InternalSemver.g:691:3: ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 ) - // InternalSemver.g:691:4: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 + // InternalSemver.g:741:3: ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 ) + // InternalSemver.g:741:4: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 { pushFollow(FOLLOW_2); rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0(); @@ -2338,23 +2514,23 @@ public final void ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS() throws Recognition // $ANTLR end "ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS" - // $ANTLR start "entryRuleWILDCARD" - // InternalSemver.g:700:1: entryRuleWILDCARD : ruleWILDCARD EOF ; - public final void entryRuleWILDCARD() throws RecognitionException { + // $ANTLR start "entryRuleALPHA_NUMERIC_CHARS" + // InternalSemver.g:750:1: entryRuleALPHA_NUMERIC_CHARS : ruleALPHA_NUMERIC_CHARS EOF ; + public final void entryRuleALPHA_NUMERIC_CHARS() throws RecognitionException { try { - // InternalSemver.g:701:1: ( ruleWILDCARD EOF ) - // InternalSemver.g:702:1: ruleWILDCARD EOF + // InternalSemver.g:751:1: ( ruleALPHA_NUMERIC_CHARS EOF ) + // InternalSemver.g:752:1: ruleALPHA_NUMERIC_CHARS EOF { if ( state.backtracking==0 ) { - before(grammarAccess.getWILDCARDRule()); + before(grammarAccess.getALPHA_NUMERIC_CHARSRule()); } pushFollow(FOLLOW_1); - ruleWILDCARD(); + ruleALPHA_NUMERIC_CHARS(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getWILDCARDRule()); + after(grammarAccess.getALPHA_NUMERIC_CHARSRule()); } match(input,EOF,FOLLOW_2); if (state.failed) return ; @@ -2369,30 +2545,33 @@ public final void entryRuleWILDCARD() throws RecognitionException { } return ; } - // $ANTLR end "entryRuleWILDCARD" + // $ANTLR end "entryRuleALPHA_NUMERIC_CHARS" - // $ANTLR start "ruleWILDCARD" - // InternalSemver.g:709:1: ruleWILDCARD : ( ( rule__WILDCARD__Alternatives ) ) ; - public final void ruleWILDCARD() throws RecognitionException { + // $ANTLR start "ruleALPHA_NUMERIC_CHARS" + // InternalSemver.g:759:1: ruleALPHA_NUMERIC_CHARS : ( ( ( ruleALPHA_NUMERIC_CHAR ) ) ( ( ruleALPHA_NUMERIC_CHAR )* ) ) ; + public final void ruleALPHA_NUMERIC_CHARS() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:713:2: ( ( ( rule__WILDCARD__Alternatives ) ) ) - // InternalSemver.g:714:2: ( ( rule__WILDCARD__Alternatives ) ) + // InternalSemver.g:763:2: ( ( ( ( ruleALPHA_NUMERIC_CHAR ) ) ( ( ruleALPHA_NUMERIC_CHAR )* ) ) ) + // InternalSemver.g:764:2: ( ( ( ruleALPHA_NUMERIC_CHAR ) ) ( ( ruleALPHA_NUMERIC_CHAR )* ) ) { - // InternalSemver.g:714:2: ( ( rule__WILDCARD__Alternatives ) ) - // InternalSemver.g:715:3: ( rule__WILDCARD__Alternatives ) + // InternalSemver.g:764:2: ( ( ( ruleALPHA_NUMERIC_CHAR ) ) ( ( ruleALPHA_NUMERIC_CHAR )* ) ) + // InternalSemver.g:765:3: ( ( ruleALPHA_NUMERIC_CHAR ) ) ( ( ruleALPHA_NUMERIC_CHAR )* ) + { + // InternalSemver.g:765:3: ( ( ruleALPHA_NUMERIC_CHAR ) ) + // InternalSemver.g:766:4: ( ruleALPHA_NUMERIC_CHAR ) { if ( state.backtracking==0 ) { - before(grammarAccess.getWILDCARDAccess().getAlternatives()); + before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getALPHA_NUMERIC_CHARParserRuleCall()); } - // InternalSemver.g:716:3: ( rule__WILDCARD__Alternatives ) - // InternalSemver.g:716:4: rule__WILDCARD__Alternatives + // InternalSemver.g:767:4: ( ruleALPHA_NUMERIC_CHAR ) + // InternalSemver.g:767:5: ruleALPHA_NUMERIC_CHAR { - pushFollow(FOLLOW_2); - rule__WILDCARD__Alternatives(); + pushFollow(FOLLOW_3); + ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return ; @@ -2400,9 +2579,53 @@ public final void ruleWILDCARD() throws RecognitionException { } if ( state.backtracking==0 ) { - after(grammarAccess.getWILDCARDAccess().getAlternatives()); + after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getALPHA_NUMERIC_CHARParserRuleCall()); + } + + } + + // InternalSemver.g:770:3: ( ( ruleALPHA_NUMERIC_CHAR )* ) + // InternalSemver.g:771:4: ( ruleALPHA_NUMERIC_CHAR )* + { + if ( state.backtracking==0 ) { + before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getALPHA_NUMERIC_CHARParserRuleCall()); + } + // InternalSemver.g:772:4: ( ruleALPHA_NUMERIC_CHAR )* + loop3: + do { + int alt3=2; + int LA3_0 = input.LA(1); + + if ( ((LA3_0>=RULE_DIGITS && LA3_0<=RULE_LETTER_OTHER)||LA3_0==47) ) { + alt3=1; + } + + + switch (alt3) { + case 1 : + // InternalSemver.g:772:5: ruleALPHA_NUMERIC_CHAR + { + pushFollow(FOLLOW_3); + ruleALPHA_NUMERIC_CHAR(); + + state._fsp--; + if (state.failed) return ; + + } + break; + + default : + break loop3; + } + } while (true); + + if ( state.backtracking==0 ) { + after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getALPHA_NUMERIC_CHARParserRuleCall()); + } + } + } @@ -2420,42 +2643,28 @@ public final void ruleWILDCARD() throws RecognitionException { } return ; } - // $ANTLR end "ruleWILDCARD" - + // $ANTLR end "ruleALPHA_NUMERIC_CHARS" - // $ANTLR start "ruleLETTER" - // InternalSemver.g:726:1: ruleLETTER : ( ( rule__LETTER__Alternatives ) ) ; - public final void ruleLETTER() throws RecognitionException { - int stackSize = keepStackSize(); - + // $ANTLR start "entryRuleALPHA_NUMERIC_CHAR" + // InternalSemver.g:782:1: entryRuleALPHA_NUMERIC_CHAR : ruleALPHA_NUMERIC_CHAR EOF ; + public final void entryRuleALPHA_NUMERIC_CHAR() throws RecognitionException { try { - // InternalSemver.g:730:2: ( ( ( rule__LETTER__Alternatives ) ) ) - // InternalSemver.g:731:2: ( ( rule__LETTER__Alternatives ) ) - { - // InternalSemver.g:731:2: ( ( rule__LETTER__Alternatives ) ) - // InternalSemver.g:732:3: ( rule__LETTER__Alternatives ) + // InternalSemver.g:783:1: ( ruleALPHA_NUMERIC_CHAR EOF ) + // InternalSemver.g:784:1: ruleALPHA_NUMERIC_CHAR EOF { if ( state.backtracking==0 ) { - before(grammarAccess.getLETTERAccess().getAlternatives()); + before(grammarAccess.getALPHA_NUMERIC_CHARRule()); } - // InternalSemver.g:733:3: ( rule__LETTER__Alternatives ) - // InternalSemver.g:733:4: rule__LETTER__Alternatives - { - pushFollow(FOLLOW_2); - rule__LETTER__Alternatives(); + pushFollow(FOLLOW_1); + ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return ; - - } - if ( state.backtracking==0 ) { - after(grammarAccess.getLETTERAccess().getAlternatives()); - } - + after(grammarAccess.getALPHA_NUMERIC_CHARRule()); } - + match(input,EOF,FOLLOW_2); if (state.failed) return ; } @@ -2465,36 +2674,33 @@ public final void ruleLETTER() throws RecognitionException { recover(input,re); } finally { - - restoreStackSize(stackSize); - } return ; } - // $ANTLR end "ruleLETTER" + // $ANTLR end "entryRuleALPHA_NUMERIC_CHAR" - // $ANTLR start "ruleLETTER_NO_VX" - // InternalSemver.g:743:1: ruleLETTER_NO_VX : ( ( rule__LETTER_NO_VX__Alternatives ) ) ; - public final void ruleLETTER_NO_VX() throws RecognitionException { + // $ANTLR start "ruleALPHA_NUMERIC_CHAR" + // InternalSemver.g:791:1: ruleALPHA_NUMERIC_CHAR : ( ( rule__ALPHA_NUMERIC_CHAR__Alternatives ) ) ; + public final void ruleALPHA_NUMERIC_CHAR() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:747:2: ( ( ( rule__LETTER_NO_VX__Alternatives ) ) ) - // InternalSemver.g:748:2: ( ( rule__LETTER_NO_VX__Alternatives ) ) + // InternalSemver.g:795:2: ( ( ( rule__ALPHA_NUMERIC_CHAR__Alternatives ) ) ) + // InternalSemver.g:796:2: ( ( rule__ALPHA_NUMERIC_CHAR__Alternatives ) ) { - // InternalSemver.g:748:2: ( ( rule__LETTER_NO_VX__Alternatives ) ) - // InternalSemver.g:749:3: ( rule__LETTER_NO_VX__Alternatives ) + // InternalSemver.g:796:2: ( ( rule__ALPHA_NUMERIC_CHAR__Alternatives ) ) + // InternalSemver.g:797:3: ( rule__ALPHA_NUMERIC_CHAR__Alternatives ) { if ( state.backtracking==0 ) { - before(grammarAccess.getLETTER_NO_VXAccess().getAlternatives()); + before(grammarAccess.getALPHA_NUMERIC_CHARAccess().getAlternatives()); } - // InternalSemver.g:750:3: ( rule__LETTER_NO_VX__Alternatives ) - // InternalSemver.g:750:4: rule__LETTER_NO_VX__Alternatives + // InternalSemver.g:798:3: ( rule__ALPHA_NUMERIC_CHAR__Alternatives ) + // InternalSemver.g:798:4: rule__ALPHA_NUMERIC_CHAR__Alternatives { pushFollow(FOLLOW_2); - rule__LETTER_NO_VX__Alternatives(); + rule__ALPHA_NUMERIC_CHAR__Alternatives(); state._fsp--; if (state.failed) return ; @@ -2502,7 +2708,7 @@ public final void ruleLETTER_NO_VX() throws RecognitionException { } if ( state.backtracking==0 ) { - after(grammarAccess.getLETTER_NO_VXAccess().getAlternatives()); + after(grammarAccess.getALPHA_NUMERIC_CHARAccess().getAlternatives()); } } @@ -2522,28 +2728,215 @@ public final void ruleLETTER_NO_VX() throws RecognitionException { } return ; } - // $ANTLR end "ruleLETTER_NO_VX" - + // $ANTLR end "ruleALPHA_NUMERIC_CHAR" - // $ANTLR start "ruleVersionComparator" - // InternalSemver.g:759:1: ruleVersionComparator : ( ( rule__VersionComparator__Alternatives ) ) ; - public final void ruleVersionComparator() throws RecognitionException { - int stackSize = keepStackSize(); - + // $ANTLR start "entryRuleWILDCARD" + // InternalSemver.g:807:1: entryRuleWILDCARD : ruleWILDCARD EOF ; + public final void entryRuleWILDCARD() throws RecognitionException { try { - // InternalSemver.g:763:1: ( ( ( rule__VersionComparator__Alternatives ) ) ) - // InternalSemver.g:764:2: ( ( rule__VersionComparator__Alternatives ) ) - { - // InternalSemver.g:764:2: ( ( rule__VersionComparator__Alternatives ) ) - // InternalSemver.g:765:3: ( rule__VersionComparator__Alternatives ) + // InternalSemver.g:808:1: ( ruleWILDCARD EOF ) + // InternalSemver.g:809:1: ruleWILDCARD EOF { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionComparatorAccess().getAlternatives()); + before(grammarAccess.getWILDCARDRule()); } - // InternalSemver.g:766:3: ( rule__VersionComparator__Alternatives ) - // InternalSemver.g:766:4: rule__VersionComparator__Alternatives - { + pushFollow(FOLLOW_1); + ruleWILDCARD(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWILDCARDRule()); + } + match(input,EOF,FOLLOW_2); if (state.failed) return ; + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return ; + } + // $ANTLR end "entryRuleWILDCARD" + + + // $ANTLR start "ruleWILDCARD" + // InternalSemver.g:816:1: ruleWILDCARD : ( ( rule__WILDCARD__Alternatives ) ) ; + public final void ruleWILDCARD() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:820:2: ( ( ( rule__WILDCARD__Alternatives ) ) ) + // InternalSemver.g:821:2: ( ( rule__WILDCARD__Alternatives ) ) + { + // InternalSemver.g:821:2: ( ( rule__WILDCARD__Alternatives ) ) + // InternalSemver.g:822:3: ( rule__WILDCARD__Alternatives ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getWILDCARDAccess().getAlternatives()); + } + // InternalSemver.g:823:3: ( rule__WILDCARD__Alternatives ) + // InternalSemver.g:823:4: rule__WILDCARD__Alternatives + { + pushFollow(FOLLOW_2); + rule__WILDCARD__Alternatives(); + + state._fsp--; + if (state.failed) return ; + + } + + if ( state.backtracking==0 ) { + after(grammarAccess.getWILDCARDAccess().getAlternatives()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "ruleWILDCARD" + + + // $ANTLR start "ruleLETTER" + // InternalSemver.g:833:1: ruleLETTER : ( ( rule__LETTER__Alternatives ) ) ; + public final void ruleLETTER() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:837:2: ( ( ( rule__LETTER__Alternatives ) ) ) + // InternalSemver.g:838:2: ( ( rule__LETTER__Alternatives ) ) + { + // InternalSemver.g:838:2: ( ( rule__LETTER__Alternatives ) ) + // InternalSemver.g:839:3: ( rule__LETTER__Alternatives ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getLETTERAccess().getAlternatives()); + } + // InternalSemver.g:840:3: ( rule__LETTER__Alternatives ) + // InternalSemver.g:840:4: rule__LETTER__Alternatives + { + pushFollow(FOLLOW_2); + rule__LETTER__Alternatives(); + + state._fsp--; + if (state.failed) return ; + + } + + if ( state.backtracking==0 ) { + after(grammarAccess.getLETTERAccess().getAlternatives()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "ruleLETTER" + + + // $ANTLR start "ruleLETTER_NO_VX" + // InternalSemver.g:850:1: ruleLETTER_NO_VX : ( ( rule__LETTER_NO_VX__Alternatives ) ) ; + public final void ruleLETTER_NO_VX() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:854:2: ( ( ( rule__LETTER_NO_VX__Alternatives ) ) ) + // InternalSemver.g:855:2: ( ( rule__LETTER_NO_VX__Alternatives ) ) + { + // InternalSemver.g:855:2: ( ( rule__LETTER_NO_VX__Alternatives ) ) + // InternalSemver.g:856:3: ( rule__LETTER_NO_VX__Alternatives ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getLETTER_NO_VXAccess().getAlternatives()); + } + // InternalSemver.g:857:3: ( rule__LETTER_NO_VX__Alternatives ) + // InternalSemver.g:857:4: rule__LETTER_NO_VX__Alternatives + { + pushFollow(FOLLOW_2); + rule__LETTER_NO_VX__Alternatives(); + + state._fsp--; + if (state.failed) return ; + + } + + if ( state.backtracking==0 ) { + after(grammarAccess.getLETTER_NO_VXAccess().getAlternatives()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "ruleLETTER_NO_VX" + + + // $ANTLR start "ruleVersionComparator" + // InternalSemver.g:866:1: ruleVersionComparator : ( ( rule__VersionComparator__Alternatives ) ) ; + public final void ruleVersionComparator() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:870:1: ( ( ( rule__VersionComparator__Alternatives ) ) ) + // InternalSemver.g:871:2: ( ( rule__VersionComparator__Alternatives ) ) + { + // InternalSemver.g:871:2: ( ( rule__VersionComparator__Alternatives ) ) + // InternalSemver.g:872:3: ( rule__VersionComparator__Alternatives ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getVersionComparatorAccess().getAlternatives()); + } + // InternalSemver.g:873:3: ( rule__VersionComparator__Alternatives ) + // InternalSemver.g:873:4: rule__VersionComparator__Alternatives + { pushFollow(FOLLOW_2); rule__VersionComparator__Alternatives(); @@ -2577,41 +2970,41 @@ public final void ruleVersionComparator() throws RecognitionException { // $ANTLR start "rule__NPMVersionRequirement__Alternatives" - // InternalSemver.g:774:1: rule__NPMVersionRequirement__Alternatives : ( ( ( rule__NPMVersionRequirement__Group_0__0 ) ) | ( ( rule__NPMVersionRequirement__Group_1__0 ) ) ); + // InternalSemver.g:881:1: rule__NPMVersionRequirement__Alternatives : ( ( ( rule__NPMVersionRequirement__Group_0__0 ) ) | ( ( rule__NPMVersionRequirement__Group_1__0 ) ) ); public final void rule__NPMVersionRequirement__Alternatives() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:778:1: ( ( ( rule__NPMVersionRequirement__Group_0__0 ) ) | ( ( rule__NPMVersionRequirement__Group_1__0 ) ) ) - int alt3=2; - int LA3_0 = input.LA(1); + // InternalSemver.g:885:1: ( ( ( rule__NPMVersionRequirement__Group_0__0 ) ) | ( ( rule__NPMVersionRequirement__Group_1__0 ) ) ) + int alt4=2; + int LA4_0 = input.LA(1); - if ( (LA3_0==EOF||(LA3_0>=RULE_DIGITS && LA3_0<=RULE_LETTER_V)||LA3_0==RULE_WS||(LA3_0>=42 && LA3_0<=48)) ) { - alt3=1; + if ( (LA4_0==EOF||(LA4_0>=RULE_ASTERIX && LA4_0<=RULE_LETTER_V)||LA4_0==RULE_WS||(LA4_0>=48 && LA4_0<=54)) ) { + alt4=1; } - else if ( ((LA3_0>=RULE_LETTER_S && LA3_0<=RULE_LETTER_OTHER)||(LA3_0>=38 && LA3_0<=39)) ) { - alt3=2; + else if ( ((LA4_0>=RULE_LETTER_A && LA4_0<=RULE_LETTER_OTHER)||LA4_0==44||LA4_0==47) ) { + alt4=2; } else { if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 3, 0, input); + new NoViableAltException("", 4, 0, input); throw nvae; } - switch (alt3) { + switch (alt4) { case 1 : - // InternalSemver.g:779:2: ( ( rule__NPMVersionRequirement__Group_0__0 ) ) + // InternalSemver.g:886:2: ( ( rule__NPMVersionRequirement__Group_0__0 ) ) { - // InternalSemver.g:779:2: ( ( rule__NPMVersionRequirement__Group_0__0 ) ) - // InternalSemver.g:780:3: ( rule__NPMVersionRequirement__Group_0__0 ) + // InternalSemver.g:886:2: ( ( rule__NPMVersionRequirement__Group_0__0 ) ) + // InternalSemver.g:887:3: ( rule__NPMVersionRequirement__Group_0__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getNPMVersionRequirementAccess().getGroup_0()); } - // InternalSemver.g:781:3: ( rule__NPMVersionRequirement__Group_0__0 ) - // InternalSemver.g:781:4: rule__NPMVersionRequirement__Group_0__0 + // InternalSemver.g:888:3: ( rule__NPMVersionRequirement__Group_0__0 ) + // InternalSemver.g:888:4: rule__NPMVersionRequirement__Group_0__0 { pushFollow(FOLLOW_2); rule__NPMVersionRequirement__Group_0__0(); @@ -2631,16 +3024,16 @@ else if ( ((LA3_0>=RULE_LETTER_S && LA3_0<=RULE_LETTER_OTHER)||(LA3_0>=38 && LA3 } break; case 2 : - // InternalSemver.g:785:2: ( ( rule__NPMVersionRequirement__Group_1__0 ) ) + // InternalSemver.g:892:2: ( ( rule__NPMVersionRequirement__Group_1__0 ) ) { - // InternalSemver.g:785:2: ( ( rule__NPMVersionRequirement__Group_1__0 ) ) - // InternalSemver.g:786:3: ( rule__NPMVersionRequirement__Group_1__0 ) + // InternalSemver.g:892:2: ( ( rule__NPMVersionRequirement__Group_1__0 ) ) + // InternalSemver.g:893:3: ( rule__NPMVersionRequirement__Group_1__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getNPMVersionRequirementAccess().getGroup_1()); } - // InternalSemver.g:787:3: ( rule__NPMVersionRequirement__Group_1__0 ) - // InternalSemver.g:787:4: rule__NPMVersionRequirement__Group_1__0 + // InternalSemver.g:894:3: ( rule__NPMVersionRequirement__Group_1__0 ) + // InternalSemver.g:894:4: rule__NPMVersionRequirement__Group_1__0 { pushFollow(FOLLOW_2); rule__NPMVersionRequirement__Group_1__0(); @@ -2677,27 +3070,27 @@ else if ( ((LA3_0>=RULE_LETTER_S && LA3_0<=RULE_LETTER_OTHER)||(LA3_0>=38 && LA3 // $ANTLR start "rule__NPMVersionRequirement__Alternatives_1_0" - // InternalSemver.g:795:1: rule__NPMVersionRequirement__Alternatives_1_0 : ( ( ( ruleLocalPathVersionRequirement ) ) | ( ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) ) ); + // InternalSemver.g:902:1: rule__NPMVersionRequirement__Alternatives_1_0 : ( ( ( ruleLocalPathVersionRequirement ) ) | ( ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) ) ); public final void rule__NPMVersionRequirement__Alternatives_1_0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:799:1: ( ( ( ruleLocalPathVersionRequirement ) ) | ( ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) ) ) - int alt4=2; - alt4 = dfa4.predict(input); - switch (alt4) { + // InternalSemver.g:906:1: ( ( ( ruleLocalPathVersionRequirement ) ) | ( ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) ) ) + int alt5=2; + alt5 = dfa5.predict(input); + switch (alt5) { case 1 : - // InternalSemver.g:800:2: ( ( ruleLocalPathVersionRequirement ) ) + // InternalSemver.g:907:2: ( ( ruleLocalPathVersionRequirement ) ) { - // InternalSemver.g:800:2: ( ( ruleLocalPathVersionRequirement ) ) - // InternalSemver.g:801:3: ( ruleLocalPathVersionRequirement ) + // InternalSemver.g:907:2: ( ( ruleLocalPathVersionRequirement ) ) + // InternalSemver.g:908:3: ( ruleLocalPathVersionRequirement ) { if ( state.backtracking==0 ) { before(grammarAccess.getNPMVersionRequirementAccess().getLocalPathVersionRequirementParserRuleCall_1_0_0()); } - // InternalSemver.g:802:3: ( ruleLocalPathVersionRequirement ) - // InternalSemver.g:802:4: ruleLocalPathVersionRequirement + // InternalSemver.g:909:3: ( ruleLocalPathVersionRequirement ) + // InternalSemver.g:909:4: ruleLocalPathVersionRequirement { pushFollow(FOLLOW_2); ruleLocalPathVersionRequirement(); @@ -2717,16 +3110,16 @@ public final void rule__NPMVersionRequirement__Alternatives_1_0() throws Recogni } break; case 2 : - // InternalSemver.g:806:2: ( ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) ) + // InternalSemver.g:913:2: ( ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) ) { - // InternalSemver.g:806:2: ( ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) ) - // InternalSemver.g:807:3: ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) + // InternalSemver.g:913:2: ( ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) ) + // InternalSemver.g:914:3: ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getNPMVersionRequirementAccess().getAlternatives_1_0_1()); } - // InternalSemver.g:808:3: ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) - // InternalSemver.g:808:4: rule__NPMVersionRequirement__Alternatives_1_0_1 + // InternalSemver.g:915:3: ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) + // InternalSemver.g:915:4: rule__NPMVersionRequirement__Alternatives_1_0_1 { pushFollow(FOLLOW_2); rule__NPMVersionRequirement__Alternatives_1_0_1(); @@ -2763,27 +3156,27 @@ public final void rule__NPMVersionRequirement__Alternatives_1_0() throws Recogni // $ANTLR start "rule__NPMVersionRequirement__Alternatives_1_0_1" - // InternalSemver.g:816:1: rule__NPMVersionRequirement__Alternatives_1_0_1 : ( ( ( ruleURLVersionRequirement ) ) | ( ruleGitHubVersionRequirement ) | ( ruleTagVersionRequirement ) ); + // InternalSemver.g:923:1: rule__NPMVersionRequirement__Alternatives_1_0_1 : ( ( ( ruleURLVersionRequirement ) ) | ( ( rule__NPMVersionRequirement__Alternatives_1_0_1_1 ) ) ); public final void rule__NPMVersionRequirement__Alternatives_1_0_1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:820:1: ( ( ( ruleURLVersionRequirement ) ) | ( ruleGitHubVersionRequirement ) | ( ruleTagVersionRequirement ) ) - int alt5=3; - alt5 = dfa5.predict(input); - switch (alt5) { + // InternalSemver.g:927:1: ( ( ( ruleURLVersionRequirement ) ) | ( ( rule__NPMVersionRequirement__Alternatives_1_0_1_1 ) ) ) + int alt6=2; + alt6 = dfa6.predict(input); + switch (alt6) { case 1 : - // InternalSemver.g:821:2: ( ( ruleURLVersionRequirement ) ) + // InternalSemver.g:928:2: ( ( ruleURLVersionRequirement ) ) { - // InternalSemver.g:821:2: ( ( ruleURLVersionRequirement ) ) - // InternalSemver.g:822:3: ( ruleURLVersionRequirement ) + // InternalSemver.g:928:2: ( ( ruleURLVersionRequirement ) ) + // InternalSemver.g:929:3: ( ruleURLVersionRequirement ) { if ( state.backtracking==0 ) { before(grammarAccess.getNPMVersionRequirementAccess().getURLVersionRequirementParserRuleCall_1_0_1_0()); } - // InternalSemver.g:823:3: ( ruleURLVersionRequirement ) - // InternalSemver.g:823:4: ruleURLVersionRequirement + // InternalSemver.g:930:3: ( ruleURLVersionRequirement ) + // InternalSemver.g:930:4: ruleURLVersionRequirement { pushFollow(FOLLOW_2); ruleURLVersionRequirement(); @@ -2803,13 +3196,99 @@ public final void rule__NPMVersionRequirement__Alternatives_1_0_1() throws Recog } break; case 2 : - // InternalSemver.g:827:2: ( ruleGitHubVersionRequirement ) + // InternalSemver.g:934:2: ( ( rule__NPMVersionRequirement__Alternatives_1_0_1_1 ) ) + { + // InternalSemver.g:934:2: ( ( rule__NPMVersionRequirement__Alternatives_1_0_1_1 ) ) + // InternalSemver.g:935:3: ( rule__NPMVersionRequirement__Alternatives_1_0_1_1 ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getNPMVersionRequirementAccess().getAlternatives_1_0_1_1()); + } + // InternalSemver.g:936:3: ( rule__NPMVersionRequirement__Alternatives_1_0_1_1 ) + // InternalSemver.g:936:4: rule__NPMVersionRequirement__Alternatives_1_0_1_1 + { + pushFollow(FOLLOW_2); + rule__NPMVersionRequirement__Alternatives_1_0_1_1(); + + state._fsp--; + if (state.failed) return ; + + } + + if ( state.backtracking==0 ) { + after(grammarAccess.getNPMVersionRequirementAccess().getAlternatives_1_0_1_1()); + } + + } + + + } + break; + + } + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__NPMVersionRequirement__Alternatives_1_0_1" + + + // $ANTLR start "rule__NPMVersionRequirement__Alternatives_1_0_1_1" + // InternalSemver.g:944:1: rule__NPMVersionRequirement__Alternatives_1_0_1_1 : ( ( ( ruleWorkspaceVersionRequirement ) ) | ( ruleGitHubVersionRequirement ) | ( ruleTagVersionRequirement ) ); + public final void rule__NPMVersionRequirement__Alternatives_1_0_1_1() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:948:1: ( ( ( ruleWorkspaceVersionRequirement ) ) | ( ruleGitHubVersionRequirement ) | ( ruleTagVersionRequirement ) ) + int alt7=3; + alt7 = dfa7.predict(input); + switch (alt7) { + case 1 : + // InternalSemver.g:949:2: ( ( ruleWorkspaceVersionRequirement ) ) + { + // InternalSemver.g:949:2: ( ( ruleWorkspaceVersionRequirement ) ) + // InternalSemver.g:950:3: ( ruleWorkspaceVersionRequirement ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getNPMVersionRequirementAccess().getWorkspaceVersionRequirementParserRuleCall_1_0_1_1_0()); + } + // InternalSemver.g:951:3: ( ruleWorkspaceVersionRequirement ) + // InternalSemver.g:951:4: ruleWorkspaceVersionRequirement + { + pushFollow(FOLLOW_2); + ruleWorkspaceVersionRequirement(); + + state._fsp--; + if (state.failed) return ; + + } + + if ( state.backtracking==0 ) { + after(grammarAccess.getNPMVersionRequirementAccess().getWorkspaceVersionRequirementParserRuleCall_1_0_1_1_0()); + } + + } + + + } + break; + case 2 : + // InternalSemver.g:955:2: ( ruleGitHubVersionRequirement ) { - // InternalSemver.g:827:2: ( ruleGitHubVersionRequirement ) - // InternalSemver.g:828:3: ruleGitHubVersionRequirement + // InternalSemver.g:955:2: ( ruleGitHubVersionRequirement ) + // InternalSemver.g:956:3: ruleGitHubVersionRequirement { if ( state.backtracking==0 ) { - before(grammarAccess.getNPMVersionRequirementAccess().getGitHubVersionRequirementParserRuleCall_1_0_1_1()); + before(grammarAccess.getNPMVersionRequirementAccess().getGitHubVersionRequirementParserRuleCall_1_0_1_1_1()); } pushFollow(FOLLOW_2); ruleGitHubVersionRequirement(); @@ -2817,7 +3296,7 @@ public final void rule__NPMVersionRequirement__Alternatives_1_0_1() throws Recog state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getNPMVersionRequirementAccess().getGitHubVersionRequirementParserRuleCall_1_0_1_1()); + after(grammarAccess.getNPMVersionRequirementAccess().getGitHubVersionRequirementParserRuleCall_1_0_1_1_1()); } } @@ -2826,13 +3305,13 @@ public final void rule__NPMVersionRequirement__Alternatives_1_0_1() throws Recog } break; case 3 : - // InternalSemver.g:833:2: ( ruleTagVersionRequirement ) + // InternalSemver.g:961:2: ( ruleTagVersionRequirement ) { - // InternalSemver.g:833:2: ( ruleTagVersionRequirement ) - // InternalSemver.g:834:3: ruleTagVersionRequirement + // InternalSemver.g:961:2: ( ruleTagVersionRequirement ) + // InternalSemver.g:962:3: ruleTagVersionRequirement { if ( state.backtracking==0 ) { - before(grammarAccess.getNPMVersionRequirementAccess().getTagVersionRequirementParserRuleCall_1_0_1_2()); + before(grammarAccess.getNPMVersionRequirementAccess().getTagVersionRequirementParserRuleCall_1_0_1_1_2()); } pushFollow(FOLLOW_2); ruleTagVersionRequirement(); @@ -2840,7 +3319,7 @@ public final void rule__NPMVersionRequirement__Alternatives_1_0_1() throws Recog state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getNPMVersionRequirementAccess().getTagVersionRequirementParserRuleCall_1_0_1_2()); + after(grammarAccess.getNPMVersionRequirementAccess().getTagVersionRequirementParserRuleCall_1_0_1_1_2()); } } @@ -2862,31 +3341,31 @@ public final void rule__NPMVersionRequirement__Alternatives_1_0_1() throws Recog } return ; } - // $ANTLR end "rule__NPMVersionRequirement__Alternatives_1_0_1" + // $ANTLR end "rule__NPMVersionRequirement__Alternatives_1_0_1_1" // $ANTLR start "rule__URLVersionSpecifier__Alternatives" - // InternalSemver.g:843:1: rule__URLVersionSpecifier__Alternatives : ( ( ( rule__URLVersionSpecifier__Group_0__0 ) ) | ( ( rule__URLVersionSpecifier__Group_1__0 ) ) | ( ( rule__URLVersionSpecifier__Group_2__0 ) ) ); + // InternalSemver.g:971:1: rule__URLVersionSpecifier__Alternatives : ( ( ( rule__URLVersionSpecifier__Group_0__0 ) ) | ( ( rule__URLVersionSpecifier__Group_1__0 ) ) | ( ( rule__URLVersionSpecifier__Group_2__0 ) ) ); public final void rule__URLVersionSpecifier__Alternatives() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:847:1: ( ( ( rule__URLVersionSpecifier__Group_0__0 ) ) | ( ( rule__URLVersionSpecifier__Group_1__0 ) ) | ( ( rule__URLVersionSpecifier__Group_2__0 ) ) ) - int alt6=3; - alt6 = dfa6.predict(input); - switch (alt6) { + // InternalSemver.g:975:1: ( ( ( rule__URLVersionSpecifier__Group_0__0 ) ) | ( ( rule__URLVersionSpecifier__Group_1__0 ) ) | ( ( rule__URLVersionSpecifier__Group_2__0 ) ) ) + int alt8=3; + alt8 = dfa8.predict(input); + switch (alt8) { case 1 : - // InternalSemver.g:848:2: ( ( rule__URLVersionSpecifier__Group_0__0 ) ) + // InternalSemver.g:976:2: ( ( rule__URLVersionSpecifier__Group_0__0 ) ) { - // InternalSemver.g:848:2: ( ( rule__URLVersionSpecifier__Group_0__0 ) ) - // InternalSemver.g:849:3: ( rule__URLVersionSpecifier__Group_0__0 ) + // InternalSemver.g:976:2: ( ( rule__URLVersionSpecifier__Group_0__0 ) ) + // InternalSemver.g:977:3: ( rule__URLVersionSpecifier__Group_0__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionSpecifierAccess().getGroup_0()); } - // InternalSemver.g:850:3: ( rule__URLVersionSpecifier__Group_0__0 ) - // InternalSemver.g:850:4: rule__URLVersionSpecifier__Group_0__0 + // InternalSemver.g:978:3: ( rule__URLVersionSpecifier__Group_0__0 ) + // InternalSemver.g:978:4: rule__URLVersionSpecifier__Group_0__0 { pushFollow(FOLLOW_2); rule__URLVersionSpecifier__Group_0__0(); @@ -2906,16 +3385,16 @@ public final void rule__URLVersionSpecifier__Alternatives() throws RecognitionEx } break; case 2 : - // InternalSemver.g:854:2: ( ( rule__URLVersionSpecifier__Group_1__0 ) ) + // InternalSemver.g:982:2: ( ( rule__URLVersionSpecifier__Group_1__0 ) ) { - // InternalSemver.g:854:2: ( ( rule__URLVersionSpecifier__Group_1__0 ) ) - // InternalSemver.g:855:3: ( rule__URLVersionSpecifier__Group_1__0 ) + // InternalSemver.g:982:2: ( ( rule__URLVersionSpecifier__Group_1__0 ) ) + // InternalSemver.g:983:3: ( rule__URLVersionSpecifier__Group_1__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionSpecifierAccess().getGroup_1()); } - // InternalSemver.g:856:3: ( rule__URLVersionSpecifier__Group_1__0 ) - // InternalSemver.g:856:4: rule__URLVersionSpecifier__Group_1__0 + // InternalSemver.g:984:3: ( rule__URLVersionSpecifier__Group_1__0 ) + // InternalSemver.g:984:4: rule__URLVersionSpecifier__Group_1__0 { pushFollow(FOLLOW_2); rule__URLVersionSpecifier__Group_1__0(); @@ -2935,16 +3414,16 @@ public final void rule__URLVersionSpecifier__Alternatives() throws RecognitionEx } break; case 3 : - // InternalSemver.g:860:2: ( ( rule__URLVersionSpecifier__Group_2__0 ) ) + // InternalSemver.g:988:2: ( ( rule__URLVersionSpecifier__Group_2__0 ) ) { - // InternalSemver.g:860:2: ( ( rule__URLVersionSpecifier__Group_2__0 ) ) - // InternalSemver.g:861:3: ( rule__URLVersionSpecifier__Group_2__0 ) + // InternalSemver.g:988:2: ( ( rule__URLVersionSpecifier__Group_2__0 ) ) + // InternalSemver.g:989:3: ( rule__URLVersionSpecifier__Group_2__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionSpecifierAccess().getGroup_2()); } - // InternalSemver.g:862:3: ( rule__URLVersionSpecifier__Group_2__0 ) - // InternalSemver.g:862:4: rule__URLVersionSpecifier__Group_2__0 + // InternalSemver.g:990:3: ( rule__URLVersionSpecifier__Group_2__0 ) + // InternalSemver.g:990:4: rule__URLVersionSpecifier__Group_2__0 { pushFollow(FOLLOW_2); rule__URLVersionSpecifier__Group_2__0(); @@ -2980,28 +3459,114 @@ public final void rule__URLVersionSpecifier__Alternatives() throws RecognitionEx // $ANTLR end "rule__URLVersionSpecifier__Alternatives" - // $ANTLR start "rule__VersionRange__Alternatives" - // InternalSemver.g:870:1: rule__VersionRange__Alternatives : ( ( ruleVersionRangeContraint ) | ( ruleHyphenVersionRange ) ); - public final void rule__VersionRange__Alternatives() throws RecognitionException { + // $ANTLR start "rule__WorkspaceVersionRequirement__Alternatives_1" + // InternalSemver.g:998:1: rule__WorkspaceVersionRequirement__Alternatives_1 : ( ( ( rule__WorkspaceVersionRequirement__VersionAssignment_1_0 ) ) | ( ( rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1 ) ) ); + public final void rule__WorkspaceVersionRequirement__Alternatives_1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:874:1: ( ( ruleVersionRangeContraint ) | ( ruleHyphenVersionRange ) ) - int alt7=2; - alt7 = dfa7.predict(input); - switch (alt7) { + // InternalSemver.g:1002:1: ( ( ( rule__WorkspaceVersionRequirement__VersionAssignment_1_0 ) ) | ( ( rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1 ) ) ) + int alt9=2; + alt9 = dfa9.predict(input); + switch (alt9) { case 1 : - // InternalSemver.g:875:2: ( ruleVersionRangeContraint ) + // InternalSemver.g:1003:2: ( ( rule__WorkspaceVersionRequirement__VersionAssignment_1_0 ) ) { - // InternalSemver.g:875:2: ( ruleVersionRangeContraint ) - // InternalSemver.g:876:3: ruleVersionRangeContraint + // InternalSemver.g:1003:2: ( ( rule__WorkspaceVersionRequirement__VersionAssignment_1_0 ) ) + // InternalSemver.g:1004:3: ( rule__WorkspaceVersionRequirement__VersionAssignment_1_0 ) { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionRangeAccess().getVersionRangeContraintParserRuleCall_0()); + before(grammarAccess.getWorkspaceVersionRequirementAccess().getVersionAssignment_1_0()); } + // InternalSemver.g:1005:3: ( rule__WorkspaceVersionRequirement__VersionAssignment_1_0 ) + // InternalSemver.g:1005:4: rule__WorkspaceVersionRequirement__VersionAssignment_1_0 + { pushFollow(FOLLOW_2); - ruleVersionRangeContraint(); + rule__WorkspaceVersionRequirement__VersionAssignment_1_0(); + + state._fsp--; + if (state.failed) return ; + + } + + if ( state.backtracking==0 ) { + after(grammarAccess.getWorkspaceVersionRequirementAccess().getVersionAssignment_1_0()); + } + + } + + + } + break; + case 2 : + // InternalSemver.g:1009:2: ( ( rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1 ) ) + { + // InternalSemver.g:1009:2: ( ( rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1 ) ) + // InternalSemver.g:1010:3: ( rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1 ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getWorkspaceVersionRequirementAccess().getOtherVersionAssignment_1_1()); + } + // InternalSemver.g:1011:3: ( rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1 ) + // InternalSemver.g:1011:4: rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1 + { + pushFollow(FOLLOW_2); + rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1(); + + state._fsp--; + if (state.failed) return ; + + } + + if ( state.backtracking==0 ) { + after(grammarAccess.getWorkspaceVersionRequirementAccess().getOtherVersionAssignment_1_1()); + } + + } + + + } + break; + + } + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__WorkspaceVersionRequirement__Alternatives_1" + + + // $ANTLR start "rule__VersionRange__Alternatives" + // InternalSemver.g:1019:1: rule__VersionRange__Alternatives : ( ( ruleVersionRangeContraint ) | ( ruleHyphenVersionRange ) ); + public final void rule__VersionRange__Alternatives() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:1023:1: ( ( ruleVersionRangeContraint ) | ( ruleHyphenVersionRange ) ) + int alt10=2; + alt10 = dfa10.predict(input); + switch (alt10) { + case 1 : + // InternalSemver.g:1024:2: ( ruleVersionRangeContraint ) + { + // InternalSemver.g:1024:2: ( ruleVersionRangeContraint ) + // InternalSemver.g:1025:3: ruleVersionRangeContraint + { + if ( state.backtracking==0 ) { + before(grammarAccess.getVersionRangeAccess().getVersionRangeContraintParserRuleCall_0()); + } + pushFollow(FOLLOW_2); + ruleVersionRangeContraint(); state._fsp--; if (state.failed) return ; @@ -3015,10 +3580,10 @@ public final void rule__VersionRange__Alternatives() throws RecognitionException } break; case 2 : - // InternalSemver.g:881:2: ( ruleHyphenVersionRange ) + // InternalSemver.g:1030:2: ( ruleHyphenVersionRange ) { - // InternalSemver.g:881:2: ( ruleHyphenVersionRange ) - // InternalSemver.g:882:3: ruleHyphenVersionRange + // InternalSemver.g:1030:2: ( ruleHyphenVersionRange ) + // InternalSemver.g:1031:3: ruleHyphenVersionRange { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeAccess().getHyphenVersionRangeParserRuleCall_1()); @@ -3055,41 +3620,41 @@ public final void rule__VersionRange__Alternatives() throws RecognitionException // $ANTLR start "rule__VersionPart__Alternatives" - // InternalSemver.g:891:1: rule__VersionPart__Alternatives : ( ( ( rule__VersionPart__WildcardAssignment_0 ) ) | ( ( rule__VersionPart__NumberRawAssignment_1 ) ) ); + // InternalSemver.g:1040:1: rule__VersionPart__Alternatives : ( ( ( rule__VersionPart__WildcardAssignment_0 ) ) | ( ( rule__VersionPart__NumberRawAssignment_1 ) ) ); public final void rule__VersionPart__Alternatives() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:895:1: ( ( ( rule__VersionPart__WildcardAssignment_0 ) ) | ( ( rule__VersionPart__NumberRawAssignment_1 ) ) ) - int alt8=2; - int LA8_0 = input.LA(1); + // InternalSemver.g:1044:1: ( ( ( rule__VersionPart__WildcardAssignment_0 ) ) | ( ( rule__VersionPart__NumberRawAssignment_1 ) ) ) + int alt11=2; + int LA11_0 = input.LA(1); - if ( ((LA8_0>=RULE_LETTER_X && LA8_0<=RULE_ASTERIX)) ) { - alt8=1; + if ( (LA11_0==RULE_ASTERIX||LA11_0==RULE_LETTER_X) ) { + alt11=1; } - else if ( (LA8_0==RULE_DIGITS) ) { - alt8=2; + else if ( (LA11_0==RULE_DIGITS) ) { + alt11=2; } else { if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 8, 0, input); + new NoViableAltException("", 11, 0, input); throw nvae; } - switch (alt8) { + switch (alt11) { case 1 : - // InternalSemver.g:896:2: ( ( rule__VersionPart__WildcardAssignment_0 ) ) + // InternalSemver.g:1045:2: ( ( rule__VersionPart__WildcardAssignment_0 ) ) { - // InternalSemver.g:896:2: ( ( rule__VersionPart__WildcardAssignment_0 ) ) - // InternalSemver.g:897:3: ( rule__VersionPart__WildcardAssignment_0 ) + // InternalSemver.g:1045:2: ( ( rule__VersionPart__WildcardAssignment_0 ) ) + // InternalSemver.g:1046:3: ( rule__VersionPart__WildcardAssignment_0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionPartAccess().getWildcardAssignment_0()); } - // InternalSemver.g:898:3: ( rule__VersionPart__WildcardAssignment_0 ) - // InternalSemver.g:898:4: rule__VersionPart__WildcardAssignment_0 + // InternalSemver.g:1047:3: ( rule__VersionPart__WildcardAssignment_0 ) + // InternalSemver.g:1047:4: rule__VersionPart__WildcardAssignment_0 { pushFollow(FOLLOW_2); rule__VersionPart__WildcardAssignment_0(); @@ -3109,16 +3674,16 @@ else if ( (LA8_0==RULE_DIGITS) ) { } break; case 2 : - // InternalSemver.g:902:2: ( ( rule__VersionPart__NumberRawAssignment_1 ) ) + // InternalSemver.g:1051:2: ( ( rule__VersionPart__NumberRawAssignment_1 ) ) { - // InternalSemver.g:902:2: ( ( rule__VersionPart__NumberRawAssignment_1 ) ) - // InternalSemver.g:903:3: ( rule__VersionPart__NumberRawAssignment_1 ) + // InternalSemver.g:1051:2: ( ( rule__VersionPart__NumberRawAssignment_1 ) ) + // InternalSemver.g:1052:3: ( rule__VersionPart__NumberRawAssignment_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionPartAccess().getNumberRawAssignment_1()); } - // InternalSemver.g:904:3: ( rule__VersionPart__NumberRawAssignment_1 ) - // InternalSemver.g:904:4: rule__VersionPart__NumberRawAssignment_1 + // InternalSemver.g:1053:3: ( rule__VersionPart__NumberRawAssignment_1 ) + // InternalSemver.g:1053:4: rule__VersionPart__NumberRawAssignment_1 { pushFollow(FOLLOW_2); rule__VersionPart__NumberRawAssignment_1(); @@ -3155,41 +3720,41 @@ else if ( (LA8_0==RULE_DIGITS) ) { // $ANTLR start "rule__Qualifier__Alternatives" - // InternalSemver.g:912:1: rule__Qualifier__Alternatives : ( ( ( rule__Qualifier__Group_0__0 ) ) | ( ( rule__Qualifier__Group_1__0 ) ) ); + // InternalSemver.g:1061:1: rule__Qualifier__Alternatives : ( ( ( rule__Qualifier__Group_0__0 ) ) | ( ( rule__Qualifier__Group_1__0 ) ) ); public final void rule__Qualifier__Alternatives() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:916:1: ( ( ( rule__Qualifier__Group_0__0 ) ) | ( ( rule__Qualifier__Group_1__0 ) ) ) - int alt9=2; - int LA9_0 = input.LA(1); + // InternalSemver.g:1065:1: ( ( ( rule__Qualifier__Group_0__0 ) ) | ( ( rule__Qualifier__Group_1__0 ) ) ) + int alt12=2; + int LA12_0 = input.LA(1); - if ( (LA9_0==38) ) { - alt9=1; + if ( (LA12_0==47) ) { + alt12=1; } - else if ( (LA9_0==40) ) { - alt9=2; + else if ( (LA12_0==45) ) { + alt12=2; } else { if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 9, 0, input); + new NoViableAltException("", 12, 0, input); throw nvae; } - switch (alt9) { + switch (alt12) { case 1 : - // InternalSemver.g:917:2: ( ( rule__Qualifier__Group_0__0 ) ) + // InternalSemver.g:1066:2: ( ( rule__Qualifier__Group_0__0 ) ) { - // InternalSemver.g:917:2: ( ( rule__Qualifier__Group_0__0 ) ) - // InternalSemver.g:918:3: ( rule__Qualifier__Group_0__0 ) + // InternalSemver.g:1066:2: ( ( rule__Qualifier__Group_0__0 ) ) + // InternalSemver.g:1067:3: ( rule__Qualifier__Group_0__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierAccess().getGroup_0()); } - // InternalSemver.g:919:3: ( rule__Qualifier__Group_0__0 ) - // InternalSemver.g:919:4: rule__Qualifier__Group_0__0 + // InternalSemver.g:1068:3: ( rule__Qualifier__Group_0__0 ) + // InternalSemver.g:1068:4: rule__Qualifier__Group_0__0 { pushFollow(FOLLOW_2); rule__Qualifier__Group_0__0(); @@ -3209,16 +3774,16 @@ else if ( (LA9_0==40) ) { } break; case 2 : - // InternalSemver.g:923:2: ( ( rule__Qualifier__Group_1__0 ) ) + // InternalSemver.g:1072:2: ( ( rule__Qualifier__Group_1__0 ) ) { - // InternalSemver.g:923:2: ( ( rule__Qualifier__Group_1__0 ) ) - // InternalSemver.g:924:3: ( rule__Qualifier__Group_1__0 ) + // InternalSemver.g:1072:2: ( ( rule__Qualifier__Group_1__0 ) ) + // InternalSemver.g:1073:3: ( rule__Qualifier__Group_1__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierAccess().getGroup_1()); } - // InternalSemver.g:925:3: ( rule__Qualifier__Group_1__0 ) - // InternalSemver.g:925:4: rule__Qualifier__Group_1__0 + // InternalSemver.g:1074:3: ( rule__Qualifier__Group_1__0 ) + // InternalSemver.g:1074:4: rule__Qualifier__Group_1__0 { pushFollow(FOLLOW_2); rule__Qualifier__Group_1__0(); @@ -3255,78 +3820,76 @@ else if ( (LA9_0==40) ) { // $ANTLR start "rule__PATH__Alternatives" - // InternalSemver.g:933:1: rule__PATH__Alternatives : ( ( '/' ) | ( '.' ) | ( '@' ) | ( '-' ) | ( '_' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ); + // InternalSemver.g:1082:1: rule__PATH__Alternatives : ( ( '/' ) | ( '.' ) | ( '@' ) | ( '_' ) | ( ruleALPHA_NUMERIC_CHAR ) ); public final void rule__PATH__Alternatives() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:937:1: ( ( '/' ) | ( '.' ) | ( '@' ) | ( '-' ) | ( '_' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ) - int alt10=7; + // InternalSemver.g:1086:1: ( ( '/' ) | ( '.' ) | ( '@' ) | ( '_' ) | ( ruleALPHA_NUMERIC_CHAR ) ) + int alt13=5; switch ( input.LA(1) ) { - case 35: - { - alt10=1; - } - break; - case 36: + case 41: { - alt10=2; + alt13=1; } break; - case 37: + case 42: { - alt10=3; + alt13=2; } break; - case 38: + case 43: { - alt10=4; + alt13=3; } break; - case 39: + case 44: { - alt10=5; + alt13=4; } break; case RULE_DIGITS: - { - alt10=6; - } - break; case RULE_LETTER_X: case RULE_LETTER_V: - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: + case RULE_LETTER_A: + case RULE_LETTER_C: + case RULE_LETTER_E: case RULE_LETTER_F: case RULE_LETTER_I: + case RULE_LETTER_K: case RULE_LETTER_L: - case RULE_LETTER_E: + case RULE_LETTER_M: + case RULE_LETTER_O: + case RULE_LETTER_P: + case RULE_LETTER_R: + case RULE_LETTER_S: + case RULE_LETTER_W: case RULE_LETTER_OTHER: + case 47: { - alt10=7; + alt13=5; } break; default: if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 10, 0, input); + new NoViableAltException("", 13, 0, input); throw nvae; } - switch (alt10) { + switch (alt13) { case 1 : - // InternalSemver.g:938:2: ( '/' ) + // InternalSemver.g:1087:2: ( '/' ) { - // InternalSemver.g:938:2: ( '/' ) - // InternalSemver.g:939:3: '/' + // InternalSemver.g:1087:2: ( '/' ) + // InternalSemver.g:1088:3: '/' { if ( state.backtracking==0 ) { before(grammarAccess.getPATHAccess().getSolidusKeyword_0()); } - match(input,35,FOLLOW_2); if (state.failed) return ; + match(input,41,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getPATHAccess().getSolidusKeyword_0()); } @@ -3337,15 +3900,15 @@ public final void rule__PATH__Alternatives() throws RecognitionException { } break; case 2 : - // InternalSemver.g:944:2: ( '.' ) + // InternalSemver.g:1093:2: ( '.' ) { - // InternalSemver.g:944:2: ( '.' ) - // InternalSemver.g:945:3: '.' + // InternalSemver.g:1093:2: ( '.' ) + // InternalSemver.g:1094:3: '.' { if ( state.backtracking==0 ) { before(grammarAccess.getPATHAccess().getFullStopKeyword_1()); } - match(input,36,FOLLOW_2); if (state.failed) return ; + match(input,42,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getPATHAccess().getFullStopKeyword_1()); } @@ -3356,15 +3919,15 @@ public final void rule__PATH__Alternatives() throws RecognitionException { } break; case 3 : - // InternalSemver.g:950:2: ( '@' ) + // InternalSemver.g:1099:2: ( '@' ) { - // InternalSemver.g:950:2: ( '@' ) - // InternalSemver.g:951:3: '@' + // InternalSemver.g:1099:2: ( '@' ) + // InternalSemver.g:1100:3: '@' { if ( state.backtracking==0 ) { before(grammarAccess.getPATHAccess().getCommercialAtKeyword_2()); } - match(input,37,FOLLOW_2); if (state.failed) return ; + match(input,43,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getPATHAccess().getCommercialAtKeyword_2()); } @@ -3375,17 +3938,17 @@ public final void rule__PATH__Alternatives() throws RecognitionException { } break; case 4 : - // InternalSemver.g:956:2: ( '-' ) + // InternalSemver.g:1105:2: ( '_' ) { - // InternalSemver.g:956:2: ( '-' ) - // InternalSemver.g:957:3: '-' + // InternalSemver.g:1105:2: ( '_' ) + // InternalSemver.g:1106:3: '_' { if ( state.backtracking==0 ) { - before(grammarAccess.getPATHAccess().getHyphenMinusKeyword_3()); + before(grammarAccess.getPATHAccess().get_Keyword_3()); } - match(input,38,FOLLOW_2); if (state.failed) return ; + match(input,44,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getPATHAccess().getHyphenMinusKeyword_3()); + after(grammarAccess.getPATHAccess().get_Keyword_3()); } } @@ -3394,59 +3957,21 @@ public final void rule__PATH__Alternatives() throws RecognitionException { } break; case 5 : - // InternalSemver.g:962:2: ( '_' ) - { - // InternalSemver.g:962:2: ( '_' ) - // InternalSemver.g:963:3: '_' - { - if ( state.backtracking==0 ) { - before(grammarAccess.getPATHAccess().get_Keyword_4()); - } - match(input,39,FOLLOW_2); if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getPATHAccess().get_Keyword_4()); - } - - } - - - } - break; - case 6 : - // InternalSemver.g:968:2: ( RULE_DIGITS ) - { - // InternalSemver.g:968:2: ( RULE_DIGITS ) - // InternalSemver.g:969:3: RULE_DIGITS - { - if ( state.backtracking==0 ) { - before(grammarAccess.getPATHAccess().getDIGITSTerminalRuleCall_5()); - } - match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getPATHAccess().getDIGITSTerminalRuleCall_5()); - } - - } - - - } - break; - case 7 : - // InternalSemver.g:974:2: ( ruleLETTER ) + // InternalSemver.g:1111:2: ( ruleALPHA_NUMERIC_CHAR ) { - // InternalSemver.g:974:2: ( ruleLETTER ) - // InternalSemver.g:975:3: ruleLETTER + // InternalSemver.g:1111:2: ( ruleALPHA_NUMERIC_CHAR ) + // InternalSemver.g:1112:3: ruleALPHA_NUMERIC_CHAR { if ( state.backtracking==0 ) { - before(grammarAccess.getPATHAccess().getLETTERParserRuleCall_6()); + before(grammarAccess.getPATHAccess().getALPHA_NUMERIC_CHARParserRuleCall_4()); } pushFollow(FOLLOW_2); - ruleLETTER(); + ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getPATHAccess().getLETTERParserRuleCall_6()); + after(grammarAccess.getPATHAccess().getALPHA_NUMERIC_CHARParserRuleCall_4()); } } @@ -3472,35 +3997,35 @@ public final void rule__PATH__Alternatives() throws RecognitionException { // $ANTLR start "rule__URL_PROTOCOL__Alternatives_1" - // InternalSemver.g:984:1: rule__URL_PROTOCOL__Alternatives_1 : ( ( ruleLETTER ) | ( '+' ) ); + // InternalSemver.g:1121:1: rule__URL_PROTOCOL__Alternatives_1 : ( ( ruleLETTER ) | ( '+' ) ); public final void rule__URL_PROTOCOL__Alternatives_1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:988:1: ( ( ruleLETTER ) | ( '+' ) ) - int alt11=2; - int LA11_0 = input.LA(1); + // InternalSemver.g:1125:1: ( ( ruleLETTER ) | ( '+' ) ) + int alt14=2; + int LA14_0 = input.LA(1); - if ( (LA11_0==RULE_LETTER_X||(LA11_0>=RULE_LETTER_V && LA11_0<=RULE_LETTER_OTHER)) ) { - alt11=1; + if ( ((LA14_0>=RULE_LETTER_X && LA14_0<=RULE_LETTER_OTHER)) ) { + alt14=1; } - else if ( (LA11_0==40) ) { - alt11=2; + else if ( (LA14_0==45) ) { + alt14=2; } else { if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 11, 0, input); + new NoViableAltException("", 14, 0, input); throw nvae; } - switch (alt11) { + switch (alt14) { case 1 : - // InternalSemver.g:989:2: ( ruleLETTER ) + // InternalSemver.g:1126:2: ( ruleLETTER ) { - // InternalSemver.g:989:2: ( ruleLETTER ) - // InternalSemver.g:990:3: ruleLETTER + // InternalSemver.g:1126:2: ( ruleLETTER ) + // InternalSemver.g:1127:3: ruleLETTER { if ( state.backtracking==0 ) { before(grammarAccess.getURL_PROTOCOLAccess().getLETTERParserRuleCall_1_0()); @@ -3520,15 +4045,15 @@ else if ( (LA11_0==40) ) { } break; case 2 : - // InternalSemver.g:995:2: ( '+' ) + // InternalSemver.g:1132:2: ( '+' ) { - // InternalSemver.g:995:2: ( '+' ) - // InternalSemver.g:996:3: '+' + // InternalSemver.g:1132:2: ( '+' ) + // InternalSemver.g:1133:3: '+' { if ( state.backtracking==0 ) { before(grammarAccess.getURL_PROTOCOLAccess().getPlusSignKeyword_1_1()); } - match(input,40,FOLLOW_2); if (state.failed) return ; + match(input,45,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURL_PROTOCOLAccess().getPlusSignKeyword_1_1()); } @@ -3556,65 +4081,42 @@ else if ( (LA11_0==40) ) { // $ANTLR start "rule__URL__Alternatives_0" - // InternalSemver.g:1005:1: rule__URL__Alternatives_0 : ( ( '-' ) | ( '_' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ); + // InternalSemver.g:1142:1: rule__URL__Alternatives_0 : ( ( '_' ) | ( ruleALPHA_NUMERIC_CHAR ) ); public final void rule__URL__Alternatives_0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1009:1: ( ( '-' ) | ( '_' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ) - int alt12=4; - switch ( input.LA(1) ) { - case 38: - { - alt12=1; - } - break; - case 39: - { - alt12=2; - } - break; - case RULE_DIGITS: - { - alt12=3; - } - break; - case RULE_LETTER_X: - case RULE_LETTER_V: - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: - case RULE_LETTER_F: - case RULE_LETTER_I: - case RULE_LETTER_L: - case RULE_LETTER_E: - case RULE_LETTER_OTHER: - { - alt12=4; - } - break; - default: + // InternalSemver.g:1146:1: ( ( '_' ) | ( ruleALPHA_NUMERIC_CHAR ) ) + int alt15=2; + int LA15_0 = input.LA(1); + + if ( (LA15_0==44) ) { + alt15=1; + } + else if ( ((LA15_0>=RULE_DIGITS && LA15_0<=RULE_LETTER_OTHER)||LA15_0==47) ) { + alt15=2; + } + else { if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 12, 0, input); + new NoViableAltException("", 15, 0, input); throw nvae; } - - switch (alt12) { + switch (alt15) { case 1 : - // InternalSemver.g:1010:2: ( '-' ) + // InternalSemver.g:1147:2: ( '_' ) { - // InternalSemver.g:1010:2: ( '-' ) - // InternalSemver.g:1011:3: '-' + // InternalSemver.g:1147:2: ( '_' ) + // InternalSemver.g:1148:3: '_' { if ( state.backtracking==0 ) { - before(grammarAccess.getURLAccess().getHyphenMinusKeyword_0_0()); + before(grammarAccess.getURLAccess().get_Keyword_0_0()); } - match(input,38,FOLLOW_2); if (state.failed) return ; + match(input,44,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURLAccess().getHyphenMinusKeyword_0_0()); + after(grammarAccess.getURLAccess().get_Keyword_0_0()); } } @@ -3623,59 +4125,21 @@ public final void rule__URL__Alternatives_0() throws RecognitionException { } break; case 2 : - // InternalSemver.g:1016:2: ( '_' ) - { - // InternalSemver.g:1016:2: ( '_' ) - // InternalSemver.g:1017:3: '_' - { - if ( state.backtracking==0 ) { - before(grammarAccess.getURLAccess().get_Keyword_0_1()); - } - match(input,39,FOLLOW_2); if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getURLAccess().get_Keyword_0_1()); - } - - } - - - } - break; - case 3 : - // InternalSemver.g:1022:2: ( RULE_DIGITS ) - { - // InternalSemver.g:1022:2: ( RULE_DIGITS ) - // InternalSemver.g:1023:3: RULE_DIGITS - { - if ( state.backtracking==0 ) { - before(grammarAccess.getURLAccess().getDIGITSTerminalRuleCall_0_2()); - } - match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getURLAccess().getDIGITSTerminalRuleCall_0_2()); - } - - } - - - } - break; - case 4 : - // InternalSemver.g:1028:2: ( ruleLETTER ) + // InternalSemver.g:1153:2: ( ruleALPHA_NUMERIC_CHAR ) { - // InternalSemver.g:1028:2: ( ruleLETTER ) - // InternalSemver.g:1029:3: ruleLETTER + // InternalSemver.g:1153:2: ( ruleALPHA_NUMERIC_CHAR ) + // InternalSemver.g:1154:3: ruleALPHA_NUMERIC_CHAR { if ( state.backtracking==0 ) { - before(grammarAccess.getURLAccess().getLETTERParserRuleCall_0_3()); + before(grammarAccess.getURLAccess().getALPHA_NUMERIC_CHARParserRuleCall_0_1()); } pushFollow(FOLLOW_2); - ruleLETTER(); + ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURLAccess().getLETTERParserRuleCall_0_3()); + after(grammarAccess.getURLAccess().getALPHA_NUMERIC_CHARParserRuleCall_0_1()); } } @@ -3701,54 +4165,54 @@ public final void rule__URL__Alternatives_0() throws RecognitionException { // $ANTLR start "rule__URL__Alternatives_1" - // InternalSemver.g:1038:1: rule__URL__Alternatives_1 : ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) ); + // InternalSemver.g:1163:1: rule__URL__Alternatives_1 : ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) ); public final void rule__URL__Alternatives_1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1042:1: ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) ) - int alt13=4; + // InternalSemver.g:1167:1: ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) ) + int alt16=4; switch ( input.LA(1) ) { - case 35: + case 41: { - alt13=1; + alt16=1; } break; - case 36: + case 42: { - alt13=2; + alt16=2; } break; - case 41: + case 46: { - alt13=3; + alt16=3; } break; - case 37: + case 43: { - alt13=4; + alt16=4; } break; default: if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 13, 0, input); + new NoViableAltException("", 16, 0, input); throw nvae; } - switch (alt13) { + switch (alt16) { case 1 : - // InternalSemver.g:1043:2: ( '/' ) + // InternalSemver.g:1168:2: ( '/' ) { - // InternalSemver.g:1043:2: ( '/' ) - // InternalSemver.g:1044:3: '/' + // InternalSemver.g:1168:2: ( '/' ) + // InternalSemver.g:1169:3: '/' { if ( state.backtracking==0 ) { before(grammarAccess.getURLAccess().getSolidusKeyword_1_0()); } - match(input,35,FOLLOW_2); if (state.failed) return ; + match(input,41,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURLAccess().getSolidusKeyword_1_0()); } @@ -3759,15 +4223,15 @@ public final void rule__URL__Alternatives_1() throws RecognitionException { } break; case 2 : - // InternalSemver.g:1049:2: ( '.' ) + // InternalSemver.g:1174:2: ( '.' ) { - // InternalSemver.g:1049:2: ( '.' ) - // InternalSemver.g:1050:3: '.' + // InternalSemver.g:1174:2: ( '.' ) + // InternalSemver.g:1175:3: '.' { if ( state.backtracking==0 ) { before(grammarAccess.getURLAccess().getFullStopKeyword_1_1()); } - match(input,36,FOLLOW_2); if (state.failed) return ; + match(input,42,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURLAccess().getFullStopKeyword_1_1()); } @@ -3778,15 +4242,15 @@ public final void rule__URL__Alternatives_1() throws RecognitionException { } break; case 3 : - // InternalSemver.g:1055:2: ( ':' ) + // InternalSemver.g:1180:2: ( ':' ) { - // InternalSemver.g:1055:2: ( ':' ) - // InternalSemver.g:1056:3: ':' + // InternalSemver.g:1180:2: ( ':' ) + // InternalSemver.g:1181:3: ':' { if ( state.backtracking==0 ) { before(grammarAccess.getURLAccess().getColonKeyword_1_2()); } - match(input,41,FOLLOW_2); if (state.failed) return ; + match(input,46,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURLAccess().getColonKeyword_1_2()); } @@ -3797,15 +4261,15 @@ public final void rule__URL__Alternatives_1() throws RecognitionException { } break; case 4 : - // InternalSemver.g:1061:2: ( '@' ) + // InternalSemver.g:1186:2: ( '@' ) { - // InternalSemver.g:1061:2: ( '@' ) - // InternalSemver.g:1062:3: '@' + // InternalSemver.g:1186:2: ( '@' ) + // InternalSemver.g:1187:3: '@' { if ( state.backtracking==0 ) { before(grammarAccess.getURLAccess().getCommercialAtKeyword_1_3()); } - match(input,37,FOLLOW_2); if (state.failed) return ; + match(input,43,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURLAccess().getCommercialAtKeyword_1_3()); } @@ -3833,83 +4297,81 @@ public final void rule__URL__Alternatives_1() throws RecognitionException { // $ANTLR start "rule__URL__Alternatives_2" - // InternalSemver.g:1071:1: rule__URL__Alternatives_2 : ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) | ( '-' ) | ( '_' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ); + // InternalSemver.g:1196:1: rule__URL__Alternatives_2 : ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) | ( '_' ) | ( ruleALPHA_NUMERIC_CHAR ) ); public final void rule__URL__Alternatives_2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1075:1: ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) | ( '-' ) | ( '_' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ) - int alt14=8; + // InternalSemver.g:1200:1: ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) | ( '_' ) | ( ruleALPHA_NUMERIC_CHAR ) ) + int alt17=6; switch ( input.LA(1) ) { - case 35: - { - alt14=1; - } - break; - case 36: - { - alt14=2; - } - break; case 41: { - alt14=3; + alt17=1; } break; - case 37: + case 42: { - alt14=4; + alt17=2; } break; - case 38: + case 46: { - alt14=5; + alt17=3; } break; - case 39: + case 43: { - alt14=6; + alt17=4; } break; - case RULE_DIGITS: + case 44: { - alt14=7; + alt17=5; } break; + case RULE_DIGITS: case RULE_LETTER_X: case RULE_LETTER_V: - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: + case RULE_LETTER_A: + case RULE_LETTER_C: + case RULE_LETTER_E: case RULE_LETTER_F: case RULE_LETTER_I: + case RULE_LETTER_K: case RULE_LETTER_L: - case RULE_LETTER_E: + case RULE_LETTER_M: + case RULE_LETTER_O: + case RULE_LETTER_P: + case RULE_LETTER_R: + case RULE_LETTER_S: + case RULE_LETTER_W: case RULE_LETTER_OTHER: + case 47: { - alt14=8; + alt17=6; } break; default: if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 14, 0, input); + new NoViableAltException("", 17, 0, input); throw nvae; } - switch (alt14) { + switch (alt17) { case 1 : - // InternalSemver.g:1076:2: ( '/' ) + // InternalSemver.g:1201:2: ( '/' ) { - // InternalSemver.g:1076:2: ( '/' ) - // InternalSemver.g:1077:3: '/' + // InternalSemver.g:1201:2: ( '/' ) + // InternalSemver.g:1202:3: '/' { if ( state.backtracking==0 ) { before(grammarAccess.getURLAccess().getSolidusKeyword_2_0()); } - match(input,35,FOLLOW_2); if (state.failed) return ; + match(input,41,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURLAccess().getSolidusKeyword_2_0()); } @@ -3920,15 +4382,15 @@ public final void rule__URL__Alternatives_2() throws RecognitionException { } break; case 2 : - // InternalSemver.g:1082:2: ( '.' ) + // InternalSemver.g:1207:2: ( '.' ) { - // InternalSemver.g:1082:2: ( '.' ) - // InternalSemver.g:1083:3: '.' + // InternalSemver.g:1207:2: ( '.' ) + // InternalSemver.g:1208:3: '.' { if ( state.backtracking==0 ) { before(grammarAccess.getURLAccess().getFullStopKeyword_2_1()); } - match(input,36,FOLLOW_2); if (state.failed) return ; + match(input,42,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURLAccess().getFullStopKeyword_2_1()); } @@ -3939,15 +4401,15 @@ public final void rule__URL__Alternatives_2() throws RecognitionException { } break; case 3 : - // InternalSemver.g:1088:2: ( ':' ) + // InternalSemver.g:1213:2: ( ':' ) { - // InternalSemver.g:1088:2: ( ':' ) - // InternalSemver.g:1089:3: ':' + // InternalSemver.g:1213:2: ( ':' ) + // InternalSemver.g:1214:3: ':' { if ( state.backtracking==0 ) { before(grammarAccess.getURLAccess().getColonKeyword_2_2()); } - match(input,41,FOLLOW_2); if (state.failed) return ; + match(input,46,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURLAccess().getColonKeyword_2_2()); } @@ -3958,15 +4420,15 @@ public final void rule__URL__Alternatives_2() throws RecognitionException { } break; case 4 : - // InternalSemver.g:1094:2: ( '@' ) + // InternalSemver.g:1219:2: ( '@' ) { - // InternalSemver.g:1094:2: ( '@' ) - // InternalSemver.g:1095:3: '@' + // InternalSemver.g:1219:2: ( '@' ) + // InternalSemver.g:1220:3: '@' { if ( state.backtracking==0 ) { before(grammarAccess.getURLAccess().getCommercialAtKeyword_2_3()); } - match(input,37,FOLLOW_2); if (state.failed) return ; + match(input,43,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURLAccess().getCommercialAtKeyword_2_3()); } @@ -3977,17 +4439,17 @@ public final void rule__URL__Alternatives_2() throws RecognitionException { } break; case 5 : - // InternalSemver.g:1100:2: ( '-' ) + // InternalSemver.g:1225:2: ( '_' ) { - // InternalSemver.g:1100:2: ( '-' ) - // InternalSemver.g:1101:3: '-' + // InternalSemver.g:1225:2: ( '_' ) + // InternalSemver.g:1226:3: '_' { if ( state.backtracking==0 ) { - before(grammarAccess.getURLAccess().getHyphenMinusKeyword_2_4()); + before(grammarAccess.getURLAccess().get_Keyword_2_4()); } - match(input,38,FOLLOW_2); if (state.failed) return ; + match(input,44,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURLAccess().getHyphenMinusKeyword_2_4()); + after(grammarAccess.getURLAccess().get_Keyword_2_4()); } } @@ -3996,59 +4458,21 @@ public final void rule__URL__Alternatives_2() throws RecognitionException { } break; case 6 : - // InternalSemver.g:1106:2: ( '_' ) - { - // InternalSemver.g:1106:2: ( '_' ) - // InternalSemver.g:1107:3: '_' - { - if ( state.backtracking==0 ) { - before(grammarAccess.getURLAccess().get_Keyword_2_5()); - } - match(input,39,FOLLOW_2); if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getURLAccess().get_Keyword_2_5()); - } - - } - - - } - break; - case 7 : - // InternalSemver.g:1112:2: ( RULE_DIGITS ) + // InternalSemver.g:1231:2: ( ruleALPHA_NUMERIC_CHAR ) { - // InternalSemver.g:1112:2: ( RULE_DIGITS ) - // InternalSemver.g:1113:3: RULE_DIGITS + // InternalSemver.g:1231:2: ( ruleALPHA_NUMERIC_CHAR ) + // InternalSemver.g:1232:3: ruleALPHA_NUMERIC_CHAR { if ( state.backtracking==0 ) { - before(grammarAccess.getURLAccess().getDIGITSTerminalRuleCall_2_6()); - } - match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getURLAccess().getDIGITSTerminalRuleCall_2_6()); - } - - } - - - } - break; - case 8 : - // InternalSemver.g:1118:2: ( ruleLETTER ) - { - // InternalSemver.g:1118:2: ( ruleLETTER ) - // InternalSemver.g:1119:3: ruleLETTER - { - if ( state.backtracking==0 ) { - before(grammarAccess.getURLAccess().getLETTERParserRuleCall_2_7()); + before(grammarAccess.getURLAccess().getALPHA_NUMERIC_CHARParserRuleCall_2_5()); } pushFollow(FOLLOW_2); - ruleLETTER(); + ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURLAccess().getLETTERParserRuleCall_2_7()); + after(grammarAccess.getURLAccess().getALPHA_NUMERIC_CHARParserRuleCall_2_5()); } } @@ -4074,58 +4498,64 @@ public final void rule__URL__Alternatives_2() throws RecognitionException { // $ANTLR start "rule__URL_NO_VX__Alternatives_0" - // InternalSemver.g:1128:1: rule__URL_NO_VX__Alternatives_0 : ( ( '-' ) | ( '_' ) | ( ruleLETTER_NO_VX ) ); + // InternalSemver.g:1241:1: rule__URL_NO_VX__Alternatives_0 : ( ( '_' ) | ( '-' ) | ( ruleLETTER_NO_VX ) ); public final void rule__URL_NO_VX__Alternatives_0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1132:1: ( ( '-' ) | ( '_' ) | ( ruleLETTER_NO_VX ) ) - int alt15=3; + // InternalSemver.g:1245:1: ( ( '_' ) | ( '-' ) | ( ruleLETTER_NO_VX ) ) + int alt18=3; switch ( input.LA(1) ) { - case 38: + case 44: { - alt15=1; + alt18=1; } break; - case 39: + case 47: { - alt15=2; + alt18=2; } break; - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: + case RULE_LETTER_A: + case RULE_LETTER_C: + case RULE_LETTER_E: case RULE_LETTER_F: case RULE_LETTER_I: + case RULE_LETTER_K: case RULE_LETTER_L: - case RULE_LETTER_E: + case RULE_LETTER_M: + case RULE_LETTER_O: + case RULE_LETTER_P: + case RULE_LETTER_R: + case RULE_LETTER_S: + case RULE_LETTER_W: case RULE_LETTER_OTHER: { - alt15=3; + alt18=3; } break; default: if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 15, 0, input); + new NoViableAltException("", 18, 0, input); throw nvae; } - switch (alt15) { + switch (alt18) { case 1 : - // InternalSemver.g:1133:2: ( '-' ) + // InternalSemver.g:1246:2: ( '_' ) { - // InternalSemver.g:1133:2: ( '-' ) - // InternalSemver.g:1134:3: '-' + // InternalSemver.g:1246:2: ( '_' ) + // InternalSemver.g:1247:3: '_' { if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_0_0()); + before(grammarAccess.getURL_NO_VXAccess().get_Keyword_0_0()); } - match(input,38,FOLLOW_2); if (state.failed) return ; + match(input,44,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_0_0()); + after(grammarAccess.getURL_NO_VXAccess().get_Keyword_0_0()); } } @@ -4134,17 +4564,17 @@ public final void rule__URL_NO_VX__Alternatives_0() throws RecognitionException } break; case 2 : - // InternalSemver.g:1139:2: ( '_' ) + // InternalSemver.g:1252:2: ( '-' ) { - // InternalSemver.g:1139:2: ( '_' ) - // InternalSemver.g:1140:3: '_' + // InternalSemver.g:1252:2: ( '-' ) + // InternalSemver.g:1253:3: '-' { if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().get_Keyword_0_1()); + before(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_0_1()); } - match(input,39,FOLLOW_2); if (state.failed) return ; + match(input,47,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().get_Keyword_0_1()); + after(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_0_1()); } } @@ -4153,10 +4583,10 @@ public final void rule__URL_NO_VX__Alternatives_0() throws RecognitionException } break; case 3 : - // InternalSemver.g:1145:2: ( ruleLETTER_NO_VX ) + // InternalSemver.g:1258:2: ( ruleLETTER_NO_VX ) { - // InternalSemver.g:1145:2: ( ruleLETTER_NO_VX ) - // InternalSemver.g:1146:3: ruleLETTER_NO_VX + // InternalSemver.g:1258:2: ( ruleLETTER_NO_VX ) + // InternalSemver.g:1259:3: ruleLETTER_NO_VX { if ( state.backtracking==0 ) { before(grammarAccess.getURL_NO_VXAccess().getLETTER_NO_VXParserRuleCall_0_2()); @@ -4193,65 +4623,42 @@ public final void rule__URL_NO_VX__Alternatives_0() throws RecognitionException // $ANTLR start "rule__URL_NO_VX__Alternatives_1" - // InternalSemver.g:1155:1: rule__URL_NO_VX__Alternatives_1 : ( ( '-' ) | ( '_' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ); + // InternalSemver.g:1268:1: rule__URL_NO_VX__Alternatives_1 : ( ( '_' ) | ( ruleALPHA_NUMERIC_CHAR ) ); public final void rule__URL_NO_VX__Alternatives_1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1159:1: ( ( '-' ) | ( '_' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ) - int alt16=4; - switch ( input.LA(1) ) { - case 38: - { - alt16=1; - } - break; - case 39: - { - alt16=2; - } - break; - case RULE_DIGITS: - { - alt16=3; - } - break; - case RULE_LETTER_X: - case RULE_LETTER_V: - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: - case RULE_LETTER_F: - case RULE_LETTER_I: - case RULE_LETTER_L: - case RULE_LETTER_E: - case RULE_LETTER_OTHER: - { - alt16=4; - } - break; - default: + // InternalSemver.g:1272:1: ( ( '_' ) | ( ruleALPHA_NUMERIC_CHAR ) ) + int alt19=2; + int LA19_0 = input.LA(1); + + if ( (LA19_0==44) ) { + alt19=1; + } + else if ( ((LA19_0>=RULE_DIGITS && LA19_0<=RULE_LETTER_OTHER)||LA19_0==47) ) { + alt19=2; + } + else { if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 16, 0, input); + new NoViableAltException("", 19, 0, input); throw nvae; } - - switch (alt16) { + switch (alt19) { case 1 : - // InternalSemver.g:1160:2: ( '-' ) + // InternalSemver.g:1273:2: ( '_' ) { - // InternalSemver.g:1160:2: ( '-' ) - // InternalSemver.g:1161:3: '-' + // InternalSemver.g:1273:2: ( '_' ) + // InternalSemver.g:1274:3: '_' { if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_1_0()); + before(grammarAccess.getURL_NO_VXAccess().get_Keyword_1_0()); } - match(input,38,FOLLOW_2); if (state.failed) return ; + match(input,44,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_1_0()); + after(grammarAccess.getURL_NO_VXAccess().get_Keyword_1_0()); } } @@ -4260,59 +4667,21 @@ public final void rule__URL_NO_VX__Alternatives_1() throws RecognitionException } break; case 2 : - // InternalSemver.g:1166:2: ( '_' ) - { - // InternalSemver.g:1166:2: ( '_' ) - // InternalSemver.g:1167:3: '_' - { - if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().get_Keyword_1_1()); - } - match(input,39,FOLLOW_2); if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().get_Keyword_1_1()); - } - - } - - - } - break; - case 3 : - // InternalSemver.g:1172:2: ( RULE_DIGITS ) - { - // InternalSemver.g:1172:2: ( RULE_DIGITS ) - // InternalSemver.g:1173:3: RULE_DIGITS - { - if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().getDIGITSTerminalRuleCall_1_2()); - } - match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().getDIGITSTerminalRuleCall_1_2()); - } - - } - - - } - break; - case 4 : - // InternalSemver.g:1178:2: ( ruleLETTER ) + // InternalSemver.g:1279:2: ( ruleALPHA_NUMERIC_CHAR ) { - // InternalSemver.g:1178:2: ( ruleLETTER ) - // InternalSemver.g:1179:3: ruleLETTER + // InternalSemver.g:1279:2: ( ruleALPHA_NUMERIC_CHAR ) + // InternalSemver.g:1280:3: ruleALPHA_NUMERIC_CHAR { if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().getLETTERParserRuleCall_1_3()); + before(grammarAccess.getURL_NO_VXAccess().getALPHA_NUMERIC_CHARParserRuleCall_1_1()); } pushFollow(FOLLOW_2); - ruleLETTER(); + ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().getLETTERParserRuleCall_1_3()); + after(grammarAccess.getURL_NO_VXAccess().getALPHA_NUMERIC_CHARParserRuleCall_1_1()); } } @@ -4338,54 +4707,54 @@ public final void rule__URL_NO_VX__Alternatives_1() throws RecognitionException // $ANTLR start "rule__URL_NO_VX__Alternatives_2" - // InternalSemver.g:1188:1: rule__URL_NO_VX__Alternatives_2 : ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) ); + // InternalSemver.g:1289:1: rule__URL_NO_VX__Alternatives_2 : ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) ); public final void rule__URL_NO_VX__Alternatives_2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1192:1: ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) ) - int alt17=4; + // InternalSemver.g:1293:1: ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) ) + int alt20=4; switch ( input.LA(1) ) { - case 35: + case 41: { - alt17=1; + alt20=1; } break; - case 36: + case 42: { - alt17=2; + alt20=2; } break; - case 41: + case 46: { - alt17=3; + alt20=3; } break; - case 37: + case 43: { - alt17=4; + alt20=4; } break; default: if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 17, 0, input); + new NoViableAltException("", 20, 0, input); throw nvae; } - switch (alt17) { + switch (alt20) { case 1 : - // InternalSemver.g:1193:2: ( '/' ) + // InternalSemver.g:1294:2: ( '/' ) { - // InternalSemver.g:1193:2: ( '/' ) - // InternalSemver.g:1194:3: '/' + // InternalSemver.g:1294:2: ( '/' ) + // InternalSemver.g:1295:3: '/' { if ( state.backtracking==0 ) { before(grammarAccess.getURL_NO_VXAccess().getSolidusKeyword_2_0()); } - match(input,35,FOLLOW_2); if (state.failed) return ; + match(input,41,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURL_NO_VXAccess().getSolidusKeyword_2_0()); } @@ -4396,15 +4765,15 @@ public final void rule__URL_NO_VX__Alternatives_2() throws RecognitionException } break; case 2 : - // InternalSemver.g:1199:2: ( '.' ) + // InternalSemver.g:1300:2: ( '.' ) { - // InternalSemver.g:1199:2: ( '.' ) - // InternalSemver.g:1200:3: '.' + // InternalSemver.g:1300:2: ( '.' ) + // InternalSemver.g:1301:3: '.' { if ( state.backtracking==0 ) { before(grammarAccess.getURL_NO_VXAccess().getFullStopKeyword_2_1()); } - match(input,36,FOLLOW_2); if (state.failed) return ; + match(input,42,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURL_NO_VXAccess().getFullStopKeyword_2_1()); } @@ -4415,15 +4784,15 @@ public final void rule__URL_NO_VX__Alternatives_2() throws RecognitionException } break; case 3 : - // InternalSemver.g:1205:2: ( ':' ) + // InternalSemver.g:1306:2: ( ':' ) { - // InternalSemver.g:1205:2: ( ':' ) - // InternalSemver.g:1206:3: ':' + // InternalSemver.g:1306:2: ( ':' ) + // InternalSemver.g:1307:3: ':' { if ( state.backtracking==0 ) { before(grammarAccess.getURL_NO_VXAccess().getColonKeyword_2_2()); } - match(input,41,FOLLOW_2); if (state.failed) return ; + match(input,46,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURL_NO_VXAccess().getColonKeyword_2_2()); } @@ -4434,15 +4803,15 @@ public final void rule__URL_NO_VX__Alternatives_2() throws RecognitionException } break; case 4 : - // InternalSemver.g:1211:2: ( '@' ) + // InternalSemver.g:1312:2: ( '@' ) { - // InternalSemver.g:1211:2: ( '@' ) - // InternalSemver.g:1212:3: '@' + // InternalSemver.g:1312:2: ( '@' ) + // InternalSemver.g:1313:3: '@' { if ( state.backtracking==0 ) { before(grammarAccess.getURL_NO_VXAccess().getCommercialAtKeyword_2_3()); } - match(input,37,FOLLOW_2); if (state.failed) return ; + match(input,43,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURL_NO_VXAccess().getCommercialAtKeyword_2_3()); } @@ -4470,83 +4839,81 @@ public final void rule__URL_NO_VX__Alternatives_2() throws RecognitionException // $ANTLR start "rule__URL_NO_VX__Alternatives_3" - // InternalSemver.g:1221:1: rule__URL_NO_VX__Alternatives_3 : ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) | ( '-' ) | ( '_' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ); + // InternalSemver.g:1322:1: rule__URL_NO_VX__Alternatives_3 : ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) | ( '_' ) | ( ruleALPHA_NUMERIC_CHAR ) ); public final void rule__URL_NO_VX__Alternatives_3() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1225:1: ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) | ( '-' ) | ( '_' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ) - int alt18=8; + // InternalSemver.g:1326:1: ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) | ( '_' ) | ( ruleALPHA_NUMERIC_CHAR ) ) + int alt21=6; switch ( input.LA(1) ) { - case 35: - { - alt18=1; - } - break; - case 36: - { - alt18=2; - } - break; case 41: { - alt18=3; + alt21=1; } break; - case 37: + case 42: { - alt18=4; + alt21=2; } break; - case 38: + case 46: { - alt18=5; + alt21=3; } break; - case 39: + case 43: { - alt18=6; + alt21=4; } break; - case RULE_DIGITS: + case 44: { - alt18=7; + alt21=5; } break; + case RULE_DIGITS: case RULE_LETTER_X: case RULE_LETTER_V: - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: + case RULE_LETTER_A: + case RULE_LETTER_C: + case RULE_LETTER_E: case RULE_LETTER_F: case RULE_LETTER_I: + case RULE_LETTER_K: case RULE_LETTER_L: - case RULE_LETTER_E: + case RULE_LETTER_M: + case RULE_LETTER_O: + case RULE_LETTER_P: + case RULE_LETTER_R: + case RULE_LETTER_S: + case RULE_LETTER_W: case RULE_LETTER_OTHER: + case 47: { - alt18=8; + alt21=6; } break; default: if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 18, 0, input); + new NoViableAltException("", 21, 0, input); throw nvae; } - switch (alt18) { + switch (alt21) { case 1 : - // InternalSemver.g:1226:2: ( '/' ) + // InternalSemver.g:1327:2: ( '/' ) { - // InternalSemver.g:1226:2: ( '/' ) - // InternalSemver.g:1227:3: '/' + // InternalSemver.g:1327:2: ( '/' ) + // InternalSemver.g:1328:3: '/' { if ( state.backtracking==0 ) { before(grammarAccess.getURL_NO_VXAccess().getSolidusKeyword_3_0()); } - match(input,35,FOLLOW_2); if (state.failed) return ; + match(input,41,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURL_NO_VXAccess().getSolidusKeyword_3_0()); } @@ -4557,15 +4924,15 @@ public final void rule__URL_NO_VX__Alternatives_3() throws RecognitionException } break; case 2 : - // InternalSemver.g:1232:2: ( '.' ) + // InternalSemver.g:1333:2: ( '.' ) { - // InternalSemver.g:1232:2: ( '.' ) - // InternalSemver.g:1233:3: '.' + // InternalSemver.g:1333:2: ( '.' ) + // InternalSemver.g:1334:3: '.' { if ( state.backtracking==0 ) { before(grammarAccess.getURL_NO_VXAccess().getFullStopKeyword_3_1()); } - match(input,36,FOLLOW_2); if (state.failed) return ; + match(input,42,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURL_NO_VXAccess().getFullStopKeyword_3_1()); } @@ -4576,15 +4943,15 @@ public final void rule__URL_NO_VX__Alternatives_3() throws RecognitionException } break; case 3 : - // InternalSemver.g:1238:2: ( ':' ) + // InternalSemver.g:1339:2: ( ':' ) { - // InternalSemver.g:1238:2: ( ':' ) - // InternalSemver.g:1239:3: ':' + // InternalSemver.g:1339:2: ( ':' ) + // InternalSemver.g:1340:3: ':' { if ( state.backtracking==0 ) { before(grammarAccess.getURL_NO_VXAccess().getColonKeyword_3_2()); } - match(input,41,FOLLOW_2); if (state.failed) return ; + match(input,46,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURL_NO_VXAccess().getColonKeyword_3_2()); } @@ -4595,15 +4962,15 @@ public final void rule__URL_NO_VX__Alternatives_3() throws RecognitionException } break; case 4 : - // InternalSemver.g:1244:2: ( '@' ) + // InternalSemver.g:1345:2: ( '@' ) { - // InternalSemver.g:1244:2: ( '@' ) - // InternalSemver.g:1245:3: '@' + // InternalSemver.g:1345:2: ( '@' ) + // InternalSemver.g:1346:3: '@' { if ( state.backtracking==0 ) { before(grammarAccess.getURL_NO_VXAccess().getCommercialAtKeyword_3_3()); } - match(input,37,FOLLOW_2); if (state.failed) return ; + match(input,43,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURL_NO_VXAccess().getCommercialAtKeyword_3_3()); } @@ -4614,17 +4981,17 @@ public final void rule__URL_NO_VX__Alternatives_3() throws RecognitionException } break; case 5 : - // InternalSemver.g:1250:2: ( '-' ) + // InternalSemver.g:1351:2: ( '_' ) { - // InternalSemver.g:1250:2: ( '-' ) - // InternalSemver.g:1251:3: '-' + // InternalSemver.g:1351:2: ( '_' ) + // InternalSemver.g:1352:3: '_' { if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_3_4()); + before(grammarAccess.getURL_NO_VXAccess().get_Keyword_3_4()); } - match(input,38,FOLLOW_2); if (state.failed) return ; + match(input,44,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_3_4()); + after(grammarAccess.getURL_NO_VXAccess().get_Keyword_3_4()); } } @@ -4633,59 +5000,21 @@ public final void rule__URL_NO_VX__Alternatives_3() throws RecognitionException } break; case 6 : - // InternalSemver.g:1256:2: ( '_' ) - { - // InternalSemver.g:1256:2: ( '_' ) - // InternalSemver.g:1257:3: '_' - { - if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().get_Keyword_3_5()); - } - match(input,39,FOLLOW_2); if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().get_Keyword_3_5()); - } - - } - - - } - break; - case 7 : - // InternalSemver.g:1262:2: ( RULE_DIGITS ) - { - // InternalSemver.g:1262:2: ( RULE_DIGITS ) - // InternalSemver.g:1263:3: RULE_DIGITS - { - if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().getDIGITSTerminalRuleCall_3_6()); - } - match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().getDIGITSTerminalRuleCall_3_6()); - } - - } - - - } - break; - case 8 : - // InternalSemver.g:1268:2: ( ruleLETTER ) + // InternalSemver.g:1357:2: ( ruleALPHA_NUMERIC_CHAR ) { - // InternalSemver.g:1268:2: ( ruleLETTER ) - // InternalSemver.g:1269:3: ruleLETTER + // InternalSemver.g:1357:2: ( ruleALPHA_NUMERIC_CHAR ) + // InternalSemver.g:1358:3: ruleALPHA_NUMERIC_CHAR { if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().getLETTERParserRuleCall_3_7()); + before(grammarAccess.getURL_NO_VXAccess().getALPHA_NUMERIC_CHARParserRuleCall_3_5()); } pushFollow(FOLLOW_2); - ruleLETTER(); + ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().getLETTERParserRuleCall_3_7()); + after(grammarAccess.getURL_NO_VXAccess().getALPHA_NUMERIC_CHARParserRuleCall_3_5()); } } @@ -4710,61 +5039,124 @@ public final void rule__URL_NO_VX__Alternatives_3() throws RecognitionException // $ANTLR end "rule__URL_NO_VX__Alternatives_3" - // $ANTLR start "rule__TAG__Alternatives_1" - // InternalSemver.g:1278:1: rule__TAG__Alternatives_1 : ( ( '-' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ); - public final void rule__TAG__Alternatives_1() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_VERSION__Alternatives" + // InternalSemver.g:1367:1: rule__WORKSPACE_VERSION__Alternatives : ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) | ( '_' ) | ( '=' ) | ( '~' ) | ( '^' ) | ( '<' ) | ( '>' ) | ( '<=' ) | ( '>=' ) | ( RULE_ASTERIX ) | ( ruleALPHA_NUMERIC_CHAR ) ); + public final void rule__WORKSPACE_VERSION__Alternatives() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1282:1: ( ( '-' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ) - int alt19=3; + // InternalSemver.g:1371:1: ( ( '/' ) | ( '.' ) | ( ':' ) | ( '@' ) | ( '_' ) | ( '=' ) | ( '~' ) | ( '^' ) | ( '<' ) | ( '>' ) | ( '<=' ) | ( '>=' ) | ( RULE_ASTERIX ) | ( ruleALPHA_NUMERIC_CHAR ) ) + int alt22=14; switch ( input.LA(1) ) { - case 38: + case 41: { - alt19=1; + alt22=1; } break; - case RULE_DIGITS: + case 42: { - alt19=2; + alt22=2; } break; - case RULE_LETTER_X: - case RULE_LETTER_V: - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: - case RULE_LETTER_F: - case RULE_LETTER_I: - case RULE_LETTER_L: - case RULE_LETTER_E: - case RULE_LETTER_OTHER: + case 46: { - alt19=3; + alt22=3; } break; - default: - if (state.backtracking>0) {state.failed=true; return ;} - NoViableAltException nvae = - new NoViableAltException("", 19, 0, input); - - throw nvae; - } - - switch (alt19) { - case 1 : - // InternalSemver.g:1283:2: ( '-' ) - { - // InternalSemver.g:1283:2: ( '-' ) - // InternalSemver.g:1284:3: '-' - { - if ( state.backtracking==0 ) { - before(grammarAccess.getTAGAccess().getHyphenMinusKeyword_1_0()); - } - match(input,38,FOLLOW_2); if (state.failed) return ; + case 43: + { + alt22=4; + } + break; + case 44: + { + alt22=5; + } + break; + case 48: + { + alt22=6; + } + break; + case 49: + { + alt22=7; + } + break; + case 50: + { + alt22=8; + } + break; + case 51: + { + alt22=9; + } + break; + case 52: + { + alt22=10; + } + break; + case 53: + { + alt22=11; + } + break; + case 54: + { + alt22=12; + } + break; + case RULE_ASTERIX: + { + alt22=13; + } + break; + case RULE_DIGITS: + case RULE_LETTER_X: + case RULE_LETTER_V: + case RULE_LETTER_A: + case RULE_LETTER_C: + case RULE_LETTER_E: + case RULE_LETTER_F: + case RULE_LETTER_I: + case RULE_LETTER_K: + case RULE_LETTER_L: + case RULE_LETTER_M: + case RULE_LETTER_O: + case RULE_LETTER_P: + case RULE_LETTER_R: + case RULE_LETTER_S: + case RULE_LETTER_W: + case RULE_LETTER_OTHER: + case 47: + { + alt22=14; + } + break; + default: + if (state.backtracking>0) {state.failed=true; return ;} + NoViableAltException nvae = + new NoViableAltException("", 22, 0, input); + + throw nvae; + } + + switch (alt22) { + case 1 : + // InternalSemver.g:1372:2: ( '/' ) + { + // InternalSemver.g:1372:2: ( '/' ) + // InternalSemver.g:1373:3: '/' + { if ( state.backtracking==0 ) { - after(grammarAccess.getTAGAccess().getHyphenMinusKeyword_1_0()); + before(grammarAccess.getWORKSPACE_VERSIONAccess().getSolidusKeyword_0()); + } + match(input,41,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_VERSIONAccess().getSolidusKeyword_0()); } } @@ -4773,17 +5165,17 @@ public final void rule__TAG__Alternatives_1() throws RecognitionException { } break; case 2 : - // InternalSemver.g:1289:2: ( RULE_DIGITS ) + // InternalSemver.g:1378:2: ( '.' ) { - // InternalSemver.g:1289:2: ( RULE_DIGITS ) - // InternalSemver.g:1290:3: RULE_DIGITS + // InternalSemver.g:1378:2: ( '.' ) + // InternalSemver.g:1379:3: '.' { if ( state.backtracking==0 ) { - before(grammarAccess.getTAGAccess().getDIGITSTerminalRuleCall_1_1()); + before(grammarAccess.getWORKSPACE_VERSIONAccess().getFullStopKeyword_1()); } - match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return ; + match(input,42,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getTAGAccess().getDIGITSTerminalRuleCall_1_1()); + after(grammarAccess.getWORKSPACE_VERSIONAccess().getFullStopKeyword_1()); } } @@ -4792,21 +5184,36 @@ public final void rule__TAG__Alternatives_1() throws RecognitionException { } break; case 3 : - // InternalSemver.g:1295:2: ( ruleLETTER ) + // InternalSemver.g:1384:2: ( ':' ) { - // InternalSemver.g:1295:2: ( ruleLETTER ) - // InternalSemver.g:1296:3: ruleLETTER + // InternalSemver.g:1384:2: ( ':' ) + // InternalSemver.g:1385:3: ':' { if ( state.backtracking==0 ) { - before(grammarAccess.getTAGAccess().getLETTERParserRuleCall_1_2()); + before(grammarAccess.getWORKSPACE_VERSIONAccess().getColonKeyword_2()); + } + match(input,46,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_VERSIONAccess().getColonKeyword_2()); } - pushFollow(FOLLOW_2); - ruleLETTER(); - state._fsp--; - if (state.failed) return ; + } + + + } + break; + case 4 : + // InternalSemver.g:1390:2: ( '@' ) + { + // InternalSemver.g:1390:2: ( '@' ) + // InternalSemver.g:1391:3: '@' + { if ( state.backtracking==0 ) { - after(grammarAccess.getTAGAccess().getLETTERParserRuleCall_1_2()); + before(grammarAccess.getWORKSPACE_VERSIONAccess().getCommercialAtKeyword_3()); + } + match(input,43,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_VERSIONAccess().getCommercialAtKeyword_3()); } } @@ -4814,78 +5221,75 @@ public final void rule__TAG__Alternatives_1() throws RecognitionException { } break; + case 5 : + // InternalSemver.g:1396:2: ( '_' ) + { + // InternalSemver.g:1396:2: ( '_' ) + // InternalSemver.g:1397:3: '_' + { + if ( state.backtracking==0 ) { + before(grammarAccess.getWORKSPACE_VERSIONAccess().get_Keyword_4()); + } + match(input,44,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_VERSIONAccess().get_Keyword_4()); + } - } - } - catch (RecognitionException re) { - reportError(re); - recover(input,re); - } - finally { + } - restoreStackSize(stackSize); - } - return ; - } - // $ANTLR end "rule__TAG__Alternatives_1" + } + break; + case 6 : + // InternalSemver.g:1402:2: ( '=' ) + { + // InternalSemver.g:1402:2: ( '=' ) + // InternalSemver.g:1403:3: '=' + { + if ( state.backtracking==0 ) { + before(grammarAccess.getWORKSPACE_VERSIONAccess().getEqualsSignKeyword_5()); + } + match(input,48,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_VERSIONAccess().getEqualsSignKeyword_5()); + } + } - // $ANTLR start "rule__ALPHA_NUMERIC_CHARS__Alternatives" - // InternalSemver.g:1305:1: rule__ALPHA_NUMERIC_CHARS__Alternatives : ( ( '-' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ); - public final void rule__ALPHA_NUMERIC_CHARS__Alternatives() throws RecognitionException { - int stackSize = keepStackSize(); - - try { - // InternalSemver.g:1309:1: ( ( '-' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ) - int alt20=3; - switch ( input.LA(1) ) { - case 38: - { - alt20=1; - } - break; - case RULE_DIGITS: - { - alt20=2; - } - break; - case RULE_LETTER_X: - case RULE_LETTER_V: - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: - case RULE_LETTER_F: - case RULE_LETTER_I: - case RULE_LETTER_L: - case RULE_LETTER_E: - case RULE_LETTER_OTHER: - { - alt20=3; - } - break; - default: - if (state.backtracking>0) {state.failed=true; return ;} - NoViableAltException nvae = - new NoViableAltException("", 20, 0, input); + } + break; + case 7 : + // InternalSemver.g:1408:2: ( '~' ) + { + // InternalSemver.g:1408:2: ( '~' ) + // InternalSemver.g:1409:3: '~' + { + if ( state.backtracking==0 ) { + before(grammarAccess.getWORKSPACE_VERSIONAccess().getTildeKeyword_6()); + } + match(input,49,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_VERSIONAccess().getTildeKeyword_6()); + } - throw nvae; - } + } - switch (alt20) { - case 1 : - // InternalSemver.g:1310:2: ( '-' ) + + } + break; + case 8 : + // InternalSemver.g:1414:2: ( '^' ) { - // InternalSemver.g:1310:2: ( '-' ) - // InternalSemver.g:1311:3: '-' + // InternalSemver.g:1414:2: ( '^' ) + // InternalSemver.g:1415:3: '^' { if ( state.backtracking==0 ) { - before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getHyphenMinusKeyword_0()); + before(grammarAccess.getWORKSPACE_VERSIONAccess().getCircumflexAccentKeyword_7()); } - match(input,38,FOLLOW_2); if (state.failed) return ; + match(input,50,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getHyphenMinusKeyword_0()); + after(grammarAccess.getWORKSPACE_VERSIONAccess().getCircumflexAccentKeyword_7()); } } @@ -4893,18 +5297,18 @@ public final void rule__ALPHA_NUMERIC_CHARS__Alternatives() throws RecognitionEx } break; - case 2 : - // InternalSemver.g:1316:2: ( RULE_DIGITS ) + case 9 : + // InternalSemver.g:1420:2: ( '<' ) { - // InternalSemver.g:1316:2: ( RULE_DIGITS ) - // InternalSemver.g:1317:3: RULE_DIGITS + // InternalSemver.g:1420:2: ( '<' ) + // InternalSemver.g:1421:3: '<' { if ( state.backtracking==0 ) { - before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getDIGITSTerminalRuleCall_1()); + before(grammarAccess.getWORKSPACE_VERSIONAccess().getLessThanSignKeyword_8()); } - match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return ; + match(input,51,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getDIGITSTerminalRuleCall_1()); + after(grammarAccess.getWORKSPACE_VERSIONAccess().getLessThanSignKeyword_8()); } } @@ -4912,22 +5316,98 @@ public final void rule__ALPHA_NUMERIC_CHARS__Alternatives() throws RecognitionEx } break; - case 3 : - // InternalSemver.g:1322:2: ( ruleLETTER ) + case 10 : + // InternalSemver.g:1426:2: ( '>' ) + { + // InternalSemver.g:1426:2: ( '>' ) + // InternalSemver.g:1427:3: '>' + { + if ( state.backtracking==0 ) { + before(grammarAccess.getWORKSPACE_VERSIONAccess().getGreaterThanSignKeyword_9()); + } + match(input,52,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_VERSIONAccess().getGreaterThanSignKeyword_9()); + } + + } + + + } + break; + case 11 : + // InternalSemver.g:1432:2: ( '<=' ) + { + // InternalSemver.g:1432:2: ( '<=' ) + // InternalSemver.g:1433:3: '<=' + { + if ( state.backtracking==0 ) { + before(grammarAccess.getWORKSPACE_VERSIONAccess().getLessThanSignEqualsSignKeyword_10()); + } + match(input,53,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_VERSIONAccess().getLessThanSignEqualsSignKeyword_10()); + } + + } + + + } + break; + case 12 : + // InternalSemver.g:1438:2: ( '>=' ) + { + // InternalSemver.g:1438:2: ( '>=' ) + // InternalSemver.g:1439:3: '>=' + { + if ( state.backtracking==0 ) { + before(grammarAccess.getWORKSPACE_VERSIONAccess().getGreaterThanSignEqualsSignKeyword_11()); + } + match(input,54,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_VERSIONAccess().getGreaterThanSignEqualsSignKeyword_11()); + } + + } + + + } + break; + case 13 : + // InternalSemver.g:1444:2: ( RULE_ASTERIX ) + { + // InternalSemver.g:1444:2: ( RULE_ASTERIX ) + // InternalSemver.g:1445:3: RULE_ASTERIX + { + if ( state.backtracking==0 ) { + before(grammarAccess.getWORKSPACE_VERSIONAccess().getASTERIXTerminalRuleCall_12()); + } + match(input,RULE_ASTERIX,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_VERSIONAccess().getASTERIXTerminalRuleCall_12()); + } + + } + + + } + break; + case 14 : + // InternalSemver.g:1450:2: ( ruleALPHA_NUMERIC_CHAR ) { - // InternalSemver.g:1322:2: ( ruleLETTER ) - // InternalSemver.g:1323:3: ruleLETTER + // InternalSemver.g:1450:2: ( ruleALPHA_NUMERIC_CHAR ) + // InternalSemver.g:1451:3: ruleALPHA_NUMERIC_CHAR { if ( state.backtracking==0 ) { - before(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getLETTERParserRuleCall_2()); + before(grammarAccess.getWORKSPACE_VERSIONAccess().getALPHA_NUMERIC_CHARParserRuleCall_13()); } pushFollow(FOLLOW_2); - ruleLETTER(); + ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getLETTERParserRuleCall_2()); + after(grammarAccess.getWORKSPACE_VERSIONAccess().getALPHA_NUMERIC_CHARParserRuleCall_13()); } } @@ -4949,64 +5429,70 @@ public final void rule__ALPHA_NUMERIC_CHARS__Alternatives() throws RecognitionEx } return ; } - // $ANTLR end "rule__ALPHA_NUMERIC_CHARS__Alternatives" + // $ANTLR end "rule__WORKSPACE_VERSION__Alternatives" - // $ANTLR start "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1" - // InternalSemver.g:1332:1: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 : ( ( '-' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ); - public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1() throws RecognitionException { + // $ANTLR start "rule__ALPHA_NUMERIC_CHAR__Alternatives" + // InternalSemver.g:1460:1: rule__ALPHA_NUMERIC_CHAR__Alternatives : ( ( '-' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ); + public final void rule__ALPHA_NUMERIC_CHAR__Alternatives() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1336:1: ( ( '-' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ) - int alt21=3; + // InternalSemver.g:1464:1: ( ( '-' ) | ( RULE_DIGITS ) | ( ruleLETTER ) ) + int alt23=3; switch ( input.LA(1) ) { - case 38: + case 47: { - alt21=1; + alt23=1; } break; case RULE_DIGITS: { - alt21=2; + alt23=2; } break; case RULE_LETTER_X: case RULE_LETTER_V: - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: + case RULE_LETTER_A: + case RULE_LETTER_C: + case RULE_LETTER_E: case RULE_LETTER_F: case RULE_LETTER_I: + case RULE_LETTER_K: case RULE_LETTER_L: - case RULE_LETTER_E: + case RULE_LETTER_M: + case RULE_LETTER_O: + case RULE_LETTER_P: + case RULE_LETTER_R: + case RULE_LETTER_S: + case RULE_LETTER_W: case RULE_LETTER_OTHER: { - alt21=3; + alt23=3; } break; default: if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 21, 0, input); + new NoViableAltException("", 23, 0, input); throw nvae; } - switch (alt21) { + switch (alt23) { case 1 : - // InternalSemver.g:1337:2: ( '-' ) + // InternalSemver.g:1465:2: ( '-' ) { - // InternalSemver.g:1337:2: ( '-' ) - // InternalSemver.g:1338:3: '-' + // InternalSemver.g:1465:2: ( '-' ) + // InternalSemver.g:1466:3: '-' { if ( state.backtracking==0 ) { - before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getHyphenMinusKeyword_1_0()); + before(grammarAccess.getALPHA_NUMERIC_CHARAccess().getHyphenMinusKeyword_0()); } - match(input,38,FOLLOW_2); if (state.failed) return ; + match(input,47,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getHyphenMinusKeyword_1_0()); + after(grammarAccess.getALPHA_NUMERIC_CHARAccess().getHyphenMinusKeyword_0()); } } @@ -5015,17 +5501,17 @@ public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1() } break; case 2 : - // InternalSemver.g:1343:2: ( RULE_DIGITS ) + // InternalSemver.g:1471:2: ( RULE_DIGITS ) { - // InternalSemver.g:1343:2: ( RULE_DIGITS ) - // InternalSemver.g:1344:3: RULE_DIGITS + // InternalSemver.g:1471:2: ( RULE_DIGITS ) + // InternalSemver.g:1472:3: RULE_DIGITS { if ( state.backtracking==0 ) { - before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getDIGITSTerminalRuleCall_1_1()); + before(grammarAccess.getALPHA_NUMERIC_CHARAccess().getDIGITSTerminalRuleCall_1()); } match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getDIGITSTerminalRuleCall_1_1()); + after(grammarAccess.getALPHA_NUMERIC_CHARAccess().getDIGITSTerminalRuleCall_1()); } } @@ -5034,13 +5520,13 @@ public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1() } break; case 3 : - // InternalSemver.g:1349:2: ( ruleLETTER ) + // InternalSemver.g:1477:2: ( ruleLETTER ) { - // InternalSemver.g:1349:2: ( ruleLETTER ) - // InternalSemver.g:1350:3: ruleLETTER + // InternalSemver.g:1477:2: ( ruleLETTER ) + // InternalSemver.g:1478:3: ruleLETTER { if ( state.backtracking==0 ) { - before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getLETTERParserRuleCall_1_2()); + before(grammarAccess.getALPHA_NUMERIC_CHARAccess().getLETTERParserRuleCall_2()); } pushFollow(FOLLOW_2); ruleLETTER(); @@ -5048,7 +5534,7 @@ public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1() state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getLETTERParserRuleCall_1_2()); + after(grammarAccess.getALPHA_NUMERIC_CHARAccess().getLETTERParserRuleCall_2()); } } @@ -5070,39 +5556,39 @@ public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1() } return ; } - // $ANTLR end "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1" + // $ANTLR end "rule__ALPHA_NUMERIC_CHAR__Alternatives" // $ANTLR start "rule__WILDCARD__Alternatives" - // InternalSemver.g:1359:1: rule__WILDCARD__Alternatives : ( ( RULE_LETTER_X ) | ( RULE_ASTERIX ) ); + // InternalSemver.g:1487:1: rule__WILDCARD__Alternatives : ( ( RULE_LETTER_X ) | ( RULE_ASTERIX ) ); public final void rule__WILDCARD__Alternatives() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1363:1: ( ( RULE_LETTER_X ) | ( RULE_ASTERIX ) ) - int alt22=2; - int LA22_0 = input.LA(1); + // InternalSemver.g:1491:1: ( ( RULE_LETTER_X ) | ( RULE_ASTERIX ) ) + int alt24=2; + int LA24_0 = input.LA(1); - if ( (LA22_0==RULE_LETTER_X) ) { - alt22=1; + if ( (LA24_0==RULE_LETTER_X) ) { + alt24=1; } - else if ( (LA22_0==RULE_ASTERIX) ) { - alt22=2; + else if ( (LA24_0==RULE_ASTERIX) ) { + alt24=2; } else { if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 22, 0, input); + new NoViableAltException("", 24, 0, input); throw nvae; } - switch (alt22) { + switch (alt24) { case 1 : - // InternalSemver.g:1364:2: ( RULE_LETTER_X ) + // InternalSemver.g:1492:2: ( RULE_LETTER_X ) { - // InternalSemver.g:1364:2: ( RULE_LETTER_X ) - // InternalSemver.g:1365:3: RULE_LETTER_X + // InternalSemver.g:1492:2: ( RULE_LETTER_X ) + // InternalSemver.g:1493:3: RULE_LETTER_X { if ( state.backtracking==0 ) { before(grammarAccess.getWILDCARDAccess().getLETTER_XTerminalRuleCall_0()); @@ -5118,10 +5604,10 @@ else if ( (LA22_0==RULE_ASTERIX) ) { } break; case 2 : - // InternalSemver.g:1370:2: ( RULE_ASTERIX ) + // InternalSemver.g:1498:2: ( RULE_ASTERIX ) { - // InternalSemver.g:1370:2: ( RULE_ASTERIX ) - // InternalSemver.g:1371:3: RULE_ASTERIX + // InternalSemver.g:1498:2: ( RULE_ASTERIX ) + // InternalSemver.g:1499:3: RULE_ASTERIX { if ( state.backtracking==0 ) { before(grammarAccess.getWILDCARDAccess().getASTERIXTerminalRuleCall_1()); @@ -5154,51 +5640,57 @@ else if ( (LA22_0==RULE_ASTERIX) ) { // $ANTLR start "rule__LETTER__Alternatives" - // InternalSemver.g:1380:1: rule__LETTER__Alternatives : ( ( RULE_LETTER_V ) | ( RULE_LETTER_X ) | ( ruleLETTER_NO_VX ) ); + // InternalSemver.g:1508:1: rule__LETTER__Alternatives : ( ( RULE_LETTER_V ) | ( RULE_LETTER_X ) | ( ruleLETTER_NO_VX ) ); public final void rule__LETTER__Alternatives() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1384:1: ( ( RULE_LETTER_V ) | ( RULE_LETTER_X ) | ( ruleLETTER_NO_VX ) ) - int alt23=3; + // InternalSemver.g:1512:1: ( ( RULE_LETTER_V ) | ( RULE_LETTER_X ) | ( ruleLETTER_NO_VX ) ) + int alt25=3; switch ( input.LA(1) ) { case RULE_LETTER_V: { - alt23=1; + alt25=1; } break; case RULE_LETTER_X: { - alt23=2; + alt25=2; } break; - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: + case RULE_LETTER_A: + case RULE_LETTER_C: + case RULE_LETTER_E: case RULE_LETTER_F: case RULE_LETTER_I: + case RULE_LETTER_K: case RULE_LETTER_L: - case RULE_LETTER_E: - case RULE_LETTER_OTHER: + case RULE_LETTER_M: + case RULE_LETTER_O: + case RULE_LETTER_P: + case RULE_LETTER_R: + case RULE_LETTER_S: + case RULE_LETTER_W: + case RULE_LETTER_OTHER: { - alt23=3; + alt25=3; } break; default: if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 23, 0, input); + new NoViableAltException("", 25, 0, input); throw nvae; } - switch (alt23) { + switch (alt25) { case 1 : - // InternalSemver.g:1385:2: ( RULE_LETTER_V ) + // InternalSemver.g:1513:2: ( RULE_LETTER_V ) { - // InternalSemver.g:1385:2: ( RULE_LETTER_V ) - // InternalSemver.g:1386:3: RULE_LETTER_V + // InternalSemver.g:1513:2: ( RULE_LETTER_V ) + // InternalSemver.g:1514:3: RULE_LETTER_V { if ( state.backtracking==0 ) { before(grammarAccess.getLETTERAccess().getLETTER_VTerminalRuleCall_0()); @@ -5214,10 +5706,10 @@ public final void rule__LETTER__Alternatives() throws RecognitionException { } break; case 2 : - // InternalSemver.g:1391:2: ( RULE_LETTER_X ) + // InternalSemver.g:1519:2: ( RULE_LETTER_X ) { - // InternalSemver.g:1391:2: ( RULE_LETTER_X ) - // InternalSemver.g:1392:3: RULE_LETTER_X + // InternalSemver.g:1519:2: ( RULE_LETTER_X ) + // InternalSemver.g:1520:3: RULE_LETTER_X { if ( state.backtracking==0 ) { before(grammarAccess.getLETTERAccess().getLETTER_XTerminalRuleCall_1()); @@ -5233,10 +5725,10 @@ public final void rule__LETTER__Alternatives() throws RecognitionException { } break; case 3 : - // InternalSemver.g:1397:2: ( ruleLETTER_NO_VX ) + // InternalSemver.g:1525:2: ( ruleLETTER_NO_VX ) { - // InternalSemver.g:1397:2: ( ruleLETTER_NO_VX ) - // InternalSemver.g:1398:3: ruleLETTER_NO_VX + // InternalSemver.g:1525:2: ( ruleLETTER_NO_VX ) + // InternalSemver.g:1526:3: ruleLETTER_NO_VX { if ( state.backtracking==0 ) { before(grammarAccess.getLETTERAccess().getLETTER_NO_VXParserRuleCall_2()); @@ -5273,76 +5765,106 @@ public final void rule__LETTER__Alternatives() throws RecognitionException { // $ANTLR start "rule__LETTER_NO_VX__Alternatives" - // InternalSemver.g:1407:1: rule__LETTER_NO_VX__Alternatives : ( ( RULE_LETTER_S ) | ( RULE_LETTER_M ) | ( RULE_LETTER_R ) | ( RULE_LETTER_F ) | ( RULE_LETTER_I ) | ( RULE_LETTER_L ) | ( RULE_LETTER_E ) | ( RULE_LETTER_OTHER ) ); + // InternalSemver.g:1535:1: rule__LETTER_NO_VX__Alternatives : ( ( RULE_LETTER_A ) | ( RULE_LETTER_C ) | ( RULE_LETTER_E ) | ( RULE_LETTER_F ) | ( RULE_LETTER_I ) | ( RULE_LETTER_K ) | ( RULE_LETTER_L ) | ( RULE_LETTER_M ) | ( RULE_LETTER_O ) | ( RULE_LETTER_P ) | ( RULE_LETTER_R ) | ( RULE_LETTER_S ) | ( RULE_LETTER_W ) | ( RULE_LETTER_OTHER ) ); public final void rule__LETTER_NO_VX__Alternatives() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1411:1: ( ( RULE_LETTER_S ) | ( RULE_LETTER_M ) | ( RULE_LETTER_R ) | ( RULE_LETTER_F ) | ( RULE_LETTER_I ) | ( RULE_LETTER_L ) | ( RULE_LETTER_E ) | ( RULE_LETTER_OTHER ) ) - int alt24=8; + // InternalSemver.g:1539:1: ( ( RULE_LETTER_A ) | ( RULE_LETTER_C ) | ( RULE_LETTER_E ) | ( RULE_LETTER_F ) | ( RULE_LETTER_I ) | ( RULE_LETTER_K ) | ( RULE_LETTER_L ) | ( RULE_LETTER_M ) | ( RULE_LETTER_O ) | ( RULE_LETTER_P ) | ( RULE_LETTER_R ) | ( RULE_LETTER_S ) | ( RULE_LETTER_W ) | ( RULE_LETTER_OTHER ) ) + int alt26=14; switch ( input.LA(1) ) { - case RULE_LETTER_S: + case RULE_LETTER_A: { - alt24=1; + alt26=1; } break; - case RULE_LETTER_M: + case RULE_LETTER_C: { - alt24=2; + alt26=2; } break; - case RULE_LETTER_R: + case RULE_LETTER_E: { - alt24=3; + alt26=3; } break; case RULE_LETTER_F: { - alt24=4; + alt26=4; } break; case RULE_LETTER_I: { - alt24=5; + alt26=5; + } + break; + case RULE_LETTER_K: + { + alt26=6; } break; case RULE_LETTER_L: { - alt24=6; + alt26=7; } break; - case RULE_LETTER_E: + case RULE_LETTER_M: + { + alt26=8; + } + break; + case RULE_LETTER_O: + { + alt26=9; + } + break; + case RULE_LETTER_P: + { + alt26=10; + } + break; + case RULE_LETTER_R: { - alt24=7; + alt26=11; + } + break; + case RULE_LETTER_S: + { + alt26=12; + } + break; + case RULE_LETTER_W: + { + alt26=13; } break; case RULE_LETTER_OTHER: { - alt24=8; + alt26=14; } break; default: if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 24, 0, input); + new NoViableAltException("", 26, 0, input); throw nvae; } - switch (alt24) { + switch (alt26) { case 1 : - // InternalSemver.g:1412:2: ( RULE_LETTER_S ) + // InternalSemver.g:1540:2: ( RULE_LETTER_A ) { - // InternalSemver.g:1412:2: ( RULE_LETTER_S ) - // InternalSemver.g:1413:3: RULE_LETTER_S + // InternalSemver.g:1540:2: ( RULE_LETTER_A ) + // InternalSemver.g:1541:3: RULE_LETTER_A { if ( state.backtracking==0 ) { - before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_STerminalRuleCall_0()); + before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_ATerminalRuleCall_0()); } - match(input,RULE_LETTER_S,FOLLOW_2); if (state.failed) return ; + match(input,RULE_LETTER_A,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_STerminalRuleCall_0()); + after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_ATerminalRuleCall_0()); } } @@ -5351,17 +5873,17 @@ public final void rule__LETTER_NO_VX__Alternatives() throws RecognitionException } break; case 2 : - // InternalSemver.g:1418:2: ( RULE_LETTER_M ) + // InternalSemver.g:1546:2: ( RULE_LETTER_C ) { - // InternalSemver.g:1418:2: ( RULE_LETTER_M ) - // InternalSemver.g:1419:3: RULE_LETTER_M + // InternalSemver.g:1546:2: ( RULE_LETTER_C ) + // InternalSemver.g:1547:3: RULE_LETTER_C { if ( state.backtracking==0 ) { - before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_MTerminalRuleCall_1()); + before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_CTerminalRuleCall_1()); } - match(input,RULE_LETTER_M,FOLLOW_2); if (state.failed) return ; + match(input,RULE_LETTER_C,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_MTerminalRuleCall_1()); + after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_CTerminalRuleCall_1()); } } @@ -5370,17 +5892,17 @@ public final void rule__LETTER_NO_VX__Alternatives() throws RecognitionException } break; case 3 : - // InternalSemver.g:1424:2: ( RULE_LETTER_R ) + // InternalSemver.g:1552:2: ( RULE_LETTER_E ) { - // InternalSemver.g:1424:2: ( RULE_LETTER_R ) - // InternalSemver.g:1425:3: RULE_LETTER_R + // InternalSemver.g:1552:2: ( RULE_LETTER_E ) + // InternalSemver.g:1553:3: RULE_LETTER_E { if ( state.backtracking==0 ) { - before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_RTerminalRuleCall_2()); + before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_ETerminalRuleCall_2()); } - match(input,RULE_LETTER_R,FOLLOW_2); if (state.failed) return ; + match(input,RULE_LETTER_E,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_RTerminalRuleCall_2()); + after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_ETerminalRuleCall_2()); } } @@ -5389,10 +5911,10 @@ public final void rule__LETTER_NO_VX__Alternatives() throws RecognitionException } break; case 4 : - // InternalSemver.g:1430:2: ( RULE_LETTER_F ) + // InternalSemver.g:1558:2: ( RULE_LETTER_F ) { - // InternalSemver.g:1430:2: ( RULE_LETTER_F ) - // InternalSemver.g:1431:3: RULE_LETTER_F + // InternalSemver.g:1558:2: ( RULE_LETTER_F ) + // InternalSemver.g:1559:3: RULE_LETTER_F { if ( state.backtracking==0 ) { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_FTerminalRuleCall_3()); @@ -5408,10 +5930,10 @@ public final void rule__LETTER_NO_VX__Alternatives() throws RecognitionException } break; case 5 : - // InternalSemver.g:1436:2: ( RULE_LETTER_I ) + // InternalSemver.g:1564:2: ( RULE_LETTER_I ) { - // InternalSemver.g:1436:2: ( RULE_LETTER_I ) - // InternalSemver.g:1437:3: RULE_LETTER_I + // InternalSemver.g:1564:2: ( RULE_LETTER_I ) + // InternalSemver.g:1565:3: RULE_LETTER_I { if ( state.backtracking==0 ) { before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_ITerminalRuleCall_4()); @@ -5427,17 +5949,17 @@ public final void rule__LETTER_NO_VX__Alternatives() throws RecognitionException } break; case 6 : - // InternalSemver.g:1442:2: ( RULE_LETTER_L ) + // InternalSemver.g:1570:2: ( RULE_LETTER_K ) { - // InternalSemver.g:1442:2: ( RULE_LETTER_L ) - // InternalSemver.g:1443:3: RULE_LETTER_L + // InternalSemver.g:1570:2: ( RULE_LETTER_K ) + // InternalSemver.g:1571:3: RULE_LETTER_K { if ( state.backtracking==0 ) { - before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_LTerminalRuleCall_5()); + before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_KTerminalRuleCall_5()); } - match(input,RULE_LETTER_L,FOLLOW_2); if (state.failed) return ; + match(input,RULE_LETTER_K,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_LTerminalRuleCall_5()); + after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_KTerminalRuleCall_5()); } } @@ -5446,17 +5968,17 @@ public final void rule__LETTER_NO_VX__Alternatives() throws RecognitionException } break; case 7 : - // InternalSemver.g:1448:2: ( RULE_LETTER_E ) + // InternalSemver.g:1576:2: ( RULE_LETTER_L ) { - // InternalSemver.g:1448:2: ( RULE_LETTER_E ) - // InternalSemver.g:1449:3: RULE_LETTER_E + // InternalSemver.g:1576:2: ( RULE_LETTER_L ) + // InternalSemver.g:1577:3: RULE_LETTER_L { if ( state.backtracking==0 ) { - before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_ETerminalRuleCall_6()); + before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_LTerminalRuleCall_6()); } - match(input,RULE_LETTER_E,FOLLOW_2); if (state.failed) return ; + match(input,RULE_LETTER_L,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_ETerminalRuleCall_6()); + after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_LTerminalRuleCall_6()); } } @@ -5465,17 +5987,131 @@ public final void rule__LETTER_NO_VX__Alternatives() throws RecognitionException } break; case 8 : - // InternalSemver.g:1454:2: ( RULE_LETTER_OTHER ) + // InternalSemver.g:1582:2: ( RULE_LETTER_M ) + { + // InternalSemver.g:1582:2: ( RULE_LETTER_M ) + // InternalSemver.g:1583:3: RULE_LETTER_M + { + if ( state.backtracking==0 ) { + before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_MTerminalRuleCall_7()); + } + match(input,RULE_LETTER_M,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_MTerminalRuleCall_7()); + } + + } + + + } + break; + case 9 : + // InternalSemver.g:1588:2: ( RULE_LETTER_O ) + { + // InternalSemver.g:1588:2: ( RULE_LETTER_O ) + // InternalSemver.g:1589:3: RULE_LETTER_O + { + if ( state.backtracking==0 ) { + before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTerminalRuleCall_8()); + } + match(input,RULE_LETTER_O,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTerminalRuleCall_8()); + } + + } + + + } + break; + case 10 : + // InternalSemver.g:1594:2: ( RULE_LETTER_P ) + { + // InternalSemver.g:1594:2: ( RULE_LETTER_P ) + // InternalSemver.g:1595:3: RULE_LETTER_P + { + if ( state.backtracking==0 ) { + before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_PTerminalRuleCall_9()); + } + match(input,RULE_LETTER_P,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_PTerminalRuleCall_9()); + } + + } + + + } + break; + case 11 : + // InternalSemver.g:1600:2: ( RULE_LETTER_R ) + { + // InternalSemver.g:1600:2: ( RULE_LETTER_R ) + // InternalSemver.g:1601:3: RULE_LETTER_R + { + if ( state.backtracking==0 ) { + before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_RTerminalRuleCall_10()); + } + match(input,RULE_LETTER_R,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_RTerminalRuleCall_10()); + } + + } + + + } + break; + case 12 : + // InternalSemver.g:1606:2: ( RULE_LETTER_S ) + { + // InternalSemver.g:1606:2: ( RULE_LETTER_S ) + // InternalSemver.g:1607:3: RULE_LETTER_S + { + if ( state.backtracking==0 ) { + before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_STerminalRuleCall_11()); + } + match(input,RULE_LETTER_S,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_STerminalRuleCall_11()); + } + + } + + + } + break; + case 13 : + // InternalSemver.g:1612:2: ( RULE_LETTER_W ) { - // InternalSemver.g:1454:2: ( RULE_LETTER_OTHER ) - // InternalSemver.g:1455:3: RULE_LETTER_OTHER + // InternalSemver.g:1612:2: ( RULE_LETTER_W ) + // InternalSemver.g:1613:3: RULE_LETTER_W { if ( state.backtracking==0 ) { - before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTHERTerminalRuleCall_7()); + before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_WTerminalRuleCall_12()); + } + match(input,RULE_LETTER_W,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_WTerminalRuleCall_12()); + } + + } + + + } + break; + case 14 : + // InternalSemver.g:1618:2: ( RULE_LETTER_OTHER ) + { + // InternalSemver.g:1618:2: ( RULE_LETTER_OTHER ) + // InternalSemver.g:1619:3: RULE_LETTER_OTHER + { + if ( state.backtracking==0 ) { + before(grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTHERTerminalRuleCall_13()); } match(input,RULE_LETTER_OTHER,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTHERTerminalRuleCall_7()); + after(grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTHERTerminalRuleCall_13()); } } @@ -5501,72 +6137,72 @@ public final void rule__LETTER_NO_VX__Alternatives() throws RecognitionException // $ANTLR start "rule__VersionComparator__Alternatives" - // InternalSemver.g:1464:1: rule__VersionComparator__Alternatives : ( ( ( '=' ) ) | ( ( '<' ) ) | ( ( '~' ) ) | ( ( '^' ) ) | ( ( '<=' ) ) | ( ( '>' ) ) | ( ( '>=' ) ) ); + // InternalSemver.g:1628:1: rule__VersionComparator__Alternatives : ( ( ( '=' ) ) | ( ( '~' ) ) | ( ( '^' ) ) | ( ( '<' ) ) | ( ( '>' ) ) | ( ( '<=' ) ) | ( ( '>=' ) ) ); public final void rule__VersionComparator__Alternatives() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1468:1: ( ( ( '=' ) ) | ( ( '<' ) ) | ( ( '~' ) ) | ( ( '^' ) ) | ( ( '<=' ) ) | ( ( '>' ) ) | ( ( '>=' ) ) ) - int alt25=7; + // InternalSemver.g:1632:1: ( ( ( '=' ) ) | ( ( '~' ) ) | ( ( '^' ) ) | ( ( '<' ) ) | ( ( '>' ) ) | ( ( '<=' ) ) | ( ( '>=' ) ) ) + int alt27=7; switch ( input.LA(1) ) { - case 42: + case 48: { - alt25=1; + alt27=1; } break; - case 43: + case 49: { - alt25=2; + alt27=2; } break; - case 44: + case 50: { - alt25=3; + alt27=3; } break; - case 45: + case 51: { - alt25=4; + alt27=4; } break; - case 46: + case 52: { - alt25=5; + alt27=5; } break; - case 47: + case 53: { - alt25=6; + alt27=6; } break; - case 48: + case 54: { - alt25=7; + alt27=7; } break; default: if (state.backtracking>0) {state.failed=true; return ;} NoViableAltException nvae = - new NoViableAltException("", 25, 0, input); + new NoViableAltException("", 27, 0, input); throw nvae; } - switch (alt25) { + switch (alt27) { case 1 : - // InternalSemver.g:1469:2: ( ( '=' ) ) + // InternalSemver.g:1633:2: ( ( '=' ) ) { - // InternalSemver.g:1469:2: ( ( '=' ) ) - // InternalSemver.g:1470:3: ( '=' ) + // InternalSemver.g:1633:2: ( ( '=' ) ) + // InternalSemver.g:1634:3: ( '=' ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionComparatorAccess().getEqualsEnumLiteralDeclaration_0()); } - // InternalSemver.g:1471:3: ( '=' ) - // InternalSemver.g:1471:4: '=' + // InternalSemver.g:1635:3: ( '=' ) + // InternalSemver.g:1635:4: '=' { - match(input,42,FOLLOW_2); if (state.failed) return ; + match(input,48,FOLLOW_2); if (state.failed) return ; } @@ -5580,23 +6216,23 @@ public final void rule__VersionComparator__Alternatives() throws RecognitionExce } break; case 2 : - // InternalSemver.g:1475:2: ( ( '<' ) ) + // InternalSemver.g:1639:2: ( ( '~' ) ) { - // InternalSemver.g:1475:2: ( ( '<' ) ) - // InternalSemver.g:1476:3: ( '<' ) + // InternalSemver.g:1639:2: ( ( '~' ) ) + // InternalSemver.g:1640:3: ( '~' ) { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_1()); + before(grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_1()); } - // InternalSemver.g:1477:3: ( '<' ) - // InternalSemver.g:1477:4: '<' + // InternalSemver.g:1641:3: ( '~' ) + // InternalSemver.g:1641:4: '~' { - match(input,43,FOLLOW_2); if (state.failed) return ; + match(input,49,FOLLOW_2); if (state.failed) return ; } if ( state.backtracking==0 ) { - after(grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_1()); + after(grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_1()); } } @@ -5605,23 +6241,23 @@ public final void rule__VersionComparator__Alternatives() throws RecognitionExce } break; case 3 : - // InternalSemver.g:1481:2: ( ( '~' ) ) + // InternalSemver.g:1645:2: ( ( '^' ) ) { - // InternalSemver.g:1481:2: ( ( '~' ) ) - // InternalSemver.g:1482:3: ( '~' ) + // InternalSemver.g:1645:2: ( ( '^' ) ) + // InternalSemver.g:1646:3: ( '^' ) { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_2()); + before(grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_2()); } - // InternalSemver.g:1483:3: ( '~' ) - // InternalSemver.g:1483:4: '~' + // InternalSemver.g:1647:3: ( '^' ) + // InternalSemver.g:1647:4: '^' { - match(input,44,FOLLOW_2); if (state.failed) return ; + match(input,50,FOLLOW_2); if (state.failed) return ; } if ( state.backtracking==0 ) { - after(grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_2()); + after(grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_2()); } } @@ -5630,23 +6266,23 @@ public final void rule__VersionComparator__Alternatives() throws RecognitionExce } break; case 4 : - // InternalSemver.g:1487:2: ( ( '^' ) ) + // InternalSemver.g:1651:2: ( ( '<' ) ) { - // InternalSemver.g:1487:2: ( ( '^' ) ) - // InternalSemver.g:1488:3: ( '^' ) + // InternalSemver.g:1651:2: ( ( '<' ) ) + // InternalSemver.g:1652:3: ( '<' ) { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_3()); + before(grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_3()); } - // InternalSemver.g:1489:3: ( '^' ) - // InternalSemver.g:1489:4: '^' + // InternalSemver.g:1653:3: ( '<' ) + // InternalSemver.g:1653:4: '<' { - match(input,45,FOLLOW_2); if (state.failed) return ; + match(input,51,FOLLOW_2); if (state.failed) return ; } if ( state.backtracking==0 ) { - after(grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_3()); + after(grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_3()); } } @@ -5655,23 +6291,23 @@ public final void rule__VersionComparator__Alternatives() throws RecognitionExce } break; case 5 : - // InternalSemver.g:1493:2: ( ( '<=' ) ) + // InternalSemver.g:1657:2: ( ( '>' ) ) { - // InternalSemver.g:1493:2: ( ( '<=' ) ) - // InternalSemver.g:1494:3: ( '<=' ) + // InternalSemver.g:1657:2: ( ( '>' ) ) + // InternalSemver.g:1658:3: ( '>' ) { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_4()); + before(grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_4()); } - // InternalSemver.g:1495:3: ( '<=' ) - // InternalSemver.g:1495:4: '<=' + // InternalSemver.g:1659:3: ( '>' ) + // InternalSemver.g:1659:4: '>' { - match(input,46,FOLLOW_2); if (state.failed) return ; + match(input,52,FOLLOW_2); if (state.failed) return ; } if ( state.backtracking==0 ) { - after(grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_4()); + after(grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_4()); } } @@ -5680,23 +6316,23 @@ public final void rule__VersionComparator__Alternatives() throws RecognitionExce } break; case 6 : - // InternalSemver.g:1499:2: ( ( '>' ) ) + // InternalSemver.g:1663:2: ( ( '<=' ) ) { - // InternalSemver.g:1499:2: ( ( '>' ) ) - // InternalSemver.g:1500:3: ( '>' ) + // InternalSemver.g:1663:2: ( ( '<=' ) ) + // InternalSemver.g:1664:3: ( '<=' ) { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_5()); + before(grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_5()); } - // InternalSemver.g:1501:3: ( '>' ) - // InternalSemver.g:1501:4: '>' + // InternalSemver.g:1665:3: ( '<=' ) + // InternalSemver.g:1665:4: '<=' { - match(input,47,FOLLOW_2); if (state.failed) return ; + match(input,53,FOLLOW_2); if (state.failed) return ; } if ( state.backtracking==0 ) { - after(grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_5()); + after(grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_5()); } } @@ -5705,18 +6341,18 @@ public final void rule__VersionComparator__Alternatives() throws RecognitionExce } break; case 7 : - // InternalSemver.g:1505:2: ( ( '>=' ) ) + // InternalSemver.g:1669:2: ( ( '>=' ) ) { - // InternalSemver.g:1505:2: ( ( '>=' ) ) - // InternalSemver.g:1506:3: ( '>=' ) + // InternalSemver.g:1669:2: ( ( '>=' ) ) + // InternalSemver.g:1670:3: ( '>=' ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionComparatorAccess().getGreaterEqualsEnumLiteralDeclaration_6()); } - // InternalSemver.g:1507:3: ( '>=' ) - // InternalSemver.g:1507:4: '>=' + // InternalSemver.g:1671:3: ( '>=' ) + // InternalSemver.g:1671:4: '>=' { - match(input,48,FOLLOW_2); if (state.failed) return ; + match(input,54,FOLLOW_2); if (state.failed) return ; } @@ -5747,16 +6383,16 @@ public final void rule__VersionComparator__Alternatives() throws RecognitionExce // $ANTLR start "rule__NPMVersionRequirement__Group_0__0" - // InternalSemver.g:1515:1: rule__NPMVersionRequirement__Group_0__0 : rule__NPMVersionRequirement__Group_0__0__Impl rule__NPMVersionRequirement__Group_0__1 ; + // InternalSemver.g:1679:1: rule__NPMVersionRequirement__Group_0__0 : rule__NPMVersionRequirement__Group_0__0__Impl rule__NPMVersionRequirement__Group_0__1 ; public final void rule__NPMVersionRequirement__Group_0__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1519:1: ( rule__NPMVersionRequirement__Group_0__0__Impl rule__NPMVersionRequirement__Group_0__1 ) - // InternalSemver.g:1520:2: rule__NPMVersionRequirement__Group_0__0__Impl rule__NPMVersionRequirement__Group_0__1 + // InternalSemver.g:1683:1: ( rule__NPMVersionRequirement__Group_0__0__Impl rule__NPMVersionRequirement__Group_0__1 ) + // InternalSemver.g:1684:2: rule__NPMVersionRequirement__Group_0__0__Impl rule__NPMVersionRequirement__Group_0__1 { - pushFollow(FOLLOW_4); + pushFollow(FOLLOW_5); rule__NPMVersionRequirement__Group_0__0__Impl(); state._fsp--; @@ -5785,31 +6421,31 @@ public final void rule__NPMVersionRequirement__Group_0__0() throws RecognitionEx // $ANTLR start "rule__NPMVersionRequirement__Group_0__0__Impl" - // InternalSemver.g:1527:1: rule__NPMVersionRequirement__Group_0__0__Impl : ( ( RULE_WS )? ) ; + // InternalSemver.g:1691:1: rule__NPMVersionRequirement__Group_0__0__Impl : ( ( RULE_WS )? ) ; public final void rule__NPMVersionRequirement__Group_0__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1531:1: ( ( ( RULE_WS )? ) ) - // InternalSemver.g:1532:1: ( ( RULE_WS )? ) + // InternalSemver.g:1695:1: ( ( ( RULE_WS )? ) ) + // InternalSemver.g:1696:1: ( ( RULE_WS )? ) { - // InternalSemver.g:1532:1: ( ( RULE_WS )? ) - // InternalSemver.g:1533:2: ( RULE_WS )? + // InternalSemver.g:1696:1: ( ( RULE_WS )? ) + // InternalSemver.g:1697:2: ( RULE_WS )? { if ( state.backtracking==0 ) { before(grammarAccess.getNPMVersionRequirementAccess().getWSTerminalRuleCall_0_0()); } - // InternalSemver.g:1534:2: ( RULE_WS )? - int alt26=2; - int LA26_0 = input.LA(1); + // InternalSemver.g:1698:2: ( RULE_WS )? + int alt28=2; + int LA28_0 = input.LA(1); - if ( (LA26_0==RULE_WS) ) { - alt26=1; + if ( (LA28_0==RULE_WS) ) { + alt28=1; } - switch (alt26) { + switch (alt28) { case 1 : - // InternalSemver.g:1534:3: RULE_WS + // InternalSemver.g:1698:3: RULE_WS { match(input,RULE_WS,FOLLOW_2); if (state.failed) return ; @@ -5843,14 +6479,14 @@ public final void rule__NPMVersionRequirement__Group_0__0__Impl() throws Recogni // $ANTLR start "rule__NPMVersionRequirement__Group_0__1" - // InternalSemver.g:1542:1: rule__NPMVersionRequirement__Group_0__1 : rule__NPMVersionRequirement__Group_0__1__Impl ; + // InternalSemver.g:1706:1: rule__NPMVersionRequirement__Group_0__1 : rule__NPMVersionRequirement__Group_0__1__Impl ; public final void rule__NPMVersionRequirement__Group_0__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1546:1: ( rule__NPMVersionRequirement__Group_0__1__Impl ) - // InternalSemver.g:1547:2: rule__NPMVersionRequirement__Group_0__1__Impl + // InternalSemver.g:1710:1: ( rule__NPMVersionRequirement__Group_0__1__Impl ) + // InternalSemver.g:1711:2: rule__NPMVersionRequirement__Group_0__1__Impl { pushFollow(FOLLOW_2); rule__NPMVersionRequirement__Group_0__1__Impl(); @@ -5876,17 +6512,17 @@ public final void rule__NPMVersionRequirement__Group_0__1() throws RecognitionEx // $ANTLR start "rule__NPMVersionRequirement__Group_0__1__Impl" - // InternalSemver.g:1553:1: rule__NPMVersionRequirement__Group_0__1__Impl : ( ruleVersionRangeSetRequirement ) ; + // InternalSemver.g:1717:1: rule__NPMVersionRequirement__Group_0__1__Impl : ( ruleVersionRangeSetRequirement ) ; public final void rule__NPMVersionRequirement__Group_0__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1557:1: ( ( ruleVersionRangeSetRequirement ) ) - // InternalSemver.g:1558:1: ( ruleVersionRangeSetRequirement ) + // InternalSemver.g:1721:1: ( ( ruleVersionRangeSetRequirement ) ) + // InternalSemver.g:1722:1: ( ruleVersionRangeSetRequirement ) { - // InternalSemver.g:1558:1: ( ruleVersionRangeSetRequirement ) - // InternalSemver.g:1559:2: ruleVersionRangeSetRequirement + // InternalSemver.g:1722:1: ( ruleVersionRangeSetRequirement ) + // InternalSemver.g:1723:2: ruleVersionRangeSetRequirement { if ( state.backtracking==0 ) { before(grammarAccess.getNPMVersionRequirementAccess().getVersionRangeSetRequirementParserRuleCall_0_1()); @@ -5921,16 +6557,16 @@ public final void rule__NPMVersionRequirement__Group_0__1__Impl() throws Recogni // $ANTLR start "rule__NPMVersionRequirement__Group_1__0" - // InternalSemver.g:1569:1: rule__NPMVersionRequirement__Group_1__0 : rule__NPMVersionRequirement__Group_1__0__Impl rule__NPMVersionRequirement__Group_1__1 ; + // InternalSemver.g:1733:1: rule__NPMVersionRequirement__Group_1__0 : rule__NPMVersionRequirement__Group_1__0__Impl rule__NPMVersionRequirement__Group_1__1 ; public final void rule__NPMVersionRequirement__Group_1__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1573:1: ( rule__NPMVersionRequirement__Group_1__0__Impl rule__NPMVersionRequirement__Group_1__1 ) - // InternalSemver.g:1574:2: rule__NPMVersionRequirement__Group_1__0__Impl rule__NPMVersionRequirement__Group_1__1 + // InternalSemver.g:1737:1: ( rule__NPMVersionRequirement__Group_1__0__Impl rule__NPMVersionRequirement__Group_1__1 ) + // InternalSemver.g:1738:2: rule__NPMVersionRequirement__Group_1__0__Impl rule__NPMVersionRequirement__Group_1__1 { - pushFollow(FOLLOW_5); + pushFollow(FOLLOW_6); rule__NPMVersionRequirement__Group_1__0__Impl(); state._fsp--; @@ -5959,23 +6595,23 @@ public final void rule__NPMVersionRequirement__Group_1__0() throws RecognitionEx // $ANTLR start "rule__NPMVersionRequirement__Group_1__0__Impl" - // InternalSemver.g:1581:1: rule__NPMVersionRequirement__Group_1__0__Impl : ( ( rule__NPMVersionRequirement__Alternatives_1_0 ) ) ; + // InternalSemver.g:1745:1: rule__NPMVersionRequirement__Group_1__0__Impl : ( ( rule__NPMVersionRequirement__Alternatives_1_0 ) ) ; public final void rule__NPMVersionRequirement__Group_1__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1585:1: ( ( ( rule__NPMVersionRequirement__Alternatives_1_0 ) ) ) - // InternalSemver.g:1586:1: ( ( rule__NPMVersionRequirement__Alternatives_1_0 ) ) + // InternalSemver.g:1749:1: ( ( ( rule__NPMVersionRequirement__Alternatives_1_0 ) ) ) + // InternalSemver.g:1750:1: ( ( rule__NPMVersionRequirement__Alternatives_1_0 ) ) { - // InternalSemver.g:1586:1: ( ( rule__NPMVersionRequirement__Alternatives_1_0 ) ) - // InternalSemver.g:1587:2: ( rule__NPMVersionRequirement__Alternatives_1_0 ) + // InternalSemver.g:1750:1: ( ( rule__NPMVersionRequirement__Alternatives_1_0 ) ) + // InternalSemver.g:1751:2: ( rule__NPMVersionRequirement__Alternatives_1_0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getNPMVersionRequirementAccess().getAlternatives_1_0()); } - // InternalSemver.g:1588:2: ( rule__NPMVersionRequirement__Alternatives_1_0 ) - // InternalSemver.g:1588:3: rule__NPMVersionRequirement__Alternatives_1_0 + // InternalSemver.g:1752:2: ( rule__NPMVersionRequirement__Alternatives_1_0 ) + // InternalSemver.g:1752:3: rule__NPMVersionRequirement__Alternatives_1_0 { pushFollow(FOLLOW_2); rule__NPMVersionRequirement__Alternatives_1_0(); @@ -6010,14 +6646,14 @@ public final void rule__NPMVersionRequirement__Group_1__0__Impl() throws Recogni // $ANTLR start "rule__NPMVersionRequirement__Group_1__1" - // InternalSemver.g:1596:1: rule__NPMVersionRequirement__Group_1__1 : rule__NPMVersionRequirement__Group_1__1__Impl ; + // InternalSemver.g:1760:1: rule__NPMVersionRequirement__Group_1__1 : rule__NPMVersionRequirement__Group_1__1__Impl ; public final void rule__NPMVersionRequirement__Group_1__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1600:1: ( rule__NPMVersionRequirement__Group_1__1__Impl ) - // InternalSemver.g:1601:2: rule__NPMVersionRequirement__Group_1__1__Impl + // InternalSemver.g:1764:1: ( rule__NPMVersionRequirement__Group_1__1__Impl ) + // InternalSemver.g:1765:2: rule__NPMVersionRequirement__Group_1__1__Impl { pushFollow(FOLLOW_2); rule__NPMVersionRequirement__Group_1__1__Impl(); @@ -6043,31 +6679,31 @@ public final void rule__NPMVersionRequirement__Group_1__1() throws RecognitionEx // $ANTLR start "rule__NPMVersionRequirement__Group_1__1__Impl" - // InternalSemver.g:1607:1: rule__NPMVersionRequirement__Group_1__1__Impl : ( ( RULE_WS )? ) ; + // InternalSemver.g:1771:1: rule__NPMVersionRequirement__Group_1__1__Impl : ( ( RULE_WS )? ) ; public final void rule__NPMVersionRequirement__Group_1__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1611:1: ( ( ( RULE_WS )? ) ) - // InternalSemver.g:1612:1: ( ( RULE_WS )? ) + // InternalSemver.g:1775:1: ( ( ( RULE_WS )? ) ) + // InternalSemver.g:1776:1: ( ( RULE_WS )? ) { - // InternalSemver.g:1612:1: ( ( RULE_WS )? ) - // InternalSemver.g:1613:2: ( RULE_WS )? + // InternalSemver.g:1776:1: ( ( RULE_WS )? ) + // InternalSemver.g:1777:2: ( RULE_WS )? { if ( state.backtracking==0 ) { before(grammarAccess.getNPMVersionRequirementAccess().getWSTerminalRuleCall_1_1()); } - // InternalSemver.g:1614:2: ( RULE_WS )? - int alt27=2; - int LA27_0 = input.LA(1); + // InternalSemver.g:1778:2: ( RULE_WS )? + int alt29=2; + int LA29_0 = input.LA(1); - if ( (LA27_0==RULE_WS) ) { - alt27=1; + if ( (LA29_0==RULE_WS) ) { + alt29=1; } - switch (alt27) { + switch (alt29) { case 1 : - // InternalSemver.g:1614:3: RULE_WS + // InternalSemver.g:1778:3: RULE_WS { match(input,RULE_WS,FOLLOW_2); if (state.failed) return ; @@ -6101,16 +6737,16 @@ public final void rule__NPMVersionRequirement__Group_1__1__Impl() throws Recogni // $ANTLR start "rule__LocalPathVersionRequirement__Group__0" - // InternalSemver.g:1623:1: rule__LocalPathVersionRequirement__Group__0 : rule__LocalPathVersionRequirement__Group__0__Impl rule__LocalPathVersionRequirement__Group__1 ; + // InternalSemver.g:1787:1: rule__LocalPathVersionRequirement__Group__0 : rule__LocalPathVersionRequirement__Group__0__Impl rule__LocalPathVersionRequirement__Group__1 ; public final void rule__LocalPathVersionRequirement__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1627:1: ( rule__LocalPathVersionRequirement__Group__0__Impl rule__LocalPathVersionRequirement__Group__1 ) - // InternalSemver.g:1628:2: rule__LocalPathVersionRequirement__Group__0__Impl rule__LocalPathVersionRequirement__Group__1 + // InternalSemver.g:1791:1: ( rule__LocalPathVersionRequirement__Group__0__Impl rule__LocalPathVersionRequirement__Group__1 ) + // InternalSemver.g:1792:2: rule__LocalPathVersionRequirement__Group__0__Impl rule__LocalPathVersionRequirement__Group__1 { - pushFollow(FOLLOW_6); + pushFollow(FOLLOW_7); rule__LocalPathVersionRequirement__Group__0__Impl(); state._fsp--; @@ -6139,17 +6775,17 @@ public final void rule__LocalPathVersionRequirement__Group__0() throws Recogniti // $ANTLR start "rule__LocalPathVersionRequirement__Group__0__Impl" - // InternalSemver.g:1635:1: rule__LocalPathVersionRequirement__Group__0__Impl : ( ruleFILE_TAG ) ; + // InternalSemver.g:1799:1: rule__LocalPathVersionRequirement__Group__0__Impl : ( ruleFILE_TAG ) ; public final void rule__LocalPathVersionRequirement__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1639:1: ( ( ruleFILE_TAG ) ) - // InternalSemver.g:1640:1: ( ruleFILE_TAG ) + // InternalSemver.g:1803:1: ( ( ruleFILE_TAG ) ) + // InternalSemver.g:1804:1: ( ruleFILE_TAG ) { - // InternalSemver.g:1640:1: ( ruleFILE_TAG ) - // InternalSemver.g:1641:2: ruleFILE_TAG + // InternalSemver.g:1804:1: ( ruleFILE_TAG ) + // InternalSemver.g:1805:2: ruleFILE_TAG { if ( state.backtracking==0 ) { before(grammarAccess.getLocalPathVersionRequirementAccess().getFILE_TAGParserRuleCall_0()); @@ -6184,14 +6820,14 @@ public final void rule__LocalPathVersionRequirement__Group__0__Impl() throws Rec // $ANTLR start "rule__LocalPathVersionRequirement__Group__1" - // InternalSemver.g:1650:1: rule__LocalPathVersionRequirement__Group__1 : rule__LocalPathVersionRequirement__Group__1__Impl ; + // InternalSemver.g:1814:1: rule__LocalPathVersionRequirement__Group__1 : rule__LocalPathVersionRequirement__Group__1__Impl ; public final void rule__LocalPathVersionRequirement__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1654:1: ( rule__LocalPathVersionRequirement__Group__1__Impl ) - // InternalSemver.g:1655:2: rule__LocalPathVersionRequirement__Group__1__Impl + // InternalSemver.g:1818:1: ( rule__LocalPathVersionRequirement__Group__1__Impl ) + // InternalSemver.g:1819:2: rule__LocalPathVersionRequirement__Group__1__Impl { pushFollow(FOLLOW_2); rule__LocalPathVersionRequirement__Group__1__Impl(); @@ -6217,23 +6853,23 @@ public final void rule__LocalPathVersionRequirement__Group__1() throws Recogniti // $ANTLR start "rule__LocalPathVersionRequirement__Group__1__Impl" - // InternalSemver.g:1661:1: rule__LocalPathVersionRequirement__Group__1__Impl : ( ( rule__LocalPathVersionRequirement__LocalPathAssignment_1 ) ) ; + // InternalSemver.g:1825:1: rule__LocalPathVersionRequirement__Group__1__Impl : ( ( rule__LocalPathVersionRequirement__LocalPathAssignment_1 ) ) ; public final void rule__LocalPathVersionRequirement__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1665:1: ( ( ( rule__LocalPathVersionRequirement__LocalPathAssignment_1 ) ) ) - // InternalSemver.g:1666:1: ( ( rule__LocalPathVersionRequirement__LocalPathAssignment_1 ) ) + // InternalSemver.g:1829:1: ( ( ( rule__LocalPathVersionRequirement__LocalPathAssignment_1 ) ) ) + // InternalSemver.g:1830:1: ( ( rule__LocalPathVersionRequirement__LocalPathAssignment_1 ) ) { - // InternalSemver.g:1666:1: ( ( rule__LocalPathVersionRequirement__LocalPathAssignment_1 ) ) - // InternalSemver.g:1667:2: ( rule__LocalPathVersionRequirement__LocalPathAssignment_1 ) + // InternalSemver.g:1830:1: ( ( rule__LocalPathVersionRequirement__LocalPathAssignment_1 ) ) + // InternalSemver.g:1831:2: ( rule__LocalPathVersionRequirement__LocalPathAssignment_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getLocalPathVersionRequirementAccess().getLocalPathAssignment_1()); } - // InternalSemver.g:1668:2: ( rule__LocalPathVersionRequirement__LocalPathAssignment_1 ) - // InternalSemver.g:1668:3: rule__LocalPathVersionRequirement__LocalPathAssignment_1 + // InternalSemver.g:1832:2: ( rule__LocalPathVersionRequirement__LocalPathAssignment_1 ) + // InternalSemver.g:1832:3: rule__LocalPathVersionRequirement__LocalPathAssignment_1 { pushFollow(FOLLOW_2); rule__LocalPathVersionRequirement__LocalPathAssignment_1(); @@ -6268,16 +6904,16 @@ public final void rule__LocalPathVersionRequirement__Group__1__Impl() throws Rec // $ANTLR start "rule__URLVersionRequirement__Group__0" - // InternalSemver.g:1677:1: rule__URLVersionRequirement__Group__0 : rule__URLVersionRequirement__Group__0__Impl rule__URLVersionRequirement__Group__1 ; + // InternalSemver.g:1841:1: rule__URLVersionRequirement__Group__0 : rule__URLVersionRequirement__Group__0__Impl rule__URLVersionRequirement__Group__1 ; public final void rule__URLVersionRequirement__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1681:1: ( rule__URLVersionRequirement__Group__0__Impl rule__URLVersionRequirement__Group__1 ) - // InternalSemver.g:1682:2: rule__URLVersionRequirement__Group__0__Impl rule__URLVersionRequirement__Group__1 + // InternalSemver.g:1845:1: ( rule__URLVersionRequirement__Group__0__Impl rule__URLVersionRequirement__Group__1 ) + // InternalSemver.g:1846:2: rule__URLVersionRequirement__Group__0__Impl rule__URLVersionRequirement__Group__1 { - pushFollow(FOLLOW_7); + pushFollow(FOLLOW_8); rule__URLVersionRequirement__Group__0__Impl(); state._fsp--; @@ -6306,23 +6942,23 @@ public final void rule__URLVersionRequirement__Group__0() throws RecognitionExce // $ANTLR start "rule__URLVersionRequirement__Group__0__Impl" - // InternalSemver.g:1689:1: rule__URLVersionRequirement__Group__0__Impl : ( ( rule__URLVersionRequirement__ProtocolAssignment_0 ) ) ; + // InternalSemver.g:1853:1: rule__URLVersionRequirement__Group__0__Impl : ( ( rule__URLVersionRequirement__ProtocolAssignment_0 ) ) ; public final void rule__URLVersionRequirement__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1693:1: ( ( ( rule__URLVersionRequirement__ProtocolAssignment_0 ) ) ) - // InternalSemver.g:1694:1: ( ( rule__URLVersionRequirement__ProtocolAssignment_0 ) ) + // InternalSemver.g:1857:1: ( ( ( rule__URLVersionRequirement__ProtocolAssignment_0 ) ) ) + // InternalSemver.g:1858:1: ( ( rule__URLVersionRequirement__ProtocolAssignment_0 ) ) { - // InternalSemver.g:1694:1: ( ( rule__URLVersionRequirement__ProtocolAssignment_0 ) ) - // InternalSemver.g:1695:2: ( rule__URLVersionRequirement__ProtocolAssignment_0 ) + // InternalSemver.g:1858:1: ( ( rule__URLVersionRequirement__ProtocolAssignment_0 ) ) + // InternalSemver.g:1859:2: ( rule__URLVersionRequirement__ProtocolAssignment_0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionRequirementAccess().getProtocolAssignment_0()); } - // InternalSemver.g:1696:2: ( rule__URLVersionRequirement__ProtocolAssignment_0 ) - // InternalSemver.g:1696:3: rule__URLVersionRequirement__ProtocolAssignment_0 + // InternalSemver.g:1860:2: ( rule__URLVersionRequirement__ProtocolAssignment_0 ) + // InternalSemver.g:1860:3: rule__URLVersionRequirement__ProtocolAssignment_0 { pushFollow(FOLLOW_2); rule__URLVersionRequirement__ProtocolAssignment_0(); @@ -6357,16 +6993,16 @@ public final void rule__URLVersionRequirement__Group__0__Impl() throws Recogniti // $ANTLR start "rule__URLVersionRequirement__Group__1" - // InternalSemver.g:1704:1: rule__URLVersionRequirement__Group__1 : rule__URLVersionRequirement__Group__1__Impl rule__URLVersionRequirement__Group__2 ; + // InternalSemver.g:1868:1: rule__URLVersionRequirement__Group__1 : rule__URLVersionRequirement__Group__1__Impl rule__URLVersionRequirement__Group__2 ; public final void rule__URLVersionRequirement__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1708:1: ( rule__URLVersionRequirement__Group__1__Impl rule__URLVersionRequirement__Group__2 ) - // InternalSemver.g:1709:2: rule__URLVersionRequirement__Group__1__Impl rule__URLVersionRequirement__Group__2 + // InternalSemver.g:1872:1: ( rule__URLVersionRequirement__Group__1__Impl rule__URLVersionRequirement__Group__2 ) + // InternalSemver.g:1873:2: rule__URLVersionRequirement__Group__1__Impl rule__URLVersionRequirement__Group__2 { - pushFollow(FOLLOW_8); + pushFollow(FOLLOW_9); rule__URLVersionRequirement__Group__1__Impl(); state._fsp--; @@ -6395,23 +7031,23 @@ public final void rule__URLVersionRequirement__Group__1() throws RecognitionExce // $ANTLR start "rule__URLVersionRequirement__Group__1__Impl" - // InternalSemver.g:1716:1: rule__URLVersionRequirement__Group__1__Impl : ( ( rule__URLVersionRequirement__Group_1__0 ) ) ; + // InternalSemver.g:1880:1: rule__URLVersionRequirement__Group__1__Impl : ( ( rule__URLVersionRequirement__Group_1__0 ) ) ; public final void rule__URLVersionRequirement__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1720:1: ( ( ( rule__URLVersionRequirement__Group_1__0 ) ) ) - // InternalSemver.g:1721:1: ( ( rule__URLVersionRequirement__Group_1__0 ) ) + // InternalSemver.g:1884:1: ( ( ( rule__URLVersionRequirement__Group_1__0 ) ) ) + // InternalSemver.g:1885:1: ( ( rule__URLVersionRequirement__Group_1__0 ) ) { - // InternalSemver.g:1721:1: ( ( rule__URLVersionRequirement__Group_1__0 ) ) - // InternalSemver.g:1722:2: ( rule__URLVersionRequirement__Group_1__0 ) + // InternalSemver.g:1885:1: ( ( rule__URLVersionRequirement__Group_1__0 ) ) + // InternalSemver.g:1886:2: ( rule__URLVersionRequirement__Group_1__0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionRequirementAccess().getGroup_1()); } - // InternalSemver.g:1723:2: ( rule__URLVersionRequirement__Group_1__0 ) - // InternalSemver.g:1723:3: rule__URLVersionRequirement__Group_1__0 + // InternalSemver.g:1887:2: ( rule__URLVersionRequirement__Group_1__0 ) + // InternalSemver.g:1887:3: rule__URLVersionRequirement__Group_1__0 { pushFollow(FOLLOW_2); rule__URLVersionRequirement__Group_1__0(); @@ -6446,16 +7082,16 @@ public final void rule__URLVersionRequirement__Group__1__Impl() throws Recogniti // $ANTLR start "rule__URLVersionRequirement__Group__2" - // InternalSemver.g:1731:1: rule__URLVersionRequirement__Group__2 : rule__URLVersionRequirement__Group__2__Impl rule__URLVersionRequirement__Group__3 ; + // InternalSemver.g:1895:1: rule__URLVersionRequirement__Group__2 : rule__URLVersionRequirement__Group__2__Impl rule__URLVersionRequirement__Group__3 ; public final void rule__URLVersionRequirement__Group__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1735:1: ( rule__URLVersionRequirement__Group__2__Impl rule__URLVersionRequirement__Group__3 ) - // InternalSemver.g:1736:2: rule__URLVersionRequirement__Group__2__Impl rule__URLVersionRequirement__Group__3 + // InternalSemver.g:1899:1: ( rule__URLVersionRequirement__Group__2__Impl rule__URLVersionRequirement__Group__3 ) + // InternalSemver.g:1900:2: rule__URLVersionRequirement__Group__2__Impl rule__URLVersionRequirement__Group__3 { - pushFollow(FOLLOW_9); + pushFollow(FOLLOW_10); rule__URLVersionRequirement__Group__2__Impl(); state._fsp--; @@ -6484,23 +7120,23 @@ public final void rule__URLVersionRequirement__Group__2() throws RecognitionExce // $ANTLR start "rule__URLVersionRequirement__Group__2__Impl" - // InternalSemver.g:1743:1: rule__URLVersionRequirement__Group__2__Impl : ( ( rule__URLVersionRequirement__UrlAssignment_2 ) ) ; + // InternalSemver.g:1907:1: rule__URLVersionRequirement__Group__2__Impl : ( ( rule__URLVersionRequirement__UrlAssignment_2 ) ) ; public final void rule__URLVersionRequirement__Group__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1747:1: ( ( ( rule__URLVersionRequirement__UrlAssignment_2 ) ) ) - // InternalSemver.g:1748:1: ( ( rule__URLVersionRequirement__UrlAssignment_2 ) ) + // InternalSemver.g:1911:1: ( ( ( rule__URLVersionRequirement__UrlAssignment_2 ) ) ) + // InternalSemver.g:1912:1: ( ( rule__URLVersionRequirement__UrlAssignment_2 ) ) { - // InternalSemver.g:1748:1: ( ( rule__URLVersionRequirement__UrlAssignment_2 ) ) - // InternalSemver.g:1749:2: ( rule__URLVersionRequirement__UrlAssignment_2 ) + // InternalSemver.g:1912:1: ( ( rule__URLVersionRequirement__UrlAssignment_2 ) ) + // InternalSemver.g:1913:2: ( rule__URLVersionRequirement__UrlAssignment_2 ) { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionRequirementAccess().getUrlAssignment_2()); } - // InternalSemver.g:1750:2: ( rule__URLVersionRequirement__UrlAssignment_2 ) - // InternalSemver.g:1750:3: rule__URLVersionRequirement__UrlAssignment_2 + // InternalSemver.g:1914:2: ( rule__URLVersionRequirement__UrlAssignment_2 ) + // InternalSemver.g:1914:3: rule__URLVersionRequirement__UrlAssignment_2 { pushFollow(FOLLOW_2); rule__URLVersionRequirement__UrlAssignment_2(); @@ -6535,14 +7171,14 @@ public final void rule__URLVersionRequirement__Group__2__Impl() throws Recogniti // $ANTLR start "rule__URLVersionRequirement__Group__3" - // InternalSemver.g:1758:1: rule__URLVersionRequirement__Group__3 : rule__URLVersionRequirement__Group__3__Impl ; + // InternalSemver.g:1922:1: rule__URLVersionRequirement__Group__3 : rule__URLVersionRequirement__Group__3__Impl ; public final void rule__URLVersionRequirement__Group__3() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1762:1: ( rule__URLVersionRequirement__Group__3__Impl ) - // InternalSemver.g:1763:2: rule__URLVersionRequirement__Group__3__Impl + // InternalSemver.g:1926:1: ( rule__URLVersionRequirement__Group__3__Impl ) + // InternalSemver.g:1927:2: rule__URLVersionRequirement__Group__3__Impl { pushFollow(FOLLOW_2); rule__URLVersionRequirement__Group__3__Impl(); @@ -6568,31 +7204,31 @@ public final void rule__URLVersionRequirement__Group__3() throws RecognitionExce // $ANTLR start "rule__URLVersionRequirement__Group__3__Impl" - // InternalSemver.g:1769:1: rule__URLVersionRequirement__Group__3__Impl : ( ( rule__URLVersionRequirement__Group_3__0 )? ) ; + // InternalSemver.g:1933:1: rule__URLVersionRequirement__Group__3__Impl : ( ( rule__URLVersionRequirement__Group_3__0 )? ) ; public final void rule__URLVersionRequirement__Group__3__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1773:1: ( ( ( rule__URLVersionRequirement__Group_3__0 )? ) ) - // InternalSemver.g:1774:1: ( ( rule__URLVersionRequirement__Group_3__0 )? ) + // InternalSemver.g:1937:1: ( ( ( rule__URLVersionRequirement__Group_3__0 )? ) ) + // InternalSemver.g:1938:1: ( ( rule__URLVersionRequirement__Group_3__0 )? ) { - // InternalSemver.g:1774:1: ( ( rule__URLVersionRequirement__Group_3__0 )? ) - // InternalSemver.g:1775:2: ( rule__URLVersionRequirement__Group_3__0 )? + // InternalSemver.g:1938:1: ( ( rule__URLVersionRequirement__Group_3__0 )? ) + // InternalSemver.g:1939:2: ( rule__URLVersionRequirement__Group_3__0 )? { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionRequirementAccess().getGroup_3()); } - // InternalSemver.g:1776:2: ( rule__URLVersionRequirement__Group_3__0 )? - int alt28=2; - int LA28_0 = input.LA(1); + // InternalSemver.g:1940:2: ( rule__URLVersionRequirement__Group_3__0 )? + int alt30=2; + int LA30_0 = input.LA(1); - if ( (LA28_0==49) ) { - alt28=1; + if ( (LA30_0==55) ) { + alt30=1; } - switch (alt28) { + switch (alt30) { case 1 : - // InternalSemver.g:1776:3: rule__URLVersionRequirement__Group_3__0 + // InternalSemver.g:1940:3: rule__URLVersionRequirement__Group_3__0 { pushFollow(FOLLOW_2); rule__URLVersionRequirement__Group_3__0(); @@ -6630,16 +7266,16 @@ public final void rule__URLVersionRequirement__Group__3__Impl() throws Recogniti // $ANTLR start "rule__URLVersionRequirement__Group_1__0" - // InternalSemver.g:1785:1: rule__URLVersionRequirement__Group_1__0 : rule__URLVersionRequirement__Group_1__0__Impl rule__URLVersionRequirement__Group_1__1 ; + // InternalSemver.g:1949:1: rule__URLVersionRequirement__Group_1__0 : rule__URLVersionRequirement__Group_1__0__Impl rule__URLVersionRequirement__Group_1__1 ; public final void rule__URLVersionRequirement__Group_1__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1789:1: ( rule__URLVersionRequirement__Group_1__0__Impl rule__URLVersionRequirement__Group_1__1 ) - // InternalSemver.g:1790:2: rule__URLVersionRequirement__Group_1__0__Impl rule__URLVersionRequirement__Group_1__1 + // InternalSemver.g:1953:1: ( rule__URLVersionRequirement__Group_1__0__Impl rule__URLVersionRequirement__Group_1__1 ) + // InternalSemver.g:1954:2: rule__URLVersionRequirement__Group_1__0__Impl rule__URLVersionRequirement__Group_1__1 { - pushFollow(FOLLOW_10); + pushFollow(FOLLOW_11); rule__URLVersionRequirement__Group_1__0__Impl(); state._fsp--; @@ -6668,22 +7304,22 @@ public final void rule__URLVersionRequirement__Group_1__0() throws RecognitionEx // $ANTLR start "rule__URLVersionRequirement__Group_1__0__Impl" - // InternalSemver.g:1797:1: rule__URLVersionRequirement__Group_1__0__Impl : ( ':' ) ; + // InternalSemver.g:1961:1: rule__URLVersionRequirement__Group_1__0__Impl : ( ':' ) ; public final void rule__URLVersionRequirement__Group_1__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1801:1: ( ( ':' ) ) - // InternalSemver.g:1802:1: ( ':' ) + // InternalSemver.g:1965:1: ( ( ':' ) ) + // InternalSemver.g:1966:1: ( ':' ) { - // InternalSemver.g:1802:1: ( ':' ) - // InternalSemver.g:1803:2: ':' + // InternalSemver.g:1966:1: ( ':' ) + // InternalSemver.g:1967:2: ':' { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionRequirementAccess().getColonKeyword_1_0()); } - match(input,41,FOLLOW_2); if (state.failed) return ; + match(input,46,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURLVersionRequirementAccess().getColonKeyword_1_0()); } @@ -6709,16 +7345,16 @@ public final void rule__URLVersionRequirement__Group_1__0__Impl() throws Recogni // $ANTLR start "rule__URLVersionRequirement__Group_1__1" - // InternalSemver.g:1812:1: rule__URLVersionRequirement__Group_1__1 : rule__URLVersionRequirement__Group_1__1__Impl rule__URLVersionRequirement__Group_1__2 ; + // InternalSemver.g:1976:1: rule__URLVersionRequirement__Group_1__1 : rule__URLVersionRequirement__Group_1__1__Impl rule__URLVersionRequirement__Group_1__2 ; public final void rule__URLVersionRequirement__Group_1__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1816:1: ( rule__URLVersionRequirement__Group_1__1__Impl rule__URLVersionRequirement__Group_1__2 ) - // InternalSemver.g:1817:2: rule__URLVersionRequirement__Group_1__1__Impl rule__URLVersionRequirement__Group_1__2 + // InternalSemver.g:1980:1: ( rule__URLVersionRequirement__Group_1__1__Impl rule__URLVersionRequirement__Group_1__2 ) + // InternalSemver.g:1981:2: rule__URLVersionRequirement__Group_1__1__Impl rule__URLVersionRequirement__Group_1__2 { - pushFollow(FOLLOW_10); + pushFollow(FOLLOW_11); rule__URLVersionRequirement__Group_1__1__Impl(); state._fsp--; @@ -6747,22 +7383,22 @@ public final void rule__URLVersionRequirement__Group_1__1() throws RecognitionEx // $ANTLR start "rule__URLVersionRequirement__Group_1__1__Impl" - // InternalSemver.g:1824:1: rule__URLVersionRequirement__Group_1__1__Impl : ( '/' ) ; + // InternalSemver.g:1988:1: rule__URLVersionRequirement__Group_1__1__Impl : ( '/' ) ; public final void rule__URLVersionRequirement__Group_1__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1828:1: ( ( '/' ) ) - // InternalSemver.g:1829:1: ( '/' ) + // InternalSemver.g:1992:1: ( ( '/' ) ) + // InternalSemver.g:1993:1: ( '/' ) { - // InternalSemver.g:1829:1: ( '/' ) - // InternalSemver.g:1830:2: '/' + // InternalSemver.g:1993:1: ( '/' ) + // InternalSemver.g:1994:2: '/' { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionRequirementAccess().getSolidusKeyword_1_1()); } - match(input,35,FOLLOW_2); if (state.failed) return ; + match(input,41,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURLVersionRequirementAccess().getSolidusKeyword_1_1()); } @@ -6788,14 +7424,14 @@ public final void rule__URLVersionRequirement__Group_1__1__Impl() throws Recogni // $ANTLR start "rule__URLVersionRequirement__Group_1__2" - // InternalSemver.g:1839:1: rule__URLVersionRequirement__Group_1__2 : rule__URLVersionRequirement__Group_1__2__Impl ; + // InternalSemver.g:2003:1: rule__URLVersionRequirement__Group_1__2 : rule__URLVersionRequirement__Group_1__2__Impl ; public final void rule__URLVersionRequirement__Group_1__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1843:1: ( rule__URLVersionRequirement__Group_1__2__Impl ) - // InternalSemver.g:1844:2: rule__URLVersionRequirement__Group_1__2__Impl + // InternalSemver.g:2007:1: ( rule__URLVersionRequirement__Group_1__2__Impl ) + // InternalSemver.g:2008:2: rule__URLVersionRequirement__Group_1__2__Impl { pushFollow(FOLLOW_2); rule__URLVersionRequirement__Group_1__2__Impl(); @@ -6821,22 +7457,22 @@ public final void rule__URLVersionRequirement__Group_1__2() throws RecognitionEx // $ANTLR start "rule__URLVersionRequirement__Group_1__2__Impl" - // InternalSemver.g:1850:1: rule__URLVersionRequirement__Group_1__2__Impl : ( '/' ) ; + // InternalSemver.g:2014:1: rule__URLVersionRequirement__Group_1__2__Impl : ( '/' ) ; public final void rule__URLVersionRequirement__Group_1__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1854:1: ( ( '/' ) ) - // InternalSemver.g:1855:1: ( '/' ) + // InternalSemver.g:2018:1: ( ( '/' ) ) + // InternalSemver.g:2019:1: ( '/' ) { - // InternalSemver.g:1855:1: ( '/' ) - // InternalSemver.g:1856:2: '/' + // InternalSemver.g:2019:1: ( '/' ) + // InternalSemver.g:2020:2: '/' { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionRequirementAccess().getSolidusKeyword_1_2()); } - match(input,35,FOLLOW_2); if (state.failed) return ; + match(input,41,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURLVersionRequirementAccess().getSolidusKeyword_1_2()); } @@ -6862,16 +7498,16 @@ public final void rule__URLVersionRequirement__Group_1__2__Impl() throws Recogni // $ANTLR start "rule__URLVersionRequirement__Group_3__0" - // InternalSemver.g:1866:1: rule__URLVersionRequirement__Group_3__0 : rule__URLVersionRequirement__Group_3__0__Impl rule__URLVersionRequirement__Group_3__1 ; + // InternalSemver.g:2030:1: rule__URLVersionRequirement__Group_3__0 : rule__URLVersionRequirement__Group_3__0__Impl rule__URLVersionRequirement__Group_3__1 ; public final void rule__URLVersionRequirement__Group_3__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1870:1: ( rule__URLVersionRequirement__Group_3__0__Impl rule__URLVersionRequirement__Group_3__1 ) - // InternalSemver.g:1871:2: rule__URLVersionRequirement__Group_3__0__Impl rule__URLVersionRequirement__Group_3__1 + // InternalSemver.g:2034:1: ( rule__URLVersionRequirement__Group_3__0__Impl rule__URLVersionRequirement__Group_3__1 ) + // InternalSemver.g:2035:2: rule__URLVersionRequirement__Group_3__0__Impl rule__URLVersionRequirement__Group_3__1 { - pushFollow(FOLLOW_11); + pushFollow(FOLLOW_12); rule__URLVersionRequirement__Group_3__0__Impl(); state._fsp--; @@ -6900,22 +7536,22 @@ public final void rule__URLVersionRequirement__Group_3__0() throws RecognitionEx // $ANTLR start "rule__URLVersionRequirement__Group_3__0__Impl" - // InternalSemver.g:1878:1: rule__URLVersionRequirement__Group_3__0__Impl : ( '#' ) ; + // InternalSemver.g:2042:1: rule__URLVersionRequirement__Group_3__0__Impl : ( '#' ) ; public final void rule__URLVersionRequirement__Group_3__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1882:1: ( ( '#' ) ) - // InternalSemver.g:1883:1: ( '#' ) + // InternalSemver.g:2046:1: ( ( '#' ) ) + // InternalSemver.g:2047:1: ( '#' ) { - // InternalSemver.g:1883:1: ( '#' ) - // InternalSemver.g:1884:2: '#' + // InternalSemver.g:2047:1: ( '#' ) + // InternalSemver.g:2048:2: '#' { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionRequirementAccess().getNumberSignKeyword_3_0()); } - match(input,49,FOLLOW_2); if (state.failed) return ; + match(input,55,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getURLVersionRequirementAccess().getNumberSignKeyword_3_0()); } @@ -6941,14 +7577,14 @@ public final void rule__URLVersionRequirement__Group_3__0__Impl() throws Recogni // $ANTLR start "rule__URLVersionRequirement__Group_3__1" - // InternalSemver.g:1893:1: rule__URLVersionRequirement__Group_3__1 : rule__URLVersionRequirement__Group_3__1__Impl ; + // InternalSemver.g:2057:1: rule__URLVersionRequirement__Group_3__1 : rule__URLVersionRequirement__Group_3__1__Impl ; public final void rule__URLVersionRequirement__Group_3__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1897:1: ( rule__URLVersionRequirement__Group_3__1__Impl ) - // InternalSemver.g:1898:2: rule__URLVersionRequirement__Group_3__1__Impl + // InternalSemver.g:2061:1: ( rule__URLVersionRequirement__Group_3__1__Impl ) + // InternalSemver.g:2062:2: rule__URLVersionRequirement__Group_3__1__Impl { pushFollow(FOLLOW_2); rule__URLVersionRequirement__Group_3__1__Impl(); @@ -6974,23 +7610,23 @@ public final void rule__URLVersionRequirement__Group_3__1() throws RecognitionEx // $ANTLR start "rule__URLVersionRequirement__Group_3__1__Impl" - // InternalSemver.g:1904:1: rule__URLVersionRequirement__Group_3__1__Impl : ( ( rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 ) ) ; + // InternalSemver.g:2068:1: rule__URLVersionRequirement__Group_3__1__Impl : ( ( rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 ) ) ; public final void rule__URLVersionRequirement__Group_3__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1908:1: ( ( ( rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 ) ) ) - // InternalSemver.g:1909:1: ( ( rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 ) ) + // InternalSemver.g:2072:1: ( ( ( rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 ) ) ) + // InternalSemver.g:2073:1: ( ( rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 ) ) { - // InternalSemver.g:1909:1: ( ( rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 ) ) - // InternalSemver.g:1910:2: ( rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 ) + // InternalSemver.g:2073:1: ( ( rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 ) ) + // InternalSemver.g:2074:2: ( rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionRequirementAccess().getVersionSpecifierAssignment_3_1()); } - // InternalSemver.g:1911:2: ( rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 ) - // InternalSemver.g:1911:3: rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 + // InternalSemver.g:2075:2: ( rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 ) + // InternalSemver.g:2075:3: rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 { pushFollow(FOLLOW_2); rule__URLVersionRequirement__VersionSpecifierAssignment_3_1(); @@ -7025,14 +7661,14 @@ public final void rule__URLVersionRequirement__Group_3__1__Impl() throws Recogni // $ANTLR start "rule__URLVersionSpecifier__Group_0__0" - // InternalSemver.g:1920:1: rule__URLVersionSpecifier__Group_0__0 : rule__URLVersionSpecifier__Group_0__0__Impl ; + // InternalSemver.g:2084:1: rule__URLVersionSpecifier__Group_0__0 : rule__URLVersionSpecifier__Group_0__0__Impl ; public final void rule__URLVersionSpecifier__Group_0__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1924:1: ( rule__URLVersionSpecifier__Group_0__0__Impl ) - // InternalSemver.g:1925:2: rule__URLVersionSpecifier__Group_0__0__Impl + // InternalSemver.g:2088:1: ( rule__URLVersionSpecifier__Group_0__0__Impl ) + // InternalSemver.g:2089:2: rule__URLVersionSpecifier__Group_0__0__Impl { pushFollow(FOLLOW_2); rule__URLVersionSpecifier__Group_0__0__Impl(); @@ -7058,17 +7694,17 @@ public final void rule__URLVersionSpecifier__Group_0__0() throws RecognitionExce // $ANTLR start "rule__URLVersionSpecifier__Group_0__0__Impl" - // InternalSemver.g:1931:1: rule__URLVersionSpecifier__Group_0__0__Impl : ( ruleURLSemver ) ; + // InternalSemver.g:2095:1: rule__URLVersionSpecifier__Group_0__0__Impl : ( ruleURLSemver ) ; public final void rule__URLVersionSpecifier__Group_0__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1935:1: ( ( ruleURLSemver ) ) - // InternalSemver.g:1936:1: ( ruleURLSemver ) + // InternalSemver.g:2099:1: ( ( ruleURLSemver ) ) + // InternalSemver.g:2100:1: ( ruleURLSemver ) { - // InternalSemver.g:1936:1: ( ruleURLSemver ) - // InternalSemver.g:1937:2: ruleURLSemver + // InternalSemver.g:2100:1: ( ruleURLSemver ) + // InternalSemver.g:2101:2: ruleURLSemver { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionSpecifierAccess().getURLSemverParserRuleCall_0_0()); @@ -7103,16 +7739,16 @@ public final void rule__URLVersionSpecifier__Group_0__0__Impl() throws Recogniti // $ANTLR start "rule__URLVersionSpecifier__Group_1__0" - // InternalSemver.g:1947:1: rule__URLVersionSpecifier__Group_1__0 : rule__URLVersionSpecifier__Group_1__0__Impl rule__URLVersionSpecifier__Group_1__1 ; + // InternalSemver.g:2111:1: rule__URLVersionSpecifier__Group_1__0 : rule__URLVersionSpecifier__Group_1__0__Impl rule__URLVersionSpecifier__Group_1__1 ; public final void rule__URLVersionSpecifier__Group_1__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1951:1: ( rule__URLVersionSpecifier__Group_1__0__Impl rule__URLVersionSpecifier__Group_1__1 ) - // InternalSemver.g:1952:2: rule__URLVersionSpecifier__Group_1__0__Impl rule__URLVersionSpecifier__Group_1__1 + // InternalSemver.g:2115:1: ( rule__URLVersionSpecifier__Group_1__0__Impl rule__URLVersionSpecifier__Group_1__1 ) + // InternalSemver.g:2116:2: rule__URLVersionSpecifier__Group_1__0__Impl rule__URLVersionSpecifier__Group_1__1 { - pushFollow(FOLLOW_12); + pushFollow(FOLLOW_13); rule__URLVersionSpecifier__Group_1__0__Impl(); state._fsp--; @@ -7141,23 +7777,23 @@ public final void rule__URLVersionSpecifier__Group_1__0() throws RecognitionExce // $ANTLR start "rule__URLVersionSpecifier__Group_1__0__Impl" - // InternalSemver.g:1959:1: rule__URLVersionSpecifier__Group_1__0__Impl : ( () ) ; + // InternalSemver.g:2123:1: rule__URLVersionSpecifier__Group_1__0__Impl : ( () ) ; public final void rule__URLVersionSpecifier__Group_1__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1963:1: ( ( () ) ) - // InternalSemver.g:1964:1: ( () ) + // InternalSemver.g:2127:1: ( ( () ) ) + // InternalSemver.g:2128:1: ( () ) { - // InternalSemver.g:1964:1: ( () ) - // InternalSemver.g:1965:2: () + // InternalSemver.g:2128:1: ( () ) + // InternalSemver.g:2129:2: () { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionSpecifierAccess().getURLCommitISHAction_1_0()); } - // InternalSemver.g:1966:2: () - // InternalSemver.g:1966:3: + // InternalSemver.g:2130:2: () + // InternalSemver.g:2130:3: { } @@ -7182,14 +7818,14 @@ public final void rule__URLVersionSpecifier__Group_1__0__Impl() throws Recogniti // $ANTLR start "rule__URLVersionSpecifier__Group_1__1" - // InternalSemver.g:1974:1: rule__URLVersionSpecifier__Group_1__1 : rule__URLVersionSpecifier__Group_1__1__Impl ; + // InternalSemver.g:2138:1: rule__URLVersionSpecifier__Group_1__1 : rule__URLVersionSpecifier__Group_1__1__Impl ; public final void rule__URLVersionSpecifier__Group_1__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1978:1: ( rule__URLVersionSpecifier__Group_1__1__Impl ) - // InternalSemver.g:1979:2: rule__URLVersionSpecifier__Group_1__1__Impl + // InternalSemver.g:2142:1: ( rule__URLVersionSpecifier__Group_1__1__Impl ) + // InternalSemver.g:2143:2: rule__URLVersionSpecifier__Group_1__1__Impl { pushFollow(FOLLOW_2); rule__URLVersionSpecifier__Group_1__1__Impl(); @@ -7215,23 +7851,23 @@ public final void rule__URLVersionSpecifier__Group_1__1() throws RecognitionExce // $ANTLR start "rule__URLVersionSpecifier__Group_1__1__Impl" - // InternalSemver.g:1985:1: rule__URLVersionSpecifier__Group_1__1__Impl : ( ( rule__URLVersionSpecifier__CommitISHAssignment_1_1 ) ) ; + // InternalSemver.g:2149:1: rule__URLVersionSpecifier__Group_1__1__Impl : ( ( rule__URLVersionSpecifier__CommitISHAssignment_1_1 ) ) ; public final void rule__URLVersionSpecifier__Group_1__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:1989:1: ( ( ( rule__URLVersionSpecifier__CommitISHAssignment_1_1 ) ) ) - // InternalSemver.g:1990:1: ( ( rule__URLVersionSpecifier__CommitISHAssignment_1_1 ) ) + // InternalSemver.g:2153:1: ( ( ( rule__URLVersionSpecifier__CommitISHAssignment_1_1 ) ) ) + // InternalSemver.g:2154:1: ( ( rule__URLVersionSpecifier__CommitISHAssignment_1_1 ) ) { - // InternalSemver.g:1990:1: ( ( rule__URLVersionSpecifier__CommitISHAssignment_1_1 ) ) - // InternalSemver.g:1991:2: ( rule__URLVersionSpecifier__CommitISHAssignment_1_1 ) + // InternalSemver.g:2154:1: ( ( rule__URLVersionSpecifier__CommitISHAssignment_1_1 ) ) + // InternalSemver.g:2155:2: ( rule__URLVersionSpecifier__CommitISHAssignment_1_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionSpecifierAccess().getCommitISHAssignment_1_1()); } - // InternalSemver.g:1992:2: ( rule__URLVersionSpecifier__CommitISHAssignment_1_1 ) - // InternalSemver.g:1992:3: rule__URLVersionSpecifier__CommitISHAssignment_1_1 + // InternalSemver.g:2156:2: ( rule__URLVersionSpecifier__CommitISHAssignment_1_1 ) + // InternalSemver.g:2156:3: rule__URLVersionSpecifier__CommitISHAssignment_1_1 { pushFollow(FOLLOW_2); rule__URLVersionSpecifier__CommitISHAssignment_1_1(); @@ -7266,16 +7902,16 @@ public final void rule__URLVersionSpecifier__Group_1__1__Impl() throws Recogniti // $ANTLR start "rule__URLVersionSpecifier__Group_2__0" - // InternalSemver.g:2001:1: rule__URLVersionSpecifier__Group_2__0 : rule__URLVersionSpecifier__Group_2__0__Impl rule__URLVersionSpecifier__Group_2__1 ; + // InternalSemver.g:2165:1: rule__URLVersionSpecifier__Group_2__0 : rule__URLVersionSpecifier__Group_2__0__Impl rule__URLVersionSpecifier__Group_2__1 ; public final void rule__URLVersionSpecifier__Group_2__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2005:1: ( rule__URLVersionSpecifier__Group_2__0__Impl rule__URLVersionSpecifier__Group_2__1 ) - // InternalSemver.g:2006:2: rule__URLVersionSpecifier__Group_2__0__Impl rule__URLVersionSpecifier__Group_2__1 + // InternalSemver.g:2169:1: ( rule__URLVersionSpecifier__Group_2__0__Impl rule__URLVersionSpecifier__Group_2__1 ) + // InternalSemver.g:2170:2: rule__URLVersionSpecifier__Group_2__0__Impl rule__URLVersionSpecifier__Group_2__1 { - pushFollow(FOLLOW_11); + pushFollow(FOLLOW_12); rule__URLVersionSpecifier__Group_2__0__Impl(); state._fsp--; @@ -7304,23 +7940,23 @@ public final void rule__URLVersionSpecifier__Group_2__0() throws RecognitionExce // $ANTLR start "rule__URLVersionSpecifier__Group_2__0__Impl" - // InternalSemver.g:2013:1: rule__URLVersionSpecifier__Group_2__0__Impl : ( () ) ; + // InternalSemver.g:2177:1: rule__URLVersionSpecifier__Group_2__0__Impl : ( () ) ; public final void rule__URLVersionSpecifier__Group_2__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2017:1: ( ( () ) ) - // InternalSemver.g:2018:1: ( () ) + // InternalSemver.g:2181:1: ( ( () ) ) + // InternalSemver.g:2182:1: ( () ) { - // InternalSemver.g:2018:1: ( () ) - // InternalSemver.g:2019:2: () + // InternalSemver.g:2182:1: ( () ) + // InternalSemver.g:2183:2: () { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionSpecifierAccess().getURLCommitISHAction_2_0()); } - // InternalSemver.g:2020:2: () - // InternalSemver.g:2020:3: + // InternalSemver.g:2184:2: () + // InternalSemver.g:2184:3: { } @@ -7345,14 +7981,14 @@ public final void rule__URLVersionSpecifier__Group_2__0__Impl() throws Recogniti // $ANTLR start "rule__URLVersionSpecifier__Group_2__1" - // InternalSemver.g:2028:1: rule__URLVersionSpecifier__Group_2__1 : rule__URLVersionSpecifier__Group_2__1__Impl ; + // InternalSemver.g:2192:1: rule__URLVersionSpecifier__Group_2__1 : rule__URLVersionSpecifier__Group_2__1__Impl ; public final void rule__URLVersionSpecifier__Group_2__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2032:1: ( rule__URLVersionSpecifier__Group_2__1__Impl ) - // InternalSemver.g:2033:2: rule__URLVersionSpecifier__Group_2__1__Impl + // InternalSemver.g:2196:1: ( rule__URLVersionSpecifier__Group_2__1__Impl ) + // InternalSemver.g:2197:2: rule__URLVersionSpecifier__Group_2__1__Impl { pushFollow(FOLLOW_2); rule__URLVersionSpecifier__Group_2__1__Impl(); @@ -7378,23 +8014,23 @@ public final void rule__URLVersionSpecifier__Group_2__1() throws RecognitionExce // $ANTLR start "rule__URLVersionSpecifier__Group_2__1__Impl" - // InternalSemver.g:2039:1: rule__URLVersionSpecifier__Group_2__1__Impl : ( ( rule__URLVersionSpecifier__CommitISHAssignment_2_1 ) ) ; + // InternalSemver.g:2203:1: rule__URLVersionSpecifier__Group_2__1__Impl : ( ( rule__URLVersionSpecifier__CommitISHAssignment_2_1 ) ) ; public final void rule__URLVersionSpecifier__Group_2__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2043:1: ( ( ( rule__URLVersionSpecifier__CommitISHAssignment_2_1 ) ) ) - // InternalSemver.g:2044:1: ( ( rule__URLVersionSpecifier__CommitISHAssignment_2_1 ) ) + // InternalSemver.g:2207:1: ( ( ( rule__URLVersionSpecifier__CommitISHAssignment_2_1 ) ) ) + // InternalSemver.g:2208:1: ( ( rule__URLVersionSpecifier__CommitISHAssignment_2_1 ) ) { - // InternalSemver.g:2044:1: ( ( rule__URLVersionSpecifier__CommitISHAssignment_2_1 ) ) - // InternalSemver.g:2045:2: ( rule__URLVersionSpecifier__CommitISHAssignment_2_1 ) + // InternalSemver.g:2208:1: ( ( rule__URLVersionSpecifier__CommitISHAssignment_2_1 ) ) + // InternalSemver.g:2209:2: ( rule__URLVersionSpecifier__CommitISHAssignment_2_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getURLVersionSpecifierAccess().getCommitISHAssignment_2_1()); } - // InternalSemver.g:2046:2: ( rule__URLVersionSpecifier__CommitISHAssignment_2_1 ) - // InternalSemver.g:2046:3: rule__URLVersionSpecifier__CommitISHAssignment_2_1 + // InternalSemver.g:2210:2: ( rule__URLVersionSpecifier__CommitISHAssignment_2_1 ) + // InternalSemver.g:2210:3: rule__URLVersionSpecifier__CommitISHAssignment_2_1 { pushFollow(FOLLOW_2); rule__URLVersionSpecifier__CommitISHAssignment_2_1(); @@ -7429,16 +8065,16 @@ public final void rule__URLVersionSpecifier__Group_2__1__Impl() throws Recogniti // $ANTLR start "rule__URLSemver__Group__0" - // InternalSemver.g:2055:1: rule__URLSemver__Group__0 : rule__URLSemver__Group__0__Impl rule__URLSemver__Group__1 ; + // InternalSemver.g:2219:1: rule__URLSemver__Group__0 : rule__URLSemver__Group__0__Impl rule__URLSemver__Group__1 ; public final void rule__URLSemver__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2059:1: ( rule__URLSemver__Group__0__Impl rule__URLSemver__Group__1 ) - // InternalSemver.g:2060:2: rule__URLSemver__Group__0__Impl rule__URLSemver__Group__1 + // InternalSemver.g:2223:1: ( rule__URLSemver__Group__0__Impl rule__URLSemver__Group__1 ) + // InternalSemver.g:2224:2: rule__URLSemver__Group__0__Impl rule__URLSemver__Group__1 { - pushFollow(FOLLOW_13); + pushFollow(FOLLOW_14); rule__URLSemver__Group__0__Impl(); state._fsp--; @@ -7467,23 +8103,23 @@ public final void rule__URLSemver__Group__0() throws RecognitionException { // $ANTLR start "rule__URLSemver__Group__0__Impl" - // InternalSemver.g:2067:1: rule__URLSemver__Group__0__Impl : ( () ) ; + // InternalSemver.g:2231:1: rule__URLSemver__Group__0__Impl : ( () ) ; public final void rule__URLSemver__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2071:1: ( ( () ) ) - // InternalSemver.g:2072:1: ( () ) + // InternalSemver.g:2235:1: ( ( () ) ) + // InternalSemver.g:2236:1: ( () ) { - // InternalSemver.g:2072:1: ( () ) - // InternalSemver.g:2073:2: () + // InternalSemver.g:2236:1: ( () ) + // InternalSemver.g:2237:2: () { if ( state.backtracking==0 ) { before(grammarAccess.getURLSemverAccess().getURLSemverAction_0()); } - // InternalSemver.g:2074:2: () - // InternalSemver.g:2074:3: + // InternalSemver.g:2238:2: () + // InternalSemver.g:2238:3: { } @@ -7508,16 +8144,16 @@ public final void rule__URLSemver__Group__0__Impl() throws RecognitionException // $ANTLR start "rule__URLSemver__Group__1" - // InternalSemver.g:2082:1: rule__URLSemver__Group__1 : rule__URLSemver__Group__1__Impl rule__URLSemver__Group__2 ; + // InternalSemver.g:2246:1: rule__URLSemver__Group__1 : rule__URLSemver__Group__1__Impl rule__URLSemver__Group__2 ; public final void rule__URLSemver__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2086:1: ( rule__URLSemver__Group__1__Impl rule__URLSemver__Group__2 ) - // InternalSemver.g:2087:2: rule__URLSemver__Group__1__Impl rule__URLSemver__Group__2 + // InternalSemver.g:2250:1: ( rule__URLSemver__Group__1__Impl rule__URLSemver__Group__2 ) + // InternalSemver.g:2251:2: rule__URLSemver__Group__1__Impl rule__URLSemver__Group__2 { - pushFollow(FOLLOW_13); + pushFollow(FOLLOW_14); rule__URLSemver__Group__1__Impl(); state._fsp--; @@ -7546,31 +8182,31 @@ public final void rule__URLSemver__Group__1() throws RecognitionException { // $ANTLR start "rule__URLSemver__Group__1__Impl" - // InternalSemver.g:2094:1: rule__URLSemver__Group__1__Impl : ( ( rule__URLSemver__WithSemverTagAssignment_1 )? ) ; + // InternalSemver.g:2258:1: rule__URLSemver__Group__1__Impl : ( ( rule__URLSemver__WithSemverTagAssignment_1 )? ) ; public final void rule__URLSemver__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2098:1: ( ( ( rule__URLSemver__WithSemverTagAssignment_1 )? ) ) - // InternalSemver.g:2099:1: ( ( rule__URLSemver__WithSemverTagAssignment_1 )? ) + // InternalSemver.g:2262:1: ( ( ( rule__URLSemver__WithSemverTagAssignment_1 )? ) ) + // InternalSemver.g:2263:1: ( ( rule__URLSemver__WithSemverTagAssignment_1 )? ) { - // InternalSemver.g:2099:1: ( ( rule__URLSemver__WithSemverTagAssignment_1 )? ) - // InternalSemver.g:2100:2: ( rule__URLSemver__WithSemverTagAssignment_1 )? + // InternalSemver.g:2263:1: ( ( rule__URLSemver__WithSemverTagAssignment_1 )? ) + // InternalSemver.g:2264:2: ( rule__URLSemver__WithSemverTagAssignment_1 )? { if ( state.backtracking==0 ) { before(grammarAccess.getURLSemverAccess().getWithSemverTagAssignment_1()); } - // InternalSemver.g:2101:2: ( rule__URLSemver__WithSemverTagAssignment_1 )? - int alt29=2; - int LA29_0 = input.LA(1); + // InternalSemver.g:2265:2: ( rule__URLSemver__WithSemverTagAssignment_1 )? + int alt31=2; + int LA31_0 = input.LA(1); - if ( (LA29_0==RULE_LETTER_S) ) { - alt29=1; + if ( (LA31_0==RULE_LETTER_S) ) { + alt31=1; } - switch (alt29) { + switch (alt31) { case 1 : - // InternalSemver.g:2101:3: rule__URLSemver__WithSemverTagAssignment_1 + // InternalSemver.g:2265:3: rule__URLSemver__WithSemverTagAssignment_1 { pushFollow(FOLLOW_2); rule__URLSemver__WithSemverTagAssignment_1(); @@ -7608,14 +8244,14 @@ public final void rule__URLSemver__Group__1__Impl() throws RecognitionException // $ANTLR start "rule__URLSemver__Group__2" - // InternalSemver.g:2109:1: rule__URLSemver__Group__2 : rule__URLSemver__Group__2__Impl ; + // InternalSemver.g:2273:1: rule__URLSemver__Group__2 : rule__URLSemver__Group__2__Impl ; public final void rule__URLSemver__Group__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2113:1: ( rule__URLSemver__Group__2__Impl ) - // InternalSemver.g:2114:2: rule__URLSemver__Group__2__Impl + // InternalSemver.g:2277:1: ( rule__URLSemver__Group__2__Impl ) + // InternalSemver.g:2278:2: rule__URLSemver__Group__2__Impl { pushFollow(FOLLOW_2); rule__URLSemver__Group__2__Impl(); @@ -7641,23 +8277,23 @@ public final void rule__URLSemver__Group__2() throws RecognitionException { // $ANTLR start "rule__URLSemver__Group__2__Impl" - // InternalSemver.g:2120:1: rule__URLSemver__Group__2__Impl : ( ( rule__URLSemver__SimpleVersionAssignment_2 ) ) ; + // InternalSemver.g:2284:1: rule__URLSemver__Group__2__Impl : ( ( rule__URLSemver__SimpleVersionAssignment_2 ) ) ; public final void rule__URLSemver__Group__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2124:1: ( ( ( rule__URLSemver__SimpleVersionAssignment_2 ) ) ) - // InternalSemver.g:2125:1: ( ( rule__URLSemver__SimpleVersionAssignment_2 ) ) + // InternalSemver.g:2288:1: ( ( ( rule__URLSemver__SimpleVersionAssignment_2 ) ) ) + // InternalSemver.g:2289:1: ( ( rule__URLSemver__SimpleVersionAssignment_2 ) ) { - // InternalSemver.g:2125:1: ( ( rule__URLSemver__SimpleVersionAssignment_2 ) ) - // InternalSemver.g:2126:2: ( rule__URLSemver__SimpleVersionAssignment_2 ) + // InternalSemver.g:2289:1: ( ( rule__URLSemver__SimpleVersionAssignment_2 ) ) + // InternalSemver.g:2290:2: ( rule__URLSemver__SimpleVersionAssignment_2 ) { if ( state.backtracking==0 ) { before(grammarAccess.getURLSemverAccess().getSimpleVersionAssignment_2()); } - // InternalSemver.g:2127:2: ( rule__URLSemver__SimpleVersionAssignment_2 ) - // InternalSemver.g:2127:3: rule__URLSemver__SimpleVersionAssignment_2 + // InternalSemver.g:2291:2: ( rule__URLSemver__SimpleVersionAssignment_2 ) + // InternalSemver.g:2291:3: rule__URLSemver__SimpleVersionAssignment_2 { pushFollow(FOLLOW_2); rule__URLSemver__SimpleVersionAssignment_2(); @@ -7691,23 +8327,23 @@ public final void rule__URLSemver__Group__2__Impl() throws RecognitionException // $ANTLR end "rule__URLSemver__Group__2__Impl" - // $ANTLR start "rule__GitHubVersionRequirement__Group__0" - // InternalSemver.g:2136:1: rule__GitHubVersionRequirement__Group__0 : rule__GitHubVersionRequirement__Group__0__Impl rule__GitHubVersionRequirement__Group__1 ; - public final void rule__GitHubVersionRequirement__Group__0() throws RecognitionException { + // $ANTLR start "rule__WorkspaceVersionRequirement__Group__0" + // InternalSemver.g:2300:1: rule__WorkspaceVersionRequirement__Group__0 : rule__WorkspaceVersionRequirement__Group__0__Impl rule__WorkspaceVersionRequirement__Group__1 ; + public final void rule__WorkspaceVersionRequirement__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2140:1: ( rule__GitHubVersionRequirement__Group__0__Impl rule__GitHubVersionRequirement__Group__1 ) - // InternalSemver.g:2141:2: rule__GitHubVersionRequirement__Group__0__Impl rule__GitHubVersionRequirement__Group__1 + // InternalSemver.g:2304:1: ( rule__WorkspaceVersionRequirement__Group__0__Impl rule__WorkspaceVersionRequirement__Group__1 ) + // InternalSemver.g:2305:2: rule__WorkspaceVersionRequirement__Group__0__Impl rule__WorkspaceVersionRequirement__Group__1 { - pushFollow(FOLLOW_9); - rule__GitHubVersionRequirement__Group__0__Impl(); + pushFollow(FOLLOW_15); + rule__WorkspaceVersionRequirement__Group__0__Impl(); state._fsp--; if (state.failed) return ; pushFollow(FOLLOW_2); - rule__GitHubVersionRequirement__Group__1(); + rule__WorkspaceVersionRequirement__Group__1(); state._fsp--; if (state.failed) return ; @@ -7726,38 +8362,32 @@ public final void rule__GitHubVersionRequirement__Group__0() throws RecognitionE } return ; } - // $ANTLR end "rule__GitHubVersionRequirement__Group__0" + // $ANTLR end "rule__WorkspaceVersionRequirement__Group__0" - // $ANTLR start "rule__GitHubVersionRequirement__Group__0__Impl" - // InternalSemver.g:2148:1: rule__GitHubVersionRequirement__Group__0__Impl : ( ( rule__GitHubVersionRequirement__GithubUrlAssignment_0 ) ) ; - public final void rule__GitHubVersionRequirement__Group__0__Impl() throws RecognitionException { + // $ANTLR start "rule__WorkspaceVersionRequirement__Group__0__Impl" + // InternalSemver.g:2312:1: rule__WorkspaceVersionRequirement__Group__0__Impl : ( ruleWORKSPACE_TAG ) ; + public final void rule__WorkspaceVersionRequirement__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2152:1: ( ( ( rule__GitHubVersionRequirement__GithubUrlAssignment_0 ) ) ) - // InternalSemver.g:2153:1: ( ( rule__GitHubVersionRequirement__GithubUrlAssignment_0 ) ) + // InternalSemver.g:2316:1: ( ( ruleWORKSPACE_TAG ) ) + // InternalSemver.g:2317:1: ( ruleWORKSPACE_TAG ) { - // InternalSemver.g:2153:1: ( ( rule__GitHubVersionRequirement__GithubUrlAssignment_0 ) ) - // InternalSemver.g:2154:2: ( rule__GitHubVersionRequirement__GithubUrlAssignment_0 ) + // InternalSemver.g:2317:1: ( ruleWORKSPACE_TAG ) + // InternalSemver.g:2318:2: ruleWORKSPACE_TAG { if ( state.backtracking==0 ) { - before(grammarAccess.getGitHubVersionRequirementAccess().getGithubUrlAssignment_0()); + before(grammarAccess.getWorkspaceVersionRequirementAccess().getWORKSPACE_TAGParserRuleCall_0()); } - // InternalSemver.g:2155:2: ( rule__GitHubVersionRequirement__GithubUrlAssignment_0 ) - // InternalSemver.g:2155:3: rule__GitHubVersionRequirement__GithubUrlAssignment_0 - { pushFollow(FOLLOW_2); - rule__GitHubVersionRequirement__GithubUrlAssignment_0(); + ruleWORKSPACE_TAG(); state._fsp--; if (state.failed) return ; - - } - if ( state.backtracking==0 ) { - after(grammarAccess.getGitHubVersionRequirementAccess().getGithubUrlAssignment_0()); + after(grammarAccess.getWorkspaceVersionRequirementAccess().getWORKSPACE_TAGParserRuleCall_0()); } } @@ -7777,21 +8407,21 @@ public final void rule__GitHubVersionRequirement__Group__0__Impl() throws Recogn } return ; } - // $ANTLR end "rule__GitHubVersionRequirement__Group__0__Impl" + // $ANTLR end "rule__WorkspaceVersionRequirement__Group__0__Impl" - // $ANTLR start "rule__GitHubVersionRequirement__Group__1" - // InternalSemver.g:2163:1: rule__GitHubVersionRequirement__Group__1 : rule__GitHubVersionRequirement__Group__1__Impl ; - public final void rule__GitHubVersionRequirement__Group__1() throws RecognitionException { + // $ANTLR start "rule__WorkspaceVersionRequirement__Group__1" + // InternalSemver.g:2327:1: rule__WorkspaceVersionRequirement__Group__1 : rule__WorkspaceVersionRequirement__Group__1__Impl ; + public final void rule__WorkspaceVersionRequirement__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2167:1: ( rule__GitHubVersionRequirement__Group__1__Impl ) - // InternalSemver.g:2168:2: rule__GitHubVersionRequirement__Group__1__Impl + // InternalSemver.g:2331:1: ( rule__WorkspaceVersionRequirement__Group__1__Impl ) + // InternalSemver.g:2332:2: rule__WorkspaceVersionRequirement__Group__1__Impl { pushFollow(FOLLOW_2); - rule__GitHubVersionRequirement__Group__1__Impl(); + rule__WorkspaceVersionRequirement__Group__1__Impl(); state._fsp--; if (state.failed) return ; @@ -7810,49 +8440,38 @@ public final void rule__GitHubVersionRequirement__Group__1() throws RecognitionE } return ; } - // $ANTLR end "rule__GitHubVersionRequirement__Group__1" + // $ANTLR end "rule__WorkspaceVersionRequirement__Group__1" - // $ANTLR start "rule__GitHubVersionRequirement__Group__1__Impl" - // InternalSemver.g:2174:1: rule__GitHubVersionRequirement__Group__1__Impl : ( ( rule__GitHubVersionRequirement__Group_1__0 )? ) ; - public final void rule__GitHubVersionRequirement__Group__1__Impl() throws RecognitionException { + // $ANTLR start "rule__WorkspaceVersionRequirement__Group__1__Impl" + // InternalSemver.g:2338:1: rule__WorkspaceVersionRequirement__Group__1__Impl : ( ( rule__WorkspaceVersionRequirement__Alternatives_1 ) ) ; + public final void rule__WorkspaceVersionRequirement__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2178:1: ( ( ( rule__GitHubVersionRequirement__Group_1__0 )? ) ) - // InternalSemver.g:2179:1: ( ( rule__GitHubVersionRequirement__Group_1__0 )? ) + // InternalSemver.g:2342:1: ( ( ( rule__WorkspaceVersionRequirement__Alternatives_1 ) ) ) + // InternalSemver.g:2343:1: ( ( rule__WorkspaceVersionRequirement__Alternatives_1 ) ) { - // InternalSemver.g:2179:1: ( ( rule__GitHubVersionRequirement__Group_1__0 )? ) - // InternalSemver.g:2180:2: ( rule__GitHubVersionRequirement__Group_1__0 )? + // InternalSemver.g:2343:1: ( ( rule__WorkspaceVersionRequirement__Alternatives_1 ) ) + // InternalSemver.g:2344:2: ( rule__WorkspaceVersionRequirement__Alternatives_1 ) { if ( state.backtracking==0 ) { - before(grammarAccess.getGitHubVersionRequirementAccess().getGroup_1()); - } - // InternalSemver.g:2181:2: ( rule__GitHubVersionRequirement__Group_1__0 )? - int alt30=2; - int LA30_0 = input.LA(1); - - if ( (LA30_0==49) ) { - alt30=1; + before(grammarAccess.getWorkspaceVersionRequirementAccess().getAlternatives_1()); } - switch (alt30) { - case 1 : - // InternalSemver.g:2181:3: rule__GitHubVersionRequirement__Group_1__0 - { - pushFollow(FOLLOW_2); - rule__GitHubVersionRequirement__Group_1__0(); - - state._fsp--; - if (state.failed) return ; + // InternalSemver.g:2345:2: ( rule__WorkspaceVersionRequirement__Alternatives_1 ) + // InternalSemver.g:2345:3: rule__WorkspaceVersionRequirement__Alternatives_1 + { + pushFollow(FOLLOW_2); + rule__WorkspaceVersionRequirement__Alternatives_1(); - } - break; + state._fsp--; + if (state.failed) return ; } if ( state.backtracking==0 ) { - after(grammarAccess.getGitHubVersionRequirementAccess().getGroup_1()); + after(grammarAccess.getWorkspaceVersionRequirementAccess().getAlternatives_1()); } } @@ -7872,26 +8491,210 @@ public final void rule__GitHubVersionRequirement__Group__1__Impl() throws Recogn } return ; } - // $ANTLR end "rule__GitHubVersionRequirement__Group__1__Impl" + // $ANTLR end "rule__WorkspaceVersionRequirement__Group__1__Impl" - // $ANTLR start "rule__GitHubVersionRequirement__Group_1__0" - // InternalSemver.g:2190:1: rule__GitHubVersionRequirement__Group_1__0 : rule__GitHubVersionRequirement__Group_1__0__Impl rule__GitHubVersionRequirement__Group_1__1 ; - public final void rule__GitHubVersionRequirement__Group_1__0() throws RecognitionException { + // $ANTLR start "rule__GitHubVersionRequirement__Group__0" + // InternalSemver.g:2354:1: rule__GitHubVersionRequirement__Group__0 : rule__GitHubVersionRequirement__Group__0__Impl rule__GitHubVersionRequirement__Group__1 ; + public final void rule__GitHubVersionRequirement__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2194:1: ( rule__GitHubVersionRequirement__Group_1__0__Impl rule__GitHubVersionRequirement__Group_1__1 ) - // InternalSemver.g:2195:2: rule__GitHubVersionRequirement__Group_1__0__Impl rule__GitHubVersionRequirement__Group_1__1 + // InternalSemver.g:2358:1: ( rule__GitHubVersionRequirement__Group__0__Impl rule__GitHubVersionRequirement__Group__1 ) + // InternalSemver.g:2359:2: rule__GitHubVersionRequirement__Group__0__Impl rule__GitHubVersionRequirement__Group__1 { - pushFollow(FOLLOW_11); - rule__GitHubVersionRequirement__Group_1__0__Impl(); + pushFollow(FOLLOW_10); + rule__GitHubVersionRequirement__Group__0__Impl(); state._fsp--; if (state.failed) return ; pushFollow(FOLLOW_2); - rule__GitHubVersionRequirement__Group_1__1(); + rule__GitHubVersionRequirement__Group__1(); + + state._fsp--; + if (state.failed) return ; + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__GitHubVersionRequirement__Group__0" + + + // $ANTLR start "rule__GitHubVersionRequirement__Group__0__Impl" + // InternalSemver.g:2366:1: rule__GitHubVersionRequirement__Group__0__Impl : ( ( rule__GitHubVersionRequirement__GithubUrlAssignment_0 ) ) ; + public final void rule__GitHubVersionRequirement__Group__0__Impl() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:2370:1: ( ( ( rule__GitHubVersionRequirement__GithubUrlAssignment_0 ) ) ) + // InternalSemver.g:2371:1: ( ( rule__GitHubVersionRequirement__GithubUrlAssignment_0 ) ) + { + // InternalSemver.g:2371:1: ( ( rule__GitHubVersionRequirement__GithubUrlAssignment_0 ) ) + // InternalSemver.g:2372:2: ( rule__GitHubVersionRequirement__GithubUrlAssignment_0 ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getGitHubVersionRequirementAccess().getGithubUrlAssignment_0()); + } + // InternalSemver.g:2373:2: ( rule__GitHubVersionRequirement__GithubUrlAssignment_0 ) + // InternalSemver.g:2373:3: rule__GitHubVersionRequirement__GithubUrlAssignment_0 + { + pushFollow(FOLLOW_2); + rule__GitHubVersionRequirement__GithubUrlAssignment_0(); + + state._fsp--; + if (state.failed) return ; + + } + + if ( state.backtracking==0 ) { + after(grammarAccess.getGitHubVersionRequirementAccess().getGithubUrlAssignment_0()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__GitHubVersionRequirement__Group__0__Impl" + + + // $ANTLR start "rule__GitHubVersionRequirement__Group__1" + // InternalSemver.g:2381:1: rule__GitHubVersionRequirement__Group__1 : rule__GitHubVersionRequirement__Group__1__Impl ; + public final void rule__GitHubVersionRequirement__Group__1() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:2385:1: ( rule__GitHubVersionRequirement__Group__1__Impl ) + // InternalSemver.g:2386:2: rule__GitHubVersionRequirement__Group__1__Impl + { + pushFollow(FOLLOW_2); + rule__GitHubVersionRequirement__Group__1__Impl(); + + state._fsp--; + if (state.failed) return ; + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__GitHubVersionRequirement__Group__1" + + + // $ANTLR start "rule__GitHubVersionRequirement__Group__1__Impl" + // InternalSemver.g:2392:1: rule__GitHubVersionRequirement__Group__1__Impl : ( ( rule__GitHubVersionRequirement__Group_1__0 )? ) ; + public final void rule__GitHubVersionRequirement__Group__1__Impl() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:2396:1: ( ( ( rule__GitHubVersionRequirement__Group_1__0 )? ) ) + // InternalSemver.g:2397:1: ( ( rule__GitHubVersionRequirement__Group_1__0 )? ) + { + // InternalSemver.g:2397:1: ( ( rule__GitHubVersionRequirement__Group_1__0 )? ) + // InternalSemver.g:2398:2: ( rule__GitHubVersionRequirement__Group_1__0 )? + { + if ( state.backtracking==0 ) { + before(grammarAccess.getGitHubVersionRequirementAccess().getGroup_1()); + } + // InternalSemver.g:2399:2: ( rule__GitHubVersionRequirement__Group_1__0 )? + int alt32=2; + int LA32_0 = input.LA(1); + + if ( (LA32_0==55) ) { + alt32=1; + } + switch (alt32) { + case 1 : + // InternalSemver.g:2399:3: rule__GitHubVersionRequirement__Group_1__0 + { + pushFollow(FOLLOW_2); + rule__GitHubVersionRequirement__Group_1__0(); + + state._fsp--; + if (state.failed) return ; + + } + break; + + } + + if ( state.backtracking==0 ) { + after(grammarAccess.getGitHubVersionRequirementAccess().getGroup_1()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__GitHubVersionRequirement__Group__1__Impl" + + + // $ANTLR start "rule__GitHubVersionRequirement__Group_1__0" + // InternalSemver.g:2408:1: rule__GitHubVersionRequirement__Group_1__0 : rule__GitHubVersionRequirement__Group_1__0__Impl rule__GitHubVersionRequirement__Group_1__1 ; + public final void rule__GitHubVersionRequirement__Group_1__0() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:2412:1: ( rule__GitHubVersionRequirement__Group_1__0__Impl rule__GitHubVersionRequirement__Group_1__1 ) + // InternalSemver.g:2413:2: rule__GitHubVersionRequirement__Group_1__0__Impl rule__GitHubVersionRequirement__Group_1__1 + { + pushFollow(FOLLOW_12); + rule__GitHubVersionRequirement__Group_1__0__Impl(); + + state._fsp--; + if (state.failed) return ; + pushFollow(FOLLOW_2); + rule__GitHubVersionRequirement__Group_1__1(); state._fsp--; if (state.failed) return ; @@ -7914,22 +8717,22 @@ public final void rule__GitHubVersionRequirement__Group_1__0() throws Recognitio // $ANTLR start "rule__GitHubVersionRequirement__Group_1__0__Impl" - // InternalSemver.g:2202:1: rule__GitHubVersionRequirement__Group_1__0__Impl : ( '#' ) ; + // InternalSemver.g:2420:1: rule__GitHubVersionRequirement__Group_1__0__Impl : ( '#' ) ; public final void rule__GitHubVersionRequirement__Group_1__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2206:1: ( ( '#' ) ) - // InternalSemver.g:2207:1: ( '#' ) + // InternalSemver.g:2424:1: ( ( '#' ) ) + // InternalSemver.g:2425:1: ( '#' ) { - // InternalSemver.g:2207:1: ( '#' ) - // InternalSemver.g:2208:2: '#' + // InternalSemver.g:2425:1: ( '#' ) + // InternalSemver.g:2426:2: '#' { if ( state.backtracking==0 ) { before(grammarAccess.getGitHubVersionRequirementAccess().getNumberSignKeyword_1_0()); } - match(input,49,FOLLOW_2); if (state.failed) return ; + match(input,55,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getGitHubVersionRequirementAccess().getNumberSignKeyword_1_0()); } @@ -7955,14 +8758,14 @@ public final void rule__GitHubVersionRequirement__Group_1__0__Impl() throws Reco // $ANTLR start "rule__GitHubVersionRequirement__Group_1__1" - // InternalSemver.g:2217:1: rule__GitHubVersionRequirement__Group_1__1 : rule__GitHubVersionRequirement__Group_1__1__Impl ; + // InternalSemver.g:2435:1: rule__GitHubVersionRequirement__Group_1__1 : rule__GitHubVersionRequirement__Group_1__1__Impl ; public final void rule__GitHubVersionRequirement__Group_1__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2221:1: ( rule__GitHubVersionRequirement__Group_1__1__Impl ) - // InternalSemver.g:2222:2: rule__GitHubVersionRequirement__Group_1__1__Impl + // InternalSemver.g:2439:1: ( rule__GitHubVersionRequirement__Group_1__1__Impl ) + // InternalSemver.g:2440:2: rule__GitHubVersionRequirement__Group_1__1__Impl { pushFollow(FOLLOW_2); rule__GitHubVersionRequirement__Group_1__1__Impl(); @@ -7988,23 +8791,23 @@ public final void rule__GitHubVersionRequirement__Group_1__1() throws Recognitio // $ANTLR start "rule__GitHubVersionRequirement__Group_1__1__Impl" - // InternalSemver.g:2228:1: rule__GitHubVersionRequirement__Group_1__1__Impl : ( ( rule__GitHubVersionRequirement__CommitISHAssignment_1_1 ) ) ; + // InternalSemver.g:2446:1: rule__GitHubVersionRequirement__Group_1__1__Impl : ( ( rule__GitHubVersionRequirement__CommitISHAssignment_1_1 ) ) ; public final void rule__GitHubVersionRequirement__Group_1__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2232:1: ( ( ( rule__GitHubVersionRequirement__CommitISHAssignment_1_1 ) ) ) - // InternalSemver.g:2233:1: ( ( rule__GitHubVersionRequirement__CommitISHAssignment_1_1 ) ) + // InternalSemver.g:2450:1: ( ( ( rule__GitHubVersionRequirement__CommitISHAssignment_1_1 ) ) ) + // InternalSemver.g:2451:1: ( ( rule__GitHubVersionRequirement__CommitISHAssignment_1_1 ) ) { - // InternalSemver.g:2233:1: ( ( rule__GitHubVersionRequirement__CommitISHAssignment_1_1 ) ) - // InternalSemver.g:2234:2: ( rule__GitHubVersionRequirement__CommitISHAssignment_1_1 ) + // InternalSemver.g:2451:1: ( ( rule__GitHubVersionRequirement__CommitISHAssignment_1_1 ) ) + // InternalSemver.g:2452:2: ( rule__GitHubVersionRequirement__CommitISHAssignment_1_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getGitHubVersionRequirementAccess().getCommitISHAssignment_1_1()); } - // InternalSemver.g:2235:2: ( rule__GitHubVersionRequirement__CommitISHAssignment_1_1 ) - // InternalSemver.g:2235:3: rule__GitHubVersionRequirement__CommitISHAssignment_1_1 + // InternalSemver.g:2453:2: ( rule__GitHubVersionRequirement__CommitISHAssignment_1_1 ) + // InternalSemver.g:2453:3: rule__GitHubVersionRequirement__CommitISHAssignment_1_1 { pushFollow(FOLLOW_2); rule__GitHubVersionRequirement__CommitISHAssignment_1_1(); @@ -8039,16 +8842,16 @@ public final void rule__GitHubVersionRequirement__Group_1__1__Impl() throws Reco // $ANTLR start "rule__VersionRangeSetRequirement__Group__0" - // InternalSemver.g:2244:1: rule__VersionRangeSetRequirement__Group__0 : rule__VersionRangeSetRequirement__Group__0__Impl rule__VersionRangeSetRequirement__Group__1 ; + // InternalSemver.g:2462:1: rule__VersionRangeSetRequirement__Group__0 : rule__VersionRangeSetRequirement__Group__0__Impl rule__VersionRangeSetRequirement__Group__1 ; public final void rule__VersionRangeSetRequirement__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2248:1: ( rule__VersionRangeSetRequirement__Group__0__Impl rule__VersionRangeSetRequirement__Group__1 ) - // InternalSemver.g:2249:2: rule__VersionRangeSetRequirement__Group__0__Impl rule__VersionRangeSetRequirement__Group__1 + // InternalSemver.g:2466:1: ( rule__VersionRangeSetRequirement__Group__0__Impl rule__VersionRangeSetRequirement__Group__1 ) + // InternalSemver.g:2467:2: rule__VersionRangeSetRequirement__Group__0__Impl rule__VersionRangeSetRequirement__Group__1 { - pushFollow(FOLLOW_4); + pushFollow(FOLLOW_5); rule__VersionRangeSetRequirement__Group__0__Impl(); state._fsp--; @@ -8077,23 +8880,23 @@ public final void rule__VersionRangeSetRequirement__Group__0() throws Recognitio // $ANTLR start "rule__VersionRangeSetRequirement__Group__0__Impl" - // InternalSemver.g:2256:1: rule__VersionRangeSetRequirement__Group__0__Impl : ( () ) ; + // InternalSemver.g:2474:1: rule__VersionRangeSetRequirement__Group__0__Impl : ( () ) ; public final void rule__VersionRangeSetRequirement__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2260:1: ( ( () ) ) - // InternalSemver.g:2261:1: ( () ) + // InternalSemver.g:2478:1: ( ( () ) ) + // InternalSemver.g:2479:1: ( () ) { - // InternalSemver.g:2261:1: ( () ) - // InternalSemver.g:2262:2: () + // InternalSemver.g:2479:1: ( () ) + // InternalSemver.g:2480:2: () { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeSetRequirementAccess().getVersionRangeSetRequirementAction_0()); } - // InternalSemver.g:2263:2: () - // InternalSemver.g:2263:3: + // InternalSemver.g:2481:2: () + // InternalSemver.g:2481:3: { } @@ -8118,14 +8921,14 @@ public final void rule__VersionRangeSetRequirement__Group__0__Impl() throws Reco // $ANTLR start "rule__VersionRangeSetRequirement__Group__1" - // InternalSemver.g:2271:1: rule__VersionRangeSetRequirement__Group__1 : rule__VersionRangeSetRequirement__Group__1__Impl ; + // InternalSemver.g:2489:1: rule__VersionRangeSetRequirement__Group__1 : rule__VersionRangeSetRequirement__Group__1__Impl ; public final void rule__VersionRangeSetRequirement__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2275:1: ( rule__VersionRangeSetRequirement__Group__1__Impl ) - // InternalSemver.g:2276:2: rule__VersionRangeSetRequirement__Group__1__Impl + // InternalSemver.g:2493:1: ( rule__VersionRangeSetRequirement__Group__1__Impl ) + // InternalSemver.g:2494:2: rule__VersionRangeSetRequirement__Group__1__Impl { pushFollow(FOLLOW_2); rule__VersionRangeSetRequirement__Group__1__Impl(); @@ -8151,31 +8954,31 @@ public final void rule__VersionRangeSetRequirement__Group__1() throws Recognitio // $ANTLR start "rule__VersionRangeSetRequirement__Group__1__Impl" - // InternalSemver.g:2282:1: rule__VersionRangeSetRequirement__Group__1__Impl : ( ( rule__VersionRangeSetRequirement__Group_1__0 )? ) ; + // InternalSemver.g:2500:1: rule__VersionRangeSetRequirement__Group__1__Impl : ( ( rule__VersionRangeSetRequirement__Group_1__0 )? ) ; public final void rule__VersionRangeSetRequirement__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2286:1: ( ( ( rule__VersionRangeSetRequirement__Group_1__0 )? ) ) - // InternalSemver.g:2287:1: ( ( rule__VersionRangeSetRequirement__Group_1__0 )? ) + // InternalSemver.g:2504:1: ( ( ( rule__VersionRangeSetRequirement__Group_1__0 )? ) ) + // InternalSemver.g:2505:1: ( ( rule__VersionRangeSetRequirement__Group_1__0 )? ) { - // InternalSemver.g:2287:1: ( ( rule__VersionRangeSetRequirement__Group_1__0 )? ) - // InternalSemver.g:2288:2: ( rule__VersionRangeSetRequirement__Group_1__0 )? + // InternalSemver.g:2505:1: ( ( rule__VersionRangeSetRequirement__Group_1__0 )? ) + // InternalSemver.g:2506:2: ( rule__VersionRangeSetRequirement__Group_1__0 )? { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeSetRequirementAccess().getGroup_1()); } - // InternalSemver.g:2289:2: ( rule__VersionRangeSetRequirement__Group_1__0 )? - int alt31=2; - int LA31_0 = input.LA(1); + // InternalSemver.g:2507:2: ( rule__VersionRangeSetRequirement__Group_1__0 )? + int alt33=2; + int LA33_0 = input.LA(1); - if ( ((LA31_0>=RULE_DIGITS && LA31_0<=RULE_LETTER_V)||(LA31_0>=42 && LA31_0<=48)) ) { - alt31=1; + if ( ((LA33_0>=RULE_ASTERIX && LA33_0<=RULE_LETTER_V)||(LA33_0>=48 && LA33_0<=54)) ) { + alt33=1; } - switch (alt31) { + switch (alt33) { case 1 : - // InternalSemver.g:2289:3: rule__VersionRangeSetRequirement__Group_1__0 + // InternalSemver.g:2507:3: rule__VersionRangeSetRequirement__Group_1__0 { pushFollow(FOLLOW_2); rule__VersionRangeSetRequirement__Group_1__0(); @@ -8213,16 +9016,16 @@ public final void rule__VersionRangeSetRequirement__Group__1__Impl() throws Reco // $ANTLR start "rule__VersionRangeSetRequirement__Group_1__0" - // InternalSemver.g:2298:1: rule__VersionRangeSetRequirement__Group_1__0 : rule__VersionRangeSetRequirement__Group_1__0__Impl rule__VersionRangeSetRequirement__Group_1__1 ; + // InternalSemver.g:2516:1: rule__VersionRangeSetRequirement__Group_1__0 : rule__VersionRangeSetRequirement__Group_1__0__Impl rule__VersionRangeSetRequirement__Group_1__1 ; public final void rule__VersionRangeSetRequirement__Group_1__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2302:1: ( rule__VersionRangeSetRequirement__Group_1__0__Impl rule__VersionRangeSetRequirement__Group_1__1 ) - // InternalSemver.g:2303:2: rule__VersionRangeSetRequirement__Group_1__0__Impl rule__VersionRangeSetRequirement__Group_1__1 + // InternalSemver.g:2520:1: ( rule__VersionRangeSetRequirement__Group_1__0__Impl rule__VersionRangeSetRequirement__Group_1__1 ) + // InternalSemver.g:2521:2: rule__VersionRangeSetRequirement__Group_1__0__Impl rule__VersionRangeSetRequirement__Group_1__1 { - pushFollow(FOLLOW_14); + pushFollow(FOLLOW_16); rule__VersionRangeSetRequirement__Group_1__0__Impl(); state._fsp--; @@ -8251,23 +9054,23 @@ public final void rule__VersionRangeSetRequirement__Group_1__0() throws Recognit // $ANTLR start "rule__VersionRangeSetRequirement__Group_1__0__Impl" - // InternalSemver.g:2310:1: rule__VersionRangeSetRequirement__Group_1__0__Impl : ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_0 ) ) ; + // InternalSemver.g:2528:1: rule__VersionRangeSetRequirement__Group_1__0__Impl : ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_0 ) ) ; public final void rule__VersionRangeSetRequirement__Group_1__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2314:1: ( ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_0 ) ) ) - // InternalSemver.g:2315:1: ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_0 ) ) + // InternalSemver.g:2532:1: ( ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_0 ) ) ) + // InternalSemver.g:2533:1: ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_0 ) ) { - // InternalSemver.g:2315:1: ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_0 ) ) - // InternalSemver.g:2316:2: ( rule__VersionRangeSetRequirement__RangesAssignment_1_0 ) + // InternalSemver.g:2533:1: ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_0 ) ) + // InternalSemver.g:2534:2: ( rule__VersionRangeSetRequirement__RangesAssignment_1_0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeSetRequirementAccess().getRangesAssignment_1_0()); } - // InternalSemver.g:2317:2: ( rule__VersionRangeSetRequirement__RangesAssignment_1_0 ) - // InternalSemver.g:2317:3: rule__VersionRangeSetRequirement__RangesAssignment_1_0 + // InternalSemver.g:2535:2: ( rule__VersionRangeSetRequirement__RangesAssignment_1_0 ) + // InternalSemver.g:2535:3: rule__VersionRangeSetRequirement__RangesAssignment_1_0 { pushFollow(FOLLOW_2); rule__VersionRangeSetRequirement__RangesAssignment_1_0(); @@ -8302,16 +9105,16 @@ public final void rule__VersionRangeSetRequirement__Group_1__0__Impl() throws Re // $ANTLR start "rule__VersionRangeSetRequirement__Group_1__1" - // InternalSemver.g:2325:1: rule__VersionRangeSetRequirement__Group_1__1 : rule__VersionRangeSetRequirement__Group_1__1__Impl rule__VersionRangeSetRequirement__Group_1__2 ; + // InternalSemver.g:2543:1: rule__VersionRangeSetRequirement__Group_1__1 : rule__VersionRangeSetRequirement__Group_1__1__Impl rule__VersionRangeSetRequirement__Group_1__2 ; public final void rule__VersionRangeSetRequirement__Group_1__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2329:1: ( rule__VersionRangeSetRequirement__Group_1__1__Impl rule__VersionRangeSetRequirement__Group_1__2 ) - // InternalSemver.g:2330:2: rule__VersionRangeSetRequirement__Group_1__1__Impl rule__VersionRangeSetRequirement__Group_1__2 + // InternalSemver.g:2547:1: ( rule__VersionRangeSetRequirement__Group_1__1__Impl rule__VersionRangeSetRequirement__Group_1__2 ) + // InternalSemver.g:2548:2: rule__VersionRangeSetRequirement__Group_1__1__Impl rule__VersionRangeSetRequirement__Group_1__2 { - pushFollow(FOLLOW_14); + pushFollow(FOLLOW_16); rule__VersionRangeSetRequirement__Group_1__1__Impl(); state._fsp--; @@ -8340,46 +9143,46 @@ public final void rule__VersionRangeSetRequirement__Group_1__1() throws Recognit // $ANTLR start "rule__VersionRangeSetRequirement__Group_1__1__Impl" - // InternalSemver.g:2337:1: rule__VersionRangeSetRequirement__Group_1__1__Impl : ( ( rule__VersionRangeSetRequirement__Group_1_1__0 )* ) ; + // InternalSemver.g:2555:1: rule__VersionRangeSetRequirement__Group_1__1__Impl : ( ( rule__VersionRangeSetRequirement__Group_1_1__0 )* ) ; public final void rule__VersionRangeSetRequirement__Group_1__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2341:1: ( ( ( rule__VersionRangeSetRequirement__Group_1_1__0 )* ) ) - // InternalSemver.g:2342:1: ( ( rule__VersionRangeSetRequirement__Group_1_1__0 )* ) + // InternalSemver.g:2559:1: ( ( ( rule__VersionRangeSetRequirement__Group_1_1__0 )* ) ) + // InternalSemver.g:2560:1: ( ( rule__VersionRangeSetRequirement__Group_1_1__0 )* ) { - // InternalSemver.g:2342:1: ( ( rule__VersionRangeSetRequirement__Group_1_1__0 )* ) - // InternalSemver.g:2343:2: ( rule__VersionRangeSetRequirement__Group_1_1__0 )* + // InternalSemver.g:2560:1: ( ( rule__VersionRangeSetRequirement__Group_1_1__0 )* ) + // InternalSemver.g:2561:2: ( rule__VersionRangeSetRequirement__Group_1_1__0 )* { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeSetRequirementAccess().getGroup_1_1()); } - // InternalSemver.g:2344:2: ( rule__VersionRangeSetRequirement__Group_1_1__0 )* - loop32: + // InternalSemver.g:2562:2: ( rule__VersionRangeSetRequirement__Group_1_1__0 )* + loop34: do { - int alt32=2; - int LA32_0 = input.LA(1); + int alt34=2; + int LA34_0 = input.LA(1); - if ( (LA32_0==RULE_WS) ) { - int LA32_1 = input.LA(2); + if ( (LA34_0==RULE_WS) ) { + int LA34_1 = input.LA(2); - if ( (LA32_1==50) ) { - alt32=1; + if ( (LA34_1==56) ) { + alt34=1; } } - else if ( (LA32_0==50) ) { - alt32=1; + else if ( (LA34_0==56) ) { + alt34=1; } - switch (alt32) { + switch (alt34) { case 1 : - // InternalSemver.g:2344:3: rule__VersionRangeSetRequirement__Group_1_1__0 + // InternalSemver.g:2562:3: rule__VersionRangeSetRequirement__Group_1_1__0 { - pushFollow(FOLLOW_15); + pushFollow(FOLLOW_17); rule__VersionRangeSetRequirement__Group_1_1__0(); state._fsp--; @@ -8389,7 +9192,7 @@ else if ( (LA32_0==50) ) { break; default : - break loop32; + break loop34; } } while (true); @@ -8418,14 +9221,14 @@ else if ( (LA32_0==50) ) { // $ANTLR start "rule__VersionRangeSetRequirement__Group_1__2" - // InternalSemver.g:2352:1: rule__VersionRangeSetRequirement__Group_1__2 : rule__VersionRangeSetRequirement__Group_1__2__Impl ; + // InternalSemver.g:2570:1: rule__VersionRangeSetRequirement__Group_1__2 : rule__VersionRangeSetRequirement__Group_1__2__Impl ; public final void rule__VersionRangeSetRequirement__Group_1__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2356:1: ( rule__VersionRangeSetRequirement__Group_1__2__Impl ) - // InternalSemver.g:2357:2: rule__VersionRangeSetRequirement__Group_1__2__Impl + // InternalSemver.g:2574:1: ( rule__VersionRangeSetRequirement__Group_1__2__Impl ) + // InternalSemver.g:2575:2: rule__VersionRangeSetRequirement__Group_1__2__Impl { pushFollow(FOLLOW_2); rule__VersionRangeSetRequirement__Group_1__2__Impl(); @@ -8451,31 +9254,31 @@ public final void rule__VersionRangeSetRequirement__Group_1__2() throws Recognit // $ANTLR start "rule__VersionRangeSetRequirement__Group_1__2__Impl" - // InternalSemver.g:2363:1: rule__VersionRangeSetRequirement__Group_1__2__Impl : ( ( RULE_WS )? ) ; + // InternalSemver.g:2581:1: rule__VersionRangeSetRequirement__Group_1__2__Impl : ( ( RULE_WS )? ) ; public final void rule__VersionRangeSetRequirement__Group_1__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2367:1: ( ( ( RULE_WS )? ) ) - // InternalSemver.g:2368:1: ( ( RULE_WS )? ) + // InternalSemver.g:2585:1: ( ( ( RULE_WS )? ) ) + // InternalSemver.g:2586:1: ( ( RULE_WS )? ) { - // InternalSemver.g:2368:1: ( ( RULE_WS )? ) - // InternalSemver.g:2369:2: ( RULE_WS )? + // InternalSemver.g:2586:1: ( ( RULE_WS )? ) + // InternalSemver.g:2587:2: ( RULE_WS )? { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeSetRequirementAccess().getWSTerminalRuleCall_1_2()); } - // InternalSemver.g:2370:2: ( RULE_WS )? - int alt33=2; - int LA33_0 = input.LA(1); + // InternalSemver.g:2588:2: ( RULE_WS )? + int alt35=2; + int LA35_0 = input.LA(1); - if ( (LA33_0==RULE_WS) ) { - alt33=1; + if ( (LA35_0==RULE_WS) ) { + alt35=1; } - switch (alt33) { + switch (alt35) { case 1 : - // InternalSemver.g:2370:3: RULE_WS + // InternalSemver.g:2588:3: RULE_WS { match(input,RULE_WS,FOLLOW_2); if (state.failed) return ; @@ -8509,16 +9312,16 @@ public final void rule__VersionRangeSetRequirement__Group_1__2__Impl() throws Re // $ANTLR start "rule__VersionRangeSetRequirement__Group_1_1__0" - // InternalSemver.g:2379:1: rule__VersionRangeSetRequirement__Group_1_1__0 : rule__VersionRangeSetRequirement__Group_1_1__0__Impl rule__VersionRangeSetRequirement__Group_1_1__1 ; + // InternalSemver.g:2597:1: rule__VersionRangeSetRequirement__Group_1_1__0 : rule__VersionRangeSetRequirement__Group_1_1__0__Impl rule__VersionRangeSetRequirement__Group_1_1__1 ; public final void rule__VersionRangeSetRequirement__Group_1_1__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2383:1: ( rule__VersionRangeSetRequirement__Group_1_1__0__Impl rule__VersionRangeSetRequirement__Group_1_1__1 ) - // InternalSemver.g:2384:2: rule__VersionRangeSetRequirement__Group_1_1__0__Impl rule__VersionRangeSetRequirement__Group_1_1__1 + // InternalSemver.g:2601:1: ( rule__VersionRangeSetRequirement__Group_1_1__0__Impl rule__VersionRangeSetRequirement__Group_1_1__1 ) + // InternalSemver.g:2602:2: rule__VersionRangeSetRequirement__Group_1_1__0__Impl rule__VersionRangeSetRequirement__Group_1_1__1 { - pushFollow(FOLLOW_14); + pushFollow(FOLLOW_16); rule__VersionRangeSetRequirement__Group_1_1__0__Impl(); state._fsp--; @@ -8547,31 +9350,31 @@ public final void rule__VersionRangeSetRequirement__Group_1_1__0() throws Recogn // $ANTLR start "rule__VersionRangeSetRequirement__Group_1_1__0__Impl" - // InternalSemver.g:2391:1: rule__VersionRangeSetRequirement__Group_1_1__0__Impl : ( ( RULE_WS )? ) ; + // InternalSemver.g:2609:1: rule__VersionRangeSetRequirement__Group_1_1__0__Impl : ( ( RULE_WS )? ) ; public final void rule__VersionRangeSetRequirement__Group_1_1__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2395:1: ( ( ( RULE_WS )? ) ) - // InternalSemver.g:2396:1: ( ( RULE_WS )? ) + // InternalSemver.g:2613:1: ( ( ( RULE_WS )? ) ) + // InternalSemver.g:2614:1: ( ( RULE_WS )? ) { - // InternalSemver.g:2396:1: ( ( RULE_WS )? ) - // InternalSemver.g:2397:2: ( RULE_WS )? + // InternalSemver.g:2614:1: ( ( RULE_WS )? ) + // InternalSemver.g:2615:2: ( RULE_WS )? { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeSetRequirementAccess().getWSTerminalRuleCall_1_1_0()); } - // InternalSemver.g:2398:2: ( RULE_WS )? - int alt34=2; - int LA34_0 = input.LA(1); + // InternalSemver.g:2616:2: ( RULE_WS )? + int alt36=2; + int LA36_0 = input.LA(1); - if ( (LA34_0==RULE_WS) ) { - alt34=1; + if ( (LA36_0==RULE_WS) ) { + alt36=1; } - switch (alt34) { + switch (alt36) { case 1 : - // InternalSemver.g:2398:3: RULE_WS + // InternalSemver.g:2616:3: RULE_WS { match(input,RULE_WS,FOLLOW_2); if (state.failed) return ; @@ -8605,16 +9408,16 @@ public final void rule__VersionRangeSetRequirement__Group_1_1__0__Impl() throws // $ANTLR start "rule__VersionRangeSetRequirement__Group_1_1__1" - // InternalSemver.g:2406:1: rule__VersionRangeSetRequirement__Group_1_1__1 : rule__VersionRangeSetRequirement__Group_1_1__1__Impl rule__VersionRangeSetRequirement__Group_1_1__2 ; + // InternalSemver.g:2624:1: rule__VersionRangeSetRequirement__Group_1_1__1 : rule__VersionRangeSetRequirement__Group_1_1__1__Impl rule__VersionRangeSetRequirement__Group_1_1__2 ; public final void rule__VersionRangeSetRequirement__Group_1_1__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2410:1: ( rule__VersionRangeSetRequirement__Group_1_1__1__Impl rule__VersionRangeSetRequirement__Group_1_1__2 ) - // InternalSemver.g:2411:2: rule__VersionRangeSetRequirement__Group_1_1__1__Impl rule__VersionRangeSetRequirement__Group_1_1__2 + // InternalSemver.g:2628:1: ( rule__VersionRangeSetRequirement__Group_1_1__1__Impl rule__VersionRangeSetRequirement__Group_1_1__2 ) + // InternalSemver.g:2629:2: rule__VersionRangeSetRequirement__Group_1_1__1__Impl rule__VersionRangeSetRequirement__Group_1_1__2 { - pushFollow(FOLLOW_16); + pushFollow(FOLLOW_18); rule__VersionRangeSetRequirement__Group_1_1__1__Impl(); state._fsp--; @@ -8643,22 +9446,22 @@ public final void rule__VersionRangeSetRequirement__Group_1_1__1() throws Recogn // $ANTLR start "rule__VersionRangeSetRequirement__Group_1_1__1__Impl" - // InternalSemver.g:2418:1: rule__VersionRangeSetRequirement__Group_1_1__1__Impl : ( '||' ) ; + // InternalSemver.g:2636:1: rule__VersionRangeSetRequirement__Group_1_1__1__Impl : ( '||' ) ; public final void rule__VersionRangeSetRequirement__Group_1_1__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2422:1: ( ( '||' ) ) - // InternalSemver.g:2423:1: ( '||' ) + // InternalSemver.g:2640:1: ( ( '||' ) ) + // InternalSemver.g:2641:1: ( '||' ) { - // InternalSemver.g:2423:1: ( '||' ) - // InternalSemver.g:2424:2: '||' + // InternalSemver.g:2641:1: ( '||' ) + // InternalSemver.g:2642:2: '||' { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeSetRequirementAccess().getVerticalLineVerticalLineKeyword_1_1_1()); } - match(input,50,FOLLOW_2); if (state.failed) return ; + match(input,56,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getVersionRangeSetRequirementAccess().getVerticalLineVerticalLineKeyword_1_1_1()); } @@ -8684,16 +9487,16 @@ public final void rule__VersionRangeSetRequirement__Group_1_1__1__Impl() throws // $ANTLR start "rule__VersionRangeSetRequirement__Group_1_1__2" - // InternalSemver.g:2433:1: rule__VersionRangeSetRequirement__Group_1_1__2 : rule__VersionRangeSetRequirement__Group_1_1__2__Impl rule__VersionRangeSetRequirement__Group_1_1__3 ; + // InternalSemver.g:2651:1: rule__VersionRangeSetRequirement__Group_1_1__2 : rule__VersionRangeSetRequirement__Group_1_1__2__Impl rule__VersionRangeSetRequirement__Group_1_1__3 ; public final void rule__VersionRangeSetRequirement__Group_1_1__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2437:1: ( rule__VersionRangeSetRequirement__Group_1_1__2__Impl rule__VersionRangeSetRequirement__Group_1_1__3 ) - // InternalSemver.g:2438:2: rule__VersionRangeSetRequirement__Group_1_1__2__Impl rule__VersionRangeSetRequirement__Group_1_1__3 + // InternalSemver.g:2655:1: ( rule__VersionRangeSetRequirement__Group_1_1__2__Impl rule__VersionRangeSetRequirement__Group_1_1__3 ) + // InternalSemver.g:2656:2: rule__VersionRangeSetRequirement__Group_1_1__2__Impl rule__VersionRangeSetRequirement__Group_1_1__3 { - pushFollow(FOLLOW_16); + pushFollow(FOLLOW_18); rule__VersionRangeSetRequirement__Group_1_1__2__Impl(); state._fsp--; @@ -8722,31 +9525,31 @@ public final void rule__VersionRangeSetRequirement__Group_1_1__2() throws Recogn // $ANTLR start "rule__VersionRangeSetRequirement__Group_1_1__2__Impl" - // InternalSemver.g:2445:1: rule__VersionRangeSetRequirement__Group_1_1__2__Impl : ( ( RULE_WS )? ) ; + // InternalSemver.g:2663:1: rule__VersionRangeSetRequirement__Group_1_1__2__Impl : ( ( RULE_WS )? ) ; public final void rule__VersionRangeSetRequirement__Group_1_1__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2449:1: ( ( ( RULE_WS )? ) ) - // InternalSemver.g:2450:1: ( ( RULE_WS )? ) + // InternalSemver.g:2667:1: ( ( ( RULE_WS )? ) ) + // InternalSemver.g:2668:1: ( ( RULE_WS )? ) { - // InternalSemver.g:2450:1: ( ( RULE_WS )? ) - // InternalSemver.g:2451:2: ( RULE_WS )? + // InternalSemver.g:2668:1: ( ( RULE_WS )? ) + // InternalSemver.g:2669:2: ( RULE_WS )? { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeSetRequirementAccess().getWSTerminalRuleCall_1_1_2()); } - // InternalSemver.g:2452:2: ( RULE_WS )? - int alt35=2; - int LA35_0 = input.LA(1); + // InternalSemver.g:2670:2: ( RULE_WS )? + int alt37=2; + int LA37_0 = input.LA(1); - if ( (LA35_0==RULE_WS) ) { - alt35=1; + if ( (LA37_0==RULE_WS) ) { + alt37=1; } - switch (alt35) { + switch (alt37) { case 1 : - // InternalSemver.g:2452:3: RULE_WS + // InternalSemver.g:2670:3: RULE_WS { match(input,RULE_WS,FOLLOW_2); if (state.failed) return ; @@ -8780,14 +9583,14 @@ public final void rule__VersionRangeSetRequirement__Group_1_1__2__Impl() throws // $ANTLR start "rule__VersionRangeSetRequirement__Group_1_1__3" - // InternalSemver.g:2460:1: rule__VersionRangeSetRequirement__Group_1_1__3 : rule__VersionRangeSetRequirement__Group_1_1__3__Impl ; + // InternalSemver.g:2678:1: rule__VersionRangeSetRequirement__Group_1_1__3 : rule__VersionRangeSetRequirement__Group_1_1__3__Impl ; public final void rule__VersionRangeSetRequirement__Group_1_1__3() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2464:1: ( rule__VersionRangeSetRequirement__Group_1_1__3__Impl ) - // InternalSemver.g:2465:2: rule__VersionRangeSetRequirement__Group_1_1__3__Impl + // InternalSemver.g:2682:1: ( rule__VersionRangeSetRequirement__Group_1_1__3__Impl ) + // InternalSemver.g:2683:2: rule__VersionRangeSetRequirement__Group_1_1__3__Impl { pushFollow(FOLLOW_2); rule__VersionRangeSetRequirement__Group_1_1__3__Impl(); @@ -8813,23 +9616,23 @@ public final void rule__VersionRangeSetRequirement__Group_1_1__3() throws Recogn // $ANTLR start "rule__VersionRangeSetRequirement__Group_1_1__3__Impl" - // InternalSemver.g:2471:1: rule__VersionRangeSetRequirement__Group_1_1__3__Impl : ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 ) ) ; + // InternalSemver.g:2689:1: rule__VersionRangeSetRequirement__Group_1_1__3__Impl : ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 ) ) ; public final void rule__VersionRangeSetRequirement__Group_1_1__3__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2475:1: ( ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 ) ) ) - // InternalSemver.g:2476:1: ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 ) ) + // InternalSemver.g:2693:1: ( ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 ) ) ) + // InternalSemver.g:2694:1: ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 ) ) { - // InternalSemver.g:2476:1: ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 ) ) - // InternalSemver.g:2477:2: ( rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 ) + // InternalSemver.g:2694:1: ( ( rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 ) ) + // InternalSemver.g:2695:2: ( rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeSetRequirementAccess().getRangesAssignment_1_1_3()); } - // InternalSemver.g:2478:2: ( rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 ) - // InternalSemver.g:2478:3: rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 + // InternalSemver.g:2696:2: ( rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 ) + // InternalSemver.g:2696:3: rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 { pushFollow(FOLLOW_2); rule__VersionRangeSetRequirement__RangesAssignment_1_1_3(); @@ -8864,16 +9667,16 @@ public final void rule__VersionRangeSetRequirement__Group_1_1__3__Impl() throws // $ANTLR start "rule__HyphenVersionRange__Group__0" - // InternalSemver.g:2487:1: rule__HyphenVersionRange__Group__0 : rule__HyphenVersionRange__Group__0__Impl rule__HyphenVersionRange__Group__1 ; + // InternalSemver.g:2705:1: rule__HyphenVersionRange__Group__0 : rule__HyphenVersionRange__Group__0__Impl rule__HyphenVersionRange__Group__1 ; public final void rule__HyphenVersionRange__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2491:1: ( rule__HyphenVersionRange__Group__0__Impl rule__HyphenVersionRange__Group__1 ) - // InternalSemver.g:2492:2: rule__HyphenVersionRange__Group__0__Impl rule__HyphenVersionRange__Group__1 + // InternalSemver.g:2709:1: ( rule__HyphenVersionRange__Group__0__Impl rule__HyphenVersionRange__Group__1 ) + // InternalSemver.g:2710:2: rule__HyphenVersionRange__Group__0__Impl rule__HyphenVersionRange__Group__1 { - pushFollow(FOLLOW_4); + pushFollow(FOLLOW_5); rule__HyphenVersionRange__Group__0__Impl(); state._fsp--; @@ -8902,23 +9705,23 @@ public final void rule__HyphenVersionRange__Group__0() throws RecognitionExcepti // $ANTLR start "rule__HyphenVersionRange__Group__0__Impl" - // InternalSemver.g:2499:1: rule__HyphenVersionRange__Group__0__Impl : ( () ) ; + // InternalSemver.g:2717:1: rule__HyphenVersionRange__Group__0__Impl : ( () ) ; public final void rule__HyphenVersionRange__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2503:1: ( ( () ) ) - // InternalSemver.g:2504:1: ( () ) + // InternalSemver.g:2721:1: ( ( () ) ) + // InternalSemver.g:2722:1: ( () ) { - // InternalSemver.g:2504:1: ( () ) - // InternalSemver.g:2505:2: () + // InternalSemver.g:2722:1: ( () ) + // InternalSemver.g:2723:2: () { if ( state.backtracking==0 ) { before(grammarAccess.getHyphenVersionRangeAccess().getHyphenVersionRangeAction_0()); } - // InternalSemver.g:2506:2: () - // InternalSemver.g:2506:3: + // InternalSemver.g:2724:2: () + // InternalSemver.g:2724:3: { } @@ -8943,16 +9746,16 @@ public final void rule__HyphenVersionRange__Group__0__Impl() throws RecognitionE // $ANTLR start "rule__HyphenVersionRange__Group__1" - // InternalSemver.g:2514:1: rule__HyphenVersionRange__Group__1 : rule__HyphenVersionRange__Group__1__Impl rule__HyphenVersionRange__Group__2 ; + // InternalSemver.g:2732:1: rule__HyphenVersionRange__Group__1 : rule__HyphenVersionRange__Group__1__Impl rule__HyphenVersionRange__Group__2 ; public final void rule__HyphenVersionRange__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2518:1: ( rule__HyphenVersionRange__Group__1__Impl rule__HyphenVersionRange__Group__2 ) - // InternalSemver.g:2519:2: rule__HyphenVersionRange__Group__1__Impl rule__HyphenVersionRange__Group__2 + // InternalSemver.g:2736:1: ( rule__HyphenVersionRange__Group__1__Impl rule__HyphenVersionRange__Group__2 ) + // InternalSemver.g:2737:2: rule__HyphenVersionRange__Group__1__Impl rule__HyphenVersionRange__Group__2 { - pushFollow(FOLLOW_5); + pushFollow(FOLLOW_6); rule__HyphenVersionRange__Group__1__Impl(); state._fsp--; @@ -8981,23 +9784,23 @@ public final void rule__HyphenVersionRange__Group__1() throws RecognitionExcepti // $ANTLR start "rule__HyphenVersionRange__Group__1__Impl" - // InternalSemver.g:2526:1: rule__HyphenVersionRange__Group__1__Impl : ( ( rule__HyphenVersionRange__FromAssignment_1 ) ) ; + // InternalSemver.g:2744:1: rule__HyphenVersionRange__Group__1__Impl : ( ( rule__HyphenVersionRange__FromAssignment_1 ) ) ; public final void rule__HyphenVersionRange__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2530:1: ( ( ( rule__HyphenVersionRange__FromAssignment_1 ) ) ) - // InternalSemver.g:2531:1: ( ( rule__HyphenVersionRange__FromAssignment_1 ) ) + // InternalSemver.g:2748:1: ( ( ( rule__HyphenVersionRange__FromAssignment_1 ) ) ) + // InternalSemver.g:2749:1: ( ( rule__HyphenVersionRange__FromAssignment_1 ) ) { - // InternalSemver.g:2531:1: ( ( rule__HyphenVersionRange__FromAssignment_1 ) ) - // InternalSemver.g:2532:2: ( rule__HyphenVersionRange__FromAssignment_1 ) + // InternalSemver.g:2749:1: ( ( rule__HyphenVersionRange__FromAssignment_1 ) ) + // InternalSemver.g:2750:2: ( rule__HyphenVersionRange__FromAssignment_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getHyphenVersionRangeAccess().getFromAssignment_1()); } - // InternalSemver.g:2533:2: ( rule__HyphenVersionRange__FromAssignment_1 ) - // InternalSemver.g:2533:3: rule__HyphenVersionRange__FromAssignment_1 + // InternalSemver.g:2751:2: ( rule__HyphenVersionRange__FromAssignment_1 ) + // InternalSemver.g:2751:3: rule__HyphenVersionRange__FromAssignment_1 { pushFollow(FOLLOW_2); rule__HyphenVersionRange__FromAssignment_1(); @@ -9032,16 +9835,16 @@ public final void rule__HyphenVersionRange__Group__1__Impl() throws RecognitionE // $ANTLR start "rule__HyphenVersionRange__Group__2" - // InternalSemver.g:2541:1: rule__HyphenVersionRange__Group__2 : rule__HyphenVersionRange__Group__2__Impl rule__HyphenVersionRange__Group__3 ; + // InternalSemver.g:2759:1: rule__HyphenVersionRange__Group__2 : rule__HyphenVersionRange__Group__2__Impl rule__HyphenVersionRange__Group__3 ; public final void rule__HyphenVersionRange__Group__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2545:1: ( rule__HyphenVersionRange__Group__2__Impl rule__HyphenVersionRange__Group__3 ) - // InternalSemver.g:2546:2: rule__HyphenVersionRange__Group__2__Impl rule__HyphenVersionRange__Group__3 + // InternalSemver.g:2763:1: ( rule__HyphenVersionRange__Group__2__Impl rule__HyphenVersionRange__Group__3 ) + // InternalSemver.g:2764:2: rule__HyphenVersionRange__Group__2__Impl rule__HyphenVersionRange__Group__3 { - pushFollow(FOLLOW_17); + pushFollow(FOLLOW_19); rule__HyphenVersionRange__Group__2__Impl(); state._fsp--; @@ -9070,17 +9873,17 @@ public final void rule__HyphenVersionRange__Group__2() throws RecognitionExcepti // $ANTLR start "rule__HyphenVersionRange__Group__2__Impl" - // InternalSemver.g:2553:1: rule__HyphenVersionRange__Group__2__Impl : ( RULE_WS ) ; + // InternalSemver.g:2771:1: rule__HyphenVersionRange__Group__2__Impl : ( RULE_WS ) ; public final void rule__HyphenVersionRange__Group__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2557:1: ( ( RULE_WS ) ) - // InternalSemver.g:2558:1: ( RULE_WS ) + // InternalSemver.g:2775:1: ( ( RULE_WS ) ) + // InternalSemver.g:2776:1: ( RULE_WS ) { - // InternalSemver.g:2558:1: ( RULE_WS ) - // InternalSemver.g:2559:2: RULE_WS + // InternalSemver.g:2776:1: ( RULE_WS ) + // InternalSemver.g:2777:2: RULE_WS { if ( state.backtracking==0 ) { before(grammarAccess.getHyphenVersionRangeAccess().getWSTerminalRuleCall_2()); @@ -9111,16 +9914,16 @@ public final void rule__HyphenVersionRange__Group__2__Impl() throws RecognitionE // $ANTLR start "rule__HyphenVersionRange__Group__3" - // InternalSemver.g:2568:1: rule__HyphenVersionRange__Group__3 : rule__HyphenVersionRange__Group__3__Impl rule__HyphenVersionRange__Group__4 ; + // InternalSemver.g:2786:1: rule__HyphenVersionRange__Group__3 : rule__HyphenVersionRange__Group__3__Impl rule__HyphenVersionRange__Group__4 ; public final void rule__HyphenVersionRange__Group__3() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2572:1: ( rule__HyphenVersionRange__Group__3__Impl rule__HyphenVersionRange__Group__4 ) - // InternalSemver.g:2573:2: rule__HyphenVersionRange__Group__3__Impl rule__HyphenVersionRange__Group__4 + // InternalSemver.g:2790:1: ( rule__HyphenVersionRange__Group__3__Impl rule__HyphenVersionRange__Group__4 ) + // InternalSemver.g:2791:2: rule__HyphenVersionRange__Group__3__Impl rule__HyphenVersionRange__Group__4 { - pushFollow(FOLLOW_5); + pushFollow(FOLLOW_6); rule__HyphenVersionRange__Group__3__Impl(); state._fsp--; @@ -9149,22 +9952,22 @@ public final void rule__HyphenVersionRange__Group__3() throws RecognitionExcepti // $ANTLR start "rule__HyphenVersionRange__Group__3__Impl" - // InternalSemver.g:2580:1: rule__HyphenVersionRange__Group__3__Impl : ( '-' ) ; + // InternalSemver.g:2798:1: rule__HyphenVersionRange__Group__3__Impl : ( '-' ) ; public final void rule__HyphenVersionRange__Group__3__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2584:1: ( ( '-' ) ) - // InternalSemver.g:2585:1: ( '-' ) + // InternalSemver.g:2802:1: ( ( '-' ) ) + // InternalSemver.g:2803:1: ( '-' ) { - // InternalSemver.g:2585:1: ( '-' ) - // InternalSemver.g:2586:2: '-' + // InternalSemver.g:2803:1: ( '-' ) + // InternalSemver.g:2804:2: '-' { if ( state.backtracking==0 ) { before(grammarAccess.getHyphenVersionRangeAccess().getHyphenMinusKeyword_3()); } - match(input,38,FOLLOW_2); if (state.failed) return ; + match(input,47,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getHyphenVersionRangeAccess().getHyphenMinusKeyword_3()); } @@ -9190,16 +9993,16 @@ public final void rule__HyphenVersionRange__Group__3__Impl() throws RecognitionE // $ANTLR start "rule__HyphenVersionRange__Group__4" - // InternalSemver.g:2595:1: rule__HyphenVersionRange__Group__4 : rule__HyphenVersionRange__Group__4__Impl rule__HyphenVersionRange__Group__5 ; + // InternalSemver.g:2813:1: rule__HyphenVersionRange__Group__4 : rule__HyphenVersionRange__Group__4__Impl rule__HyphenVersionRange__Group__5 ; public final void rule__HyphenVersionRange__Group__4() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2599:1: ( rule__HyphenVersionRange__Group__4__Impl rule__HyphenVersionRange__Group__5 ) - // InternalSemver.g:2600:2: rule__HyphenVersionRange__Group__4__Impl rule__HyphenVersionRange__Group__5 + // InternalSemver.g:2817:1: ( rule__HyphenVersionRange__Group__4__Impl rule__HyphenVersionRange__Group__5 ) + // InternalSemver.g:2818:2: rule__HyphenVersionRange__Group__4__Impl rule__HyphenVersionRange__Group__5 { - pushFollow(FOLLOW_4); + pushFollow(FOLLOW_5); rule__HyphenVersionRange__Group__4__Impl(); state._fsp--; @@ -9228,17 +10031,17 @@ public final void rule__HyphenVersionRange__Group__4() throws RecognitionExcepti // $ANTLR start "rule__HyphenVersionRange__Group__4__Impl" - // InternalSemver.g:2607:1: rule__HyphenVersionRange__Group__4__Impl : ( RULE_WS ) ; + // InternalSemver.g:2825:1: rule__HyphenVersionRange__Group__4__Impl : ( RULE_WS ) ; public final void rule__HyphenVersionRange__Group__4__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2611:1: ( ( RULE_WS ) ) - // InternalSemver.g:2612:1: ( RULE_WS ) + // InternalSemver.g:2829:1: ( ( RULE_WS ) ) + // InternalSemver.g:2830:1: ( RULE_WS ) { - // InternalSemver.g:2612:1: ( RULE_WS ) - // InternalSemver.g:2613:2: RULE_WS + // InternalSemver.g:2830:1: ( RULE_WS ) + // InternalSemver.g:2831:2: RULE_WS { if ( state.backtracking==0 ) { before(grammarAccess.getHyphenVersionRangeAccess().getWSTerminalRuleCall_4()); @@ -9269,14 +10072,14 @@ public final void rule__HyphenVersionRange__Group__4__Impl() throws RecognitionE // $ANTLR start "rule__HyphenVersionRange__Group__5" - // InternalSemver.g:2622:1: rule__HyphenVersionRange__Group__5 : rule__HyphenVersionRange__Group__5__Impl ; + // InternalSemver.g:2840:1: rule__HyphenVersionRange__Group__5 : rule__HyphenVersionRange__Group__5__Impl ; public final void rule__HyphenVersionRange__Group__5() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2626:1: ( rule__HyphenVersionRange__Group__5__Impl ) - // InternalSemver.g:2627:2: rule__HyphenVersionRange__Group__5__Impl + // InternalSemver.g:2844:1: ( rule__HyphenVersionRange__Group__5__Impl ) + // InternalSemver.g:2845:2: rule__HyphenVersionRange__Group__5__Impl { pushFollow(FOLLOW_2); rule__HyphenVersionRange__Group__5__Impl(); @@ -9302,23 +10105,23 @@ public final void rule__HyphenVersionRange__Group__5() throws RecognitionExcepti // $ANTLR start "rule__HyphenVersionRange__Group__5__Impl" - // InternalSemver.g:2633:1: rule__HyphenVersionRange__Group__5__Impl : ( ( rule__HyphenVersionRange__ToAssignment_5 ) ) ; + // InternalSemver.g:2851:1: rule__HyphenVersionRange__Group__5__Impl : ( ( rule__HyphenVersionRange__ToAssignment_5 ) ) ; public final void rule__HyphenVersionRange__Group__5__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2637:1: ( ( ( rule__HyphenVersionRange__ToAssignment_5 ) ) ) - // InternalSemver.g:2638:1: ( ( rule__HyphenVersionRange__ToAssignment_5 ) ) + // InternalSemver.g:2855:1: ( ( ( rule__HyphenVersionRange__ToAssignment_5 ) ) ) + // InternalSemver.g:2856:1: ( ( rule__HyphenVersionRange__ToAssignment_5 ) ) { - // InternalSemver.g:2638:1: ( ( rule__HyphenVersionRange__ToAssignment_5 ) ) - // InternalSemver.g:2639:2: ( rule__HyphenVersionRange__ToAssignment_5 ) + // InternalSemver.g:2856:1: ( ( rule__HyphenVersionRange__ToAssignment_5 ) ) + // InternalSemver.g:2857:2: ( rule__HyphenVersionRange__ToAssignment_5 ) { if ( state.backtracking==0 ) { before(grammarAccess.getHyphenVersionRangeAccess().getToAssignment_5()); } - // InternalSemver.g:2640:2: ( rule__HyphenVersionRange__ToAssignment_5 ) - // InternalSemver.g:2640:3: rule__HyphenVersionRange__ToAssignment_5 + // InternalSemver.g:2858:2: ( rule__HyphenVersionRange__ToAssignment_5 ) + // InternalSemver.g:2858:3: rule__HyphenVersionRange__ToAssignment_5 { pushFollow(FOLLOW_2); rule__HyphenVersionRange__ToAssignment_5(); @@ -9353,16 +10156,16 @@ public final void rule__HyphenVersionRange__Group__5__Impl() throws RecognitionE // $ANTLR start "rule__VersionRangeContraint__Group__0" - // InternalSemver.g:2649:1: rule__VersionRangeContraint__Group__0 : rule__VersionRangeContraint__Group__0__Impl rule__VersionRangeContraint__Group__1 ; + // InternalSemver.g:2867:1: rule__VersionRangeContraint__Group__0 : rule__VersionRangeContraint__Group__0__Impl rule__VersionRangeContraint__Group__1 ; public final void rule__VersionRangeContraint__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2653:1: ( rule__VersionRangeContraint__Group__0__Impl rule__VersionRangeContraint__Group__1 ) - // InternalSemver.g:2654:2: rule__VersionRangeContraint__Group__0__Impl rule__VersionRangeContraint__Group__1 + // InternalSemver.g:2871:1: ( rule__VersionRangeContraint__Group__0__Impl rule__VersionRangeContraint__Group__1 ) + // InternalSemver.g:2872:2: rule__VersionRangeContraint__Group__0__Impl rule__VersionRangeContraint__Group__1 { - pushFollow(FOLLOW_4); + pushFollow(FOLLOW_5); rule__VersionRangeContraint__Group__0__Impl(); state._fsp--; @@ -9391,23 +10194,23 @@ public final void rule__VersionRangeContraint__Group__0() throws RecognitionExce // $ANTLR start "rule__VersionRangeContraint__Group__0__Impl" - // InternalSemver.g:2661:1: rule__VersionRangeContraint__Group__0__Impl : ( () ) ; + // InternalSemver.g:2879:1: rule__VersionRangeContraint__Group__0__Impl : ( () ) ; public final void rule__VersionRangeContraint__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2665:1: ( ( () ) ) - // InternalSemver.g:2666:1: ( () ) + // InternalSemver.g:2883:1: ( ( () ) ) + // InternalSemver.g:2884:1: ( () ) { - // InternalSemver.g:2666:1: ( () ) - // InternalSemver.g:2667:2: () + // InternalSemver.g:2884:1: ( () ) + // InternalSemver.g:2885:2: () { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeContraintAccess().getVersionRangeConstraintAction_0()); } - // InternalSemver.g:2668:2: () - // InternalSemver.g:2668:3: + // InternalSemver.g:2886:2: () + // InternalSemver.g:2886:3: { } @@ -9432,16 +10235,16 @@ public final void rule__VersionRangeContraint__Group__0__Impl() throws Recogniti // $ANTLR start "rule__VersionRangeContraint__Group__1" - // InternalSemver.g:2676:1: rule__VersionRangeContraint__Group__1 : rule__VersionRangeContraint__Group__1__Impl rule__VersionRangeContraint__Group__2 ; + // InternalSemver.g:2894:1: rule__VersionRangeContraint__Group__1 : rule__VersionRangeContraint__Group__1__Impl rule__VersionRangeContraint__Group__2 ; public final void rule__VersionRangeContraint__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2680:1: ( rule__VersionRangeContraint__Group__1__Impl rule__VersionRangeContraint__Group__2 ) - // InternalSemver.g:2681:2: rule__VersionRangeContraint__Group__1__Impl rule__VersionRangeContraint__Group__2 + // InternalSemver.g:2898:1: ( rule__VersionRangeContraint__Group__1__Impl rule__VersionRangeContraint__Group__2 ) + // InternalSemver.g:2899:2: rule__VersionRangeContraint__Group__1__Impl rule__VersionRangeContraint__Group__2 { - pushFollow(FOLLOW_5); + pushFollow(FOLLOW_6); rule__VersionRangeContraint__Group__1__Impl(); state._fsp--; @@ -9470,23 +10273,23 @@ public final void rule__VersionRangeContraint__Group__1() throws RecognitionExce // $ANTLR start "rule__VersionRangeContraint__Group__1__Impl" - // InternalSemver.g:2688:1: rule__VersionRangeContraint__Group__1__Impl : ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_1 ) ) ; + // InternalSemver.g:2906:1: rule__VersionRangeContraint__Group__1__Impl : ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_1 ) ) ; public final void rule__VersionRangeContraint__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2692:1: ( ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_1 ) ) ) - // InternalSemver.g:2693:1: ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_1 ) ) + // InternalSemver.g:2910:1: ( ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_1 ) ) ) + // InternalSemver.g:2911:1: ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_1 ) ) { - // InternalSemver.g:2693:1: ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_1 ) ) - // InternalSemver.g:2694:2: ( rule__VersionRangeContraint__VersionConstraintsAssignment_1 ) + // InternalSemver.g:2911:1: ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_1 ) ) + // InternalSemver.g:2912:2: ( rule__VersionRangeContraint__VersionConstraintsAssignment_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeContraintAccess().getVersionConstraintsAssignment_1()); } - // InternalSemver.g:2695:2: ( rule__VersionRangeContraint__VersionConstraintsAssignment_1 ) - // InternalSemver.g:2695:3: rule__VersionRangeContraint__VersionConstraintsAssignment_1 + // InternalSemver.g:2913:2: ( rule__VersionRangeContraint__VersionConstraintsAssignment_1 ) + // InternalSemver.g:2913:3: rule__VersionRangeContraint__VersionConstraintsAssignment_1 { pushFollow(FOLLOW_2); rule__VersionRangeContraint__VersionConstraintsAssignment_1(); @@ -9521,14 +10324,14 @@ public final void rule__VersionRangeContraint__Group__1__Impl() throws Recogniti // $ANTLR start "rule__VersionRangeContraint__Group__2" - // InternalSemver.g:2703:1: rule__VersionRangeContraint__Group__2 : rule__VersionRangeContraint__Group__2__Impl ; + // InternalSemver.g:2921:1: rule__VersionRangeContraint__Group__2 : rule__VersionRangeContraint__Group__2__Impl ; public final void rule__VersionRangeContraint__Group__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2707:1: ( rule__VersionRangeContraint__Group__2__Impl ) - // InternalSemver.g:2708:2: rule__VersionRangeContraint__Group__2__Impl + // InternalSemver.g:2925:1: ( rule__VersionRangeContraint__Group__2__Impl ) + // InternalSemver.g:2926:2: rule__VersionRangeContraint__Group__2__Impl { pushFollow(FOLLOW_2); rule__VersionRangeContraint__Group__2__Impl(); @@ -9554,43 +10357,43 @@ public final void rule__VersionRangeContraint__Group__2() throws RecognitionExce // $ANTLR start "rule__VersionRangeContraint__Group__2__Impl" - // InternalSemver.g:2714:1: rule__VersionRangeContraint__Group__2__Impl : ( ( rule__VersionRangeContraint__Group_2__0 )* ) ; + // InternalSemver.g:2932:1: rule__VersionRangeContraint__Group__2__Impl : ( ( rule__VersionRangeContraint__Group_2__0 )* ) ; public final void rule__VersionRangeContraint__Group__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2718:1: ( ( ( rule__VersionRangeContraint__Group_2__0 )* ) ) - // InternalSemver.g:2719:1: ( ( rule__VersionRangeContraint__Group_2__0 )* ) + // InternalSemver.g:2936:1: ( ( ( rule__VersionRangeContraint__Group_2__0 )* ) ) + // InternalSemver.g:2937:1: ( ( rule__VersionRangeContraint__Group_2__0 )* ) { - // InternalSemver.g:2719:1: ( ( rule__VersionRangeContraint__Group_2__0 )* ) - // InternalSemver.g:2720:2: ( rule__VersionRangeContraint__Group_2__0 )* + // InternalSemver.g:2937:1: ( ( rule__VersionRangeContraint__Group_2__0 )* ) + // InternalSemver.g:2938:2: ( rule__VersionRangeContraint__Group_2__0 )* { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeContraintAccess().getGroup_2()); } - // InternalSemver.g:2721:2: ( rule__VersionRangeContraint__Group_2__0 )* - loop36: + // InternalSemver.g:2939:2: ( rule__VersionRangeContraint__Group_2__0 )* + loop38: do { - int alt36=2; - int LA36_0 = input.LA(1); + int alt38=2; + int LA38_0 = input.LA(1); - if ( (LA36_0==RULE_WS) ) { - int LA36_2 = input.LA(2); + if ( (LA38_0==RULE_WS) ) { + int LA38_2 = input.LA(2); - if ( ((LA36_2>=RULE_DIGITS && LA36_2<=RULE_LETTER_V)||(LA36_2>=42 && LA36_2<=48)) ) { - alt36=1; + if ( ((LA38_2>=RULE_ASTERIX && LA38_2<=RULE_LETTER_V)||(LA38_2>=48 && LA38_2<=54)) ) { + alt38=1; } } - switch (alt36) { + switch (alt38) { case 1 : - // InternalSemver.g:2721:3: rule__VersionRangeContraint__Group_2__0 + // InternalSemver.g:2939:3: rule__VersionRangeContraint__Group_2__0 { - pushFollow(FOLLOW_18); + pushFollow(FOLLOW_20); rule__VersionRangeContraint__Group_2__0(); state._fsp--; @@ -9600,7 +10403,7 @@ public final void rule__VersionRangeContraint__Group__2__Impl() throws Recogniti break; default : - break loop36; + break loop38; } } while (true); @@ -9629,16 +10432,16 @@ public final void rule__VersionRangeContraint__Group__2__Impl() throws Recogniti // $ANTLR start "rule__VersionRangeContraint__Group_2__0" - // InternalSemver.g:2730:1: rule__VersionRangeContraint__Group_2__0 : rule__VersionRangeContraint__Group_2__0__Impl rule__VersionRangeContraint__Group_2__1 ; + // InternalSemver.g:2948:1: rule__VersionRangeContraint__Group_2__0 : rule__VersionRangeContraint__Group_2__0__Impl rule__VersionRangeContraint__Group_2__1 ; public final void rule__VersionRangeContraint__Group_2__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2734:1: ( rule__VersionRangeContraint__Group_2__0__Impl rule__VersionRangeContraint__Group_2__1 ) - // InternalSemver.g:2735:2: rule__VersionRangeContraint__Group_2__0__Impl rule__VersionRangeContraint__Group_2__1 + // InternalSemver.g:2952:1: ( rule__VersionRangeContraint__Group_2__0__Impl rule__VersionRangeContraint__Group_2__1 ) + // InternalSemver.g:2953:2: rule__VersionRangeContraint__Group_2__0__Impl rule__VersionRangeContraint__Group_2__1 { - pushFollow(FOLLOW_4); + pushFollow(FOLLOW_5); rule__VersionRangeContraint__Group_2__0__Impl(); state._fsp--; @@ -9667,17 +10470,17 @@ public final void rule__VersionRangeContraint__Group_2__0() throws RecognitionEx // $ANTLR start "rule__VersionRangeContraint__Group_2__0__Impl" - // InternalSemver.g:2742:1: rule__VersionRangeContraint__Group_2__0__Impl : ( RULE_WS ) ; + // InternalSemver.g:2960:1: rule__VersionRangeContraint__Group_2__0__Impl : ( RULE_WS ) ; public final void rule__VersionRangeContraint__Group_2__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2746:1: ( ( RULE_WS ) ) - // InternalSemver.g:2747:1: ( RULE_WS ) + // InternalSemver.g:2964:1: ( ( RULE_WS ) ) + // InternalSemver.g:2965:1: ( RULE_WS ) { - // InternalSemver.g:2747:1: ( RULE_WS ) - // InternalSemver.g:2748:2: RULE_WS + // InternalSemver.g:2965:1: ( RULE_WS ) + // InternalSemver.g:2966:2: RULE_WS { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeContraintAccess().getWSTerminalRuleCall_2_0()); @@ -9708,14 +10511,14 @@ public final void rule__VersionRangeContraint__Group_2__0__Impl() throws Recogni // $ANTLR start "rule__VersionRangeContraint__Group_2__1" - // InternalSemver.g:2757:1: rule__VersionRangeContraint__Group_2__1 : rule__VersionRangeContraint__Group_2__1__Impl ; + // InternalSemver.g:2975:1: rule__VersionRangeContraint__Group_2__1 : rule__VersionRangeContraint__Group_2__1__Impl ; public final void rule__VersionRangeContraint__Group_2__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2761:1: ( rule__VersionRangeContraint__Group_2__1__Impl ) - // InternalSemver.g:2762:2: rule__VersionRangeContraint__Group_2__1__Impl + // InternalSemver.g:2979:1: ( rule__VersionRangeContraint__Group_2__1__Impl ) + // InternalSemver.g:2980:2: rule__VersionRangeContraint__Group_2__1__Impl { pushFollow(FOLLOW_2); rule__VersionRangeContraint__Group_2__1__Impl(); @@ -9741,23 +10544,23 @@ public final void rule__VersionRangeContraint__Group_2__1() throws RecognitionEx // $ANTLR start "rule__VersionRangeContraint__Group_2__1__Impl" - // InternalSemver.g:2768:1: rule__VersionRangeContraint__Group_2__1__Impl : ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 ) ) ; + // InternalSemver.g:2986:1: rule__VersionRangeContraint__Group_2__1__Impl : ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 ) ) ; public final void rule__VersionRangeContraint__Group_2__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2772:1: ( ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 ) ) ) - // InternalSemver.g:2773:1: ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 ) ) + // InternalSemver.g:2990:1: ( ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 ) ) ) + // InternalSemver.g:2991:1: ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 ) ) { - // InternalSemver.g:2773:1: ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 ) ) - // InternalSemver.g:2774:2: ( rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 ) + // InternalSemver.g:2991:1: ( ( rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 ) ) + // InternalSemver.g:2992:2: ( rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionRangeContraintAccess().getVersionConstraintsAssignment_2_1()); } - // InternalSemver.g:2775:2: ( rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 ) - // InternalSemver.g:2775:3: rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 + // InternalSemver.g:2993:2: ( rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 ) + // InternalSemver.g:2993:3: rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 { pushFollow(FOLLOW_2); rule__VersionRangeContraint__VersionConstraintsAssignment_2_1(); @@ -9792,16 +10595,16 @@ public final void rule__VersionRangeContraint__Group_2__1__Impl() throws Recogni // $ANTLR start "rule__SimpleVersion__Group__0" - // InternalSemver.g:2784:1: rule__SimpleVersion__Group__0 : rule__SimpleVersion__Group__0__Impl rule__SimpleVersion__Group__1 ; + // InternalSemver.g:3002:1: rule__SimpleVersion__Group__0 : rule__SimpleVersion__Group__0__Impl rule__SimpleVersion__Group__1 ; public final void rule__SimpleVersion__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2788:1: ( rule__SimpleVersion__Group__0__Impl rule__SimpleVersion__Group__1 ) - // InternalSemver.g:2789:2: rule__SimpleVersion__Group__0__Impl rule__SimpleVersion__Group__1 + // InternalSemver.g:3006:1: ( rule__SimpleVersion__Group__0__Impl rule__SimpleVersion__Group__1 ) + // InternalSemver.g:3007:2: rule__SimpleVersion__Group__0__Impl rule__SimpleVersion__Group__1 { - pushFollow(FOLLOW_4); + pushFollow(FOLLOW_5); rule__SimpleVersion__Group__0__Impl(); state._fsp--; @@ -9830,37 +10633,37 @@ public final void rule__SimpleVersion__Group__0() throws RecognitionException { // $ANTLR start "rule__SimpleVersion__Group__0__Impl" - // InternalSemver.g:2796:1: rule__SimpleVersion__Group__0__Impl : ( ( rule__SimpleVersion__Group_0__0 )* ) ; + // InternalSemver.g:3014:1: rule__SimpleVersion__Group__0__Impl : ( ( rule__SimpleVersion__Group_0__0 )* ) ; public final void rule__SimpleVersion__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2800:1: ( ( ( rule__SimpleVersion__Group_0__0 )* ) ) - // InternalSemver.g:2801:1: ( ( rule__SimpleVersion__Group_0__0 )* ) + // InternalSemver.g:3018:1: ( ( ( rule__SimpleVersion__Group_0__0 )* ) ) + // InternalSemver.g:3019:1: ( ( rule__SimpleVersion__Group_0__0 )* ) { - // InternalSemver.g:2801:1: ( ( rule__SimpleVersion__Group_0__0 )* ) - // InternalSemver.g:2802:2: ( rule__SimpleVersion__Group_0__0 )* + // InternalSemver.g:3019:1: ( ( rule__SimpleVersion__Group_0__0 )* ) + // InternalSemver.g:3020:2: ( rule__SimpleVersion__Group_0__0 )* { if ( state.backtracking==0 ) { before(grammarAccess.getSimpleVersionAccess().getGroup_0()); } - // InternalSemver.g:2803:2: ( rule__SimpleVersion__Group_0__0 )* - loop37: + // InternalSemver.g:3021:2: ( rule__SimpleVersion__Group_0__0 )* + loop39: do { - int alt37=2; - int LA37_0 = input.LA(1); + int alt39=2; + int LA39_0 = input.LA(1); - if ( ((LA37_0>=42 && LA37_0<=48)) ) { - alt37=1; + if ( ((LA39_0>=48 && LA39_0<=54)) ) { + alt39=1; } - switch (alt37) { + switch (alt39) { case 1 : - // InternalSemver.g:2803:3: rule__SimpleVersion__Group_0__0 + // InternalSemver.g:3021:3: rule__SimpleVersion__Group_0__0 { - pushFollow(FOLLOW_19); + pushFollow(FOLLOW_21); rule__SimpleVersion__Group_0__0(); state._fsp--; @@ -9870,7 +10673,7 @@ public final void rule__SimpleVersion__Group__0__Impl() throws RecognitionExcept break; default : - break loop37; + break loop39; } } while (true); @@ -9899,16 +10702,16 @@ public final void rule__SimpleVersion__Group__0__Impl() throws RecognitionExcept // $ANTLR start "rule__SimpleVersion__Group__1" - // InternalSemver.g:2811:1: rule__SimpleVersion__Group__1 : rule__SimpleVersion__Group__1__Impl rule__SimpleVersion__Group__2 ; + // InternalSemver.g:3029:1: rule__SimpleVersion__Group__1 : rule__SimpleVersion__Group__1__Impl rule__SimpleVersion__Group__2 ; public final void rule__SimpleVersion__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2815:1: ( rule__SimpleVersion__Group__1__Impl rule__SimpleVersion__Group__2 ) - // InternalSemver.g:2816:2: rule__SimpleVersion__Group__1__Impl rule__SimpleVersion__Group__2 + // InternalSemver.g:3033:1: ( rule__SimpleVersion__Group__1__Impl rule__SimpleVersion__Group__2 ) + // InternalSemver.g:3034:2: rule__SimpleVersion__Group__1__Impl rule__SimpleVersion__Group__2 { - pushFollow(FOLLOW_4); + pushFollow(FOLLOW_5); rule__SimpleVersion__Group__1__Impl(); state._fsp--; @@ -9937,31 +10740,31 @@ public final void rule__SimpleVersion__Group__1() throws RecognitionException { // $ANTLR start "rule__SimpleVersion__Group__1__Impl" - // InternalSemver.g:2823:1: rule__SimpleVersion__Group__1__Impl : ( ( rule__SimpleVersion__WithLetterVAssignment_1 )? ) ; + // InternalSemver.g:3041:1: rule__SimpleVersion__Group__1__Impl : ( ( rule__SimpleVersion__WithLetterVAssignment_1 )? ) ; public final void rule__SimpleVersion__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2827:1: ( ( ( rule__SimpleVersion__WithLetterVAssignment_1 )? ) ) - // InternalSemver.g:2828:1: ( ( rule__SimpleVersion__WithLetterVAssignment_1 )? ) + // InternalSemver.g:3045:1: ( ( ( rule__SimpleVersion__WithLetterVAssignment_1 )? ) ) + // InternalSemver.g:3046:1: ( ( rule__SimpleVersion__WithLetterVAssignment_1 )? ) { - // InternalSemver.g:2828:1: ( ( rule__SimpleVersion__WithLetterVAssignment_1 )? ) - // InternalSemver.g:2829:2: ( rule__SimpleVersion__WithLetterVAssignment_1 )? + // InternalSemver.g:3046:1: ( ( rule__SimpleVersion__WithLetterVAssignment_1 )? ) + // InternalSemver.g:3047:2: ( rule__SimpleVersion__WithLetterVAssignment_1 )? { if ( state.backtracking==0 ) { before(grammarAccess.getSimpleVersionAccess().getWithLetterVAssignment_1()); } - // InternalSemver.g:2830:2: ( rule__SimpleVersion__WithLetterVAssignment_1 )? - int alt38=2; - int LA38_0 = input.LA(1); + // InternalSemver.g:3048:2: ( rule__SimpleVersion__WithLetterVAssignment_1 )? + int alt40=2; + int LA40_0 = input.LA(1); - if ( (LA38_0==RULE_LETTER_V) ) { - alt38=1; + if ( (LA40_0==RULE_LETTER_V) ) { + alt40=1; } - switch (alt38) { + switch (alt40) { case 1 : - // InternalSemver.g:2830:3: rule__SimpleVersion__WithLetterVAssignment_1 + // InternalSemver.g:3048:3: rule__SimpleVersion__WithLetterVAssignment_1 { pushFollow(FOLLOW_2); rule__SimpleVersion__WithLetterVAssignment_1(); @@ -9999,14 +10802,14 @@ public final void rule__SimpleVersion__Group__1__Impl() throws RecognitionExcept // $ANTLR start "rule__SimpleVersion__Group__2" - // InternalSemver.g:2838:1: rule__SimpleVersion__Group__2 : rule__SimpleVersion__Group__2__Impl ; + // InternalSemver.g:3056:1: rule__SimpleVersion__Group__2 : rule__SimpleVersion__Group__2__Impl ; public final void rule__SimpleVersion__Group__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2842:1: ( rule__SimpleVersion__Group__2__Impl ) - // InternalSemver.g:2843:2: rule__SimpleVersion__Group__2__Impl + // InternalSemver.g:3060:1: ( rule__SimpleVersion__Group__2__Impl ) + // InternalSemver.g:3061:2: rule__SimpleVersion__Group__2__Impl { pushFollow(FOLLOW_2); rule__SimpleVersion__Group__2__Impl(); @@ -10032,23 +10835,23 @@ public final void rule__SimpleVersion__Group__2() throws RecognitionException { // $ANTLR start "rule__SimpleVersion__Group__2__Impl" - // InternalSemver.g:2849:1: rule__SimpleVersion__Group__2__Impl : ( ( rule__SimpleVersion__NumberAssignment_2 ) ) ; + // InternalSemver.g:3067:1: rule__SimpleVersion__Group__2__Impl : ( ( rule__SimpleVersion__NumberAssignment_2 ) ) ; public final void rule__SimpleVersion__Group__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2853:1: ( ( ( rule__SimpleVersion__NumberAssignment_2 ) ) ) - // InternalSemver.g:2854:1: ( ( rule__SimpleVersion__NumberAssignment_2 ) ) + // InternalSemver.g:3071:1: ( ( ( rule__SimpleVersion__NumberAssignment_2 ) ) ) + // InternalSemver.g:3072:1: ( ( rule__SimpleVersion__NumberAssignment_2 ) ) { - // InternalSemver.g:2854:1: ( ( rule__SimpleVersion__NumberAssignment_2 ) ) - // InternalSemver.g:2855:2: ( rule__SimpleVersion__NumberAssignment_2 ) + // InternalSemver.g:3072:1: ( ( rule__SimpleVersion__NumberAssignment_2 ) ) + // InternalSemver.g:3073:2: ( rule__SimpleVersion__NumberAssignment_2 ) { if ( state.backtracking==0 ) { before(grammarAccess.getSimpleVersionAccess().getNumberAssignment_2()); } - // InternalSemver.g:2856:2: ( rule__SimpleVersion__NumberAssignment_2 ) - // InternalSemver.g:2856:3: rule__SimpleVersion__NumberAssignment_2 + // InternalSemver.g:3074:2: ( rule__SimpleVersion__NumberAssignment_2 ) + // InternalSemver.g:3074:3: rule__SimpleVersion__NumberAssignment_2 { pushFollow(FOLLOW_2); rule__SimpleVersion__NumberAssignment_2(); @@ -10083,16 +10886,16 @@ public final void rule__SimpleVersion__Group__2__Impl() throws RecognitionExcept // $ANTLR start "rule__SimpleVersion__Group_0__0" - // InternalSemver.g:2865:1: rule__SimpleVersion__Group_0__0 : rule__SimpleVersion__Group_0__0__Impl rule__SimpleVersion__Group_0__1 ; + // InternalSemver.g:3083:1: rule__SimpleVersion__Group_0__0 : rule__SimpleVersion__Group_0__0__Impl rule__SimpleVersion__Group_0__1 ; public final void rule__SimpleVersion__Group_0__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2869:1: ( rule__SimpleVersion__Group_0__0__Impl rule__SimpleVersion__Group_0__1 ) - // InternalSemver.g:2870:2: rule__SimpleVersion__Group_0__0__Impl rule__SimpleVersion__Group_0__1 + // InternalSemver.g:3087:1: ( rule__SimpleVersion__Group_0__0__Impl rule__SimpleVersion__Group_0__1 ) + // InternalSemver.g:3088:2: rule__SimpleVersion__Group_0__0__Impl rule__SimpleVersion__Group_0__1 { - pushFollow(FOLLOW_5); + pushFollow(FOLLOW_6); rule__SimpleVersion__Group_0__0__Impl(); state._fsp--; @@ -10121,23 +10924,23 @@ public final void rule__SimpleVersion__Group_0__0() throws RecognitionException // $ANTLR start "rule__SimpleVersion__Group_0__0__Impl" - // InternalSemver.g:2877:1: rule__SimpleVersion__Group_0__0__Impl : ( ( rule__SimpleVersion__ComparatorsAssignment_0_0 ) ) ; + // InternalSemver.g:3095:1: rule__SimpleVersion__Group_0__0__Impl : ( ( rule__SimpleVersion__ComparatorsAssignment_0_0 ) ) ; public final void rule__SimpleVersion__Group_0__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2881:1: ( ( ( rule__SimpleVersion__ComparatorsAssignment_0_0 ) ) ) - // InternalSemver.g:2882:1: ( ( rule__SimpleVersion__ComparatorsAssignment_0_0 ) ) + // InternalSemver.g:3099:1: ( ( ( rule__SimpleVersion__ComparatorsAssignment_0_0 ) ) ) + // InternalSemver.g:3100:1: ( ( rule__SimpleVersion__ComparatorsAssignment_0_0 ) ) { - // InternalSemver.g:2882:1: ( ( rule__SimpleVersion__ComparatorsAssignment_0_0 ) ) - // InternalSemver.g:2883:2: ( rule__SimpleVersion__ComparatorsAssignment_0_0 ) + // InternalSemver.g:3100:1: ( ( rule__SimpleVersion__ComparatorsAssignment_0_0 ) ) + // InternalSemver.g:3101:2: ( rule__SimpleVersion__ComparatorsAssignment_0_0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getSimpleVersionAccess().getComparatorsAssignment_0_0()); } - // InternalSemver.g:2884:2: ( rule__SimpleVersion__ComparatorsAssignment_0_0 ) - // InternalSemver.g:2884:3: rule__SimpleVersion__ComparatorsAssignment_0_0 + // InternalSemver.g:3102:2: ( rule__SimpleVersion__ComparatorsAssignment_0_0 ) + // InternalSemver.g:3102:3: rule__SimpleVersion__ComparatorsAssignment_0_0 { pushFollow(FOLLOW_2); rule__SimpleVersion__ComparatorsAssignment_0_0(); @@ -10172,14 +10975,14 @@ public final void rule__SimpleVersion__Group_0__0__Impl() throws RecognitionExce // $ANTLR start "rule__SimpleVersion__Group_0__1" - // InternalSemver.g:2892:1: rule__SimpleVersion__Group_0__1 : rule__SimpleVersion__Group_0__1__Impl ; + // InternalSemver.g:3110:1: rule__SimpleVersion__Group_0__1 : rule__SimpleVersion__Group_0__1__Impl ; public final void rule__SimpleVersion__Group_0__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2896:1: ( rule__SimpleVersion__Group_0__1__Impl ) - // InternalSemver.g:2897:2: rule__SimpleVersion__Group_0__1__Impl + // InternalSemver.g:3114:1: ( rule__SimpleVersion__Group_0__1__Impl ) + // InternalSemver.g:3115:2: rule__SimpleVersion__Group_0__1__Impl { pushFollow(FOLLOW_2); rule__SimpleVersion__Group_0__1__Impl(); @@ -10205,31 +11008,31 @@ public final void rule__SimpleVersion__Group_0__1() throws RecognitionException // $ANTLR start "rule__SimpleVersion__Group_0__1__Impl" - // InternalSemver.g:2903:1: rule__SimpleVersion__Group_0__1__Impl : ( ( RULE_WS )? ) ; + // InternalSemver.g:3121:1: rule__SimpleVersion__Group_0__1__Impl : ( ( RULE_WS )? ) ; public final void rule__SimpleVersion__Group_0__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2907:1: ( ( ( RULE_WS )? ) ) - // InternalSemver.g:2908:1: ( ( RULE_WS )? ) + // InternalSemver.g:3125:1: ( ( ( RULE_WS )? ) ) + // InternalSemver.g:3126:1: ( ( RULE_WS )? ) { - // InternalSemver.g:2908:1: ( ( RULE_WS )? ) - // InternalSemver.g:2909:2: ( RULE_WS )? + // InternalSemver.g:3126:1: ( ( RULE_WS )? ) + // InternalSemver.g:3127:2: ( RULE_WS )? { if ( state.backtracking==0 ) { before(grammarAccess.getSimpleVersionAccess().getWSTerminalRuleCall_0_1()); } - // InternalSemver.g:2910:2: ( RULE_WS )? - int alt39=2; - int LA39_0 = input.LA(1); + // InternalSemver.g:3128:2: ( RULE_WS )? + int alt41=2; + int LA41_0 = input.LA(1); - if ( (LA39_0==RULE_WS) ) { - alt39=1; + if ( (LA41_0==RULE_WS) ) { + alt41=1; } - switch (alt39) { + switch (alt41) { case 1 : - // InternalSemver.g:2910:3: RULE_WS + // InternalSemver.g:3128:3: RULE_WS { match(input,RULE_WS,FOLLOW_2); if (state.failed) return ; @@ -10263,16 +11066,16 @@ public final void rule__SimpleVersion__Group_0__1__Impl() throws RecognitionExce // $ANTLR start "rule__VersionNumber__Group__0" - // InternalSemver.g:2919:1: rule__VersionNumber__Group__0 : rule__VersionNumber__Group__0__Impl rule__VersionNumber__Group__1 ; + // InternalSemver.g:3137:1: rule__VersionNumber__Group__0 : rule__VersionNumber__Group__0__Impl rule__VersionNumber__Group__1 ; public final void rule__VersionNumber__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2923:1: ( rule__VersionNumber__Group__0__Impl rule__VersionNumber__Group__1 ) - // InternalSemver.g:2924:2: rule__VersionNumber__Group__0__Impl rule__VersionNumber__Group__1 + // InternalSemver.g:3141:1: ( rule__VersionNumber__Group__0__Impl rule__VersionNumber__Group__1 ) + // InternalSemver.g:3142:2: rule__VersionNumber__Group__0__Impl rule__VersionNumber__Group__1 { - pushFollow(FOLLOW_20); + pushFollow(FOLLOW_22); rule__VersionNumber__Group__0__Impl(); state._fsp--; @@ -10301,23 +11104,23 @@ public final void rule__VersionNumber__Group__0() throws RecognitionException { // $ANTLR start "rule__VersionNumber__Group__0__Impl" - // InternalSemver.g:2931:1: rule__VersionNumber__Group__0__Impl : ( ( rule__VersionNumber__MajorAssignment_0 ) ) ; + // InternalSemver.g:3149:1: rule__VersionNumber__Group__0__Impl : ( ( rule__VersionNumber__MajorAssignment_0 ) ) ; public final void rule__VersionNumber__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2935:1: ( ( ( rule__VersionNumber__MajorAssignment_0 ) ) ) - // InternalSemver.g:2936:1: ( ( rule__VersionNumber__MajorAssignment_0 ) ) + // InternalSemver.g:3153:1: ( ( ( rule__VersionNumber__MajorAssignment_0 ) ) ) + // InternalSemver.g:3154:1: ( ( rule__VersionNumber__MajorAssignment_0 ) ) { - // InternalSemver.g:2936:1: ( ( rule__VersionNumber__MajorAssignment_0 ) ) - // InternalSemver.g:2937:2: ( rule__VersionNumber__MajorAssignment_0 ) + // InternalSemver.g:3154:1: ( ( rule__VersionNumber__MajorAssignment_0 ) ) + // InternalSemver.g:3155:2: ( rule__VersionNumber__MajorAssignment_0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionNumberAccess().getMajorAssignment_0()); } - // InternalSemver.g:2938:2: ( rule__VersionNumber__MajorAssignment_0 ) - // InternalSemver.g:2938:3: rule__VersionNumber__MajorAssignment_0 + // InternalSemver.g:3156:2: ( rule__VersionNumber__MajorAssignment_0 ) + // InternalSemver.g:3156:3: rule__VersionNumber__MajorAssignment_0 { pushFollow(FOLLOW_2); rule__VersionNumber__MajorAssignment_0(); @@ -10352,16 +11155,16 @@ public final void rule__VersionNumber__Group__0__Impl() throws RecognitionExcept // $ANTLR start "rule__VersionNumber__Group__1" - // InternalSemver.g:2946:1: rule__VersionNumber__Group__1 : rule__VersionNumber__Group__1__Impl rule__VersionNumber__Group__2 ; + // InternalSemver.g:3164:1: rule__VersionNumber__Group__1 : rule__VersionNumber__Group__1__Impl rule__VersionNumber__Group__2 ; public final void rule__VersionNumber__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2950:1: ( rule__VersionNumber__Group__1__Impl rule__VersionNumber__Group__2 ) - // InternalSemver.g:2951:2: rule__VersionNumber__Group__1__Impl rule__VersionNumber__Group__2 + // InternalSemver.g:3168:1: ( rule__VersionNumber__Group__1__Impl rule__VersionNumber__Group__2 ) + // InternalSemver.g:3169:2: rule__VersionNumber__Group__1__Impl rule__VersionNumber__Group__2 { - pushFollow(FOLLOW_20); + pushFollow(FOLLOW_22); rule__VersionNumber__Group__1__Impl(); state._fsp--; @@ -10390,31 +11193,31 @@ public final void rule__VersionNumber__Group__1() throws RecognitionException { // $ANTLR start "rule__VersionNumber__Group__1__Impl" - // InternalSemver.g:2958:1: rule__VersionNumber__Group__1__Impl : ( ( rule__VersionNumber__Group_1__0 )? ) ; + // InternalSemver.g:3176:1: rule__VersionNumber__Group__1__Impl : ( ( rule__VersionNumber__Group_1__0 )? ) ; public final void rule__VersionNumber__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2962:1: ( ( ( rule__VersionNumber__Group_1__0 )? ) ) - // InternalSemver.g:2963:1: ( ( rule__VersionNumber__Group_1__0 )? ) + // InternalSemver.g:3180:1: ( ( ( rule__VersionNumber__Group_1__0 )? ) ) + // InternalSemver.g:3181:1: ( ( rule__VersionNumber__Group_1__0 )? ) { - // InternalSemver.g:2963:1: ( ( rule__VersionNumber__Group_1__0 )? ) - // InternalSemver.g:2964:2: ( rule__VersionNumber__Group_1__0 )? + // InternalSemver.g:3181:1: ( ( rule__VersionNumber__Group_1__0 )? ) + // InternalSemver.g:3182:2: ( rule__VersionNumber__Group_1__0 )? { if ( state.backtracking==0 ) { before(grammarAccess.getVersionNumberAccess().getGroup_1()); } - // InternalSemver.g:2965:2: ( rule__VersionNumber__Group_1__0 )? - int alt40=2; - int LA40_0 = input.LA(1); + // InternalSemver.g:3183:2: ( rule__VersionNumber__Group_1__0 )? + int alt42=2; + int LA42_0 = input.LA(1); - if ( (LA40_0==36) ) { - alt40=1; + if ( (LA42_0==42) ) { + alt42=1; } - switch (alt40) { + switch (alt42) { case 1 : - // InternalSemver.g:2965:3: rule__VersionNumber__Group_1__0 + // InternalSemver.g:3183:3: rule__VersionNumber__Group_1__0 { pushFollow(FOLLOW_2); rule__VersionNumber__Group_1__0(); @@ -10452,14 +11255,14 @@ public final void rule__VersionNumber__Group__1__Impl() throws RecognitionExcept // $ANTLR start "rule__VersionNumber__Group__2" - // InternalSemver.g:2973:1: rule__VersionNumber__Group__2 : rule__VersionNumber__Group__2__Impl ; + // InternalSemver.g:3191:1: rule__VersionNumber__Group__2 : rule__VersionNumber__Group__2__Impl ; public final void rule__VersionNumber__Group__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2977:1: ( rule__VersionNumber__Group__2__Impl ) - // InternalSemver.g:2978:2: rule__VersionNumber__Group__2__Impl + // InternalSemver.g:3195:1: ( rule__VersionNumber__Group__2__Impl ) + // InternalSemver.g:3196:2: rule__VersionNumber__Group__2__Impl { pushFollow(FOLLOW_2); rule__VersionNumber__Group__2__Impl(); @@ -10485,31 +11288,31 @@ public final void rule__VersionNumber__Group__2() throws RecognitionException { // $ANTLR start "rule__VersionNumber__Group__2__Impl" - // InternalSemver.g:2984:1: rule__VersionNumber__Group__2__Impl : ( ( rule__VersionNumber__QualifierAssignment_2 )? ) ; + // InternalSemver.g:3202:1: rule__VersionNumber__Group__2__Impl : ( ( rule__VersionNumber__QualifierAssignment_2 )? ) ; public final void rule__VersionNumber__Group__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:2988:1: ( ( ( rule__VersionNumber__QualifierAssignment_2 )? ) ) - // InternalSemver.g:2989:1: ( ( rule__VersionNumber__QualifierAssignment_2 )? ) + // InternalSemver.g:3206:1: ( ( ( rule__VersionNumber__QualifierAssignment_2 )? ) ) + // InternalSemver.g:3207:1: ( ( rule__VersionNumber__QualifierAssignment_2 )? ) { - // InternalSemver.g:2989:1: ( ( rule__VersionNumber__QualifierAssignment_2 )? ) - // InternalSemver.g:2990:2: ( rule__VersionNumber__QualifierAssignment_2 )? + // InternalSemver.g:3207:1: ( ( rule__VersionNumber__QualifierAssignment_2 )? ) + // InternalSemver.g:3208:2: ( rule__VersionNumber__QualifierAssignment_2 )? { if ( state.backtracking==0 ) { before(grammarAccess.getVersionNumberAccess().getQualifierAssignment_2()); } - // InternalSemver.g:2991:2: ( rule__VersionNumber__QualifierAssignment_2 )? - int alt41=2; - int LA41_0 = input.LA(1); + // InternalSemver.g:3209:2: ( rule__VersionNumber__QualifierAssignment_2 )? + int alt43=2; + int LA43_0 = input.LA(1); - if ( (LA41_0==38||LA41_0==40) ) { - alt41=1; + if ( (LA43_0==45||LA43_0==47) ) { + alt43=1; } - switch (alt41) { + switch (alt43) { case 1 : - // InternalSemver.g:2991:3: rule__VersionNumber__QualifierAssignment_2 + // InternalSemver.g:3209:3: rule__VersionNumber__QualifierAssignment_2 { pushFollow(FOLLOW_2); rule__VersionNumber__QualifierAssignment_2(); @@ -10547,16 +11350,16 @@ public final void rule__VersionNumber__Group__2__Impl() throws RecognitionExcept // $ANTLR start "rule__VersionNumber__Group_1__0" - // InternalSemver.g:3000:1: rule__VersionNumber__Group_1__0 : rule__VersionNumber__Group_1__0__Impl rule__VersionNumber__Group_1__1 ; + // InternalSemver.g:3218:1: rule__VersionNumber__Group_1__0 : rule__VersionNumber__Group_1__0__Impl rule__VersionNumber__Group_1__1 ; public final void rule__VersionNumber__Group_1__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3004:1: ( rule__VersionNumber__Group_1__0__Impl rule__VersionNumber__Group_1__1 ) - // InternalSemver.g:3005:2: rule__VersionNumber__Group_1__0__Impl rule__VersionNumber__Group_1__1 + // InternalSemver.g:3222:1: ( rule__VersionNumber__Group_1__0__Impl rule__VersionNumber__Group_1__1 ) + // InternalSemver.g:3223:2: rule__VersionNumber__Group_1__0__Impl rule__VersionNumber__Group_1__1 { - pushFollow(FOLLOW_4); + pushFollow(FOLLOW_5); rule__VersionNumber__Group_1__0__Impl(); state._fsp--; @@ -10585,22 +11388,22 @@ public final void rule__VersionNumber__Group_1__0() throws RecognitionException // $ANTLR start "rule__VersionNumber__Group_1__0__Impl" - // InternalSemver.g:3012:1: rule__VersionNumber__Group_1__0__Impl : ( '.' ) ; + // InternalSemver.g:3230:1: rule__VersionNumber__Group_1__0__Impl : ( '.' ) ; public final void rule__VersionNumber__Group_1__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3016:1: ( ( '.' ) ) - // InternalSemver.g:3017:1: ( '.' ) + // InternalSemver.g:3234:1: ( ( '.' ) ) + // InternalSemver.g:3235:1: ( '.' ) { - // InternalSemver.g:3017:1: ( '.' ) - // InternalSemver.g:3018:2: '.' + // InternalSemver.g:3235:1: ( '.' ) + // InternalSemver.g:3236:2: '.' { if ( state.backtracking==0 ) { before(grammarAccess.getVersionNumberAccess().getFullStopKeyword_1_0()); } - match(input,36,FOLLOW_2); if (state.failed) return ; + match(input,42,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getVersionNumberAccess().getFullStopKeyword_1_0()); } @@ -10626,16 +11429,16 @@ public final void rule__VersionNumber__Group_1__0__Impl() throws RecognitionExce // $ANTLR start "rule__VersionNumber__Group_1__1" - // InternalSemver.g:3027:1: rule__VersionNumber__Group_1__1 : rule__VersionNumber__Group_1__1__Impl rule__VersionNumber__Group_1__2 ; + // InternalSemver.g:3245:1: rule__VersionNumber__Group_1__1 : rule__VersionNumber__Group_1__1__Impl rule__VersionNumber__Group_1__2 ; public final void rule__VersionNumber__Group_1__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3031:1: ( rule__VersionNumber__Group_1__1__Impl rule__VersionNumber__Group_1__2 ) - // InternalSemver.g:3032:2: rule__VersionNumber__Group_1__1__Impl rule__VersionNumber__Group_1__2 + // InternalSemver.g:3249:1: ( rule__VersionNumber__Group_1__1__Impl rule__VersionNumber__Group_1__2 ) + // InternalSemver.g:3250:2: rule__VersionNumber__Group_1__1__Impl rule__VersionNumber__Group_1__2 { - pushFollow(FOLLOW_21); + pushFollow(FOLLOW_23); rule__VersionNumber__Group_1__1__Impl(); state._fsp--; @@ -10664,23 +11467,23 @@ public final void rule__VersionNumber__Group_1__1() throws RecognitionException // $ANTLR start "rule__VersionNumber__Group_1__1__Impl" - // InternalSemver.g:3039:1: rule__VersionNumber__Group_1__1__Impl : ( ( rule__VersionNumber__MinorAssignment_1_1 ) ) ; + // InternalSemver.g:3257:1: rule__VersionNumber__Group_1__1__Impl : ( ( rule__VersionNumber__MinorAssignment_1_1 ) ) ; public final void rule__VersionNumber__Group_1__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3043:1: ( ( ( rule__VersionNumber__MinorAssignment_1_1 ) ) ) - // InternalSemver.g:3044:1: ( ( rule__VersionNumber__MinorAssignment_1_1 ) ) + // InternalSemver.g:3261:1: ( ( ( rule__VersionNumber__MinorAssignment_1_1 ) ) ) + // InternalSemver.g:3262:1: ( ( rule__VersionNumber__MinorAssignment_1_1 ) ) { - // InternalSemver.g:3044:1: ( ( rule__VersionNumber__MinorAssignment_1_1 ) ) - // InternalSemver.g:3045:2: ( rule__VersionNumber__MinorAssignment_1_1 ) + // InternalSemver.g:3262:1: ( ( rule__VersionNumber__MinorAssignment_1_1 ) ) + // InternalSemver.g:3263:2: ( rule__VersionNumber__MinorAssignment_1_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionNumberAccess().getMinorAssignment_1_1()); } - // InternalSemver.g:3046:2: ( rule__VersionNumber__MinorAssignment_1_1 ) - // InternalSemver.g:3046:3: rule__VersionNumber__MinorAssignment_1_1 + // InternalSemver.g:3264:2: ( rule__VersionNumber__MinorAssignment_1_1 ) + // InternalSemver.g:3264:3: rule__VersionNumber__MinorAssignment_1_1 { pushFollow(FOLLOW_2); rule__VersionNumber__MinorAssignment_1_1(); @@ -10715,14 +11518,14 @@ public final void rule__VersionNumber__Group_1__1__Impl() throws RecognitionExce // $ANTLR start "rule__VersionNumber__Group_1__2" - // InternalSemver.g:3054:1: rule__VersionNumber__Group_1__2 : rule__VersionNumber__Group_1__2__Impl ; + // InternalSemver.g:3272:1: rule__VersionNumber__Group_1__2 : rule__VersionNumber__Group_1__2__Impl ; public final void rule__VersionNumber__Group_1__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3058:1: ( rule__VersionNumber__Group_1__2__Impl ) - // InternalSemver.g:3059:2: rule__VersionNumber__Group_1__2__Impl + // InternalSemver.g:3276:1: ( rule__VersionNumber__Group_1__2__Impl ) + // InternalSemver.g:3277:2: rule__VersionNumber__Group_1__2__Impl { pushFollow(FOLLOW_2); rule__VersionNumber__Group_1__2__Impl(); @@ -10748,31 +11551,31 @@ public final void rule__VersionNumber__Group_1__2() throws RecognitionException // $ANTLR start "rule__VersionNumber__Group_1__2__Impl" - // InternalSemver.g:3065:1: rule__VersionNumber__Group_1__2__Impl : ( ( rule__VersionNumber__Group_1_2__0 )? ) ; + // InternalSemver.g:3283:1: rule__VersionNumber__Group_1__2__Impl : ( ( rule__VersionNumber__Group_1_2__0 )? ) ; public final void rule__VersionNumber__Group_1__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3069:1: ( ( ( rule__VersionNumber__Group_1_2__0 )? ) ) - // InternalSemver.g:3070:1: ( ( rule__VersionNumber__Group_1_2__0 )? ) + // InternalSemver.g:3287:1: ( ( ( rule__VersionNumber__Group_1_2__0 )? ) ) + // InternalSemver.g:3288:1: ( ( rule__VersionNumber__Group_1_2__0 )? ) { - // InternalSemver.g:3070:1: ( ( rule__VersionNumber__Group_1_2__0 )? ) - // InternalSemver.g:3071:2: ( rule__VersionNumber__Group_1_2__0 )? + // InternalSemver.g:3288:1: ( ( rule__VersionNumber__Group_1_2__0 )? ) + // InternalSemver.g:3289:2: ( rule__VersionNumber__Group_1_2__0 )? { if ( state.backtracking==0 ) { before(grammarAccess.getVersionNumberAccess().getGroup_1_2()); } - // InternalSemver.g:3072:2: ( rule__VersionNumber__Group_1_2__0 )? - int alt42=2; - int LA42_0 = input.LA(1); + // InternalSemver.g:3290:2: ( rule__VersionNumber__Group_1_2__0 )? + int alt44=2; + int LA44_0 = input.LA(1); - if ( (LA42_0==36) ) { - alt42=1; + if ( (LA44_0==42) ) { + alt44=1; } - switch (alt42) { + switch (alt44) { case 1 : - // InternalSemver.g:3072:3: rule__VersionNumber__Group_1_2__0 + // InternalSemver.g:3290:3: rule__VersionNumber__Group_1_2__0 { pushFollow(FOLLOW_2); rule__VersionNumber__Group_1_2__0(); @@ -10810,16 +11613,16 @@ public final void rule__VersionNumber__Group_1__2__Impl() throws RecognitionExce // $ANTLR start "rule__VersionNumber__Group_1_2__0" - // InternalSemver.g:3081:1: rule__VersionNumber__Group_1_2__0 : rule__VersionNumber__Group_1_2__0__Impl rule__VersionNumber__Group_1_2__1 ; + // InternalSemver.g:3299:1: rule__VersionNumber__Group_1_2__0 : rule__VersionNumber__Group_1_2__0__Impl rule__VersionNumber__Group_1_2__1 ; public final void rule__VersionNumber__Group_1_2__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3085:1: ( rule__VersionNumber__Group_1_2__0__Impl rule__VersionNumber__Group_1_2__1 ) - // InternalSemver.g:3086:2: rule__VersionNumber__Group_1_2__0__Impl rule__VersionNumber__Group_1_2__1 + // InternalSemver.g:3303:1: ( rule__VersionNumber__Group_1_2__0__Impl rule__VersionNumber__Group_1_2__1 ) + // InternalSemver.g:3304:2: rule__VersionNumber__Group_1_2__0__Impl rule__VersionNumber__Group_1_2__1 { - pushFollow(FOLLOW_4); + pushFollow(FOLLOW_5); rule__VersionNumber__Group_1_2__0__Impl(); state._fsp--; @@ -10848,22 +11651,22 @@ public final void rule__VersionNumber__Group_1_2__0() throws RecognitionExceptio // $ANTLR start "rule__VersionNumber__Group_1_2__0__Impl" - // InternalSemver.g:3093:1: rule__VersionNumber__Group_1_2__0__Impl : ( '.' ) ; + // InternalSemver.g:3311:1: rule__VersionNumber__Group_1_2__0__Impl : ( '.' ) ; public final void rule__VersionNumber__Group_1_2__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3097:1: ( ( '.' ) ) - // InternalSemver.g:3098:1: ( '.' ) + // InternalSemver.g:3315:1: ( ( '.' ) ) + // InternalSemver.g:3316:1: ( '.' ) { - // InternalSemver.g:3098:1: ( '.' ) - // InternalSemver.g:3099:2: '.' + // InternalSemver.g:3316:1: ( '.' ) + // InternalSemver.g:3317:2: '.' { if ( state.backtracking==0 ) { before(grammarAccess.getVersionNumberAccess().getFullStopKeyword_1_2_0()); } - match(input,36,FOLLOW_2); if (state.failed) return ; + match(input,42,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getVersionNumberAccess().getFullStopKeyword_1_2_0()); } @@ -10889,16 +11692,16 @@ public final void rule__VersionNumber__Group_1_2__0__Impl() throws RecognitionEx // $ANTLR start "rule__VersionNumber__Group_1_2__1" - // InternalSemver.g:3108:1: rule__VersionNumber__Group_1_2__1 : rule__VersionNumber__Group_1_2__1__Impl rule__VersionNumber__Group_1_2__2 ; + // InternalSemver.g:3326:1: rule__VersionNumber__Group_1_2__1 : rule__VersionNumber__Group_1_2__1__Impl rule__VersionNumber__Group_1_2__2 ; public final void rule__VersionNumber__Group_1_2__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3112:1: ( rule__VersionNumber__Group_1_2__1__Impl rule__VersionNumber__Group_1_2__2 ) - // InternalSemver.g:3113:2: rule__VersionNumber__Group_1_2__1__Impl rule__VersionNumber__Group_1_2__2 + // InternalSemver.g:3330:1: ( rule__VersionNumber__Group_1_2__1__Impl rule__VersionNumber__Group_1_2__2 ) + // InternalSemver.g:3331:2: rule__VersionNumber__Group_1_2__1__Impl rule__VersionNumber__Group_1_2__2 { - pushFollow(FOLLOW_21); + pushFollow(FOLLOW_23); rule__VersionNumber__Group_1_2__1__Impl(); state._fsp--; @@ -10927,23 +11730,23 @@ public final void rule__VersionNumber__Group_1_2__1() throws RecognitionExceptio // $ANTLR start "rule__VersionNumber__Group_1_2__1__Impl" - // InternalSemver.g:3120:1: rule__VersionNumber__Group_1_2__1__Impl : ( ( rule__VersionNumber__PatchAssignment_1_2_1 ) ) ; + // InternalSemver.g:3338:1: rule__VersionNumber__Group_1_2__1__Impl : ( ( rule__VersionNumber__PatchAssignment_1_2_1 ) ) ; public final void rule__VersionNumber__Group_1_2__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3124:1: ( ( ( rule__VersionNumber__PatchAssignment_1_2_1 ) ) ) - // InternalSemver.g:3125:1: ( ( rule__VersionNumber__PatchAssignment_1_2_1 ) ) + // InternalSemver.g:3342:1: ( ( ( rule__VersionNumber__PatchAssignment_1_2_1 ) ) ) + // InternalSemver.g:3343:1: ( ( rule__VersionNumber__PatchAssignment_1_2_1 ) ) { - // InternalSemver.g:3125:1: ( ( rule__VersionNumber__PatchAssignment_1_2_1 ) ) - // InternalSemver.g:3126:2: ( rule__VersionNumber__PatchAssignment_1_2_1 ) + // InternalSemver.g:3343:1: ( ( rule__VersionNumber__PatchAssignment_1_2_1 ) ) + // InternalSemver.g:3344:2: ( rule__VersionNumber__PatchAssignment_1_2_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionNumberAccess().getPatchAssignment_1_2_1()); } - // InternalSemver.g:3127:2: ( rule__VersionNumber__PatchAssignment_1_2_1 ) - // InternalSemver.g:3127:3: rule__VersionNumber__PatchAssignment_1_2_1 + // InternalSemver.g:3345:2: ( rule__VersionNumber__PatchAssignment_1_2_1 ) + // InternalSemver.g:3345:3: rule__VersionNumber__PatchAssignment_1_2_1 { pushFollow(FOLLOW_2); rule__VersionNumber__PatchAssignment_1_2_1(); @@ -10978,14 +11781,14 @@ public final void rule__VersionNumber__Group_1_2__1__Impl() throws RecognitionEx // $ANTLR start "rule__VersionNumber__Group_1_2__2" - // InternalSemver.g:3135:1: rule__VersionNumber__Group_1_2__2 : rule__VersionNumber__Group_1_2__2__Impl ; + // InternalSemver.g:3353:1: rule__VersionNumber__Group_1_2__2 : rule__VersionNumber__Group_1_2__2__Impl ; public final void rule__VersionNumber__Group_1_2__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3139:1: ( rule__VersionNumber__Group_1_2__2__Impl ) - // InternalSemver.g:3140:2: rule__VersionNumber__Group_1_2__2__Impl + // InternalSemver.g:3357:1: ( rule__VersionNumber__Group_1_2__2__Impl ) + // InternalSemver.g:3358:2: rule__VersionNumber__Group_1_2__2__Impl { pushFollow(FOLLOW_2); rule__VersionNumber__Group_1_2__2__Impl(); @@ -11011,37 +11814,37 @@ public final void rule__VersionNumber__Group_1_2__2() throws RecognitionExceptio // $ANTLR start "rule__VersionNumber__Group_1_2__2__Impl" - // InternalSemver.g:3146:1: rule__VersionNumber__Group_1_2__2__Impl : ( ( rule__VersionNumber__Group_1_2_2__0 )* ) ; + // InternalSemver.g:3364:1: rule__VersionNumber__Group_1_2__2__Impl : ( ( rule__VersionNumber__Group_1_2_2__0 )* ) ; public final void rule__VersionNumber__Group_1_2__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3150:1: ( ( ( rule__VersionNumber__Group_1_2_2__0 )* ) ) - // InternalSemver.g:3151:1: ( ( rule__VersionNumber__Group_1_2_2__0 )* ) + // InternalSemver.g:3368:1: ( ( ( rule__VersionNumber__Group_1_2_2__0 )* ) ) + // InternalSemver.g:3369:1: ( ( rule__VersionNumber__Group_1_2_2__0 )* ) { - // InternalSemver.g:3151:1: ( ( rule__VersionNumber__Group_1_2_2__0 )* ) - // InternalSemver.g:3152:2: ( rule__VersionNumber__Group_1_2_2__0 )* + // InternalSemver.g:3369:1: ( ( rule__VersionNumber__Group_1_2_2__0 )* ) + // InternalSemver.g:3370:2: ( rule__VersionNumber__Group_1_2_2__0 )* { if ( state.backtracking==0 ) { before(grammarAccess.getVersionNumberAccess().getGroup_1_2_2()); } - // InternalSemver.g:3153:2: ( rule__VersionNumber__Group_1_2_2__0 )* - loop43: + // InternalSemver.g:3371:2: ( rule__VersionNumber__Group_1_2_2__0 )* + loop45: do { - int alt43=2; - int LA43_0 = input.LA(1); + int alt45=2; + int LA45_0 = input.LA(1); - if ( (LA43_0==36) ) { - alt43=1; + if ( (LA45_0==42) ) { + alt45=1; } - switch (alt43) { + switch (alt45) { case 1 : - // InternalSemver.g:3153:3: rule__VersionNumber__Group_1_2_2__0 + // InternalSemver.g:3371:3: rule__VersionNumber__Group_1_2_2__0 { - pushFollow(FOLLOW_22); + pushFollow(FOLLOW_24); rule__VersionNumber__Group_1_2_2__0(); state._fsp--; @@ -11051,7 +11854,7 @@ public final void rule__VersionNumber__Group_1_2__2__Impl() throws RecognitionEx break; default : - break loop43; + break loop45; } } while (true); @@ -11080,16 +11883,16 @@ public final void rule__VersionNumber__Group_1_2__2__Impl() throws RecognitionEx // $ANTLR start "rule__VersionNumber__Group_1_2_2__0" - // InternalSemver.g:3162:1: rule__VersionNumber__Group_1_2_2__0 : rule__VersionNumber__Group_1_2_2__0__Impl rule__VersionNumber__Group_1_2_2__1 ; + // InternalSemver.g:3380:1: rule__VersionNumber__Group_1_2_2__0 : rule__VersionNumber__Group_1_2_2__0__Impl rule__VersionNumber__Group_1_2_2__1 ; public final void rule__VersionNumber__Group_1_2_2__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3166:1: ( rule__VersionNumber__Group_1_2_2__0__Impl rule__VersionNumber__Group_1_2_2__1 ) - // InternalSemver.g:3167:2: rule__VersionNumber__Group_1_2_2__0__Impl rule__VersionNumber__Group_1_2_2__1 + // InternalSemver.g:3384:1: ( rule__VersionNumber__Group_1_2_2__0__Impl rule__VersionNumber__Group_1_2_2__1 ) + // InternalSemver.g:3385:2: rule__VersionNumber__Group_1_2_2__0__Impl rule__VersionNumber__Group_1_2_2__1 { - pushFollow(FOLLOW_4); + pushFollow(FOLLOW_5); rule__VersionNumber__Group_1_2_2__0__Impl(); state._fsp--; @@ -11118,22 +11921,22 @@ public final void rule__VersionNumber__Group_1_2_2__0() throws RecognitionExcept // $ANTLR start "rule__VersionNumber__Group_1_2_2__0__Impl" - // InternalSemver.g:3174:1: rule__VersionNumber__Group_1_2_2__0__Impl : ( '.' ) ; + // InternalSemver.g:3392:1: rule__VersionNumber__Group_1_2_2__0__Impl : ( '.' ) ; public final void rule__VersionNumber__Group_1_2_2__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3178:1: ( ( '.' ) ) - // InternalSemver.g:3179:1: ( '.' ) + // InternalSemver.g:3396:1: ( ( '.' ) ) + // InternalSemver.g:3397:1: ( '.' ) { - // InternalSemver.g:3179:1: ( '.' ) - // InternalSemver.g:3180:2: '.' + // InternalSemver.g:3397:1: ( '.' ) + // InternalSemver.g:3398:2: '.' { if ( state.backtracking==0 ) { before(grammarAccess.getVersionNumberAccess().getFullStopKeyword_1_2_2_0()); } - match(input,36,FOLLOW_2); if (state.failed) return ; + match(input,42,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getVersionNumberAccess().getFullStopKeyword_1_2_2_0()); } @@ -11159,14 +11962,14 @@ public final void rule__VersionNumber__Group_1_2_2__0__Impl() throws Recognition // $ANTLR start "rule__VersionNumber__Group_1_2_2__1" - // InternalSemver.g:3189:1: rule__VersionNumber__Group_1_2_2__1 : rule__VersionNumber__Group_1_2_2__1__Impl ; + // InternalSemver.g:3407:1: rule__VersionNumber__Group_1_2_2__1 : rule__VersionNumber__Group_1_2_2__1__Impl ; public final void rule__VersionNumber__Group_1_2_2__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3193:1: ( rule__VersionNumber__Group_1_2_2__1__Impl ) - // InternalSemver.g:3194:2: rule__VersionNumber__Group_1_2_2__1__Impl + // InternalSemver.g:3411:1: ( rule__VersionNumber__Group_1_2_2__1__Impl ) + // InternalSemver.g:3412:2: rule__VersionNumber__Group_1_2_2__1__Impl { pushFollow(FOLLOW_2); rule__VersionNumber__Group_1_2_2__1__Impl(); @@ -11192,23 +11995,23 @@ public final void rule__VersionNumber__Group_1_2_2__1() throws RecognitionExcept // $ANTLR start "rule__VersionNumber__Group_1_2_2__1__Impl" - // InternalSemver.g:3200:1: rule__VersionNumber__Group_1_2_2__1__Impl : ( ( rule__VersionNumber__ExtendedAssignment_1_2_2_1 ) ) ; + // InternalSemver.g:3418:1: rule__VersionNumber__Group_1_2_2__1__Impl : ( ( rule__VersionNumber__ExtendedAssignment_1_2_2_1 ) ) ; public final void rule__VersionNumber__Group_1_2_2__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3204:1: ( ( ( rule__VersionNumber__ExtendedAssignment_1_2_2_1 ) ) ) - // InternalSemver.g:3205:1: ( ( rule__VersionNumber__ExtendedAssignment_1_2_2_1 ) ) + // InternalSemver.g:3422:1: ( ( ( rule__VersionNumber__ExtendedAssignment_1_2_2_1 ) ) ) + // InternalSemver.g:3423:1: ( ( rule__VersionNumber__ExtendedAssignment_1_2_2_1 ) ) { - // InternalSemver.g:3205:1: ( ( rule__VersionNumber__ExtendedAssignment_1_2_2_1 ) ) - // InternalSemver.g:3206:2: ( rule__VersionNumber__ExtendedAssignment_1_2_2_1 ) + // InternalSemver.g:3423:1: ( ( rule__VersionNumber__ExtendedAssignment_1_2_2_1 ) ) + // InternalSemver.g:3424:2: ( rule__VersionNumber__ExtendedAssignment_1_2_2_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getVersionNumberAccess().getExtendedAssignment_1_2_2_1()); } - // InternalSemver.g:3207:2: ( rule__VersionNumber__ExtendedAssignment_1_2_2_1 ) - // InternalSemver.g:3207:3: rule__VersionNumber__ExtendedAssignment_1_2_2_1 + // InternalSemver.g:3425:2: ( rule__VersionNumber__ExtendedAssignment_1_2_2_1 ) + // InternalSemver.g:3425:3: rule__VersionNumber__ExtendedAssignment_1_2_2_1 { pushFollow(FOLLOW_2); rule__VersionNumber__ExtendedAssignment_1_2_2_1(); @@ -11243,16 +12046,16 @@ public final void rule__VersionNumber__Group_1_2_2__1__Impl() throws Recognition // $ANTLR start "rule__Qualifier__Group_0__0" - // InternalSemver.g:3216:1: rule__Qualifier__Group_0__0 : rule__Qualifier__Group_0__0__Impl rule__Qualifier__Group_0__1 ; + // InternalSemver.g:3434:1: rule__Qualifier__Group_0__0 : rule__Qualifier__Group_0__0__Impl rule__Qualifier__Group_0__1 ; public final void rule__Qualifier__Group_0__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3220:1: ( rule__Qualifier__Group_0__0__Impl rule__Qualifier__Group_0__1 ) - // InternalSemver.g:3221:2: rule__Qualifier__Group_0__0__Impl rule__Qualifier__Group_0__1 + // InternalSemver.g:3438:1: ( rule__Qualifier__Group_0__0__Impl rule__Qualifier__Group_0__1 ) + // InternalSemver.g:3439:2: rule__Qualifier__Group_0__0__Impl rule__Qualifier__Group_0__1 { - pushFollow(FOLLOW_11); + pushFollow(FOLLOW_12); rule__Qualifier__Group_0__0__Impl(); state._fsp--; @@ -11281,22 +12084,22 @@ public final void rule__Qualifier__Group_0__0() throws RecognitionException { // $ANTLR start "rule__Qualifier__Group_0__0__Impl" - // InternalSemver.g:3228:1: rule__Qualifier__Group_0__0__Impl : ( '-' ) ; + // InternalSemver.g:3446:1: rule__Qualifier__Group_0__0__Impl : ( '-' ) ; public final void rule__Qualifier__Group_0__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3232:1: ( ( '-' ) ) - // InternalSemver.g:3233:1: ( '-' ) + // InternalSemver.g:3450:1: ( ( '-' ) ) + // InternalSemver.g:3451:1: ( '-' ) { - // InternalSemver.g:3233:1: ( '-' ) - // InternalSemver.g:3234:2: '-' + // InternalSemver.g:3451:1: ( '-' ) + // InternalSemver.g:3452:2: '-' { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierAccess().getHyphenMinusKeyword_0_0()); } - match(input,38,FOLLOW_2); if (state.failed) return ; + match(input,47,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getQualifierAccess().getHyphenMinusKeyword_0_0()); } @@ -11322,16 +12125,16 @@ public final void rule__Qualifier__Group_0__0__Impl() throws RecognitionExceptio // $ANTLR start "rule__Qualifier__Group_0__1" - // InternalSemver.g:3243:1: rule__Qualifier__Group_0__1 : rule__Qualifier__Group_0__1__Impl rule__Qualifier__Group_0__2 ; + // InternalSemver.g:3461:1: rule__Qualifier__Group_0__1 : rule__Qualifier__Group_0__1__Impl rule__Qualifier__Group_0__2 ; public final void rule__Qualifier__Group_0__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3247:1: ( rule__Qualifier__Group_0__1__Impl rule__Qualifier__Group_0__2 ) - // InternalSemver.g:3248:2: rule__Qualifier__Group_0__1__Impl rule__Qualifier__Group_0__2 + // InternalSemver.g:3465:1: ( rule__Qualifier__Group_0__1__Impl rule__Qualifier__Group_0__2 ) + // InternalSemver.g:3466:2: rule__Qualifier__Group_0__1__Impl rule__Qualifier__Group_0__2 { - pushFollow(FOLLOW_23); + pushFollow(FOLLOW_25); rule__Qualifier__Group_0__1__Impl(); state._fsp--; @@ -11360,23 +12163,23 @@ public final void rule__Qualifier__Group_0__1() throws RecognitionException { // $ANTLR start "rule__Qualifier__Group_0__1__Impl" - // InternalSemver.g:3255:1: rule__Qualifier__Group_0__1__Impl : ( ( rule__Qualifier__PreReleaseAssignment_0_1 ) ) ; + // InternalSemver.g:3473:1: rule__Qualifier__Group_0__1__Impl : ( ( rule__Qualifier__PreReleaseAssignment_0_1 ) ) ; public final void rule__Qualifier__Group_0__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3259:1: ( ( ( rule__Qualifier__PreReleaseAssignment_0_1 ) ) ) - // InternalSemver.g:3260:1: ( ( rule__Qualifier__PreReleaseAssignment_0_1 ) ) + // InternalSemver.g:3477:1: ( ( ( rule__Qualifier__PreReleaseAssignment_0_1 ) ) ) + // InternalSemver.g:3478:1: ( ( rule__Qualifier__PreReleaseAssignment_0_1 ) ) { - // InternalSemver.g:3260:1: ( ( rule__Qualifier__PreReleaseAssignment_0_1 ) ) - // InternalSemver.g:3261:2: ( rule__Qualifier__PreReleaseAssignment_0_1 ) + // InternalSemver.g:3478:1: ( ( rule__Qualifier__PreReleaseAssignment_0_1 ) ) + // InternalSemver.g:3479:2: ( rule__Qualifier__PreReleaseAssignment_0_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierAccess().getPreReleaseAssignment_0_1()); } - // InternalSemver.g:3262:2: ( rule__Qualifier__PreReleaseAssignment_0_1 ) - // InternalSemver.g:3262:3: rule__Qualifier__PreReleaseAssignment_0_1 + // InternalSemver.g:3480:2: ( rule__Qualifier__PreReleaseAssignment_0_1 ) + // InternalSemver.g:3480:3: rule__Qualifier__PreReleaseAssignment_0_1 { pushFollow(FOLLOW_2); rule__Qualifier__PreReleaseAssignment_0_1(); @@ -11411,14 +12214,14 @@ public final void rule__Qualifier__Group_0__1__Impl() throws RecognitionExceptio // $ANTLR start "rule__Qualifier__Group_0__2" - // InternalSemver.g:3270:1: rule__Qualifier__Group_0__2 : rule__Qualifier__Group_0__2__Impl ; + // InternalSemver.g:3488:1: rule__Qualifier__Group_0__2 : rule__Qualifier__Group_0__2__Impl ; public final void rule__Qualifier__Group_0__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3274:1: ( rule__Qualifier__Group_0__2__Impl ) - // InternalSemver.g:3275:2: rule__Qualifier__Group_0__2__Impl + // InternalSemver.g:3492:1: ( rule__Qualifier__Group_0__2__Impl ) + // InternalSemver.g:3493:2: rule__Qualifier__Group_0__2__Impl { pushFollow(FOLLOW_2); rule__Qualifier__Group_0__2__Impl(); @@ -11444,31 +12247,31 @@ public final void rule__Qualifier__Group_0__2() throws RecognitionException { // $ANTLR start "rule__Qualifier__Group_0__2__Impl" - // InternalSemver.g:3281:1: rule__Qualifier__Group_0__2__Impl : ( ( rule__Qualifier__Group_0_2__0 )? ) ; + // InternalSemver.g:3499:1: rule__Qualifier__Group_0__2__Impl : ( ( rule__Qualifier__Group_0_2__0 )? ) ; public final void rule__Qualifier__Group_0__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3285:1: ( ( ( rule__Qualifier__Group_0_2__0 )? ) ) - // InternalSemver.g:3286:1: ( ( rule__Qualifier__Group_0_2__0 )? ) + // InternalSemver.g:3503:1: ( ( ( rule__Qualifier__Group_0_2__0 )? ) ) + // InternalSemver.g:3504:1: ( ( rule__Qualifier__Group_0_2__0 )? ) { - // InternalSemver.g:3286:1: ( ( rule__Qualifier__Group_0_2__0 )? ) - // InternalSemver.g:3287:2: ( rule__Qualifier__Group_0_2__0 )? + // InternalSemver.g:3504:1: ( ( rule__Qualifier__Group_0_2__0 )? ) + // InternalSemver.g:3505:2: ( rule__Qualifier__Group_0_2__0 )? { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierAccess().getGroup_0_2()); } - // InternalSemver.g:3288:2: ( rule__Qualifier__Group_0_2__0 )? - int alt44=2; - int LA44_0 = input.LA(1); + // InternalSemver.g:3506:2: ( rule__Qualifier__Group_0_2__0 )? + int alt46=2; + int LA46_0 = input.LA(1); - if ( (LA44_0==40) ) { - alt44=1; + if ( (LA46_0==45) ) { + alt46=1; } - switch (alt44) { + switch (alt46) { case 1 : - // InternalSemver.g:3288:3: rule__Qualifier__Group_0_2__0 + // InternalSemver.g:3506:3: rule__Qualifier__Group_0_2__0 { pushFollow(FOLLOW_2); rule__Qualifier__Group_0_2__0(); @@ -11506,16 +12309,16 @@ public final void rule__Qualifier__Group_0__2__Impl() throws RecognitionExceptio // $ANTLR start "rule__Qualifier__Group_0_2__0" - // InternalSemver.g:3297:1: rule__Qualifier__Group_0_2__0 : rule__Qualifier__Group_0_2__0__Impl rule__Qualifier__Group_0_2__1 ; + // InternalSemver.g:3515:1: rule__Qualifier__Group_0_2__0 : rule__Qualifier__Group_0_2__0__Impl rule__Qualifier__Group_0_2__1 ; public final void rule__Qualifier__Group_0_2__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3301:1: ( rule__Qualifier__Group_0_2__0__Impl rule__Qualifier__Group_0_2__1 ) - // InternalSemver.g:3302:2: rule__Qualifier__Group_0_2__0__Impl rule__Qualifier__Group_0_2__1 + // InternalSemver.g:3519:1: ( rule__Qualifier__Group_0_2__0__Impl rule__Qualifier__Group_0_2__1 ) + // InternalSemver.g:3520:2: rule__Qualifier__Group_0_2__0__Impl rule__Qualifier__Group_0_2__1 { - pushFollow(FOLLOW_11); + pushFollow(FOLLOW_12); rule__Qualifier__Group_0_2__0__Impl(); state._fsp--; @@ -11544,22 +12347,22 @@ public final void rule__Qualifier__Group_0_2__0() throws RecognitionException { // $ANTLR start "rule__Qualifier__Group_0_2__0__Impl" - // InternalSemver.g:3309:1: rule__Qualifier__Group_0_2__0__Impl : ( '+' ) ; + // InternalSemver.g:3527:1: rule__Qualifier__Group_0_2__0__Impl : ( '+' ) ; public final void rule__Qualifier__Group_0_2__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3313:1: ( ( '+' ) ) - // InternalSemver.g:3314:1: ( '+' ) + // InternalSemver.g:3531:1: ( ( '+' ) ) + // InternalSemver.g:3532:1: ( '+' ) { - // InternalSemver.g:3314:1: ( '+' ) - // InternalSemver.g:3315:2: '+' + // InternalSemver.g:3532:1: ( '+' ) + // InternalSemver.g:3533:2: '+' { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierAccess().getPlusSignKeyword_0_2_0()); } - match(input,40,FOLLOW_2); if (state.failed) return ; + match(input,45,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getQualifierAccess().getPlusSignKeyword_0_2_0()); } @@ -11585,14 +12388,14 @@ public final void rule__Qualifier__Group_0_2__0__Impl() throws RecognitionExcept // $ANTLR start "rule__Qualifier__Group_0_2__1" - // InternalSemver.g:3324:1: rule__Qualifier__Group_0_2__1 : rule__Qualifier__Group_0_2__1__Impl ; + // InternalSemver.g:3542:1: rule__Qualifier__Group_0_2__1 : rule__Qualifier__Group_0_2__1__Impl ; public final void rule__Qualifier__Group_0_2__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3328:1: ( rule__Qualifier__Group_0_2__1__Impl ) - // InternalSemver.g:3329:2: rule__Qualifier__Group_0_2__1__Impl + // InternalSemver.g:3546:1: ( rule__Qualifier__Group_0_2__1__Impl ) + // InternalSemver.g:3547:2: rule__Qualifier__Group_0_2__1__Impl { pushFollow(FOLLOW_2); rule__Qualifier__Group_0_2__1__Impl(); @@ -11618,23 +12421,23 @@ public final void rule__Qualifier__Group_0_2__1() throws RecognitionException { // $ANTLR start "rule__Qualifier__Group_0_2__1__Impl" - // InternalSemver.g:3335:1: rule__Qualifier__Group_0_2__1__Impl : ( ( rule__Qualifier__BuildMetadataAssignment_0_2_1 ) ) ; + // InternalSemver.g:3553:1: rule__Qualifier__Group_0_2__1__Impl : ( ( rule__Qualifier__BuildMetadataAssignment_0_2_1 ) ) ; public final void rule__Qualifier__Group_0_2__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3339:1: ( ( ( rule__Qualifier__BuildMetadataAssignment_0_2_1 ) ) ) - // InternalSemver.g:3340:1: ( ( rule__Qualifier__BuildMetadataAssignment_0_2_1 ) ) + // InternalSemver.g:3557:1: ( ( ( rule__Qualifier__BuildMetadataAssignment_0_2_1 ) ) ) + // InternalSemver.g:3558:1: ( ( rule__Qualifier__BuildMetadataAssignment_0_2_1 ) ) { - // InternalSemver.g:3340:1: ( ( rule__Qualifier__BuildMetadataAssignment_0_2_1 ) ) - // InternalSemver.g:3341:2: ( rule__Qualifier__BuildMetadataAssignment_0_2_1 ) + // InternalSemver.g:3558:1: ( ( rule__Qualifier__BuildMetadataAssignment_0_2_1 ) ) + // InternalSemver.g:3559:2: ( rule__Qualifier__BuildMetadataAssignment_0_2_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierAccess().getBuildMetadataAssignment_0_2_1()); } - // InternalSemver.g:3342:2: ( rule__Qualifier__BuildMetadataAssignment_0_2_1 ) - // InternalSemver.g:3342:3: rule__Qualifier__BuildMetadataAssignment_0_2_1 + // InternalSemver.g:3560:2: ( rule__Qualifier__BuildMetadataAssignment_0_2_1 ) + // InternalSemver.g:3560:3: rule__Qualifier__BuildMetadataAssignment_0_2_1 { pushFollow(FOLLOW_2); rule__Qualifier__BuildMetadataAssignment_0_2_1(); @@ -11669,16 +12472,16 @@ public final void rule__Qualifier__Group_0_2__1__Impl() throws RecognitionExcept // $ANTLR start "rule__Qualifier__Group_1__0" - // InternalSemver.g:3351:1: rule__Qualifier__Group_1__0 : rule__Qualifier__Group_1__0__Impl rule__Qualifier__Group_1__1 ; + // InternalSemver.g:3569:1: rule__Qualifier__Group_1__0 : rule__Qualifier__Group_1__0__Impl rule__Qualifier__Group_1__1 ; public final void rule__Qualifier__Group_1__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3355:1: ( rule__Qualifier__Group_1__0__Impl rule__Qualifier__Group_1__1 ) - // InternalSemver.g:3356:2: rule__Qualifier__Group_1__0__Impl rule__Qualifier__Group_1__1 + // InternalSemver.g:3573:1: ( rule__Qualifier__Group_1__0__Impl rule__Qualifier__Group_1__1 ) + // InternalSemver.g:3574:2: rule__Qualifier__Group_1__0__Impl rule__Qualifier__Group_1__1 { - pushFollow(FOLLOW_11); + pushFollow(FOLLOW_12); rule__Qualifier__Group_1__0__Impl(); state._fsp--; @@ -11707,22 +12510,22 @@ public final void rule__Qualifier__Group_1__0() throws RecognitionException { // $ANTLR start "rule__Qualifier__Group_1__0__Impl" - // InternalSemver.g:3363:1: rule__Qualifier__Group_1__0__Impl : ( '+' ) ; + // InternalSemver.g:3581:1: rule__Qualifier__Group_1__0__Impl : ( '+' ) ; public final void rule__Qualifier__Group_1__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3367:1: ( ( '+' ) ) - // InternalSemver.g:3368:1: ( '+' ) + // InternalSemver.g:3585:1: ( ( '+' ) ) + // InternalSemver.g:3586:1: ( '+' ) { - // InternalSemver.g:3368:1: ( '+' ) - // InternalSemver.g:3369:2: '+' + // InternalSemver.g:3586:1: ( '+' ) + // InternalSemver.g:3587:2: '+' { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierAccess().getPlusSignKeyword_1_0()); } - match(input,40,FOLLOW_2); if (state.failed) return ; + match(input,45,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getQualifierAccess().getPlusSignKeyword_1_0()); } @@ -11748,14 +12551,14 @@ public final void rule__Qualifier__Group_1__0__Impl() throws RecognitionExceptio // $ANTLR start "rule__Qualifier__Group_1__1" - // InternalSemver.g:3378:1: rule__Qualifier__Group_1__1 : rule__Qualifier__Group_1__1__Impl ; + // InternalSemver.g:3596:1: rule__Qualifier__Group_1__1 : rule__Qualifier__Group_1__1__Impl ; public final void rule__Qualifier__Group_1__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3382:1: ( rule__Qualifier__Group_1__1__Impl ) - // InternalSemver.g:3383:2: rule__Qualifier__Group_1__1__Impl + // InternalSemver.g:3600:1: ( rule__Qualifier__Group_1__1__Impl ) + // InternalSemver.g:3601:2: rule__Qualifier__Group_1__1__Impl { pushFollow(FOLLOW_2); rule__Qualifier__Group_1__1__Impl(); @@ -11781,23 +12584,23 @@ public final void rule__Qualifier__Group_1__1() throws RecognitionException { // $ANTLR start "rule__Qualifier__Group_1__1__Impl" - // InternalSemver.g:3389:1: rule__Qualifier__Group_1__1__Impl : ( ( rule__Qualifier__BuildMetadataAssignment_1_1 ) ) ; + // InternalSemver.g:3607:1: rule__Qualifier__Group_1__1__Impl : ( ( rule__Qualifier__BuildMetadataAssignment_1_1 ) ) ; public final void rule__Qualifier__Group_1__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3393:1: ( ( ( rule__Qualifier__BuildMetadataAssignment_1_1 ) ) ) - // InternalSemver.g:3394:1: ( ( rule__Qualifier__BuildMetadataAssignment_1_1 ) ) + // InternalSemver.g:3611:1: ( ( ( rule__Qualifier__BuildMetadataAssignment_1_1 ) ) ) + // InternalSemver.g:3612:1: ( ( rule__Qualifier__BuildMetadataAssignment_1_1 ) ) { - // InternalSemver.g:3394:1: ( ( rule__Qualifier__BuildMetadataAssignment_1_1 ) ) - // InternalSemver.g:3395:2: ( rule__Qualifier__BuildMetadataAssignment_1_1 ) + // InternalSemver.g:3612:1: ( ( rule__Qualifier__BuildMetadataAssignment_1_1 ) ) + // InternalSemver.g:3613:2: ( rule__Qualifier__BuildMetadataAssignment_1_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierAccess().getBuildMetadataAssignment_1_1()); } - // InternalSemver.g:3396:2: ( rule__Qualifier__BuildMetadataAssignment_1_1 ) - // InternalSemver.g:3396:3: rule__Qualifier__BuildMetadataAssignment_1_1 + // InternalSemver.g:3614:2: ( rule__Qualifier__BuildMetadataAssignment_1_1 ) + // InternalSemver.g:3614:3: rule__Qualifier__BuildMetadataAssignment_1_1 { pushFollow(FOLLOW_2); rule__Qualifier__BuildMetadataAssignment_1_1(); @@ -11832,16 +12635,16 @@ public final void rule__Qualifier__Group_1__1__Impl() throws RecognitionExceptio // $ANTLR start "rule__QualifierTag__Group__0" - // InternalSemver.g:3405:1: rule__QualifierTag__Group__0 : rule__QualifierTag__Group__0__Impl rule__QualifierTag__Group__1 ; + // InternalSemver.g:3623:1: rule__QualifierTag__Group__0 : rule__QualifierTag__Group__0__Impl rule__QualifierTag__Group__1 ; public final void rule__QualifierTag__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3409:1: ( rule__QualifierTag__Group__0__Impl rule__QualifierTag__Group__1 ) - // InternalSemver.g:3410:2: rule__QualifierTag__Group__0__Impl rule__QualifierTag__Group__1 + // InternalSemver.g:3627:1: ( rule__QualifierTag__Group__0__Impl rule__QualifierTag__Group__1 ) + // InternalSemver.g:3628:2: rule__QualifierTag__Group__0__Impl rule__QualifierTag__Group__1 { - pushFollow(FOLLOW_21); + pushFollow(FOLLOW_23); rule__QualifierTag__Group__0__Impl(); state._fsp--; @@ -11870,23 +12673,23 @@ public final void rule__QualifierTag__Group__0() throws RecognitionException { // $ANTLR start "rule__QualifierTag__Group__0__Impl" - // InternalSemver.g:3417:1: rule__QualifierTag__Group__0__Impl : ( ( rule__QualifierTag__PartsAssignment_0 ) ) ; + // InternalSemver.g:3635:1: rule__QualifierTag__Group__0__Impl : ( ( rule__QualifierTag__PartsAssignment_0 ) ) ; public final void rule__QualifierTag__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3421:1: ( ( ( rule__QualifierTag__PartsAssignment_0 ) ) ) - // InternalSemver.g:3422:1: ( ( rule__QualifierTag__PartsAssignment_0 ) ) + // InternalSemver.g:3639:1: ( ( ( rule__QualifierTag__PartsAssignment_0 ) ) ) + // InternalSemver.g:3640:1: ( ( rule__QualifierTag__PartsAssignment_0 ) ) { - // InternalSemver.g:3422:1: ( ( rule__QualifierTag__PartsAssignment_0 ) ) - // InternalSemver.g:3423:2: ( rule__QualifierTag__PartsAssignment_0 ) + // InternalSemver.g:3640:1: ( ( rule__QualifierTag__PartsAssignment_0 ) ) + // InternalSemver.g:3641:2: ( rule__QualifierTag__PartsAssignment_0 ) { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierTagAccess().getPartsAssignment_0()); } - // InternalSemver.g:3424:2: ( rule__QualifierTag__PartsAssignment_0 ) - // InternalSemver.g:3424:3: rule__QualifierTag__PartsAssignment_0 + // InternalSemver.g:3642:2: ( rule__QualifierTag__PartsAssignment_0 ) + // InternalSemver.g:3642:3: rule__QualifierTag__PartsAssignment_0 { pushFollow(FOLLOW_2); rule__QualifierTag__PartsAssignment_0(); @@ -11921,14 +12724,14 @@ public final void rule__QualifierTag__Group__0__Impl() throws RecognitionExcepti // $ANTLR start "rule__QualifierTag__Group__1" - // InternalSemver.g:3432:1: rule__QualifierTag__Group__1 : rule__QualifierTag__Group__1__Impl ; + // InternalSemver.g:3650:1: rule__QualifierTag__Group__1 : rule__QualifierTag__Group__1__Impl ; public final void rule__QualifierTag__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3436:1: ( rule__QualifierTag__Group__1__Impl ) - // InternalSemver.g:3437:2: rule__QualifierTag__Group__1__Impl + // InternalSemver.g:3654:1: ( rule__QualifierTag__Group__1__Impl ) + // InternalSemver.g:3655:2: rule__QualifierTag__Group__1__Impl { pushFollow(FOLLOW_2); rule__QualifierTag__Group__1__Impl(); @@ -11954,37 +12757,37 @@ public final void rule__QualifierTag__Group__1() throws RecognitionException { // $ANTLR start "rule__QualifierTag__Group__1__Impl" - // InternalSemver.g:3443:1: rule__QualifierTag__Group__1__Impl : ( ( rule__QualifierTag__Group_1__0 )* ) ; + // InternalSemver.g:3661:1: rule__QualifierTag__Group__1__Impl : ( ( rule__QualifierTag__Group_1__0 )* ) ; public final void rule__QualifierTag__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3447:1: ( ( ( rule__QualifierTag__Group_1__0 )* ) ) - // InternalSemver.g:3448:1: ( ( rule__QualifierTag__Group_1__0 )* ) + // InternalSemver.g:3665:1: ( ( ( rule__QualifierTag__Group_1__0 )* ) ) + // InternalSemver.g:3666:1: ( ( rule__QualifierTag__Group_1__0 )* ) { - // InternalSemver.g:3448:1: ( ( rule__QualifierTag__Group_1__0 )* ) - // InternalSemver.g:3449:2: ( rule__QualifierTag__Group_1__0 )* + // InternalSemver.g:3666:1: ( ( rule__QualifierTag__Group_1__0 )* ) + // InternalSemver.g:3667:2: ( rule__QualifierTag__Group_1__0 )* { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierTagAccess().getGroup_1()); } - // InternalSemver.g:3450:2: ( rule__QualifierTag__Group_1__0 )* - loop45: + // InternalSemver.g:3668:2: ( rule__QualifierTag__Group_1__0 )* + loop47: do { - int alt45=2; - int LA45_0 = input.LA(1); + int alt47=2; + int LA47_0 = input.LA(1); - if ( (LA45_0==36) ) { - alt45=1; + if ( (LA47_0==42) ) { + alt47=1; } - switch (alt45) { + switch (alt47) { case 1 : - // InternalSemver.g:3450:3: rule__QualifierTag__Group_1__0 + // InternalSemver.g:3668:3: rule__QualifierTag__Group_1__0 { - pushFollow(FOLLOW_22); + pushFollow(FOLLOW_24); rule__QualifierTag__Group_1__0(); state._fsp--; @@ -11994,7 +12797,7 @@ public final void rule__QualifierTag__Group__1__Impl() throws RecognitionExcepti break; default : - break loop45; + break loop47; } } while (true); @@ -12023,16 +12826,16 @@ public final void rule__QualifierTag__Group__1__Impl() throws RecognitionExcepti // $ANTLR start "rule__QualifierTag__Group_1__0" - // InternalSemver.g:3459:1: rule__QualifierTag__Group_1__0 : rule__QualifierTag__Group_1__0__Impl rule__QualifierTag__Group_1__1 ; + // InternalSemver.g:3677:1: rule__QualifierTag__Group_1__0 : rule__QualifierTag__Group_1__0__Impl rule__QualifierTag__Group_1__1 ; public final void rule__QualifierTag__Group_1__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3463:1: ( rule__QualifierTag__Group_1__0__Impl rule__QualifierTag__Group_1__1 ) - // InternalSemver.g:3464:2: rule__QualifierTag__Group_1__0__Impl rule__QualifierTag__Group_1__1 + // InternalSemver.g:3681:1: ( rule__QualifierTag__Group_1__0__Impl rule__QualifierTag__Group_1__1 ) + // InternalSemver.g:3682:2: rule__QualifierTag__Group_1__0__Impl rule__QualifierTag__Group_1__1 { - pushFollow(FOLLOW_11); + pushFollow(FOLLOW_12); rule__QualifierTag__Group_1__0__Impl(); state._fsp--; @@ -12061,22 +12864,22 @@ public final void rule__QualifierTag__Group_1__0() throws RecognitionException { // $ANTLR start "rule__QualifierTag__Group_1__0__Impl" - // InternalSemver.g:3471:1: rule__QualifierTag__Group_1__0__Impl : ( '.' ) ; + // InternalSemver.g:3689:1: rule__QualifierTag__Group_1__0__Impl : ( '.' ) ; public final void rule__QualifierTag__Group_1__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3475:1: ( ( '.' ) ) - // InternalSemver.g:3476:1: ( '.' ) + // InternalSemver.g:3693:1: ( ( '.' ) ) + // InternalSemver.g:3694:1: ( '.' ) { - // InternalSemver.g:3476:1: ( '.' ) - // InternalSemver.g:3477:2: '.' + // InternalSemver.g:3694:1: ( '.' ) + // InternalSemver.g:3695:2: '.' { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierTagAccess().getFullStopKeyword_1_0()); } - match(input,36,FOLLOW_2); if (state.failed) return ; + match(input,42,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getQualifierTagAccess().getFullStopKeyword_1_0()); } @@ -12102,14 +12905,14 @@ public final void rule__QualifierTag__Group_1__0__Impl() throws RecognitionExcep // $ANTLR start "rule__QualifierTag__Group_1__1" - // InternalSemver.g:3486:1: rule__QualifierTag__Group_1__1 : rule__QualifierTag__Group_1__1__Impl ; + // InternalSemver.g:3704:1: rule__QualifierTag__Group_1__1 : rule__QualifierTag__Group_1__1__Impl ; public final void rule__QualifierTag__Group_1__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3490:1: ( rule__QualifierTag__Group_1__1__Impl ) - // InternalSemver.g:3491:2: rule__QualifierTag__Group_1__1__Impl + // InternalSemver.g:3708:1: ( rule__QualifierTag__Group_1__1__Impl ) + // InternalSemver.g:3709:2: rule__QualifierTag__Group_1__1__Impl { pushFollow(FOLLOW_2); rule__QualifierTag__Group_1__1__Impl(); @@ -12135,23 +12938,23 @@ public final void rule__QualifierTag__Group_1__1() throws RecognitionException { // $ANTLR start "rule__QualifierTag__Group_1__1__Impl" - // InternalSemver.g:3497:1: rule__QualifierTag__Group_1__1__Impl : ( ( rule__QualifierTag__PartsAssignment_1_1 ) ) ; + // InternalSemver.g:3715:1: rule__QualifierTag__Group_1__1__Impl : ( ( rule__QualifierTag__PartsAssignment_1_1 ) ) ; public final void rule__QualifierTag__Group_1__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3501:1: ( ( ( rule__QualifierTag__PartsAssignment_1_1 ) ) ) - // InternalSemver.g:3502:1: ( ( rule__QualifierTag__PartsAssignment_1_1 ) ) + // InternalSemver.g:3719:1: ( ( ( rule__QualifierTag__PartsAssignment_1_1 ) ) ) + // InternalSemver.g:3720:1: ( ( rule__QualifierTag__PartsAssignment_1_1 ) ) { - // InternalSemver.g:3502:1: ( ( rule__QualifierTag__PartsAssignment_1_1 ) ) - // InternalSemver.g:3503:2: ( rule__QualifierTag__PartsAssignment_1_1 ) + // InternalSemver.g:3720:1: ( ( rule__QualifierTag__PartsAssignment_1_1 ) ) + // InternalSemver.g:3721:2: ( rule__QualifierTag__PartsAssignment_1_1 ) { if ( state.backtracking==0 ) { before(grammarAccess.getQualifierTagAccess().getPartsAssignment_1_1()); } - // InternalSemver.g:3504:2: ( rule__QualifierTag__PartsAssignment_1_1 ) - // InternalSemver.g:3504:3: rule__QualifierTag__PartsAssignment_1_1 + // InternalSemver.g:3722:2: ( rule__QualifierTag__PartsAssignment_1_1 ) + // InternalSemver.g:3722:3: rule__QualifierTag__PartsAssignment_1_1 { pushFollow(FOLLOW_2); rule__QualifierTag__PartsAssignment_1_1(); @@ -12186,16 +12989,16 @@ public final void rule__QualifierTag__Group_1__1__Impl() throws RecognitionExcep // $ANTLR start "rule__FILE_TAG__Group__0" - // InternalSemver.g:3513:1: rule__FILE_TAG__Group__0 : rule__FILE_TAG__Group__0__Impl rule__FILE_TAG__Group__1 ; + // InternalSemver.g:3731:1: rule__FILE_TAG__Group__0 : rule__FILE_TAG__Group__0__Impl rule__FILE_TAG__Group__1 ; public final void rule__FILE_TAG__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3517:1: ( rule__FILE_TAG__Group__0__Impl rule__FILE_TAG__Group__1 ) - // InternalSemver.g:3518:2: rule__FILE_TAG__Group__0__Impl rule__FILE_TAG__Group__1 + // InternalSemver.g:3735:1: ( rule__FILE_TAG__Group__0__Impl rule__FILE_TAG__Group__1 ) + // InternalSemver.g:3736:2: rule__FILE_TAG__Group__0__Impl rule__FILE_TAG__Group__1 { - pushFollow(FOLLOW_24); + pushFollow(FOLLOW_26); rule__FILE_TAG__Group__0__Impl(); state._fsp--; @@ -12224,17 +13027,17 @@ public final void rule__FILE_TAG__Group__0() throws RecognitionException { // $ANTLR start "rule__FILE_TAG__Group__0__Impl" - // InternalSemver.g:3525:1: rule__FILE_TAG__Group__0__Impl : ( RULE_LETTER_F ) ; + // InternalSemver.g:3743:1: rule__FILE_TAG__Group__0__Impl : ( RULE_LETTER_F ) ; public final void rule__FILE_TAG__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3529:1: ( ( RULE_LETTER_F ) ) - // InternalSemver.g:3530:1: ( RULE_LETTER_F ) + // InternalSemver.g:3747:1: ( ( RULE_LETTER_F ) ) + // InternalSemver.g:3748:1: ( RULE_LETTER_F ) { - // InternalSemver.g:3530:1: ( RULE_LETTER_F ) - // InternalSemver.g:3531:2: RULE_LETTER_F + // InternalSemver.g:3748:1: ( RULE_LETTER_F ) + // InternalSemver.g:3749:2: RULE_LETTER_F { if ( state.backtracking==0 ) { before(grammarAccess.getFILE_TAGAccess().getLETTER_FTerminalRuleCall_0()); @@ -12265,16 +13068,16 @@ public final void rule__FILE_TAG__Group__0__Impl() throws RecognitionException { // $ANTLR start "rule__FILE_TAG__Group__1" - // InternalSemver.g:3540:1: rule__FILE_TAG__Group__1 : rule__FILE_TAG__Group__1__Impl rule__FILE_TAG__Group__2 ; + // InternalSemver.g:3758:1: rule__FILE_TAG__Group__1 : rule__FILE_TAG__Group__1__Impl rule__FILE_TAG__Group__2 ; public final void rule__FILE_TAG__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3544:1: ( rule__FILE_TAG__Group__1__Impl rule__FILE_TAG__Group__2 ) - // InternalSemver.g:3545:2: rule__FILE_TAG__Group__1__Impl rule__FILE_TAG__Group__2 + // InternalSemver.g:3762:1: ( rule__FILE_TAG__Group__1__Impl rule__FILE_TAG__Group__2 ) + // InternalSemver.g:3763:2: rule__FILE_TAG__Group__1__Impl rule__FILE_TAG__Group__2 { - pushFollow(FOLLOW_25); + pushFollow(FOLLOW_27); rule__FILE_TAG__Group__1__Impl(); state._fsp--; @@ -12303,17 +13106,17 @@ public final void rule__FILE_TAG__Group__1() throws RecognitionException { // $ANTLR start "rule__FILE_TAG__Group__1__Impl" - // InternalSemver.g:3552:1: rule__FILE_TAG__Group__1__Impl : ( RULE_LETTER_I ) ; + // InternalSemver.g:3770:1: rule__FILE_TAG__Group__1__Impl : ( RULE_LETTER_I ) ; public final void rule__FILE_TAG__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3556:1: ( ( RULE_LETTER_I ) ) - // InternalSemver.g:3557:1: ( RULE_LETTER_I ) + // InternalSemver.g:3774:1: ( ( RULE_LETTER_I ) ) + // InternalSemver.g:3775:1: ( RULE_LETTER_I ) { - // InternalSemver.g:3557:1: ( RULE_LETTER_I ) - // InternalSemver.g:3558:2: RULE_LETTER_I + // InternalSemver.g:3775:1: ( RULE_LETTER_I ) + // InternalSemver.g:3776:2: RULE_LETTER_I { if ( state.backtracking==0 ) { before(grammarAccess.getFILE_TAGAccess().getLETTER_ITerminalRuleCall_1()); @@ -12344,16 +13147,16 @@ public final void rule__FILE_TAG__Group__1__Impl() throws RecognitionException { // $ANTLR start "rule__FILE_TAG__Group__2" - // InternalSemver.g:3567:1: rule__FILE_TAG__Group__2 : rule__FILE_TAG__Group__2__Impl rule__FILE_TAG__Group__3 ; + // InternalSemver.g:3785:1: rule__FILE_TAG__Group__2 : rule__FILE_TAG__Group__2__Impl rule__FILE_TAG__Group__3 ; public final void rule__FILE_TAG__Group__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3571:1: ( rule__FILE_TAG__Group__2__Impl rule__FILE_TAG__Group__3 ) - // InternalSemver.g:3572:2: rule__FILE_TAG__Group__2__Impl rule__FILE_TAG__Group__3 + // InternalSemver.g:3789:1: ( rule__FILE_TAG__Group__2__Impl rule__FILE_TAG__Group__3 ) + // InternalSemver.g:3790:2: rule__FILE_TAG__Group__2__Impl rule__FILE_TAG__Group__3 { - pushFollow(FOLLOW_26); + pushFollow(FOLLOW_28); rule__FILE_TAG__Group__2__Impl(); state._fsp--; @@ -12382,17 +13185,17 @@ public final void rule__FILE_TAG__Group__2() throws RecognitionException { // $ANTLR start "rule__FILE_TAG__Group__2__Impl" - // InternalSemver.g:3579:1: rule__FILE_TAG__Group__2__Impl : ( RULE_LETTER_L ) ; + // InternalSemver.g:3797:1: rule__FILE_TAG__Group__2__Impl : ( RULE_LETTER_L ) ; public final void rule__FILE_TAG__Group__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3583:1: ( ( RULE_LETTER_L ) ) - // InternalSemver.g:3584:1: ( RULE_LETTER_L ) + // InternalSemver.g:3801:1: ( ( RULE_LETTER_L ) ) + // InternalSemver.g:3802:1: ( RULE_LETTER_L ) { - // InternalSemver.g:3584:1: ( RULE_LETTER_L ) - // InternalSemver.g:3585:2: RULE_LETTER_L + // InternalSemver.g:3802:1: ( RULE_LETTER_L ) + // InternalSemver.g:3803:2: RULE_LETTER_L { if ( state.backtracking==0 ) { before(grammarAccess.getFILE_TAGAccess().getLETTER_LTerminalRuleCall_2()); @@ -12423,16 +13226,16 @@ public final void rule__FILE_TAG__Group__2__Impl() throws RecognitionException { // $ANTLR start "rule__FILE_TAG__Group__3" - // InternalSemver.g:3594:1: rule__FILE_TAG__Group__3 : rule__FILE_TAG__Group__3__Impl rule__FILE_TAG__Group__4 ; + // InternalSemver.g:3812:1: rule__FILE_TAG__Group__3 : rule__FILE_TAG__Group__3__Impl rule__FILE_TAG__Group__4 ; public final void rule__FILE_TAG__Group__3() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3598:1: ( rule__FILE_TAG__Group__3__Impl rule__FILE_TAG__Group__4 ) - // InternalSemver.g:3599:2: rule__FILE_TAG__Group__3__Impl rule__FILE_TAG__Group__4 + // InternalSemver.g:3816:1: ( rule__FILE_TAG__Group__3__Impl rule__FILE_TAG__Group__4 ) + // InternalSemver.g:3817:2: rule__FILE_TAG__Group__3__Impl rule__FILE_TAG__Group__4 { - pushFollow(FOLLOW_7); + pushFollow(FOLLOW_8); rule__FILE_TAG__Group__3__Impl(); state._fsp--; @@ -12461,17 +13264,17 @@ public final void rule__FILE_TAG__Group__3() throws RecognitionException { // $ANTLR start "rule__FILE_TAG__Group__3__Impl" - // InternalSemver.g:3606:1: rule__FILE_TAG__Group__3__Impl : ( RULE_LETTER_E ) ; + // InternalSemver.g:3824:1: rule__FILE_TAG__Group__3__Impl : ( RULE_LETTER_E ) ; public final void rule__FILE_TAG__Group__3__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3610:1: ( ( RULE_LETTER_E ) ) - // InternalSemver.g:3611:1: ( RULE_LETTER_E ) + // InternalSemver.g:3828:1: ( ( RULE_LETTER_E ) ) + // InternalSemver.g:3829:1: ( RULE_LETTER_E ) { - // InternalSemver.g:3611:1: ( RULE_LETTER_E ) - // InternalSemver.g:3612:2: RULE_LETTER_E + // InternalSemver.g:3829:1: ( RULE_LETTER_E ) + // InternalSemver.g:3830:2: RULE_LETTER_E { if ( state.backtracking==0 ) { before(grammarAccess.getFILE_TAGAccess().getLETTER_ETerminalRuleCall_3()); @@ -12502,14 +13305,14 @@ public final void rule__FILE_TAG__Group__3__Impl() throws RecognitionException { // $ANTLR start "rule__FILE_TAG__Group__4" - // InternalSemver.g:3621:1: rule__FILE_TAG__Group__4 : rule__FILE_TAG__Group__4__Impl ; + // InternalSemver.g:3839:1: rule__FILE_TAG__Group__4 : rule__FILE_TAG__Group__4__Impl ; public final void rule__FILE_TAG__Group__4() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3625:1: ( rule__FILE_TAG__Group__4__Impl ) - // InternalSemver.g:3626:2: rule__FILE_TAG__Group__4__Impl + // InternalSemver.g:3843:1: ( rule__FILE_TAG__Group__4__Impl ) + // InternalSemver.g:3844:2: rule__FILE_TAG__Group__4__Impl { pushFollow(FOLLOW_2); rule__FILE_TAG__Group__4__Impl(); @@ -12535,22 +13338,22 @@ public final void rule__FILE_TAG__Group__4() throws RecognitionException { // $ANTLR start "rule__FILE_TAG__Group__4__Impl" - // InternalSemver.g:3632:1: rule__FILE_TAG__Group__4__Impl : ( ':' ) ; + // InternalSemver.g:3850:1: rule__FILE_TAG__Group__4__Impl : ( ':' ) ; public final void rule__FILE_TAG__Group__4__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3636:1: ( ( ':' ) ) - // InternalSemver.g:3637:1: ( ':' ) + // InternalSemver.g:3854:1: ( ( ':' ) ) + // InternalSemver.g:3855:1: ( ':' ) { - // InternalSemver.g:3637:1: ( ':' ) - // InternalSemver.g:3638:2: ':' + // InternalSemver.g:3855:1: ( ':' ) + // InternalSemver.g:3856:2: ':' { if ( state.backtracking==0 ) { before(grammarAccess.getFILE_TAGAccess().getColonKeyword_4()); } - match(input,41,FOLLOW_2); if (state.failed) return ; + match(input,46,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getFILE_TAGAccess().getColonKeyword_4()); } @@ -12576,16 +13379,16 @@ public final void rule__FILE_TAG__Group__4__Impl() throws RecognitionException { // $ANTLR start "rule__SEMVER_TAG__Group__0" - // InternalSemver.g:3648:1: rule__SEMVER_TAG__Group__0 : rule__SEMVER_TAG__Group__0__Impl rule__SEMVER_TAG__Group__1 ; + // InternalSemver.g:3866:1: rule__SEMVER_TAG__Group__0 : rule__SEMVER_TAG__Group__0__Impl rule__SEMVER_TAG__Group__1 ; public final void rule__SEMVER_TAG__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3652:1: ( rule__SEMVER_TAG__Group__0__Impl rule__SEMVER_TAG__Group__1 ) - // InternalSemver.g:3653:2: rule__SEMVER_TAG__Group__0__Impl rule__SEMVER_TAG__Group__1 + // InternalSemver.g:3870:1: ( rule__SEMVER_TAG__Group__0__Impl rule__SEMVER_TAG__Group__1 ) + // InternalSemver.g:3871:2: rule__SEMVER_TAG__Group__0__Impl rule__SEMVER_TAG__Group__1 { - pushFollow(FOLLOW_26); + pushFollow(FOLLOW_28); rule__SEMVER_TAG__Group__0__Impl(); state._fsp--; @@ -12614,17 +13417,17 @@ public final void rule__SEMVER_TAG__Group__0() throws RecognitionException { // $ANTLR start "rule__SEMVER_TAG__Group__0__Impl" - // InternalSemver.g:3660:1: rule__SEMVER_TAG__Group__0__Impl : ( RULE_LETTER_S ) ; + // InternalSemver.g:3878:1: rule__SEMVER_TAG__Group__0__Impl : ( RULE_LETTER_S ) ; public final void rule__SEMVER_TAG__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3664:1: ( ( RULE_LETTER_S ) ) - // InternalSemver.g:3665:1: ( RULE_LETTER_S ) + // InternalSemver.g:3882:1: ( ( RULE_LETTER_S ) ) + // InternalSemver.g:3883:1: ( RULE_LETTER_S ) { - // InternalSemver.g:3665:1: ( RULE_LETTER_S ) - // InternalSemver.g:3666:2: RULE_LETTER_S + // InternalSemver.g:3883:1: ( RULE_LETTER_S ) + // InternalSemver.g:3884:2: RULE_LETTER_S { if ( state.backtracking==0 ) { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_STerminalRuleCall_0()); @@ -12655,16 +13458,16 @@ public final void rule__SEMVER_TAG__Group__0__Impl() throws RecognitionException // $ANTLR start "rule__SEMVER_TAG__Group__1" - // InternalSemver.g:3675:1: rule__SEMVER_TAG__Group__1 : rule__SEMVER_TAG__Group__1__Impl rule__SEMVER_TAG__Group__2 ; + // InternalSemver.g:3893:1: rule__SEMVER_TAG__Group__1 : rule__SEMVER_TAG__Group__1__Impl rule__SEMVER_TAG__Group__2 ; public final void rule__SEMVER_TAG__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3679:1: ( rule__SEMVER_TAG__Group__1__Impl rule__SEMVER_TAG__Group__2 ) - // InternalSemver.g:3680:2: rule__SEMVER_TAG__Group__1__Impl rule__SEMVER_TAG__Group__2 + // InternalSemver.g:3897:1: ( rule__SEMVER_TAG__Group__1__Impl rule__SEMVER_TAG__Group__2 ) + // InternalSemver.g:3898:2: rule__SEMVER_TAG__Group__1__Impl rule__SEMVER_TAG__Group__2 { - pushFollow(FOLLOW_27); + pushFollow(FOLLOW_29); rule__SEMVER_TAG__Group__1__Impl(); state._fsp--; @@ -12693,17 +13496,17 @@ public final void rule__SEMVER_TAG__Group__1() throws RecognitionException { // $ANTLR start "rule__SEMVER_TAG__Group__1__Impl" - // InternalSemver.g:3687:1: rule__SEMVER_TAG__Group__1__Impl : ( RULE_LETTER_E ) ; + // InternalSemver.g:3905:1: rule__SEMVER_TAG__Group__1__Impl : ( RULE_LETTER_E ) ; public final void rule__SEMVER_TAG__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3691:1: ( ( RULE_LETTER_E ) ) - // InternalSemver.g:3692:1: ( RULE_LETTER_E ) + // InternalSemver.g:3909:1: ( ( RULE_LETTER_E ) ) + // InternalSemver.g:3910:1: ( RULE_LETTER_E ) { - // InternalSemver.g:3692:1: ( RULE_LETTER_E ) - // InternalSemver.g:3693:2: RULE_LETTER_E + // InternalSemver.g:3910:1: ( RULE_LETTER_E ) + // InternalSemver.g:3911:2: RULE_LETTER_E { if ( state.backtracking==0 ) { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_ETerminalRuleCall_1()); @@ -12734,16 +13537,16 @@ public final void rule__SEMVER_TAG__Group__1__Impl() throws RecognitionException // $ANTLR start "rule__SEMVER_TAG__Group__2" - // InternalSemver.g:3702:1: rule__SEMVER_TAG__Group__2 : rule__SEMVER_TAG__Group__2__Impl rule__SEMVER_TAG__Group__3 ; + // InternalSemver.g:3920:1: rule__SEMVER_TAG__Group__2 : rule__SEMVER_TAG__Group__2__Impl rule__SEMVER_TAG__Group__3 ; public final void rule__SEMVER_TAG__Group__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3706:1: ( rule__SEMVER_TAG__Group__2__Impl rule__SEMVER_TAG__Group__3 ) - // InternalSemver.g:3707:2: rule__SEMVER_TAG__Group__2__Impl rule__SEMVER_TAG__Group__3 + // InternalSemver.g:3924:1: ( rule__SEMVER_TAG__Group__2__Impl rule__SEMVER_TAG__Group__3 ) + // InternalSemver.g:3925:2: rule__SEMVER_TAG__Group__2__Impl rule__SEMVER_TAG__Group__3 { - pushFollow(FOLLOW_28); + pushFollow(FOLLOW_30); rule__SEMVER_TAG__Group__2__Impl(); state._fsp--; @@ -12772,17 +13575,17 @@ public final void rule__SEMVER_TAG__Group__2() throws RecognitionException { // $ANTLR start "rule__SEMVER_TAG__Group__2__Impl" - // InternalSemver.g:3714:1: rule__SEMVER_TAG__Group__2__Impl : ( RULE_LETTER_M ) ; + // InternalSemver.g:3932:1: rule__SEMVER_TAG__Group__2__Impl : ( RULE_LETTER_M ) ; public final void rule__SEMVER_TAG__Group__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3718:1: ( ( RULE_LETTER_M ) ) - // InternalSemver.g:3719:1: ( RULE_LETTER_M ) + // InternalSemver.g:3936:1: ( ( RULE_LETTER_M ) ) + // InternalSemver.g:3937:1: ( RULE_LETTER_M ) { - // InternalSemver.g:3719:1: ( RULE_LETTER_M ) - // InternalSemver.g:3720:2: RULE_LETTER_M + // InternalSemver.g:3937:1: ( RULE_LETTER_M ) + // InternalSemver.g:3938:2: RULE_LETTER_M { if ( state.backtracking==0 ) { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_MTerminalRuleCall_2()); @@ -12813,16 +13616,16 @@ public final void rule__SEMVER_TAG__Group__2__Impl() throws RecognitionException // $ANTLR start "rule__SEMVER_TAG__Group__3" - // InternalSemver.g:3729:1: rule__SEMVER_TAG__Group__3 : rule__SEMVER_TAG__Group__3__Impl rule__SEMVER_TAG__Group__4 ; + // InternalSemver.g:3947:1: rule__SEMVER_TAG__Group__3 : rule__SEMVER_TAG__Group__3__Impl rule__SEMVER_TAG__Group__4 ; public final void rule__SEMVER_TAG__Group__3() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3733:1: ( rule__SEMVER_TAG__Group__3__Impl rule__SEMVER_TAG__Group__4 ) - // InternalSemver.g:3734:2: rule__SEMVER_TAG__Group__3__Impl rule__SEMVER_TAG__Group__4 + // InternalSemver.g:3951:1: ( rule__SEMVER_TAG__Group__3__Impl rule__SEMVER_TAG__Group__4 ) + // InternalSemver.g:3952:2: rule__SEMVER_TAG__Group__3__Impl rule__SEMVER_TAG__Group__4 { - pushFollow(FOLLOW_26); + pushFollow(FOLLOW_28); rule__SEMVER_TAG__Group__3__Impl(); state._fsp--; @@ -12851,17 +13654,17 @@ public final void rule__SEMVER_TAG__Group__3() throws RecognitionException { // $ANTLR start "rule__SEMVER_TAG__Group__3__Impl" - // InternalSemver.g:3741:1: rule__SEMVER_TAG__Group__3__Impl : ( RULE_LETTER_V ) ; + // InternalSemver.g:3959:1: rule__SEMVER_TAG__Group__3__Impl : ( RULE_LETTER_V ) ; public final void rule__SEMVER_TAG__Group__3__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3745:1: ( ( RULE_LETTER_V ) ) - // InternalSemver.g:3746:1: ( RULE_LETTER_V ) + // InternalSemver.g:3963:1: ( ( RULE_LETTER_V ) ) + // InternalSemver.g:3964:1: ( RULE_LETTER_V ) { - // InternalSemver.g:3746:1: ( RULE_LETTER_V ) - // InternalSemver.g:3747:2: RULE_LETTER_V + // InternalSemver.g:3964:1: ( RULE_LETTER_V ) + // InternalSemver.g:3965:2: RULE_LETTER_V { if ( state.backtracking==0 ) { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_VTerminalRuleCall_3()); @@ -12892,16 +13695,16 @@ public final void rule__SEMVER_TAG__Group__3__Impl() throws RecognitionException // $ANTLR start "rule__SEMVER_TAG__Group__4" - // InternalSemver.g:3756:1: rule__SEMVER_TAG__Group__4 : rule__SEMVER_TAG__Group__4__Impl rule__SEMVER_TAG__Group__5 ; + // InternalSemver.g:3974:1: rule__SEMVER_TAG__Group__4 : rule__SEMVER_TAG__Group__4__Impl rule__SEMVER_TAG__Group__5 ; public final void rule__SEMVER_TAG__Group__4() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3760:1: ( rule__SEMVER_TAG__Group__4__Impl rule__SEMVER_TAG__Group__5 ) - // InternalSemver.g:3761:2: rule__SEMVER_TAG__Group__4__Impl rule__SEMVER_TAG__Group__5 + // InternalSemver.g:3978:1: ( rule__SEMVER_TAG__Group__4__Impl rule__SEMVER_TAG__Group__5 ) + // InternalSemver.g:3979:2: rule__SEMVER_TAG__Group__4__Impl rule__SEMVER_TAG__Group__5 { - pushFollow(FOLLOW_29); + pushFollow(FOLLOW_31); rule__SEMVER_TAG__Group__4__Impl(); state._fsp--; @@ -12930,17 +13733,17 @@ public final void rule__SEMVER_TAG__Group__4() throws RecognitionException { // $ANTLR start "rule__SEMVER_TAG__Group__4__Impl" - // InternalSemver.g:3768:1: rule__SEMVER_TAG__Group__4__Impl : ( RULE_LETTER_E ) ; + // InternalSemver.g:3986:1: rule__SEMVER_TAG__Group__4__Impl : ( RULE_LETTER_E ) ; public final void rule__SEMVER_TAG__Group__4__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3772:1: ( ( RULE_LETTER_E ) ) - // InternalSemver.g:3773:1: ( RULE_LETTER_E ) + // InternalSemver.g:3990:1: ( ( RULE_LETTER_E ) ) + // InternalSemver.g:3991:1: ( RULE_LETTER_E ) { - // InternalSemver.g:3773:1: ( RULE_LETTER_E ) - // InternalSemver.g:3774:2: RULE_LETTER_E + // InternalSemver.g:3991:1: ( RULE_LETTER_E ) + // InternalSemver.g:3992:2: RULE_LETTER_E { if ( state.backtracking==0 ) { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_ETerminalRuleCall_4()); @@ -12971,16 +13774,16 @@ public final void rule__SEMVER_TAG__Group__4__Impl() throws RecognitionException // $ANTLR start "rule__SEMVER_TAG__Group__5" - // InternalSemver.g:3783:1: rule__SEMVER_TAG__Group__5 : rule__SEMVER_TAG__Group__5__Impl rule__SEMVER_TAG__Group__6 ; + // InternalSemver.g:4001:1: rule__SEMVER_TAG__Group__5 : rule__SEMVER_TAG__Group__5__Impl rule__SEMVER_TAG__Group__6 ; public final void rule__SEMVER_TAG__Group__5() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3787:1: ( rule__SEMVER_TAG__Group__5__Impl rule__SEMVER_TAG__Group__6 ) - // InternalSemver.g:3788:2: rule__SEMVER_TAG__Group__5__Impl rule__SEMVER_TAG__Group__6 + // InternalSemver.g:4005:1: ( rule__SEMVER_TAG__Group__5__Impl rule__SEMVER_TAG__Group__6 ) + // InternalSemver.g:4006:2: rule__SEMVER_TAG__Group__5__Impl rule__SEMVER_TAG__Group__6 { - pushFollow(FOLLOW_7); + pushFollow(FOLLOW_8); rule__SEMVER_TAG__Group__5__Impl(); state._fsp--; @@ -13009,17 +13812,17 @@ public final void rule__SEMVER_TAG__Group__5() throws RecognitionException { // $ANTLR start "rule__SEMVER_TAG__Group__5__Impl" - // InternalSemver.g:3795:1: rule__SEMVER_TAG__Group__5__Impl : ( RULE_LETTER_R ) ; + // InternalSemver.g:4013:1: rule__SEMVER_TAG__Group__5__Impl : ( RULE_LETTER_R ) ; public final void rule__SEMVER_TAG__Group__5__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3799:1: ( ( RULE_LETTER_R ) ) - // InternalSemver.g:3800:1: ( RULE_LETTER_R ) + // InternalSemver.g:4017:1: ( ( RULE_LETTER_R ) ) + // InternalSemver.g:4018:1: ( RULE_LETTER_R ) { - // InternalSemver.g:3800:1: ( RULE_LETTER_R ) - // InternalSemver.g:3801:2: RULE_LETTER_R + // InternalSemver.g:4018:1: ( RULE_LETTER_R ) + // InternalSemver.g:4019:2: RULE_LETTER_R { if ( state.backtracking==0 ) { before(grammarAccess.getSEMVER_TAGAccess().getLETTER_RTerminalRuleCall_5()); @@ -13050,14 +13853,14 @@ public final void rule__SEMVER_TAG__Group__5__Impl() throws RecognitionException // $ANTLR start "rule__SEMVER_TAG__Group__6" - // InternalSemver.g:3810:1: rule__SEMVER_TAG__Group__6 : rule__SEMVER_TAG__Group__6__Impl ; + // InternalSemver.g:4028:1: rule__SEMVER_TAG__Group__6 : rule__SEMVER_TAG__Group__6__Impl ; public final void rule__SEMVER_TAG__Group__6() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3814:1: ( rule__SEMVER_TAG__Group__6__Impl ) - // InternalSemver.g:3815:2: rule__SEMVER_TAG__Group__6__Impl + // InternalSemver.g:4032:1: ( rule__SEMVER_TAG__Group__6__Impl ) + // InternalSemver.g:4033:2: rule__SEMVER_TAG__Group__6__Impl { pushFollow(FOLLOW_2); rule__SEMVER_TAG__Group__6__Impl(); @@ -13083,22 +13886,22 @@ public final void rule__SEMVER_TAG__Group__6() throws RecognitionException { // $ANTLR start "rule__SEMVER_TAG__Group__6__Impl" - // InternalSemver.g:3821:1: rule__SEMVER_TAG__Group__6__Impl : ( ':' ) ; + // InternalSemver.g:4039:1: rule__SEMVER_TAG__Group__6__Impl : ( ':' ) ; public final void rule__SEMVER_TAG__Group__6__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3825:1: ( ( ':' ) ) - // InternalSemver.g:3826:1: ( ':' ) + // InternalSemver.g:4043:1: ( ( ':' ) ) + // InternalSemver.g:4044:1: ( ':' ) { - // InternalSemver.g:3826:1: ( ':' ) - // InternalSemver.g:3827:2: ':' + // InternalSemver.g:4044:1: ( ':' ) + // InternalSemver.g:4045:2: ':' { if ( state.backtracking==0 ) { before(grammarAccess.getSEMVER_TAGAccess().getColonKeyword_6()); } - match(input,41,FOLLOW_2); if (state.failed) return ; + match(input,46,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { after(grammarAccess.getSEMVER_TAGAccess().getColonKeyword_6()); } @@ -13123,23 +13926,23 @@ public final void rule__SEMVER_TAG__Group__6__Impl() throws RecognitionException // $ANTLR end "rule__SEMVER_TAG__Group__6__Impl" - // $ANTLR start "rule__URL_PROTOCOL__Group__0" - // InternalSemver.g:3837:1: rule__URL_PROTOCOL__Group__0 : rule__URL_PROTOCOL__Group__0__Impl rule__URL_PROTOCOL__Group__1 ; - public final void rule__URL_PROTOCOL__Group__0() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__0" + // InternalSemver.g:4055:1: rule__WORKSPACE_TAG__Group__0 : rule__WORKSPACE_TAG__Group__0__Impl rule__WORKSPACE_TAG__Group__1 ; + public final void rule__WORKSPACE_TAG__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3841:1: ( rule__URL_PROTOCOL__Group__0__Impl rule__URL_PROTOCOL__Group__1 ) - // InternalSemver.g:3842:2: rule__URL_PROTOCOL__Group__0__Impl rule__URL_PROTOCOL__Group__1 + // InternalSemver.g:4059:1: ( rule__WORKSPACE_TAG__Group__0__Impl rule__WORKSPACE_TAG__Group__1 ) + // InternalSemver.g:4060:2: rule__WORKSPACE_TAG__Group__0__Impl rule__WORKSPACE_TAG__Group__1 { - pushFollow(FOLLOW_30); - rule__URL_PROTOCOL__Group__0__Impl(); + pushFollow(FOLLOW_32); + rule__WORKSPACE_TAG__Group__0__Impl(); state._fsp--; if (state.failed) return ; pushFollow(FOLLOW_2); - rule__URL_PROTOCOL__Group__1(); + rule__WORKSPACE_TAG__Group__1(); state._fsp--; if (state.failed) return ; @@ -13158,32 +13961,28 @@ public final void rule__URL_PROTOCOL__Group__0() throws RecognitionException { } return ; } - // $ANTLR end "rule__URL_PROTOCOL__Group__0" + // $ANTLR end "rule__WORKSPACE_TAG__Group__0" - // $ANTLR start "rule__URL_PROTOCOL__Group__0__Impl" - // InternalSemver.g:3849:1: rule__URL_PROTOCOL__Group__0__Impl : ( ruleLETTER_NO_VX ) ; - public final void rule__URL_PROTOCOL__Group__0__Impl() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__0__Impl" + // InternalSemver.g:4067:1: rule__WORKSPACE_TAG__Group__0__Impl : ( RULE_LETTER_W ) ; + public final void rule__WORKSPACE_TAG__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3853:1: ( ( ruleLETTER_NO_VX ) ) - // InternalSemver.g:3854:1: ( ruleLETTER_NO_VX ) + // InternalSemver.g:4071:1: ( ( RULE_LETTER_W ) ) + // InternalSemver.g:4072:1: ( RULE_LETTER_W ) { - // InternalSemver.g:3854:1: ( ruleLETTER_NO_VX ) - // InternalSemver.g:3855:2: ruleLETTER_NO_VX + // InternalSemver.g:4072:1: ( RULE_LETTER_W ) + // InternalSemver.g:4073:2: RULE_LETTER_W { if ( state.backtracking==0 ) { - before(grammarAccess.getURL_PROTOCOLAccess().getLETTER_NO_VXParserRuleCall_0()); + before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_WTerminalRuleCall_0()); } - pushFollow(FOLLOW_2); - ruleLETTER_NO_VX(); - - state._fsp--; - if (state.failed) return ; + match(input,RULE_LETTER_W,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURL_PROTOCOLAccess().getLETTER_NO_VXParserRuleCall_0()); + after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_WTerminalRuleCall_0()); } } @@ -13203,21 +14002,26 @@ public final void rule__URL_PROTOCOL__Group__0__Impl() throws RecognitionExcepti } return ; } - // $ANTLR end "rule__URL_PROTOCOL__Group__0__Impl" + // $ANTLR end "rule__WORKSPACE_TAG__Group__0__Impl" - // $ANTLR start "rule__URL_PROTOCOL__Group__1" - // InternalSemver.g:3864:1: rule__URL_PROTOCOL__Group__1 : rule__URL_PROTOCOL__Group__1__Impl ; - public final void rule__URL_PROTOCOL__Group__1() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__1" + // InternalSemver.g:4082:1: rule__WORKSPACE_TAG__Group__1 : rule__WORKSPACE_TAG__Group__1__Impl rule__WORKSPACE_TAG__Group__2 ; + public final void rule__WORKSPACE_TAG__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3868:1: ( rule__URL_PROTOCOL__Group__1__Impl ) - // InternalSemver.g:3869:2: rule__URL_PROTOCOL__Group__1__Impl + // InternalSemver.g:4086:1: ( rule__WORKSPACE_TAG__Group__1__Impl rule__WORKSPACE_TAG__Group__2 ) + // InternalSemver.g:4087:2: rule__WORKSPACE_TAG__Group__1__Impl rule__WORKSPACE_TAG__Group__2 { + pushFollow(FOLLOW_31); + rule__WORKSPACE_TAG__Group__1__Impl(); + + state._fsp--; + if (state.failed) return ; pushFollow(FOLLOW_2); - rule__URL_PROTOCOL__Group__1__Impl(); + rule__WORKSPACE_TAG__Group__2(); state._fsp--; if (state.failed) return ; @@ -13236,87 +14040,30 @@ public final void rule__URL_PROTOCOL__Group__1() throws RecognitionException { } return ; } - // $ANTLR end "rule__URL_PROTOCOL__Group__1" + // $ANTLR end "rule__WORKSPACE_TAG__Group__1" - // $ANTLR start "rule__URL_PROTOCOL__Group__1__Impl" - // InternalSemver.g:3875:1: rule__URL_PROTOCOL__Group__1__Impl : ( ( ( rule__URL_PROTOCOL__Alternatives_1 ) ) ( ( rule__URL_PROTOCOL__Alternatives_1 )* ) ) ; - public final void rule__URL_PROTOCOL__Group__1__Impl() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__1__Impl" + // InternalSemver.g:4094:1: rule__WORKSPACE_TAG__Group__1__Impl : ( RULE_LETTER_O ) ; + public final void rule__WORKSPACE_TAG__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3879:1: ( ( ( ( rule__URL_PROTOCOL__Alternatives_1 ) ) ( ( rule__URL_PROTOCOL__Alternatives_1 )* ) ) ) - // InternalSemver.g:3880:1: ( ( ( rule__URL_PROTOCOL__Alternatives_1 ) ) ( ( rule__URL_PROTOCOL__Alternatives_1 )* ) ) + // InternalSemver.g:4098:1: ( ( RULE_LETTER_O ) ) + // InternalSemver.g:4099:1: ( RULE_LETTER_O ) { - // InternalSemver.g:3880:1: ( ( ( rule__URL_PROTOCOL__Alternatives_1 ) ) ( ( rule__URL_PROTOCOL__Alternatives_1 )* ) ) - // InternalSemver.g:3881:2: ( ( rule__URL_PROTOCOL__Alternatives_1 ) ) ( ( rule__URL_PROTOCOL__Alternatives_1 )* ) - { - // InternalSemver.g:3881:2: ( ( rule__URL_PROTOCOL__Alternatives_1 ) ) - // InternalSemver.g:3882:3: ( rule__URL_PROTOCOL__Alternatives_1 ) - { - if ( state.backtracking==0 ) { - before(grammarAccess.getURL_PROTOCOLAccess().getAlternatives_1()); - } - // InternalSemver.g:3883:3: ( rule__URL_PROTOCOL__Alternatives_1 ) - // InternalSemver.g:3883:4: rule__URL_PROTOCOL__Alternatives_1 - { - pushFollow(FOLLOW_31); - rule__URL_PROTOCOL__Alternatives_1(); - - state._fsp--; - if (state.failed) return ; - - } - - if ( state.backtracking==0 ) { - after(grammarAccess.getURL_PROTOCOLAccess().getAlternatives_1()); - } - - } - - // InternalSemver.g:3886:2: ( ( rule__URL_PROTOCOL__Alternatives_1 )* ) - // InternalSemver.g:3887:3: ( rule__URL_PROTOCOL__Alternatives_1 )* + // InternalSemver.g:4099:1: ( RULE_LETTER_O ) + // InternalSemver.g:4100:2: RULE_LETTER_O { if ( state.backtracking==0 ) { - before(grammarAccess.getURL_PROTOCOLAccess().getAlternatives_1()); + before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_OTerminalRuleCall_1()); } - // InternalSemver.g:3888:3: ( rule__URL_PROTOCOL__Alternatives_1 )* - loop46: - do { - int alt46=2; - int LA46_0 = input.LA(1); - - if ( (LA46_0==RULE_LETTER_X||(LA46_0>=RULE_LETTER_V && LA46_0<=RULE_LETTER_OTHER)||LA46_0==40) ) { - alt46=1; - } - - - switch (alt46) { - case 1 : - // InternalSemver.g:3888:4: rule__URL_PROTOCOL__Alternatives_1 - { - pushFollow(FOLLOW_31); - rule__URL_PROTOCOL__Alternatives_1(); - - state._fsp--; - if (state.failed) return ; - - } - break; - - default : - break loop46; - } - } while (true); - + match(input,RULE_LETTER_O,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURL_PROTOCOLAccess().getAlternatives_1()); - } - + after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_OTerminalRuleCall_1()); } - } @@ -13334,26 +14081,26 @@ public final void rule__URL_PROTOCOL__Group__1__Impl() throws RecognitionExcepti } return ; } - // $ANTLR end "rule__URL_PROTOCOL__Group__1__Impl" + // $ANTLR end "rule__WORKSPACE_TAG__Group__1__Impl" - // $ANTLR start "rule__URL__Group__0" - // InternalSemver.g:3898:1: rule__URL__Group__0 : rule__URL__Group__0__Impl rule__URL__Group__1 ; - public final void rule__URL__Group__0() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__2" + // InternalSemver.g:4109:1: rule__WORKSPACE_TAG__Group__2 : rule__WORKSPACE_TAG__Group__2__Impl rule__WORKSPACE_TAG__Group__3 ; + public final void rule__WORKSPACE_TAG__Group__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3902:1: ( rule__URL__Group__0__Impl rule__URL__Group__1 ) - // InternalSemver.g:3903:2: rule__URL__Group__0__Impl rule__URL__Group__1 + // InternalSemver.g:4113:1: ( rule__WORKSPACE_TAG__Group__2__Impl rule__WORKSPACE_TAG__Group__3 ) + // InternalSemver.g:4114:2: rule__WORKSPACE_TAG__Group__2__Impl rule__WORKSPACE_TAG__Group__3 { - pushFollow(FOLLOW_8); - rule__URL__Group__0__Impl(); + pushFollow(FOLLOW_33); + rule__WORKSPACE_TAG__Group__2__Impl(); state._fsp--; if (state.failed) return ; pushFollow(FOLLOW_2); - rule__URL__Group__1(); + rule__WORKSPACE_TAG__Group__3(); state._fsp--; if (state.failed) return ; @@ -13372,56 +14119,28 @@ public final void rule__URL__Group__0() throws RecognitionException { } return ; } - // $ANTLR end "rule__URL__Group__0" + // $ANTLR end "rule__WORKSPACE_TAG__Group__2" - // $ANTLR start "rule__URL__Group__0__Impl" - // InternalSemver.g:3910:1: rule__URL__Group__0__Impl : ( ( rule__URL__Alternatives_0 )* ) ; - public final void rule__URL__Group__0__Impl() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__2__Impl" + // InternalSemver.g:4121:1: rule__WORKSPACE_TAG__Group__2__Impl : ( RULE_LETTER_R ) ; + public final void rule__WORKSPACE_TAG__Group__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3914:1: ( ( ( rule__URL__Alternatives_0 )* ) ) - // InternalSemver.g:3915:1: ( ( rule__URL__Alternatives_0 )* ) + // InternalSemver.g:4125:1: ( ( RULE_LETTER_R ) ) + // InternalSemver.g:4126:1: ( RULE_LETTER_R ) { - // InternalSemver.g:3915:1: ( ( rule__URL__Alternatives_0 )* ) - // InternalSemver.g:3916:2: ( rule__URL__Alternatives_0 )* + // InternalSemver.g:4126:1: ( RULE_LETTER_R ) + // InternalSemver.g:4127:2: RULE_LETTER_R { if ( state.backtracking==0 ) { - before(grammarAccess.getURLAccess().getAlternatives_0()); + before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_RTerminalRuleCall_2()); } - // InternalSemver.g:3917:2: ( rule__URL__Alternatives_0 )* - loop47: - do { - int alt47=2; - int LA47_0 = input.LA(1); - - if ( ((LA47_0>=RULE_DIGITS && LA47_0<=RULE_LETTER_X)||(LA47_0>=RULE_LETTER_V && LA47_0<=RULE_LETTER_OTHER)||(LA47_0>=38 && LA47_0<=39)) ) { - alt47=1; - } - - - switch (alt47) { - case 1 : - // InternalSemver.g:3917:3: rule__URL__Alternatives_0 - { - pushFollow(FOLLOW_3); - rule__URL__Alternatives_0(); - - state._fsp--; - if (state.failed) return ; - - } - break; - - default : - break loop47; - } - } while (true); - + match(input,RULE_LETTER_R,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURLAccess().getAlternatives_0()); + after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_RTerminalRuleCall_2()); } } @@ -13441,26 +14160,26 @@ public final void rule__URL__Group__0__Impl() throws RecognitionException { } return ; } - // $ANTLR end "rule__URL__Group__0__Impl" + // $ANTLR end "rule__WORKSPACE_TAG__Group__2__Impl" - // $ANTLR start "rule__URL__Group__1" - // InternalSemver.g:3925:1: rule__URL__Group__1 : rule__URL__Group__1__Impl rule__URL__Group__2 ; - public final void rule__URL__Group__1() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__3" + // InternalSemver.g:4136:1: rule__WORKSPACE_TAG__Group__3 : rule__WORKSPACE_TAG__Group__3__Impl rule__WORKSPACE_TAG__Group__4 ; + public final void rule__WORKSPACE_TAG__Group__3() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3929:1: ( rule__URL__Group__1__Impl rule__URL__Group__2 ) - // InternalSemver.g:3930:2: rule__URL__Group__1__Impl rule__URL__Group__2 + // InternalSemver.g:4140:1: ( rule__WORKSPACE_TAG__Group__3__Impl rule__WORKSPACE_TAG__Group__4 ) + // InternalSemver.g:4141:2: rule__WORKSPACE_TAG__Group__3__Impl rule__WORKSPACE_TAG__Group__4 { - pushFollow(FOLLOW_8); - rule__URL__Group__1__Impl(); + pushFollow(FOLLOW_34); + rule__WORKSPACE_TAG__Group__3__Impl(); state._fsp--; if (state.failed) return ; pushFollow(FOLLOW_2); - rule__URL__Group__2(); + rule__WORKSPACE_TAG__Group__4(); state._fsp--; if (state.failed) return ; @@ -13479,38 +14198,28 @@ public final void rule__URL__Group__1() throws RecognitionException { } return ; } - // $ANTLR end "rule__URL__Group__1" + // $ANTLR end "rule__WORKSPACE_TAG__Group__3" - // $ANTLR start "rule__URL__Group__1__Impl" - // InternalSemver.g:3937:1: rule__URL__Group__1__Impl : ( ( rule__URL__Alternatives_1 ) ) ; - public final void rule__URL__Group__1__Impl() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__3__Impl" + // InternalSemver.g:4148:1: rule__WORKSPACE_TAG__Group__3__Impl : ( RULE_LETTER_K ) ; + public final void rule__WORKSPACE_TAG__Group__3__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3941:1: ( ( ( rule__URL__Alternatives_1 ) ) ) - // InternalSemver.g:3942:1: ( ( rule__URL__Alternatives_1 ) ) + // InternalSemver.g:4152:1: ( ( RULE_LETTER_K ) ) + // InternalSemver.g:4153:1: ( RULE_LETTER_K ) { - // InternalSemver.g:3942:1: ( ( rule__URL__Alternatives_1 ) ) - // InternalSemver.g:3943:2: ( rule__URL__Alternatives_1 ) + // InternalSemver.g:4153:1: ( RULE_LETTER_K ) + // InternalSemver.g:4154:2: RULE_LETTER_K { if ( state.backtracking==0 ) { - before(grammarAccess.getURLAccess().getAlternatives_1()); - } - // InternalSemver.g:3944:2: ( rule__URL__Alternatives_1 ) - // InternalSemver.g:3944:3: rule__URL__Alternatives_1 - { - pushFollow(FOLLOW_2); - rule__URL__Alternatives_1(); - - state._fsp--; - if (state.failed) return ; - + before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_KTerminalRuleCall_3()); } - + match(input,RULE_LETTER_K,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURLAccess().getAlternatives_1()); + after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_KTerminalRuleCall_3()); } } @@ -13530,21 +14239,26 @@ public final void rule__URL__Group__1__Impl() throws RecognitionException { } return ; } - // $ANTLR end "rule__URL__Group__1__Impl" + // $ANTLR end "rule__WORKSPACE_TAG__Group__3__Impl" - // $ANTLR start "rule__URL__Group__2" - // InternalSemver.g:3952:1: rule__URL__Group__2 : rule__URL__Group__2__Impl ; - public final void rule__URL__Group__2() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__4" + // InternalSemver.g:4163:1: rule__WORKSPACE_TAG__Group__4 : rule__WORKSPACE_TAG__Group__4__Impl rule__WORKSPACE_TAG__Group__5 ; + public final void rule__WORKSPACE_TAG__Group__4() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3956:1: ( rule__URL__Group__2__Impl ) - // InternalSemver.g:3957:2: rule__URL__Group__2__Impl + // InternalSemver.g:4167:1: ( rule__WORKSPACE_TAG__Group__4__Impl rule__WORKSPACE_TAG__Group__5 ) + // InternalSemver.g:4168:2: rule__WORKSPACE_TAG__Group__4__Impl rule__WORKSPACE_TAG__Group__5 { + pushFollow(FOLLOW_35); + rule__WORKSPACE_TAG__Group__4__Impl(); + + state._fsp--; + if (state.failed) return ; pushFollow(FOLLOW_2); - rule__URL__Group__2__Impl(); + rule__WORKSPACE_TAG__Group__5(); state._fsp--; if (state.failed) return ; @@ -13563,56 +14277,28 @@ public final void rule__URL__Group__2() throws RecognitionException { } return ; } - // $ANTLR end "rule__URL__Group__2" + // $ANTLR end "rule__WORKSPACE_TAG__Group__4" - // $ANTLR start "rule__URL__Group__2__Impl" - // InternalSemver.g:3963:1: rule__URL__Group__2__Impl : ( ( rule__URL__Alternatives_2 )* ) ; - public final void rule__URL__Group__2__Impl() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__4__Impl" + // InternalSemver.g:4175:1: rule__WORKSPACE_TAG__Group__4__Impl : ( RULE_LETTER_S ) ; + public final void rule__WORKSPACE_TAG__Group__4__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3967:1: ( ( ( rule__URL__Alternatives_2 )* ) ) - // InternalSemver.g:3968:1: ( ( rule__URL__Alternatives_2 )* ) + // InternalSemver.g:4179:1: ( ( RULE_LETTER_S ) ) + // InternalSemver.g:4180:1: ( RULE_LETTER_S ) { - // InternalSemver.g:3968:1: ( ( rule__URL__Alternatives_2 )* ) - // InternalSemver.g:3969:2: ( rule__URL__Alternatives_2 )* + // InternalSemver.g:4180:1: ( RULE_LETTER_S ) + // InternalSemver.g:4181:2: RULE_LETTER_S { if ( state.backtracking==0 ) { - before(grammarAccess.getURLAccess().getAlternatives_2()); + before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_STerminalRuleCall_4()); } - // InternalSemver.g:3970:2: ( rule__URL__Alternatives_2 )* - loop48: - do { - int alt48=2; - int LA48_0 = input.LA(1); - - if ( ((LA48_0>=RULE_DIGITS && LA48_0<=RULE_LETTER_X)||(LA48_0>=RULE_LETTER_V && LA48_0<=RULE_LETTER_OTHER)||(LA48_0>=35 && LA48_0<=39)||LA48_0==41) ) { - alt48=1; - } - - - switch (alt48) { - case 1 : - // InternalSemver.g:3970:3: rule__URL__Alternatives_2 - { - pushFollow(FOLLOW_32); - rule__URL__Alternatives_2(); - - state._fsp--; - if (state.failed) return ; - - } - break; - - default : - break loop48; - } - } while (true); - + match(input,RULE_LETTER_S,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURLAccess().getAlternatives_2()); + after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_STerminalRuleCall_4()); } } @@ -13632,26 +14318,26 @@ public final void rule__URL__Group__2__Impl() throws RecognitionException { } return ; } - // $ANTLR end "rule__URL__Group__2__Impl" + // $ANTLR end "rule__WORKSPACE_TAG__Group__4__Impl" - // $ANTLR start "rule__URL_NO_VX__Group__0" - // InternalSemver.g:3979:1: rule__URL_NO_VX__Group__0 : rule__URL_NO_VX__Group__0__Impl rule__URL_NO_VX__Group__1 ; - public final void rule__URL_NO_VX__Group__0() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__5" + // InternalSemver.g:4190:1: rule__WORKSPACE_TAG__Group__5 : rule__WORKSPACE_TAG__Group__5__Impl rule__WORKSPACE_TAG__Group__6 ; + public final void rule__WORKSPACE_TAG__Group__5() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3983:1: ( rule__URL_NO_VX__Group__0__Impl rule__URL_NO_VX__Group__1 ) - // InternalSemver.g:3984:2: rule__URL_NO_VX__Group__0__Impl rule__URL_NO_VX__Group__1 + // InternalSemver.g:4194:1: ( rule__WORKSPACE_TAG__Group__5__Impl rule__WORKSPACE_TAG__Group__6 ) + // InternalSemver.g:4195:2: rule__WORKSPACE_TAG__Group__5__Impl rule__WORKSPACE_TAG__Group__6 { - pushFollow(FOLLOW_8); - rule__URL_NO_VX__Group__0__Impl(); + pushFollow(FOLLOW_36); + rule__WORKSPACE_TAG__Group__5__Impl(); state._fsp--; if (state.failed) return ; pushFollow(FOLLOW_2); - rule__URL_NO_VX__Group__1(); + rule__WORKSPACE_TAG__Group__6(); state._fsp--; if (state.failed) return ; @@ -13670,38 +14356,28 @@ public final void rule__URL_NO_VX__Group__0() throws RecognitionException { } return ; } - // $ANTLR end "rule__URL_NO_VX__Group__0" + // $ANTLR end "rule__WORKSPACE_TAG__Group__5" - // $ANTLR start "rule__URL_NO_VX__Group__0__Impl" - // InternalSemver.g:3991:1: rule__URL_NO_VX__Group__0__Impl : ( ( rule__URL_NO_VX__Alternatives_0 ) ) ; - public final void rule__URL_NO_VX__Group__0__Impl() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__5__Impl" + // InternalSemver.g:4202:1: rule__WORKSPACE_TAG__Group__5__Impl : ( RULE_LETTER_P ) ; + public final void rule__WORKSPACE_TAG__Group__5__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:3995:1: ( ( ( rule__URL_NO_VX__Alternatives_0 ) ) ) - // InternalSemver.g:3996:1: ( ( rule__URL_NO_VX__Alternatives_0 ) ) + // InternalSemver.g:4206:1: ( ( RULE_LETTER_P ) ) + // InternalSemver.g:4207:1: ( RULE_LETTER_P ) { - // InternalSemver.g:3996:1: ( ( rule__URL_NO_VX__Alternatives_0 ) ) - // InternalSemver.g:3997:2: ( rule__URL_NO_VX__Alternatives_0 ) + // InternalSemver.g:4207:1: ( RULE_LETTER_P ) + // InternalSemver.g:4208:2: RULE_LETTER_P { if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().getAlternatives_0()); - } - // InternalSemver.g:3998:2: ( rule__URL_NO_VX__Alternatives_0 ) - // InternalSemver.g:3998:3: rule__URL_NO_VX__Alternatives_0 - { - pushFollow(FOLLOW_2); - rule__URL_NO_VX__Alternatives_0(); - - state._fsp--; - if (state.failed) return ; - + before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_PTerminalRuleCall_5()); } - + match(input,RULE_LETTER_P,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().getAlternatives_0()); + after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_PTerminalRuleCall_5()); } } @@ -13721,26 +14397,26 @@ public final void rule__URL_NO_VX__Group__0__Impl() throws RecognitionException } return ; } - // $ANTLR end "rule__URL_NO_VX__Group__0__Impl" + // $ANTLR end "rule__WORKSPACE_TAG__Group__5__Impl" - // $ANTLR start "rule__URL_NO_VX__Group__1" - // InternalSemver.g:4006:1: rule__URL_NO_VX__Group__1 : rule__URL_NO_VX__Group__1__Impl rule__URL_NO_VX__Group__2 ; - public final void rule__URL_NO_VX__Group__1() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__6" + // InternalSemver.g:4217:1: rule__WORKSPACE_TAG__Group__6 : rule__WORKSPACE_TAG__Group__6__Impl rule__WORKSPACE_TAG__Group__7 ; + public final void rule__WORKSPACE_TAG__Group__6() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4010:1: ( rule__URL_NO_VX__Group__1__Impl rule__URL_NO_VX__Group__2 ) - // InternalSemver.g:4011:2: rule__URL_NO_VX__Group__1__Impl rule__URL_NO_VX__Group__2 + // InternalSemver.g:4221:1: ( rule__WORKSPACE_TAG__Group__6__Impl rule__WORKSPACE_TAG__Group__7 ) + // InternalSemver.g:4222:2: rule__WORKSPACE_TAG__Group__6__Impl rule__WORKSPACE_TAG__Group__7 { - pushFollow(FOLLOW_8); - rule__URL_NO_VX__Group__1__Impl(); + pushFollow(FOLLOW_37); + rule__WORKSPACE_TAG__Group__6__Impl(); state._fsp--; if (state.failed) return ; pushFollow(FOLLOW_2); - rule__URL_NO_VX__Group__2(); + rule__WORKSPACE_TAG__Group__7(); state._fsp--; if (state.failed) return ; @@ -13759,56 +14435,107 @@ public final void rule__URL_NO_VX__Group__1() throws RecognitionException { } return ; } - // $ANTLR end "rule__URL_NO_VX__Group__1" + // $ANTLR end "rule__WORKSPACE_TAG__Group__6" - // $ANTLR start "rule__URL_NO_VX__Group__1__Impl" - // InternalSemver.g:4018:1: rule__URL_NO_VX__Group__1__Impl : ( ( rule__URL_NO_VX__Alternatives_1 )* ) ; - public final void rule__URL_NO_VX__Group__1__Impl() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__6__Impl" + // InternalSemver.g:4229:1: rule__WORKSPACE_TAG__Group__6__Impl : ( RULE_LETTER_A ) ; + public final void rule__WORKSPACE_TAG__Group__6__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4022:1: ( ( ( rule__URL_NO_VX__Alternatives_1 )* ) ) - // InternalSemver.g:4023:1: ( ( rule__URL_NO_VX__Alternatives_1 )* ) + // InternalSemver.g:4233:1: ( ( RULE_LETTER_A ) ) + // InternalSemver.g:4234:1: ( RULE_LETTER_A ) { - // InternalSemver.g:4023:1: ( ( rule__URL_NO_VX__Alternatives_1 )* ) - // InternalSemver.g:4024:2: ( rule__URL_NO_VX__Alternatives_1 )* + // InternalSemver.g:4234:1: ( RULE_LETTER_A ) + // InternalSemver.g:4235:2: RULE_LETTER_A { if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().getAlternatives_1()); + before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_ATerminalRuleCall_6()); + } + match(input,RULE_LETTER_A,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_ATerminalRuleCall_6()); } - // InternalSemver.g:4025:2: ( rule__URL_NO_VX__Alternatives_1 )* - loop49: - do { - int alt49=2; - int LA49_0 = input.LA(1); - if ( ((LA49_0>=RULE_DIGITS && LA49_0<=RULE_LETTER_X)||(LA49_0>=RULE_LETTER_V && LA49_0<=RULE_LETTER_OTHER)||(LA49_0>=38 && LA49_0<=39)) ) { - alt49=1; - } + } - switch (alt49) { - case 1 : - // InternalSemver.g:4025:3: rule__URL_NO_VX__Alternatives_1 - { - pushFollow(FOLLOW_3); - rule__URL_NO_VX__Alternatives_1(); + } - state._fsp--; - if (state.failed) return ; + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { - } - break; + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__WORKSPACE_TAG__Group__6__Impl" + + + // $ANTLR start "rule__WORKSPACE_TAG__Group__7" + // InternalSemver.g:4244:1: rule__WORKSPACE_TAG__Group__7 : rule__WORKSPACE_TAG__Group__7__Impl rule__WORKSPACE_TAG__Group__8 ; + public final void rule__WORKSPACE_TAG__Group__7() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:4248:1: ( rule__WORKSPACE_TAG__Group__7__Impl rule__WORKSPACE_TAG__Group__8 ) + // InternalSemver.g:4249:2: rule__WORKSPACE_TAG__Group__7__Impl rule__WORKSPACE_TAG__Group__8 + { + pushFollow(FOLLOW_28); + rule__WORKSPACE_TAG__Group__7__Impl(); + + state._fsp--; + if (state.failed) return ; + pushFollow(FOLLOW_2); + rule__WORKSPACE_TAG__Group__8(); + + state._fsp--; + if (state.failed) return ; + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__WORKSPACE_TAG__Group__7" - default : - break loop49; - } - } while (true); + // $ANTLR start "rule__WORKSPACE_TAG__Group__7__Impl" + // InternalSemver.g:4256:1: rule__WORKSPACE_TAG__Group__7__Impl : ( RULE_LETTER_C ) ; + public final void rule__WORKSPACE_TAG__Group__7__Impl() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:4260:1: ( ( RULE_LETTER_C ) ) + // InternalSemver.g:4261:1: ( RULE_LETTER_C ) + { + // InternalSemver.g:4261:1: ( RULE_LETTER_C ) + // InternalSemver.g:4262:2: RULE_LETTER_C + { if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().getAlternatives_1()); + before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_CTerminalRuleCall_7()); + } + match(input,RULE_LETTER_C,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_CTerminalRuleCall_7()); } } @@ -13828,26 +14555,26 @@ public final void rule__URL_NO_VX__Group__1__Impl() throws RecognitionException } return ; } - // $ANTLR end "rule__URL_NO_VX__Group__1__Impl" + // $ANTLR end "rule__WORKSPACE_TAG__Group__7__Impl" - // $ANTLR start "rule__URL_NO_VX__Group__2" - // InternalSemver.g:4033:1: rule__URL_NO_VX__Group__2 : rule__URL_NO_VX__Group__2__Impl rule__URL_NO_VX__Group__3 ; - public final void rule__URL_NO_VX__Group__2() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__8" + // InternalSemver.g:4271:1: rule__WORKSPACE_TAG__Group__8 : rule__WORKSPACE_TAG__Group__8__Impl rule__WORKSPACE_TAG__Group__9 ; + public final void rule__WORKSPACE_TAG__Group__8() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4037:1: ( rule__URL_NO_VX__Group__2__Impl rule__URL_NO_VX__Group__3 ) - // InternalSemver.g:4038:2: rule__URL_NO_VX__Group__2__Impl rule__URL_NO_VX__Group__3 + // InternalSemver.g:4275:1: ( rule__WORKSPACE_TAG__Group__8__Impl rule__WORKSPACE_TAG__Group__9 ) + // InternalSemver.g:4276:2: rule__WORKSPACE_TAG__Group__8__Impl rule__WORKSPACE_TAG__Group__9 { pushFollow(FOLLOW_8); - rule__URL_NO_VX__Group__2__Impl(); + rule__WORKSPACE_TAG__Group__8__Impl(); state._fsp--; if (state.failed) return ; pushFollow(FOLLOW_2); - rule__URL_NO_VX__Group__3(); + rule__WORKSPACE_TAG__Group__9(); state._fsp--; if (state.failed) return ; @@ -13866,38 +14593,28 @@ public final void rule__URL_NO_VX__Group__2() throws RecognitionException { } return ; } - // $ANTLR end "rule__URL_NO_VX__Group__2" + // $ANTLR end "rule__WORKSPACE_TAG__Group__8" - // $ANTLR start "rule__URL_NO_VX__Group__2__Impl" - // InternalSemver.g:4045:1: rule__URL_NO_VX__Group__2__Impl : ( ( rule__URL_NO_VX__Alternatives_2 ) ) ; - public final void rule__URL_NO_VX__Group__2__Impl() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__8__Impl" + // InternalSemver.g:4283:1: rule__WORKSPACE_TAG__Group__8__Impl : ( RULE_LETTER_E ) ; + public final void rule__WORKSPACE_TAG__Group__8__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4049:1: ( ( ( rule__URL_NO_VX__Alternatives_2 ) ) ) - // InternalSemver.g:4050:1: ( ( rule__URL_NO_VX__Alternatives_2 ) ) + // InternalSemver.g:4287:1: ( ( RULE_LETTER_E ) ) + // InternalSemver.g:4288:1: ( RULE_LETTER_E ) { - // InternalSemver.g:4050:1: ( ( rule__URL_NO_VX__Alternatives_2 ) ) - // InternalSemver.g:4051:2: ( rule__URL_NO_VX__Alternatives_2 ) + // InternalSemver.g:4288:1: ( RULE_LETTER_E ) + // InternalSemver.g:4289:2: RULE_LETTER_E { if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().getAlternatives_2()); - } - // InternalSemver.g:4052:2: ( rule__URL_NO_VX__Alternatives_2 ) - // InternalSemver.g:4052:3: rule__URL_NO_VX__Alternatives_2 - { - pushFollow(FOLLOW_2); - rule__URL_NO_VX__Alternatives_2(); - - state._fsp--; - if (state.failed) return ; - + before(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_ETerminalRuleCall_8()); } - + match(input,RULE_LETTER_E,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().getAlternatives_2()); + after(grammarAccess.getWORKSPACE_TAGAccess().getLETTER_ETerminalRuleCall_8()); } } @@ -13917,21 +14634,21 @@ public final void rule__URL_NO_VX__Group__2__Impl() throws RecognitionException } return ; } - // $ANTLR end "rule__URL_NO_VX__Group__2__Impl" + // $ANTLR end "rule__WORKSPACE_TAG__Group__8__Impl" - // $ANTLR start "rule__URL_NO_VX__Group__3" - // InternalSemver.g:4060:1: rule__URL_NO_VX__Group__3 : rule__URL_NO_VX__Group__3__Impl ; - public final void rule__URL_NO_VX__Group__3() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__9" + // InternalSemver.g:4298:1: rule__WORKSPACE_TAG__Group__9 : rule__WORKSPACE_TAG__Group__9__Impl ; + public final void rule__WORKSPACE_TAG__Group__9() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4064:1: ( rule__URL_NO_VX__Group__3__Impl ) - // InternalSemver.g:4065:2: rule__URL_NO_VX__Group__3__Impl + // InternalSemver.g:4302:1: ( rule__WORKSPACE_TAG__Group__9__Impl ) + // InternalSemver.g:4303:2: rule__WORKSPACE_TAG__Group__9__Impl { pushFollow(FOLLOW_2); - rule__URL_NO_VX__Group__3__Impl(); + rule__WORKSPACE_TAG__Group__9__Impl(); state._fsp--; if (state.failed) return ; @@ -13950,56 +14667,28 @@ public final void rule__URL_NO_VX__Group__3() throws RecognitionException { } return ; } - // $ANTLR end "rule__URL_NO_VX__Group__3" + // $ANTLR end "rule__WORKSPACE_TAG__Group__9" - // $ANTLR start "rule__URL_NO_VX__Group__3__Impl" - // InternalSemver.g:4071:1: rule__URL_NO_VX__Group__3__Impl : ( ( rule__URL_NO_VX__Alternatives_3 )* ) ; - public final void rule__URL_NO_VX__Group__3__Impl() throws RecognitionException { + // $ANTLR start "rule__WORKSPACE_TAG__Group__9__Impl" + // InternalSemver.g:4309:1: rule__WORKSPACE_TAG__Group__9__Impl : ( ':' ) ; + public final void rule__WORKSPACE_TAG__Group__9__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4075:1: ( ( ( rule__URL_NO_VX__Alternatives_3 )* ) ) - // InternalSemver.g:4076:1: ( ( rule__URL_NO_VX__Alternatives_3 )* ) + // InternalSemver.g:4313:1: ( ( ':' ) ) + // InternalSemver.g:4314:1: ( ':' ) { - // InternalSemver.g:4076:1: ( ( rule__URL_NO_VX__Alternatives_3 )* ) - // InternalSemver.g:4077:2: ( rule__URL_NO_VX__Alternatives_3 )* + // InternalSemver.g:4314:1: ( ':' ) + // InternalSemver.g:4315:2: ':' { if ( state.backtracking==0 ) { - before(grammarAccess.getURL_NO_VXAccess().getAlternatives_3()); + before(grammarAccess.getWORKSPACE_TAGAccess().getColonKeyword_9()); } - // InternalSemver.g:4078:2: ( rule__URL_NO_VX__Alternatives_3 )* - loop50: - do { - int alt50=2; - int LA50_0 = input.LA(1); - - if ( ((LA50_0>=RULE_DIGITS && LA50_0<=RULE_LETTER_X)||(LA50_0>=RULE_LETTER_V && LA50_0<=RULE_LETTER_OTHER)||(LA50_0>=35 && LA50_0<=39)||LA50_0==41) ) { - alt50=1; - } - - - switch (alt50) { - case 1 : - // InternalSemver.g:4078:3: rule__URL_NO_VX__Alternatives_3 - { - pushFollow(FOLLOW_32); - rule__URL_NO_VX__Alternatives_3(); - - state._fsp--; - if (state.failed) return ; - - } - break; - - default : - break loop50; - } - } while (true); - + match(input,46,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURL_NO_VXAccess().getAlternatives_3()); + after(grammarAccess.getWORKSPACE_TAGAccess().getColonKeyword_9()); } } @@ -14019,26 +14708,26 @@ public final void rule__URL_NO_VX__Group__3__Impl() throws RecognitionException } return ; } - // $ANTLR end "rule__URL_NO_VX__Group__3__Impl" + // $ANTLR end "rule__WORKSPACE_TAG__Group__9__Impl" - // $ANTLR start "rule__TAG__Group__0" - // InternalSemver.g:4087:1: rule__TAG__Group__0 : rule__TAG__Group__0__Impl rule__TAG__Group__1 ; - public final void rule__TAG__Group__0() throws RecognitionException { + // $ANTLR start "rule__URL_PROTOCOL__Group__0" + // InternalSemver.g:4325:1: rule__URL_PROTOCOL__Group__0 : rule__URL_PROTOCOL__Group__0__Impl rule__URL_PROTOCOL__Group__1 ; + public final void rule__URL_PROTOCOL__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4091:1: ( rule__TAG__Group__0__Impl rule__TAG__Group__1 ) - // InternalSemver.g:4092:2: rule__TAG__Group__0__Impl rule__TAG__Group__1 + // InternalSemver.g:4329:1: ( rule__URL_PROTOCOL__Group__0__Impl rule__URL_PROTOCOL__Group__1 ) + // InternalSemver.g:4330:2: rule__URL_PROTOCOL__Group__0__Impl rule__URL_PROTOCOL__Group__1 { - pushFollow(FOLLOW_6); - rule__TAG__Group__0__Impl(); + pushFollow(FOLLOW_38); + rule__URL_PROTOCOL__Group__0__Impl(); state._fsp--; if (state.failed) return ; pushFollow(FOLLOW_2); - rule__TAG__Group__1(); + rule__URL_PROTOCOL__Group__1(); state._fsp--; if (state.failed) return ; @@ -14057,24 +14746,24 @@ public final void rule__TAG__Group__0() throws RecognitionException { } return ; } - // $ANTLR end "rule__TAG__Group__0" + // $ANTLR end "rule__URL_PROTOCOL__Group__0" - // $ANTLR start "rule__TAG__Group__0__Impl" - // InternalSemver.g:4099:1: rule__TAG__Group__0__Impl : ( ruleLETTER_NO_VX ) ; - public final void rule__TAG__Group__0__Impl() throws RecognitionException { + // $ANTLR start "rule__URL_PROTOCOL__Group__0__Impl" + // InternalSemver.g:4337:1: rule__URL_PROTOCOL__Group__0__Impl : ( ruleLETTER_NO_VX ) ; + public final void rule__URL_PROTOCOL__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4103:1: ( ( ruleLETTER_NO_VX ) ) - // InternalSemver.g:4104:1: ( ruleLETTER_NO_VX ) + // InternalSemver.g:4341:1: ( ( ruleLETTER_NO_VX ) ) + // InternalSemver.g:4342:1: ( ruleLETTER_NO_VX ) { - // InternalSemver.g:4104:1: ( ruleLETTER_NO_VX ) - // InternalSemver.g:4105:2: ruleLETTER_NO_VX + // InternalSemver.g:4342:1: ( ruleLETTER_NO_VX ) + // InternalSemver.g:4343:2: ruleLETTER_NO_VX { if ( state.backtracking==0 ) { - before(grammarAccess.getTAGAccess().getLETTER_NO_VXParserRuleCall_0()); + before(grammarAccess.getURL_PROTOCOLAccess().getLETTER_NO_VXParserRuleCall_0()); } pushFollow(FOLLOW_2); ruleLETTER_NO_VX(); @@ -14082,7 +14771,7 @@ public final void rule__TAG__Group__0__Impl() throws RecognitionException { state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getTAGAccess().getLETTER_NO_VXParserRuleCall_0()); + after(grammarAccess.getURL_PROTOCOLAccess().getLETTER_NO_VXParserRuleCall_0()); } } @@ -14102,21 +14791,21 @@ public final void rule__TAG__Group__0__Impl() throws RecognitionException { } return ; } - // $ANTLR end "rule__TAG__Group__0__Impl" + // $ANTLR end "rule__URL_PROTOCOL__Group__0__Impl" - // $ANTLR start "rule__TAG__Group__1" - // InternalSemver.g:4114:1: rule__TAG__Group__1 : rule__TAG__Group__1__Impl ; - public final void rule__TAG__Group__1() throws RecognitionException { + // $ANTLR start "rule__URL_PROTOCOL__Group__1" + // InternalSemver.g:4352:1: rule__URL_PROTOCOL__Group__1 : rule__URL_PROTOCOL__Group__1__Impl ; + public final void rule__URL_PROTOCOL__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4118:1: ( rule__TAG__Group__1__Impl ) - // InternalSemver.g:4119:2: rule__TAG__Group__1__Impl + // InternalSemver.g:4356:1: ( rule__URL_PROTOCOL__Group__1__Impl ) + // InternalSemver.g:4357:2: rule__URL_PROTOCOL__Group__1__Impl { pushFollow(FOLLOW_2); - rule__TAG__Group__1__Impl(); + rule__URL_PROTOCOL__Group__1__Impl(); state._fsp--; if (state.failed) return ; @@ -14135,33 +14824,33 @@ public final void rule__TAG__Group__1() throws RecognitionException { } return ; } - // $ANTLR end "rule__TAG__Group__1" + // $ANTLR end "rule__URL_PROTOCOL__Group__1" - // $ANTLR start "rule__TAG__Group__1__Impl" - // InternalSemver.g:4125:1: rule__TAG__Group__1__Impl : ( ( ( rule__TAG__Alternatives_1 ) ) ( ( rule__TAG__Alternatives_1 )* ) ) ; - public final void rule__TAG__Group__1__Impl() throws RecognitionException { + // $ANTLR start "rule__URL_PROTOCOL__Group__1__Impl" + // InternalSemver.g:4363:1: rule__URL_PROTOCOL__Group__1__Impl : ( ( ( rule__URL_PROTOCOL__Alternatives_1 ) ) ( ( rule__URL_PROTOCOL__Alternatives_1 )* ) ) ; + public final void rule__URL_PROTOCOL__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4129:1: ( ( ( ( rule__TAG__Alternatives_1 ) ) ( ( rule__TAG__Alternatives_1 )* ) ) ) - // InternalSemver.g:4130:1: ( ( ( rule__TAG__Alternatives_1 ) ) ( ( rule__TAG__Alternatives_1 )* ) ) + // InternalSemver.g:4367:1: ( ( ( ( rule__URL_PROTOCOL__Alternatives_1 ) ) ( ( rule__URL_PROTOCOL__Alternatives_1 )* ) ) ) + // InternalSemver.g:4368:1: ( ( ( rule__URL_PROTOCOL__Alternatives_1 ) ) ( ( rule__URL_PROTOCOL__Alternatives_1 )* ) ) { - // InternalSemver.g:4130:1: ( ( ( rule__TAG__Alternatives_1 ) ) ( ( rule__TAG__Alternatives_1 )* ) ) - // InternalSemver.g:4131:2: ( ( rule__TAG__Alternatives_1 ) ) ( ( rule__TAG__Alternatives_1 )* ) + // InternalSemver.g:4368:1: ( ( ( rule__URL_PROTOCOL__Alternatives_1 ) ) ( ( rule__URL_PROTOCOL__Alternatives_1 )* ) ) + // InternalSemver.g:4369:2: ( ( rule__URL_PROTOCOL__Alternatives_1 ) ) ( ( rule__URL_PROTOCOL__Alternatives_1 )* ) { - // InternalSemver.g:4131:2: ( ( rule__TAG__Alternatives_1 ) ) - // InternalSemver.g:4132:3: ( rule__TAG__Alternatives_1 ) + // InternalSemver.g:4369:2: ( ( rule__URL_PROTOCOL__Alternatives_1 ) ) + // InternalSemver.g:4370:3: ( rule__URL_PROTOCOL__Alternatives_1 ) { if ( state.backtracking==0 ) { - before(grammarAccess.getTAGAccess().getAlternatives_1()); + before(grammarAccess.getURL_PROTOCOLAccess().getAlternatives_1()); } - // InternalSemver.g:4133:3: ( rule__TAG__Alternatives_1 ) - // InternalSemver.g:4133:4: rule__TAG__Alternatives_1 + // InternalSemver.g:4371:3: ( rule__URL_PROTOCOL__Alternatives_1 ) + // InternalSemver.g:4371:4: rule__URL_PROTOCOL__Alternatives_1 { - pushFollow(FOLLOW_3); - rule__TAG__Alternatives_1(); + pushFollow(FOLLOW_39); + rule__URL_PROTOCOL__Alternatives_1(); state._fsp--; if (state.failed) return ; @@ -14169,34 +14858,34 @@ public final void rule__TAG__Group__1__Impl() throws RecognitionException { } if ( state.backtracking==0 ) { - after(grammarAccess.getTAGAccess().getAlternatives_1()); + after(grammarAccess.getURL_PROTOCOLAccess().getAlternatives_1()); } } - // InternalSemver.g:4136:2: ( ( rule__TAG__Alternatives_1 )* ) - // InternalSemver.g:4137:3: ( rule__TAG__Alternatives_1 )* + // InternalSemver.g:4374:2: ( ( rule__URL_PROTOCOL__Alternatives_1 )* ) + // InternalSemver.g:4375:3: ( rule__URL_PROTOCOL__Alternatives_1 )* { if ( state.backtracking==0 ) { - before(grammarAccess.getTAGAccess().getAlternatives_1()); + before(grammarAccess.getURL_PROTOCOLAccess().getAlternatives_1()); } - // InternalSemver.g:4138:3: ( rule__TAG__Alternatives_1 )* - loop51: + // InternalSemver.g:4376:3: ( rule__URL_PROTOCOL__Alternatives_1 )* + loop48: do { - int alt51=2; - int LA51_0 = input.LA(1); + int alt48=2; + int LA48_0 = input.LA(1); - if ( ((LA51_0>=RULE_DIGITS && LA51_0<=RULE_LETTER_X)||(LA51_0>=RULE_LETTER_V && LA51_0<=RULE_LETTER_OTHER)||LA51_0==38) ) { - alt51=1; + if ( ((LA48_0>=RULE_LETTER_X && LA48_0<=RULE_LETTER_OTHER)||LA48_0==45) ) { + alt48=1; } - switch (alt51) { + switch (alt48) { case 1 : - // InternalSemver.g:4138:4: rule__TAG__Alternatives_1 + // InternalSemver.g:4376:4: rule__URL_PROTOCOL__Alternatives_1 { - pushFollow(FOLLOW_3); - rule__TAG__Alternatives_1(); + pushFollow(FOLLOW_39); + rule__URL_PROTOCOL__Alternatives_1(); state._fsp--; if (state.failed) return ; @@ -14205,12 +14894,12 @@ public final void rule__TAG__Group__1__Impl() throws RecognitionException { break; default : - break loop51; + break loop48; } } while (true); if ( state.backtracking==0 ) { - after(grammarAccess.getTAGAccess().getAlternatives_1()); + after(grammarAccess.getURL_PROTOCOLAccess().getAlternatives_1()); } } @@ -14233,26 +14922,26 @@ public final void rule__TAG__Group__1__Impl() throws RecognitionException { } return ; } - // $ANTLR end "rule__TAG__Group__1__Impl" + // $ANTLR end "rule__URL_PROTOCOL__Group__1__Impl" - // $ANTLR start "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0" - // InternalSemver.g:4148:1: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 : rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1 ; - public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0() throws RecognitionException { + // $ANTLR start "rule__URL__Group__0" + // InternalSemver.g:4386:1: rule__URL__Group__0 : rule__URL__Group__0__Impl rule__URL__Group__1 ; + public final void rule__URL__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4152:1: ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1 ) - // InternalSemver.g:4153:2: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1 + // InternalSemver.g:4390:1: ( rule__URL__Group__0__Impl rule__URL__Group__1 ) + // InternalSemver.g:4391:2: rule__URL__Group__0__Impl rule__URL__Group__1 { - pushFollow(FOLLOW_6); - rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl(); + pushFollow(FOLLOW_9); + rule__URL__Group__0__Impl(); state._fsp--; if (state.failed) return ; pushFollow(FOLLOW_2); - rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1(); + rule__URL__Group__1(); state._fsp--; if (state.failed) return ; @@ -14271,28 +14960,56 @@ public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0() throws } return ; } - // $ANTLR end "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0" + // $ANTLR end "rule__URL__Group__0" - // $ANTLR start "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl" - // InternalSemver.g:4160:1: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl : ( RULE_DIGITS ) ; - public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl() throws RecognitionException { + // $ANTLR start "rule__URL__Group__0__Impl" + // InternalSemver.g:4398:1: rule__URL__Group__0__Impl : ( ( rule__URL__Alternatives_0 )* ) ; + public final void rule__URL__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4164:1: ( ( RULE_DIGITS ) ) - // InternalSemver.g:4165:1: ( RULE_DIGITS ) + // InternalSemver.g:4402:1: ( ( ( rule__URL__Alternatives_0 )* ) ) + // InternalSemver.g:4403:1: ( ( rule__URL__Alternatives_0 )* ) { - // InternalSemver.g:4165:1: ( RULE_DIGITS ) - // InternalSemver.g:4166:2: RULE_DIGITS + // InternalSemver.g:4403:1: ( ( rule__URL__Alternatives_0 )* ) + // InternalSemver.g:4404:2: ( rule__URL__Alternatives_0 )* { if ( state.backtracking==0 ) { - before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getDIGITSTerminalRuleCall_0()); + before(grammarAccess.getURLAccess().getAlternatives_0()); } - match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return ; + // InternalSemver.g:4405:2: ( rule__URL__Alternatives_0 )* + loop49: + do { + int alt49=2; + int LA49_0 = input.LA(1); + + if ( ((LA49_0>=RULE_DIGITS && LA49_0<=RULE_LETTER_OTHER)||LA49_0==44||LA49_0==47) ) { + alt49=1; + } + + + switch (alt49) { + case 1 : + // InternalSemver.g:4405:3: rule__URL__Alternatives_0 + { + pushFollow(FOLLOW_3); + rule__URL__Alternatives_0(); + + state._fsp--; + if (state.failed) return ; + + } + break; + + default : + break loop49; + } + } while (true); + if ( state.backtracking==0 ) { - after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getDIGITSTerminalRuleCall_0()); + after(grammarAccess.getURLAccess().getAlternatives_0()); } } @@ -14312,21 +15029,26 @@ public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl() } return ; } - // $ANTLR end "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl" + // $ANTLR end "rule__URL__Group__0__Impl" - // $ANTLR start "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1" - // InternalSemver.g:4175:1: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1 : rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl ; - public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1() throws RecognitionException { + // $ANTLR start "rule__URL__Group__1" + // InternalSemver.g:4413:1: rule__URL__Group__1 : rule__URL__Group__1__Impl rule__URL__Group__2 ; + public final void rule__URL__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4179:1: ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl ) - // InternalSemver.g:4180:2: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl + // InternalSemver.g:4417:1: ( rule__URL__Group__1__Impl rule__URL__Group__2 ) + // InternalSemver.g:4418:2: rule__URL__Group__1__Impl rule__URL__Group__2 { + pushFollow(FOLLOW_9); + rule__URL__Group__1__Impl(); + + state._fsp--; + if (state.failed) return ; pushFollow(FOLLOW_2); - rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl(); + rule__URL__Group__2(); state._fsp--; if (state.failed) return ; @@ -14345,33 +15067,30 @@ public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1() throws } return ; } - // $ANTLR end "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1" + // $ANTLR end "rule__URL__Group__1" - // $ANTLR start "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl" - // InternalSemver.g:4186:1: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl : ( ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 ) ) ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 )* ) ) ; - public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl() throws RecognitionException { + // $ANTLR start "rule__URL__Group__1__Impl" + // InternalSemver.g:4425:1: rule__URL__Group__1__Impl : ( ( rule__URL__Alternatives_1 ) ) ; + public final void rule__URL__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4190:1: ( ( ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 ) ) ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 )* ) ) ) - // InternalSemver.g:4191:1: ( ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 ) ) ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 )* ) ) - { - // InternalSemver.g:4191:1: ( ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 ) ) ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 )* ) ) - // InternalSemver.g:4192:2: ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 ) ) ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 )* ) + // InternalSemver.g:4429:1: ( ( ( rule__URL__Alternatives_1 ) ) ) + // InternalSemver.g:4430:1: ( ( rule__URL__Alternatives_1 ) ) { - // InternalSemver.g:4192:2: ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 ) ) - // InternalSemver.g:4193:3: ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 ) + // InternalSemver.g:4430:1: ( ( rule__URL__Alternatives_1 ) ) + // InternalSemver.g:4431:2: ( rule__URL__Alternatives_1 ) { if ( state.backtracking==0 ) { - before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getAlternatives_1()); + before(grammarAccess.getURLAccess().getAlternatives_1()); } - // InternalSemver.g:4194:3: ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 ) - // InternalSemver.g:4194:4: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 + // InternalSemver.g:4432:2: ( rule__URL__Alternatives_1 ) + // InternalSemver.g:4432:3: rule__URL__Alternatives_1 { - pushFollow(FOLLOW_3); - rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1(); + pushFollow(FOLLOW_2); + rule__URL__Alternatives_1(); state._fsp--; if (state.failed) return ; @@ -14379,100 +15098,44 @@ public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl() } if ( state.backtracking==0 ) { - after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getAlternatives_1()); + after(grammarAccess.getURLAccess().getAlternatives_1()); } } - // InternalSemver.g:4197:2: ( ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 )* ) - // InternalSemver.g:4198:3: ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 )* - { - if ( state.backtracking==0 ) { - before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getAlternatives_1()); + } - // InternalSemver.g:4199:3: ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 )* - loop52: - do { - int alt52=2; - int LA52_0 = input.LA(1); - if ( ((LA52_0>=RULE_DIGITS && LA52_0<=RULE_LETTER_X)||(LA52_0>=RULE_LETTER_V && LA52_0<=RULE_LETTER_OTHER)||LA52_0==38) ) { - alt52=1; - } - - - switch (alt52) { - case 1 : - // InternalSemver.g:4199:4: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1 - { - pushFollow(FOLLOW_3); - rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Alternatives_1(); - - state._fsp--; - if (state.failed) return ; - - } - break; - - default : - break loop52; - } - } while (true); - - if ( state.backtracking==0 ) { - after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getAlternatives_1()); - } - - } - - - } - - - } - - } - catch (RecognitionException re) { - reportError(re); - recover(input,re); - } - finally { + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { restoreStackSize(stackSize); } return ; } - // $ANTLR end "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl" + // $ANTLR end "rule__URL__Group__1__Impl" - // $ANTLR start "rule__LocalPathVersionRequirement__LocalPathAssignment_1" - // InternalSemver.g:4209:1: rule__LocalPathVersionRequirement__LocalPathAssignment_1 : ( rulePATH ) ; - public final void rule__LocalPathVersionRequirement__LocalPathAssignment_1() throws RecognitionException { + // $ANTLR start "rule__URL__Group__2" + // InternalSemver.g:4440:1: rule__URL__Group__2 : rule__URL__Group__2__Impl ; + public final void rule__URL__Group__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4213:1: ( ( rulePATH ) ) - // InternalSemver.g:4214:2: ( rulePATH ) - { - // InternalSemver.g:4214:2: ( rulePATH ) - // InternalSemver.g:4215:3: rulePATH + // InternalSemver.g:4444:1: ( rule__URL__Group__2__Impl ) + // InternalSemver.g:4445:2: rule__URL__Group__2__Impl { - if ( state.backtracking==0 ) { - before(grammarAccess.getLocalPathVersionRequirementAccess().getLocalPathPATHParserRuleCall_1_0()); - } pushFollow(FOLLOW_2); - rulePATH(); + rule__URL__Group__2__Impl(); state._fsp--; if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getLocalPathVersionRequirementAccess().getLocalPathPATHParserRuleCall_1_0()); - } - - } - } @@ -14488,32 +15151,56 @@ public final void rule__LocalPathVersionRequirement__LocalPathAssignment_1() thr } return ; } - // $ANTLR end "rule__LocalPathVersionRequirement__LocalPathAssignment_1" + // $ANTLR end "rule__URL__Group__2" - // $ANTLR start "rule__URLVersionRequirement__ProtocolAssignment_0" - // InternalSemver.g:4224:1: rule__URLVersionRequirement__ProtocolAssignment_0 : ( ruleURL_PROTOCOL ) ; - public final void rule__URLVersionRequirement__ProtocolAssignment_0() throws RecognitionException { + // $ANTLR start "rule__URL__Group__2__Impl" + // InternalSemver.g:4451:1: rule__URL__Group__2__Impl : ( ( rule__URL__Alternatives_2 )* ) ; + public final void rule__URL__Group__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4228:1: ( ( ruleURL_PROTOCOL ) ) - // InternalSemver.g:4229:2: ( ruleURL_PROTOCOL ) + // InternalSemver.g:4455:1: ( ( ( rule__URL__Alternatives_2 )* ) ) + // InternalSemver.g:4456:1: ( ( rule__URL__Alternatives_2 )* ) { - // InternalSemver.g:4229:2: ( ruleURL_PROTOCOL ) - // InternalSemver.g:4230:3: ruleURL_PROTOCOL + // InternalSemver.g:4456:1: ( ( rule__URL__Alternatives_2 )* ) + // InternalSemver.g:4457:2: ( rule__URL__Alternatives_2 )* { if ( state.backtracking==0 ) { - before(grammarAccess.getURLVersionRequirementAccess().getProtocolURL_PROTOCOLParserRuleCall_0_0()); + before(grammarAccess.getURLAccess().getAlternatives_2()); } - pushFollow(FOLLOW_2); - ruleURL_PROTOCOL(); + // InternalSemver.g:4458:2: ( rule__URL__Alternatives_2 )* + loop50: + do { + int alt50=2; + int LA50_0 = input.LA(1); + + if ( ((LA50_0>=RULE_DIGITS && LA50_0<=RULE_LETTER_OTHER)||(LA50_0>=41 && LA50_0<=44)||(LA50_0>=46 && LA50_0<=47)) ) { + alt50=1; + } + + + switch (alt50) { + case 1 : + // InternalSemver.g:4458:3: rule__URL__Alternatives_2 + { + pushFollow(FOLLOW_40); + rule__URL__Alternatives_2(); + + state._fsp--; + if (state.failed) return ; + + } + break; + + default : + break loop50; + } + } while (true); - state._fsp--; - if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURLVersionRequirementAccess().getProtocolURL_PROTOCOLParserRuleCall_0_0()); + after(grammarAccess.getURLAccess().getAlternatives_2()); } } @@ -14533,36 +15220,29 @@ public final void rule__URLVersionRequirement__ProtocolAssignment_0() throws Rec } return ; } - // $ANTLR end "rule__URLVersionRequirement__ProtocolAssignment_0" + // $ANTLR end "rule__URL__Group__2__Impl" - // $ANTLR start "rule__URLVersionRequirement__UrlAssignment_2" - // InternalSemver.g:4239:1: rule__URLVersionRequirement__UrlAssignment_2 : ( ruleURL ) ; - public final void rule__URLVersionRequirement__UrlAssignment_2() throws RecognitionException { + // $ANTLR start "rule__URL_NO_VX__Group__0" + // InternalSemver.g:4467:1: rule__URL_NO_VX__Group__0 : rule__URL_NO_VX__Group__0__Impl rule__URL_NO_VX__Group__1 ; + public final void rule__URL_NO_VX__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4243:1: ( ( ruleURL ) ) - // InternalSemver.g:4244:2: ( ruleURL ) - { - // InternalSemver.g:4244:2: ( ruleURL ) - // InternalSemver.g:4245:3: ruleURL + // InternalSemver.g:4471:1: ( rule__URL_NO_VX__Group__0__Impl rule__URL_NO_VX__Group__1 ) + // InternalSemver.g:4472:2: rule__URL_NO_VX__Group__0__Impl rule__URL_NO_VX__Group__1 { - if ( state.backtracking==0 ) { - before(grammarAccess.getURLVersionRequirementAccess().getUrlURLParserRuleCall_2_0()); - } - pushFollow(FOLLOW_2); - ruleURL(); + pushFollow(FOLLOW_9); + rule__URL_NO_VX__Group__0__Impl(); state._fsp--; if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getURLVersionRequirementAccess().getUrlURLParserRuleCall_2_0()); - } - - } + pushFollow(FOLLOW_2); + rule__URL_NO_VX__Group__1(); + state._fsp--; + if (state.failed) return ; } @@ -14578,32 +15258,38 @@ public final void rule__URLVersionRequirement__UrlAssignment_2() throws Recognit } return ; } - // $ANTLR end "rule__URLVersionRequirement__UrlAssignment_2" + // $ANTLR end "rule__URL_NO_VX__Group__0" - // $ANTLR start "rule__URLVersionRequirement__VersionSpecifierAssignment_3_1" - // InternalSemver.g:4254:1: rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 : ( ruleURLVersionSpecifier ) ; - public final void rule__URLVersionRequirement__VersionSpecifierAssignment_3_1() throws RecognitionException { + // $ANTLR start "rule__URL_NO_VX__Group__0__Impl" + // InternalSemver.g:4479:1: rule__URL_NO_VX__Group__0__Impl : ( ( rule__URL_NO_VX__Alternatives_0 ) ) ; + public final void rule__URL_NO_VX__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4258:1: ( ( ruleURLVersionSpecifier ) ) - // InternalSemver.g:4259:2: ( ruleURLVersionSpecifier ) + // InternalSemver.g:4483:1: ( ( ( rule__URL_NO_VX__Alternatives_0 ) ) ) + // InternalSemver.g:4484:1: ( ( rule__URL_NO_VX__Alternatives_0 ) ) { - // InternalSemver.g:4259:2: ( ruleURLVersionSpecifier ) - // InternalSemver.g:4260:3: ruleURLVersionSpecifier + // InternalSemver.g:4484:1: ( ( rule__URL_NO_VX__Alternatives_0 ) ) + // InternalSemver.g:4485:2: ( rule__URL_NO_VX__Alternatives_0 ) { if ( state.backtracking==0 ) { - before(grammarAccess.getURLVersionRequirementAccess().getVersionSpecifierURLVersionSpecifierParserRuleCall_3_1_0()); + before(grammarAccess.getURL_NO_VXAccess().getAlternatives_0()); } + // InternalSemver.g:4486:2: ( rule__URL_NO_VX__Alternatives_0 ) + // InternalSemver.g:4486:3: rule__URL_NO_VX__Alternatives_0 + { pushFollow(FOLLOW_2); - ruleURLVersionSpecifier(); + rule__URL_NO_VX__Alternatives_0(); state._fsp--; if (state.failed) return ; + + } + if ( state.backtracking==0 ) { - after(grammarAccess.getURLVersionRequirementAccess().getVersionSpecifierURLVersionSpecifierParserRuleCall_3_1_0()); + after(grammarAccess.getURL_NO_VXAccess().getAlternatives_0()); } } @@ -14623,36 +15309,29 @@ public final void rule__URLVersionRequirement__VersionSpecifierAssignment_3_1() } return ; } - // $ANTLR end "rule__URLVersionRequirement__VersionSpecifierAssignment_3_1" + // $ANTLR end "rule__URL_NO_VX__Group__0__Impl" - // $ANTLR start "rule__URLVersionSpecifier__CommitISHAssignment_1_1" - // InternalSemver.g:4269:1: rule__URLVersionSpecifier__CommitISHAssignment_1_1 : ( ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ; - public final void rule__URLVersionSpecifier__CommitISHAssignment_1_1() throws RecognitionException { + // $ANTLR start "rule__URL_NO_VX__Group__1" + // InternalSemver.g:4494:1: rule__URL_NO_VX__Group__1 : rule__URL_NO_VX__Group__1__Impl rule__URL_NO_VX__Group__2 ; + public final void rule__URL_NO_VX__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4273:1: ( ( ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) - // InternalSemver.g:4274:2: ( ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) + // InternalSemver.g:4498:1: ( rule__URL_NO_VX__Group__1__Impl rule__URL_NO_VX__Group__2 ) + // InternalSemver.g:4499:2: rule__URL_NO_VX__Group__1__Impl rule__URL_NO_VX__Group__2 { - // InternalSemver.g:4274:2: ( ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) - // InternalSemver.g:4275:3: ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS - { - if ( state.backtracking==0 ) { - before(grammarAccess.getURLVersionSpecifierAccess().getCommitISHALPHA_NUMERIC_CHARS_START_WITH_DIGITSParserRuleCall_1_1_0()); - } - pushFollow(FOLLOW_2); - ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS(); + pushFollow(FOLLOW_9); + rule__URL_NO_VX__Group__1__Impl(); state._fsp--; if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getURLVersionSpecifierAccess().getCommitISHALPHA_NUMERIC_CHARS_START_WITH_DIGITSParserRuleCall_1_1_0()); - } - - } + pushFollow(FOLLOW_2); + rule__URL_NO_VX__Group__2(); + state._fsp--; + if (state.failed) return ; } @@ -14668,32 +15347,56 @@ public final void rule__URLVersionSpecifier__CommitISHAssignment_1_1() throws Re } return ; } - // $ANTLR end "rule__URLVersionSpecifier__CommitISHAssignment_1_1" + // $ANTLR end "rule__URL_NO_VX__Group__1" - // $ANTLR start "rule__URLVersionSpecifier__CommitISHAssignment_2_1" - // InternalSemver.g:4284:1: rule__URLVersionSpecifier__CommitISHAssignment_2_1 : ( ruleALPHA_NUMERIC_CHARS ) ; - public final void rule__URLVersionSpecifier__CommitISHAssignment_2_1() throws RecognitionException { + // $ANTLR start "rule__URL_NO_VX__Group__1__Impl" + // InternalSemver.g:4506:1: rule__URL_NO_VX__Group__1__Impl : ( ( rule__URL_NO_VX__Alternatives_1 )* ) ; + public final void rule__URL_NO_VX__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4288:1: ( ( ruleALPHA_NUMERIC_CHARS ) ) - // InternalSemver.g:4289:2: ( ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:4510:1: ( ( ( rule__URL_NO_VX__Alternatives_1 )* ) ) + // InternalSemver.g:4511:1: ( ( rule__URL_NO_VX__Alternatives_1 )* ) { - // InternalSemver.g:4289:2: ( ruleALPHA_NUMERIC_CHARS ) - // InternalSemver.g:4290:3: ruleALPHA_NUMERIC_CHARS + // InternalSemver.g:4511:1: ( ( rule__URL_NO_VX__Alternatives_1 )* ) + // InternalSemver.g:4512:2: ( rule__URL_NO_VX__Alternatives_1 )* { if ( state.backtracking==0 ) { - before(grammarAccess.getURLVersionSpecifierAccess().getCommitISHALPHA_NUMERIC_CHARSParserRuleCall_2_1_0()); + before(grammarAccess.getURL_NO_VXAccess().getAlternatives_1()); } - pushFollow(FOLLOW_2); - ruleALPHA_NUMERIC_CHARS(); + // InternalSemver.g:4513:2: ( rule__URL_NO_VX__Alternatives_1 )* + loop51: + do { + int alt51=2; + int LA51_0 = input.LA(1); + + if ( ((LA51_0>=RULE_DIGITS && LA51_0<=RULE_LETTER_OTHER)||LA51_0==44||LA51_0==47) ) { + alt51=1; + } + + + switch (alt51) { + case 1 : + // InternalSemver.g:4513:3: rule__URL_NO_VX__Alternatives_1 + { + pushFollow(FOLLOW_3); + rule__URL_NO_VX__Alternatives_1(); + + state._fsp--; + if (state.failed) return ; + + } + break; + + default : + break loop51; + } + } while (true); - state._fsp--; - if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getURLVersionSpecifierAccess().getCommitISHALPHA_NUMERIC_CHARSParserRuleCall_2_1_0()); + after(grammarAccess.getURL_NO_VXAccess().getAlternatives_1()); } } @@ -14713,36 +15416,29 @@ public final void rule__URLVersionSpecifier__CommitISHAssignment_2_1() throws Re } return ; } - // $ANTLR end "rule__URLVersionSpecifier__CommitISHAssignment_2_1" + // $ANTLR end "rule__URL_NO_VX__Group__1__Impl" - // $ANTLR start "rule__URLSemver__WithSemverTagAssignment_1" - // InternalSemver.g:4299:1: rule__URLSemver__WithSemverTagAssignment_1 : ( ruleSEMVER_TAG ) ; - public final void rule__URLSemver__WithSemverTagAssignment_1() throws RecognitionException { + // $ANTLR start "rule__URL_NO_VX__Group__2" + // InternalSemver.g:4521:1: rule__URL_NO_VX__Group__2 : rule__URL_NO_VX__Group__2__Impl rule__URL_NO_VX__Group__3 ; + public final void rule__URL_NO_VX__Group__2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4303:1: ( ( ruleSEMVER_TAG ) ) - // InternalSemver.g:4304:2: ( ruleSEMVER_TAG ) + // InternalSemver.g:4525:1: ( rule__URL_NO_VX__Group__2__Impl rule__URL_NO_VX__Group__3 ) + // InternalSemver.g:4526:2: rule__URL_NO_VX__Group__2__Impl rule__URL_NO_VX__Group__3 { - // InternalSemver.g:4304:2: ( ruleSEMVER_TAG ) - // InternalSemver.g:4305:3: ruleSEMVER_TAG - { - if ( state.backtracking==0 ) { - before(grammarAccess.getURLSemverAccess().getWithSemverTagSEMVER_TAGParserRuleCall_1_0()); - } - pushFollow(FOLLOW_2); - ruleSEMVER_TAG(); + pushFollow(FOLLOW_9); + rule__URL_NO_VX__Group__2__Impl(); state._fsp--; if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getURLSemverAccess().getWithSemverTagSEMVER_TAGParserRuleCall_1_0()); - } - - } + pushFollow(FOLLOW_2); + rule__URL_NO_VX__Group__3(); + state._fsp--; + if (state.failed) return ; } @@ -14758,32 +15454,38 @@ public final void rule__URLSemver__WithSemverTagAssignment_1() throws Recognitio } return ; } - // $ANTLR end "rule__URLSemver__WithSemverTagAssignment_1" + // $ANTLR end "rule__URL_NO_VX__Group__2" - // $ANTLR start "rule__URLSemver__SimpleVersionAssignment_2" - // InternalSemver.g:4314:1: rule__URLSemver__SimpleVersionAssignment_2 : ( ruleSimpleVersion ) ; - public final void rule__URLSemver__SimpleVersionAssignment_2() throws RecognitionException { + // $ANTLR start "rule__URL_NO_VX__Group__2__Impl" + // InternalSemver.g:4533:1: rule__URL_NO_VX__Group__2__Impl : ( ( rule__URL_NO_VX__Alternatives_2 ) ) ; + public final void rule__URL_NO_VX__Group__2__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4318:1: ( ( ruleSimpleVersion ) ) - // InternalSemver.g:4319:2: ( ruleSimpleVersion ) + // InternalSemver.g:4537:1: ( ( ( rule__URL_NO_VX__Alternatives_2 ) ) ) + // InternalSemver.g:4538:1: ( ( rule__URL_NO_VX__Alternatives_2 ) ) { - // InternalSemver.g:4319:2: ( ruleSimpleVersion ) - // InternalSemver.g:4320:3: ruleSimpleVersion + // InternalSemver.g:4538:1: ( ( rule__URL_NO_VX__Alternatives_2 ) ) + // InternalSemver.g:4539:2: ( rule__URL_NO_VX__Alternatives_2 ) { if ( state.backtracking==0 ) { - before(grammarAccess.getURLSemverAccess().getSimpleVersionSimpleVersionParserRuleCall_2_0()); + before(grammarAccess.getURL_NO_VXAccess().getAlternatives_2()); } + // InternalSemver.g:4540:2: ( rule__URL_NO_VX__Alternatives_2 ) + // InternalSemver.g:4540:3: rule__URL_NO_VX__Alternatives_2 + { pushFollow(FOLLOW_2); - ruleSimpleVersion(); + rule__URL_NO_VX__Alternatives_2(); state._fsp--; if (state.failed) return ; + + } + if ( state.backtracking==0 ) { - after(grammarAccess.getURLSemverAccess().getSimpleVersionSimpleVersionParserRuleCall_2_0()); + after(grammarAccess.getURL_NO_VXAccess().getAlternatives_2()); } } @@ -14803,36 +15505,24 @@ public final void rule__URLSemver__SimpleVersionAssignment_2() throws Recognitio } return ; } - // $ANTLR end "rule__URLSemver__SimpleVersionAssignment_2" + // $ANTLR end "rule__URL_NO_VX__Group__2__Impl" - // $ANTLR start "rule__TagVersionRequirement__TagNameAssignment" - // InternalSemver.g:4329:1: rule__TagVersionRequirement__TagNameAssignment : ( ruleTAG ) ; - public final void rule__TagVersionRequirement__TagNameAssignment() throws RecognitionException { + // $ANTLR start "rule__URL_NO_VX__Group__3" + // InternalSemver.g:4548:1: rule__URL_NO_VX__Group__3 : rule__URL_NO_VX__Group__3__Impl ; + public final void rule__URL_NO_VX__Group__3() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4333:1: ( ( ruleTAG ) ) - // InternalSemver.g:4334:2: ( ruleTAG ) - { - // InternalSemver.g:4334:2: ( ruleTAG ) - // InternalSemver.g:4335:3: ruleTAG + // InternalSemver.g:4552:1: ( rule__URL_NO_VX__Group__3__Impl ) + // InternalSemver.g:4553:2: rule__URL_NO_VX__Group__3__Impl { - if ( state.backtracking==0 ) { - before(grammarAccess.getTagVersionRequirementAccess().getTagNameTAGParserRuleCall_0()); - } pushFollow(FOLLOW_2); - ruleTAG(); + rule__URL_NO_VX__Group__3__Impl(); state._fsp--; if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getTagVersionRequirementAccess().getTagNameTAGParserRuleCall_0()); - } - - } - } @@ -14848,32 +15538,56 @@ public final void rule__TagVersionRequirement__TagNameAssignment() throws Recogn } return ; } - // $ANTLR end "rule__TagVersionRequirement__TagNameAssignment" + // $ANTLR end "rule__URL_NO_VX__Group__3" - // $ANTLR start "rule__GitHubVersionRequirement__GithubUrlAssignment_0" - // InternalSemver.g:4344:1: rule__GitHubVersionRequirement__GithubUrlAssignment_0 : ( ruleURL_NO_VX ) ; - public final void rule__GitHubVersionRequirement__GithubUrlAssignment_0() throws RecognitionException { + // $ANTLR start "rule__URL_NO_VX__Group__3__Impl" + // InternalSemver.g:4559:1: rule__URL_NO_VX__Group__3__Impl : ( ( rule__URL_NO_VX__Alternatives_3 )* ) ; + public final void rule__URL_NO_VX__Group__3__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4348:1: ( ( ruleURL_NO_VX ) ) - // InternalSemver.g:4349:2: ( ruleURL_NO_VX ) + // InternalSemver.g:4563:1: ( ( ( rule__URL_NO_VX__Alternatives_3 )* ) ) + // InternalSemver.g:4564:1: ( ( rule__URL_NO_VX__Alternatives_3 )* ) { - // InternalSemver.g:4349:2: ( ruleURL_NO_VX ) - // InternalSemver.g:4350:3: ruleURL_NO_VX + // InternalSemver.g:4564:1: ( ( rule__URL_NO_VX__Alternatives_3 )* ) + // InternalSemver.g:4565:2: ( rule__URL_NO_VX__Alternatives_3 )* { if ( state.backtracking==0 ) { - before(grammarAccess.getGitHubVersionRequirementAccess().getGithubUrlURL_NO_VXParserRuleCall_0_0()); + before(grammarAccess.getURL_NO_VXAccess().getAlternatives_3()); } - pushFollow(FOLLOW_2); - ruleURL_NO_VX(); + // InternalSemver.g:4566:2: ( rule__URL_NO_VX__Alternatives_3 )* + loop52: + do { + int alt52=2; + int LA52_0 = input.LA(1); + + if ( ((LA52_0>=RULE_DIGITS && LA52_0<=RULE_LETTER_OTHER)||(LA52_0>=41 && LA52_0<=44)||(LA52_0>=46 && LA52_0<=47)) ) { + alt52=1; + } + + + switch (alt52) { + case 1 : + // InternalSemver.g:4566:3: rule__URL_NO_VX__Alternatives_3 + { + pushFollow(FOLLOW_40); + rule__URL_NO_VX__Alternatives_3(); + + state._fsp--; + if (state.failed) return ; + + } + break; + + default : + break loop52; + } + } while (true); - state._fsp--; - if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getGitHubVersionRequirementAccess().getGithubUrlURL_NO_VXParserRuleCall_0_0()); + after(grammarAccess.getURL_NO_VXAccess().getAlternatives_3()); } } @@ -14893,36 +15607,29 @@ public final void rule__GitHubVersionRequirement__GithubUrlAssignment_0() throws } return ; } - // $ANTLR end "rule__GitHubVersionRequirement__GithubUrlAssignment_0" + // $ANTLR end "rule__URL_NO_VX__Group__3__Impl" - // $ANTLR start "rule__GitHubVersionRequirement__CommitISHAssignment_1_1" - // InternalSemver.g:4359:1: rule__GitHubVersionRequirement__CommitISHAssignment_1_1 : ( ruleALPHA_NUMERIC_CHARS ) ; - public final void rule__GitHubVersionRequirement__CommitISHAssignment_1_1() throws RecognitionException { + // $ANTLR start "rule__TAG__Group__0" + // InternalSemver.g:4575:1: rule__TAG__Group__0 : rule__TAG__Group__0__Impl rule__TAG__Group__1 ; + public final void rule__TAG__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4363:1: ( ( ruleALPHA_NUMERIC_CHARS ) ) - // InternalSemver.g:4364:2: ( ruleALPHA_NUMERIC_CHARS ) - { - // InternalSemver.g:4364:2: ( ruleALPHA_NUMERIC_CHARS ) - // InternalSemver.g:4365:3: ruleALPHA_NUMERIC_CHARS + // InternalSemver.g:4579:1: ( rule__TAG__Group__0__Impl rule__TAG__Group__1 ) + // InternalSemver.g:4580:2: rule__TAG__Group__0__Impl rule__TAG__Group__1 { - if ( state.backtracking==0 ) { - before(grammarAccess.getGitHubVersionRequirementAccess().getCommitISHALPHA_NUMERIC_CHARSParserRuleCall_1_1_0()); - } - pushFollow(FOLLOW_2); - ruleALPHA_NUMERIC_CHARS(); + pushFollow(FOLLOW_12); + rule__TAG__Group__0__Impl(); state._fsp--; if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getGitHubVersionRequirementAccess().getCommitISHALPHA_NUMERIC_CHARSParserRuleCall_1_1_0()); - } - - } + pushFollow(FOLLOW_2); + rule__TAG__Group__1(); + state._fsp--; + if (state.failed) return ; } @@ -14938,32 +15645,32 @@ public final void rule__GitHubVersionRequirement__CommitISHAssignment_1_1() thro } return ; } - // $ANTLR end "rule__GitHubVersionRequirement__CommitISHAssignment_1_1" + // $ANTLR end "rule__TAG__Group__0" - // $ANTLR start "rule__VersionRangeSetRequirement__RangesAssignment_1_0" - // InternalSemver.g:4374:1: rule__VersionRangeSetRequirement__RangesAssignment_1_0 : ( ruleVersionRange ) ; - public final void rule__VersionRangeSetRequirement__RangesAssignment_1_0() throws RecognitionException { + // $ANTLR start "rule__TAG__Group__0__Impl" + // InternalSemver.g:4587:1: rule__TAG__Group__0__Impl : ( ruleLETTER_NO_VX ) ; + public final void rule__TAG__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4378:1: ( ( ruleVersionRange ) ) - // InternalSemver.g:4379:2: ( ruleVersionRange ) + // InternalSemver.g:4591:1: ( ( ruleLETTER_NO_VX ) ) + // InternalSemver.g:4592:1: ( ruleLETTER_NO_VX ) { - // InternalSemver.g:4379:2: ( ruleVersionRange ) - // InternalSemver.g:4380:3: ruleVersionRange + // InternalSemver.g:4592:1: ( ruleLETTER_NO_VX ) + // InternalSemver.g:4593:2: ruleLETTER_NO_VX { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionRangeSetRequirementAccess().getRangesVersionRangeParserRuleCall_1_0_0()); + before(grammarAccess.getTAGAccess().getLETTER_NO_VXParserRuleCall_0()); } pushFollow(FOLLOW_2); - ruleVersionRange(); + ruleLETTER_NO_VX(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getVersionRangeSetRequirementAccess().getRangesVersionRangeParserRuleCall_1_0_0()); + after(grammarAccess.getTAGAccess().getLETTER_NO_VXParserRuleCall_0()); } } @@ -14983,36 +15690,24 @@ public final void rule__VersionRangeSetRequirement__RangesAssignment_1_0() throw } return ; } - // $ANTLR end "rule__VersionRangeSetRequirement__RangesAssignment_1_0" + // $ANTLR end "rule__TAG__Group__0__Impl" - // $ANTLR start "rule__VersionRangeSetRequirement__RangesAssignment_1_1_3" - // InternalSemver.g:4389:1: rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 : ( ruleVersionRange ) ; - public final void rule__VersionRangeSetRequirement__RangesAssignment_1_1_3() throws RecognitionException { + // $ANTLR start "rule__TAG__Group__1" + // InternalSemver.g:4602:1: rule__TAG__Group__1 : rule__TAG__Group__1__Impl ; + public final void rule__TAG__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4393:1: ( ( ruleVersionRange ) ) - // InternalSemver.g:4394:2: ( ruleVersionRange ) + // InternalSemver.g:4606:1: ( rule__TAG__Group__1__Impl ) + // InternalSemver.g:4607:2: rule__TAG__Group__1__Impl { - // InternalSemver.g:4394:2: ( ruleVersionRange ) - // InternalSemver.g:4395:3: ruleVersionRange - { - if ( state.backtracking==0 ) { - before(grammarAccess.getVersionRangeSetRequirementAccess().getRangesVersionRangeParserRuleCall_1_1_3_0()); - } pushFollow(FOLLOW_2); - ruleVersionRange(); + rule__TAG__Group__1__Impl(); state._fsp--; if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getVersionRangeSetRequirementAccess().getRangesVersionRangeParserRuleCall_1_1_3_0()); - } - - } - } @@ -15028,32 +15723,32 @@ public final void rule__VersionRangeSetRequirement__RangesAssignment_1_1_3() thr } return ; } - // $ANTLR end "rule__VersionRangeSetRequirement__RangesAssignment_1_1_3" + // $ANTLR end "rule__TAG__Group__1" - // $ANTLR start "rule__HyphenVersionRange__FromAssignment_1" - // InternalSemver.g:4404:1: rule__HyphenVersionRange__FromAssignment_1 : ( ruleVersionNumber ) ; - public final void rule__HyphenVersionRange__FromAssignment_1() throws RecognitionException { + // $ANTLR start "rule__TAG__Group__1__Impl" + // InternalSemver.g:4613:1: rule__TAG__Group__1__Impl : ( ruleALPHA_NUMERIC_CHARS ) ; + public final void rule__TAG__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4408:1: ( ( ruleVersionNumber ) ) - // InternalSemver.g:4409:2: ( ruleVersionNumber ) + // InternalSemver.g:4617:1: ( ( ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:4618:1: ( ruleALPHA_NUMERIC_CHARS ) { - // InternalSemver.g:4409:2: ( ruleVersionNumber ) - // InternalSemver.g:4410:3: ruleVersionNumber + // InternalSemver.g:4618:1: ( ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:4619:2: ruleALPHA_NUMERIC_CHARS { if ( state.backtracking==0 ) { - before(grammarAccess.getHyphenVersionRangeAccess().getFromVersionNumberParserRuleCall_1_0()); + before(grammarAccess.getTAGAccess().getALPHA_NUMERIC_CHARSParserRuleCall_1()); } pushFollow(FOLLOW_2); - ruleVersionNumber(); + ruleALPHA_NUMERIC_CHARS(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getHyphenVersionRangeAccess().getFromVersionNumberParserRuleCall_1_0()); + after(grammarAccess.getTAGAccess().getALPHA_NUMERIC_CHARSParserRuleCall_1()); } } @@ -15073,36 +15768,29 @@ public final void rule__HyphenVersionRange__FromAssignment_1() throws Recognitio } return ; } - // $ANTLR end "rule__HyphenVersionRange__FromAssignment_1" + // $ANTLR end "rule__TAG__Group__1__Impl" - // $ANTLR start "rule__HyphenVersionRange__ToAssignment_5" - // InternalSemver.g:4419:1: rule__HyphenVersionRange__ToAssignment_5 : ( ruleVersionNumber ) ; - public final void rule__HyphenVersionRange__ToAssignment_5() throws RecognitionException { + // $ANTLR start "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0" + // InternalSemver.g:4629:1: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0 : rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1 ; + public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4423:1: ( ( ruleVersionNumber ) ) - // InternalSemver.g:4424:2: ( ruleVersionNumber ) + // InternalSemver.g:4633:1: ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1 ) + // InternalSemver.g:4634:2: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1 { - // InternalSemver.g:4424:2: ( ruleVersionNumber ) - // InternalSemver.g:4425:3: ruleVersionNumber - { - if ( state.backtracking==0 ) { - before(grammarAccess.getHyphenVersionRangeAccess().getToVersionNumberParserRuleCall_5_0()); - } - pushFollow(FOLLOW_2); - ruleVersionNumber(); + pushFollow(FOLLOW_12); + rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl(); state._fsp--; if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getHyphenVersionRangeAccess().getToVersionNumberParserRuleCall_5_0()); - } - - } + pushFollow(FOLLOW_2); + rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1(); + state._fsp--; + if (state.failed) return ; } @@ -15118,32 +15806,28 @@ public final void rule__HyphenVersionRange__ToAssignment_5() throws RecognitionE } return ; } - // $ANTLR end "rule__HyphenVersionRange__ToAssignment_5" + // $ANTLR end "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0" - // $ANTLR start "rule__VersionRangeContraint__VersionConstraintsAssignment_1" - // InternalSemver.g:4434:1: rule__VersionRangeContraint__VersionConstraintsAssignment_1 : ( ruleSimpleVersion ) ; - public final void rule__VersionRangeContraint__VersionConstraintsAssignment_1() throws RecognitionException { + // $ANTLR start "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl" + // InternalSemver.g:4641:1: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl : ( RULE_DIGITS ) ; + public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4438:1: ( ( ruleSimpleVersion ) ) - // InternalSemver.g:4439:2: ( ruleSimpleVersion ) + // InternalSemver.g:4645:1: ( ( RULE_DIGITS ) ) + // InternalSemver.g:4646:1: ( RULE_DIGITS ) { - // InternalSemver.g:4439:2: ( ruleSimpleVersion ) - // InternalSemver.g:4440:3: ruleSimpleVersion + // InternalSemver.g:4646:1: ( RULE_DIGITS ) + // InternalSemver.g:4647:2: RULE_DIGITS { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionRangeContraintAccess().getVersionConstraintsSimpleVersionParserRuleCall_1_0()); + before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getDIGITSTerminalRuleCall_0()); } - pushFollow(FOLLOW_2); - ruleSimpleVersion(); - - state._fsp--; - if (state.failed) return ; + match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getVersionRangeContraintAccess().getVersionConstraintsSimpleVersionParserRuleCall_1_0()); + after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getDIGITSTerminalRuleCall_0()); } } @@ -15163,36 +15847,24 @@ public final void rule__VersionRangeContraint__VersionConstraintsAssignment_1() } return ; } - // $ANTLR end "rule__VersionRangeContraint__VersionConstraintsAssignment_1" + // $ANTLR end "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__0__Impl" - // $ANTLR start "rule__VersionRangeContraint__VersionConstraintsAssignment_2_1" - // InternalSemver.g:4449:1: rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 : ( ruleSimpleVersion ) ; - public final void rule__VersionRangeContraint__VersionConstraintsAssignment_2_1() throws RecognitionException { + // $ANTLR start "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1" + // InternalSemver.g:4656:1: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1 : rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl ; + public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4453:1: ( ( ruleSimpleVersion ) ) - // InternalSemver.g:4454:2: ( ruleSimpleVersion ) - { - // InternalSemver.g:4454:2: ( ruleSimpleVersion ) - // InternalSemver.g:4455:3: ruleSimpleVersion + // InternalSemver.g:4660:1: ( rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl ) + // InternalSemver.g:4661:2: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl { - if ( state.backtracking==0 ) { - before(grammarAccess.getVersionRangeContraintAccess().getVersionConstraintsSimpleVersionParserRuleCall_2_1_0()); - } pushFollow(FOLLOW_2); - ruleSimpleVersion(); + rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl(); state._fsp--; if (state.failed) return ; - if ( state.backtracking==0 ) { - after(grammarAccess.getVersionRangeContraintAccess().getVersionConstraintsSimpleVersionParserRuleCall_2_1_0()); - } - - } - } @@ -15208,32 +15880,32 @@ public final void rule__VersionRangeContraint__VersionConstraintsAssignment_2_1( } return ; } - // $ANTLR end "rule__VersionRangeContraint__VersionConstraintsAssignment_2_1" + // $ANTLR end "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1" - // $ANTLR start "rule__SimpleVersion__ComparatorsAssignment_0_0" - // InternalSemver.g:4464:1: rule__SimpleVersion__ComparatorsAssignment_0_0 : ( ruleVersionComparator ) ; - public final void rule__SimpleVersion__ComparatorsAssignment_0_0() throws RecognitionException { + // $ANTLR start "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl" + // InternalSemver.g:4667:1: rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl : ( ruleALPHA_NUMERIC_CHARS ) ; + public final void rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4468:1: ( ( ruleVersionComparator ) ) - // InternalSemver.g:4469:2: ( ruleVersionComparator ) + // InternalSemver.g:4671:1: ( ( ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:4672:1: ( ruleALPHA_NUMERIC_CHARS ) { - // InternalSemver.g:4469:2: ( ruleVersionComparator ) - // InternalSemver.g:4470:3: ruleVersionComparator + // InternalSemver.g:4672:1: ( ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:4673:2: ruleALPHA_NUMERIC_CHARS { if ( state.backtracking==0 ) { - before(grammarAccess.getSimpleVersionAccess().getComparatorsVersionComparatorEnumRuleCall_0_0_0()); + before(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getALPHA_NUMERIC_CHARSParserRuleCall_1()); } pushFollow(FOLLOW_2); - ruleVersionComparator(); + ruleALPHA_NUMERIC_CHARS(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getSimpleVersionAccess().getComparatorsVersionComparatorEnumRuleCall_0_0_0()); + after(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getALPHA_NUMERIC_CHARSParserRuleCall_1()); } } @@ -15253,28 +15925,32 @@ public final void rule__SimpleVersion__ComparatorsAssignment_0_0() throws Recogn } return ; } - // $ANTLR end "rule__SimpleVersion__ComparatorsAssignment_0_0" + // $ANTLR end "rule__ALPHA_NUMERIC_CHARS_START_WITH_DIGITS__Group__1__Impl" - // $ANTLR start "rule__SimpleVersion__WithLetterVAssignment_1" - // InternalSemver.g:4479:1: rule__SimpleVersion__WithLetterVAssignment_1 : ( RULE_LETTER_V ) ; - public final void rule__SimpleVersion__WithLetterVAssignment_1() throws RecognitionException { + // $ANTLR start "rule__LocalPathVersionRequirement__LocalPathAssignment_1" + // InternalSemver.g:4683:1: rule__LocalPathVersionRequirement__LocalPathAssignment_1 : ( rulePATH ) ; + public final void rule__LocalPathVersionRequirement__LocalPathAssignment_1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4483:1: ( ( RULE_LETTER_V ) ) - // InternalSemver.g:4484:2: ( RULE_LETTER_V ) + // InternalSemver.g:4687:1: ( ( rulePATH ) ) + // InternalSemver.g:4688:2: ( rulePATH ) { - // InternalSemver.g:4484:2: ( RULE_LETTER_V ) - // InternalSemver.g:4485:3: RULE_LETTER_V + // InternalSemver.g:4688:2: ( rulePATH ) + // InternalSemver.g:4689:3: rulePATH { if ( state.backtracking==0 ) { - before(grammarAccess.getSimpleVersionAccess().getWithLetterVLETTER_VTerminalRuleCall_1_0()); + before(grammarAccess.getLocalPathVersionRequirementAccess().getLocalPathPATHParserRuleCall_1_0()); } - match(input,RULE_LETTER_V,FOLLOW_2); if (state.failed) return ; + pushFollow(FOLLOW_2); + rulePATH(); + + state._fsp--; + if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getSimpleVersionAccess().getWithLetterVLETTER_VTerminalRuleCall_1_0()); + after(grammarAccess.getLocalPathVersionRequirementAccess().getLocalPathPATHParserRuleCall_1_0()); } } @@ -15294,32 +15970,32 @@ public final void rule__SimpleVersion__WithLetterVAssignment_1() throws Recognit } return ; } - // $ANTLR end "rule__SimpleVersion__WithLetterVAssignment_1" + // $ANTLR end "rule__LocalPathVersionRequirement__LocalPathAssignment_1" - // $ANTLR start "rule__SimpleVersion__NumberAssignment_2" - // InternalSemver.g:4494:1: rule__SimpleVersion__NumberAssignment_2 : ( ruleVersionNumber ) ; - public final void rule__SimpleVersion__NumberAssignment_2() throws RecognitionException { + // $ANTLR start "rule__URLVersionRequirement__ProtocolAssignment_0" + // InternalSemver.g:4698:1: rule__URLVersionRequirement__ProtocolAssignment_0 : ( ruleURL_PROTOCOL ) ; + public final void rule__URLVersionRequirement__ProtocolAssignment_0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4498:1: ( ( ruleVersionNumber ) ) - // InternalSemver.g:4499:2: ( ruleVersionNumber ) + // InternalSemver.g:4702:1: ( ( ruleURL_PROTOCOL ) ) + // InternalSemver.g:4703:2: ( ruleURL_PROTOCOL ) { - // InternalSemver.g:4499:2: ( ruleVersionNumber ) - // InternalSemver.g:4500:3: ruleVersionNumber + // InternalSemver.g:4703:2: ( ruleURL_PROTOCOL ) + // InternalSemver.g:4704:3: ruleURL_PROTOCOL { if ( state.backtracking==0 ) { - before(grammarAccess.getSimpleVersionAccess().getNumberVersionNumberParserRuleCall_2_0()); + before(grammarAccess.getURLVersionRequirementAccess().getProtocolURL_PROTOCOLParserRuleCall_0_0()); } pushFollow(FOLLOW_2); - ruleVersionNumber(); + ruleURL_PROTOCOL(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getSimpleVersionAccess().getNumberVersionNumberParserRuleCall_2_0()); + after(grammarAccess.getURLVersionRequirementAccess().getProtocolURL_PROTOCOLParserRuleCall_0_0()); } } @@ -15339,32 +16015,32 @@ public final void rule__SimpleVersion__NumberAssignment_2() throws RecognitionEx } return ; } - // $ANTLR end "rule__SimpleVersion__NumberAssignment_2" + // $ANTLR end "rule__URLVersionRequirement__ProtocolAssignment_0" - // $ANTLR start "rule__VersionNumber__MajorAssignment_0" - // InternalSemver.g:4509:1: rule__VersionNumber__MajorAssignment_0 : ( ruleVersionPart ) ; - public final void rule__VersionNumber__MajorAssignment_0() throws RecognitionException { + // $ANTLR start "rule__URLVersionRequirement__UrlAssignment_2" + // InternalSemver.g:4713:1: rule__URLVersionRequirement__UrlAssignment_2 : ( ruleURL ) ; + public final void rule__URLVersionRequirement__UrlAssignment_2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4513:1: ( ( ruleVersionPart ) ) - // InternalSemver.g:4514:2: ( ruleVersionPart ) + // InternalSemver.g:4717:1: ( ( ruleURL ) ) + // InternalSemver.g:4718:2: ( ruleURL ) { - // InternalSemver.g:4514:2: ( ruleVersionPart ) - // InternalSemver.g:4515:3: ruleVersionPart + // InternalSemver.g:4718:2: ( ruleURL ) + // InternalSemver.g:4719:3: ruleURL { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionNumberAccess().getMajorVersionPartParserRuleCall_0_0()); + before(grammarAccess.getURLVersionRequirementAccess().getUrlURLParserRuleCall_2_0()); } pushFollow(FOLLOW_2); - ruleVersionPart(); + ruleURL(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getVersionNumberAccess().getMajorVersionPartParserRuleCall_0_0()); + after(grammarAccess.getURLVersionRequirementAccess().getUrlURLParserRuleCall_2_0()); } } @@ -15384,32 +16060,32 @@ public final void rule__VersionNumber__MajorAssignment_0() throws RecognitionExc } return ; } - // $ANTLR end "rule__VersionNumber__MajorAssignment_0" + // $ANTLR end "rule__URLVersionRequirement__UrlAssignment_2" - // $ANTLR start "rule__VersionNumber__MinorAssignment_1_1" - // InternalSemver.g:4524:1: rule__VersionNumber__MinorAssignment_1_1 : ( ruleVersionPart ) ; - public final void rule__VersionNumber__MinorAssignment_1_1() throws RecognitionException { + // $ANTLR start "rule__URLVersionRequirement__VersionSpecifierAssignment_3_1" + // InternalSemver.g:4728:1: rule__URLVersionRequirement__VersionSpecifierAssignment_3_1 : ( ruleURLVersionSpecifier ) ; + public final void rule__URLVersionRequirement__VersionSpecifierAssignment_3_1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4528:1: ( ( ruleVersionPart ) ) - // InternalSemver.g:4529:2: ( ruleVersionPart ) + // InternalSemver.g:4732:1: ( ( ruleURLVersionSpecifier ) ) + // InternalSemver.g:4733:2: ( ruleURLVersionSpecifier ) { - // InternalSemver.g:4529:2: ( ruleVersionPart ) - // InternalSemver.g:4530:3: ruleVersionPart + // InternalSemver.g:4733:2: ( ruleURLVersionSpecifier ) + // InternalSemver.g:4734:3: ruleURLVersionSpecifier { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionNumberAccess().getMinorVersionPartParserRuleCall_1_1_0()); + before(grammarAccess.getURLVersionRequirementAccess().getVersionSpecifierURLVersionSpecifierParserRuleCall_3_1_0()); } pushFollow(FOLLOW_2); - ruleVersionPart(); + ruleURLVersionSpecifier(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getVersionNumberAccess().getMinorVersionPartParserRuleCall_1_1_0()); + after(grammarAccess.getURLVersionRequirementAccess().getVersionSpecifierURLVersionSpecifierParserRuleCall_3_1_0()); } } @@ -15429,32 +16105,32 @@ public final void rule__VersionNumber__MinorAssignment_1_1() throws RecognitionE } return ; } - // $ANTLR end "rule__VersionNumber__MinorAssignment_1_1" + // $ANTLR end "rule__URLVersionRequirement__VersionSpecifierAssignment_3_1" - // $ANTLR start "rule__VersionNumber__PatchAssignment_1_2_1" - // InternalSemver.g:4539:1: rule__VersionNumber__PatchAssignment_1_2_1 : ( ruleVersionPart ) ; - public final void rule__VersionNumber__PatchAssignment_1_2_1() throws RecognitionException { + // $ANTLR start "rule__URLVersionSpecifier__CommitISHAssignment_1_1" + // InternalSemver.g:4743:1: rule__URLVersionSpecifier__CommitISHAssignment_1_1 : ( ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ; + public final void rule__URLVersionSpecifier__CommitISHAssignment_1_1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4543:1: ( ( ruleVersionPart ) ) - // InternalSemver.g:4544:2: ( ruleVersionPart ) + // InternalSemver.g:4747:1: ( ( ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) + // InternalSemver.g:4748:2: ( ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) { - // InternalSemver.g:4544:2: ( ruleVersionPart ) - // InternalSemver.g:4545:3: ruleVersionPart + // InternalSemver.g:4748:2: ( ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) + // InternalSemver.g:4749:3: ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionNumberAccess().getPatchVersionPartParserRuleCall_1_2_1_0()); + before(grammarAccess.getURLVersionSpecifierAccess().getCommitISHALPHA_NUMERIC_CHARS_START_WITH_DIGITSParserRuleCall_1_1_0()); } pushFollow(FOLLOW_2); - ruleVersionPart(); + ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getVersionNumberAccess().getPatchVersionPartParserRuleCall_1_2_1_0()); + after(grammarAccess.getURLVersionSpecifierAccess().getCommitISHALPHA_NUMERIC_CHARS_START_WITH_DIGITSParserRuleCall_1_1_0()); } } @@ -15474,32 +16150,32 @@ public final void rule__VersionNumber__PatchAssignment_1_2_1() throws Recognitio } return ; } - // $ANTLR end "rule__VersionNumber__PatchAssignment_1_2_1" + // $ANTLR end "rule__URLVersionSpecifier__CommitISHAssignment_1_1" - // $ANTLR start "rule__VersionNumber__ExtendedAssignment_1_2_2_1" - // InternalSemver.g:4554:1: rule__VersionNumber__ExtendedAssignment_1_2_2_1 : ( ruleVersionPart ) ; - public final void rule__VersionNumber__ExtendedAssignment_1_2_2_1() throws RecognitionException { + // $ANTLR start "rule__URLVersionSpecifier__CommitISHAssignment_2_1" + // InternalSemver.g:4758:1: rule__URLVersionSpecifier__CommitISHAssignment_2_1 : ( ruleALPHA_NUMERIC_CHARS ) ; + public final void rule__URLVersionSpecifier__CommitISHAssignment_2_1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4558:1: ( ( ruleVersionPart ) ) - // InternalSemver.g:4559:2: ( ruleVersionPart ) + // InternalSemver.g:4762:1: ( ( ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:4763:2: ( ruleALPHA_NUMERIC_CHARS ) { - // InternalSemver.g:4559:2: ( ruleVersionPart ) - // InternalSemver.g:4560:3: ruleVersionPart + // InternalSemver.g:4763:2: ( ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:4764:3: ruleALPHA_NUMERIC_CHARS { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionNumberAccess().getExtendedVersionPartParserRuleCall_1_2_2_1_0()); + before(grammarAccess.getURLVersionSpecifierAccess().getCommitISHALPHA_NUMERIC_CHARSParserRuleCall_2_1_0()); } pushFollow(FOLLOW_2); - ruleVersionPart(); + ruleALPHA_NUMERIC_CHARS(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getVersionNumberAccess().getExtendedVersionPartParserRuleCall_1_2_2_1_0()); + after(grammarAccess.getURLVersionSpecifierAccess().getCommitISHALPHA_NUMERIC_CHARSParserRuleCall_2_1_0()); } } @@ -15519,32 +16195,32 @@ public final void rule__VersionNumber__ExtendedAssignment_1_2_2_1() throws Recog } return ; } - // $ANTLR end "rule__VersionNumber__ExtendedAssignment_1_2_2_1" + // $ANTLR end "rule__URLVersionSpecifier__CommitISHAssignment_2_1" - // $ANTLR start "rule__VersionNumber__QualifierAssignment_2" - // InternalSemver.g:4569:1: rule__VersionNumber__QualifierAssignment_2 : ( ruleQualifier ) ; - public final void rule__VersionNumber__QualifierAssignment_2() throws RecognitionException { + // $ANTLR start "rule__URLSemver__WithSemverTagAssignment_1" + // InternalSemver.g:4773:1: rule__URLSemver__WithSemverTagAssignment_1 : ( ruleSEMVER_TAG ) ; + public final void rule__URLSemver__WithSemverTagAssignment_1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4573:1: ( ( ruleQualifier ) ) - // InternalSemver.g:4574:2: ( ruleQualifier ) + // InternalSemver.g:4777:1: ( ( ruleSEMVER_TAG ) ) + // InternalSemver.g:4778:2: ( ruleSEMVER_TAG ) { - // InternalSemver.g:4574:2: ( ruleQualifier ) - // InternalSemver.g:4575:3: ruleQualifier + // InternalSemver.g:4778:2: ( ruleSEMVER_TAG ) + // InternalSemver.g:4779:3: ruleSEMVER_TAG { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionNumberAccess().getQualifierQualifierParserRuleCall_2_0()); + before(grammarAccess.getURLSemverAccess().getWithSemverTagSEMVER_TAGParserRuleCall_1_0()); } pushFollow(FOLLOW_2); - ruleQualifier(); + ruleSEMVER_TAG(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getVersionNumberAccess().getQualifierQualifierParserRuleCall_2_0()); + after(grammarAccess.getURLSemverAccess().getWithSemverTagSEMVER_TAGParserRuleCall_1_0()); } } @@ -15564,32 +16240,32 @@ public final void rule__VersionNumber__QualifierAssignment_2() throws Recognitio } return ; } - // $ANTLR end "rule__VersionNumber__QualifierAssignment_2" + // $ANTLR end "rule__URLSemver__WithSemverTagAssignment_1" - // $ANTLR start "rule__VersionPart__WildcardAssignment_0" - // InternalSemver.g:4584:1: rule__VersionPart__WildcardAssignment_0 : ( ruleWILDCARD ) ; - public final void rule__VersionPart__WildcardAssignment_0() throws RecognitionException { + // $ANTLR start "rule__URLSemver__SimpleVersionAssignment_2" + // InternalSemver.g:4788:1: rule__URLSemver__SimpleVersionAssignment_2 : ( ruleSimpleVersion ) ; + public final void rule__URLSemver__SimpleVersionAssignment_2() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4588:1: ( ( ruleWILDCARD ) ) - // InternalSemver.g:4589:2: ( ruleWILDCARD ) + // InternalSemver.g:4792:1: ( ( ruleSimpleVersion ) ) + // InternalSemver.g:4793:2: ( ruleSimpleVersion ) { - // InternalSemver.g:4589:2: ( ruleWILDCARD ) - // InternalSemver.g:4590:3: ruleWILDCARD + // InternalSemver.g:4793:2: ( ruleSimpleVersion ) + // InternalSemver.g:4794:3: ruleSimpleVersion { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionPartAccess().getWildcardWILDCARDParserRuleCall_0_0()); + before(grammarAccess.getURLSemverAccess().getSimpleVersionSimpleVersionParserRuleCall_2_0()); } pushFollow(FOLLOW_2); - ruleWILDCARD(); + ruleSimpleVersion(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getVersionPartAccess().getWildcardWILDCARDParserRuleCall_0_0()); + after(grammarAccess.getURLSemverAccess().getSimpleVersionSimpleVersionParserRuleCall_2_0()); } } @@ -15609,28 +16285,32 @@ public final void rule__VersionPart__WildcardAssignment_0() throws RecognitionEx } return ; } - // $ANTLR end "rule__VersionPart__WildcardAssignment_0" + // $ANTLR end "rule__URLSemver__SimpleVersionAssignment_2" - // $ANTLR start "rule__VersionPart__NumberRawAssignment_1" - // InternalSemver.g:4599:1: rule__VersionPart__NumberRawAssignment_1 : ( RULE_DIGITS ) ; - public final void rule__VersionPart__NumberRawAssignment_1() throws RecognitionException { + // $ANTLR start "rule__WorkspaceVersionRequirement__VersionAssignment_1_0" + // InternalSemver.g:4803:1: rule__WorkspaceVersionRequirement__VersionAssignment_1_0 : ( ruleSimpleVersion ) ; + public final void rule__WorkspaceVersionRequirement__VersionAssignment_1_0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4603:1: ( ( RULE_DIGITS ) ) - // InternalSemver.g:4604:2: ( RULE_DIGITS ) + // InternalSemver.g:4807:1: ( ( ruleSimpleVersion ) ) + // InternalSemver.g:4808:2: ( ruleSimpleVersion ) { - // InternalSemver.g:4604:2: ( RULE_DIGITS ) - // InternalSemver.g:4605:3: RULE_DIGITS + // InternalSemver.g:4808:2: ( ruleSimpleVersion ) + // InternalSemver.g:4809:3: ruleSimpleVersion { if ( state.backtracking==0 ) { - before(grammarAccess.getVersionPartAccess().getNumberRawDIGITSTerminalRuleCall_1_0()); + before(grammarAccess.getWorkspaceVersionRequirementAccess().getVersionSimpleVersionParserRuleCall_1_0_0()); } - match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return ; + pushFollow(FOLLOW_2); + ruleSimpleVersion(); + + state._fsp--; + if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getVersionPartAccess().getNumberRawDIGITSTerminalRuleCall_1_0()); + after(grammarAccess.getWorkspaceVersionRequirementAccess().getVersionSimpleVersionParserRuleCall_1_0_0()); } } @@ -15650,32 +16330,32 @@ public final void rule__VersionPart__NumberRawAssignment_1() throws RecognitionE } return ; } - // $ANTLR end "rule__VersionPart__NumberRawAssignment_1" + // $ANTLR end "rule__WorkspaceVersionRequirement__VersionAssignment_1_0" - // $ANTLR start "rule__Qualifier__PreReleaseAssignment_0_1" - // InternalSemver.g:4614:1: rule__Qualifier__PreReleaseAssignment_0_1 : ( ruleQualifierTag ) ; - public final void rule__Qualifier__PreReleaseAssignment_0_1() throws RecognitionException { + // $ANTLR start "rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1" + // InternalSemver.g:4818:1: rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1 : ( ruleWORKSPACE_VERSION ) ; + public final void rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4618:1: ( ( ruleQualifierTag ) ) - // InternalSemver.g:4619:2: ( ruleQualifierTag ) + // InternalSemver.g:4822:1: ( ( ruleWORKSPACE_VERSION ) ) + // InternalSemver.g:4823:2: ( ruleWORKSPACE_VERSION ) { - // InternalSemver.g:4619:2: ( ruleQualifierTag ) - // InternalSemver.g:4620:3: ruleQualifierTag + // InternalSemver.g:4823:2: ( ruleWORKSPACE_VERSION ) + // InternalSemver.g:4824:3: ruleWORKSPACE_VERSION { if ( state.backtracking==0 ) { - before(grammarAccess.getQualifierAccess().getPreReleaseQualifierTagParserRuleCall_0_1_0()); + before(grammarAccess.getWorkspaceVersionRequirementAccess().getOtherVersionWORKSPACE_VERSIONParserRuleCall_1_1_0()); } pushFollow(FOLLOW_2); - ruleQualifierTag(); + ruleWORKSPACE_VERSION(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getQualifierAccess().getPreReleaseQualifierTagParserRuleCall_0_1_0()); + after(grammarAccess.getWorkspaceVersionRequirementAccess().getOtherVersionWORKSPACE_VERSIONParserRuleCall_1_1_0()); } } @@ -15695,32 +16375,32 @@ public final void rule__Qualifier__PreReleaseAssignment_0_1() throws Recognition } return ; } - // $ANTLR end "rule__Qualifier__PreReleaseAssignment_0_1" + // $ANTLR end "rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1" - // $ANTLR start "rule__Qualifier__BuildMetadataAssignment_0_2_1" - // InternalSemver.g:4629:1: rule__Qualifier__BuildMetadataAssignment_0_2_1 : ( ruleQualifierTag ) ; - public final void rule__Qualifier__BuildMetadataAssignment_0_2_1() throws RecognitionException { + // $ANTLR start "rule__GitHubVersionRequirement__GithubUrlAssignment_0" + // InternalSemver.g:4833:1: rule__GitHubVersionRequirement__GithubUrlAssignment_0 : ( ruleURL_NO_VX ) ; + public final void rule__GitHubVersionRequirement__GithubUrlAssignment_0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4633:1: ( ( ruleQualifierTag ) ) - // InternalSemver.g:4634:2: ( ruleQualifierTag ) + // InternalSemver.g:4837:1: ( ( ruleURL_NO_VX ) ) + // InternalSemver.g:4838:2: ( ruleURL_NO_VX ) { - // InternalSemver.g:4634:2: ( ruleQualifierTag ) - // InternalSemver.g:4635:3: ruleQualifierTag + // InternalSemver.g:4838:2: ( ruleURL_NO_VX ) + // InternalSemver.g:4839:3: ruleURL_NO_VX { if ( state.backtracking==0 ) { - before(grammarAccess.getQualifierAccess().getBuildMetadataQualifierTagParserRuleCall_0_2_1_0()); + before(grammarAccess.getGitHubVersionRequirementAccess().getGithubUrlURL_NO_VXParserRuleCall_0_0()); } pushFollow(FOLLOW_2); - ruleQualifierTag(); + ruleURL_NO_VX(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getQualifierAccess().getBuildMetadataQualifierTagParserRuleCall_0_2_1_0()); + after(grammarAccess.getGitHubVersionRequirementAccess().getGithubUrlURL_NO_VXParserRuleCall_0_0()); } } @@ -15740,32 +16420,32 @@ public final void rule__Qualifier__BuildMetadataAssignment_0_2_1() throws Recogn } return ; } - // $ANTLR end "rule__Qualifier__BuildMetadataAssignment_0_2_1" + // $ANTLR end "rule__GitHubVersionRequirement__GithubUrlAssignment_0" - // $ANTLR start "rule__Qualifier__BuildMetadataAssignment_1_1" - // InternalSemver.g:4644:1: rule__Qualifier__BuildMetadataAssignment_1_1 : ( ruleQualifierTag ) ; - public final void rule__Qualifier__BuildMetadataAssignment_1_1() throws RecognitionException { + // $ANTLR start "rule__GitHubVersionRequirement__CommitISHAssignment_1_1" + // InternalSemver.g:4848:1: rule__GitHubVersionRequirement__CommitISHAssignment_1_1 : ( ruleALPHA_NUMERIC_CHARS ) ; + public final void rule__GitHubVersionRequirement__CommitISHAssignment_1_1() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4648:1: ( ( ruleQualifierTag ) ) - // InternalSemver.g:4649:2: ( ruleQualifierTag ) + // InternalSemver.g:4852:1: ( ( ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:4853:2: ( ruleALPHA_NUMERIC_CHARS ) { - // InternalSemver.g:4649:2: ( ruleQualifierTag ) - // InternalSemver.g:4650:3: ruleQualifierTag + // InternalSemver.g:4853:2: ( ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:4854:3: ruleALPHA_NUMERIC_CHARS { if ( state.backtracking==0 ) { - before(grammarAccess.getQualifierAccess().getBuildMetadataQualifierTagParserRuleCall_1_1_0()); + before(grammarAccess.getGitHubVersionRequirementAccess().getCommitISHALPHA_NUMERIC_CHARSParserRuleCall_1_1_0()); } pushFollow(FOLLOW_2); - ruleQualifierTag(); + ruleALPHA_NUMERIC_CHARS(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getQualifierAccess().getBuildMetadataQualifierTagParserRuleCall_1_1_0()); + after(grammarAccess.getGitHubVersionRequirementAccess().getCommitISHALPHA_NUMERIC_CHARSParserRuleCall_1_1_0()); } } @@ -15785,32 +16465,32 @@ public final void rule__Qualifier__BuildMetadataAssignment_1_1() throws Recognit } return ; } - // $ANTLR end "rule__Qualifier__BuildMetadataAssignment_1_1" + // $ANTLR end "rule__GitHubVersionRequirement__CommitISHAssignment_1_1" - // $ANTLR start "rule__QualifierTag__PartsAssignment_0" - // InternalSemver.g:4659:1: rule__QualifierTag__PartsAssignment_0 : ( ruleALPHA_NUMERIC_CHARS ) ; - public final void rule__QualifierTag__PartsAssignment_0() throws RecognitionException { + // $ANTLR start "rule__TagVersionRequirement__TagNameAssignment" + // InternalSemver.g:4863:1: rule__TagVersionRequirement__TagNameAssignment : ( ruleTAG ) ; + public final void rule__TagVersionRequirement__TagNameAssignment() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4663:1: ( ( ruleALPHA_NUMERIC_CHARS ) ) - // InternalSemver.g:4664:2: ( ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:4867:1: ( ( ruleTAG ) ) + // InternalSemver.g:4868:2: ( ruleTAG ) { - // InternalSemver.g:4664:2: ( ruleALPHA_NUMERIC_CHARS ) - // InternalSemver.g:4665:3: ruleALPHA_NUMERIC_CHARS + // InternalSemver.g:4868:2: ( ruleTAG ) + // InternalSemver.g:4869:3: ruleTAG { if ( state.backtracking==0 ) { - before(grammarAccess.getQualifierTagAccess().getPartsALPHA_NUMERIC_CHARSParserRuleCall_0_0()); + before(grammarAccess.getTagVersionRequirementAccess().getTagNameTAGParserRuleCall_0()); } pushFollow(FOLLOW_2); - ruleALPHA_NUMERIC_CHARS(); + ruleTAG(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getQualifierTagAccess().getPartsALPHA_NUMERIC_CHARSParserRuleCall_0_0()); + after(grammarAccess.getTagVersionRequirementAccess().getTagNameTAGParserRuleCall_0()); } } @@ -15830,32 +16510,32 @@ public final void rule__QualifierTag__PartsAssignment_0() throws RecognitionExce } return ; } - // $ANTLR end "rule__QualifierTag__PartsAssignment_0" + // $ANTLR end "rule__TagVersionRequirement__TagNameAssignment" - // $ANTLR start "rule__QualifierTag__PartsAssignment_1_1" - // InternalSemver.g:4674:1: rule__QualifierTag__PartsAssignment_1_1 : ( ruleALPHA_NUMERIC_CHARS ) ; - public final void rule__QualifierTag__PartsAssignment_1_1() throws RecognitionException { + // $ANTLR start "rule__VersionRangeSetRequirement__RangesAssignment_1_0" + // InternalSemver.g:4878:1: rule__VersionRangeSetRequirement__RangesAssignment_1_0 : ( ruleVersionRange ) ; + public final void rule__VersionRangeSetRequirement__RangesAssignment_1_0() throws RecognitionException { int stackSize = keepStackSize(); try { - // InternalSemver.g:4678:1: ( ( ruleALPHA_NUMERIC_CHARS ) ) - // InternalSemver.g:4679:2: ( ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:4882:1: ( ( ruleVersionRange ) ) + // InternalSemver.g:4883:2: ( ruleVersionRange ) { - // InternalSemver.g:4679:2: ( ruleALPHA_NUMERIC_CHARS ) - // InternalSemver.g:4680:3: ruleALPHA_NUMERIC_CHARS + // InternalSemver.g:4883:2: ( ruleVersionRange ) + // InternalSemver.g:4884:3: ruleVersionRange { if ( state.backtracking==0 ) { - before(grammarAccess.getQualifierTagAccess().getPartsALPHA_NUMERIC_CHARSParserRuleCall_1_1_0()); + before(grammarAccess.getVersionRangeSetRequirementAccess().getRangesVersionRangeParserRuleCall_1_0_0()); } pushFollow(FOLLOW_2); - ruleALPHA_NUMERIC_CHARS(); + ruleVersionRange(); state._fsp--; if (state.failed) return ; if ( state.backtracking==0 ) { - after(grammarAccess.getQualifierTagAccess().getPartsALPHA_NUMERIC_CHARSParserRuleCall_1_1_0()); + after(grammarAccess.getVersionRangeSetRequirementAccess().getRangesVersionRangeParserRuleCall_1_0_0()); } } @@ -15875,200 +16555,1917 @@ public final void rule__QualifierTag__PartsAssignment_1_1() throws RecognitionEx } return ; } - // $ANTLR end "rule__QualifierTag__PartsAssignment_1_1" + // $ANTLR end "rule__VersionRangeSetRequirement__RangesAssignment_1_0" - // $ANTLR start synpred4_InternalSemver - public final void synpred4_InternalSemver_fragment() throws RecognitionException { - // InternalSemver.g:800:2: ( ( ( ruleLocalPathVersionRequirement ) ) ) - // InternalSemver.g:800:2: ( ( ruleLocalPathVersionRequirement ) ) - { - // InternalSemver.g:800:2: ( ( ruleLocalPathVersionRequirement ) ) - // InternalSemver.g:801:3: ( ruleLocalPathVersionRequirement ) - { - if ( state.backtracking==0 ) { - before(grammarAccess.getNPMVersionRequirementAccess().getLocalPathVersionRequirementParserRuleCall_1_0_0()); - } - // InternalSemver.g:802:3: ( ruleLocalPathVersionRequirement ) - // InternalSemver.g:802:4: ruleLocalPathVersionRequirement - { - pushFollow(FOLLOW_2); - ruleLocalPathVersionRequirement(); - state._fsp--; - if (state.failed) return ; + // $ANTLR start "rule__VersionRangeSetRequirement__RangesAssignment_1_1_3" + // InternalSemver.g:4893:1: rule__VersionRangeSetRequirement__RangesAssignment_1_1_3 : ( ruleVersionRange ) ; + public final void rule__VersionRangeSetRequirement__RangesAssignment_1_1_3() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:4897:1: ( ( ruleVersionRange ) ) + // InternalSemver.g:4898:2: ( ruleVersionRange ) + { + // InternalSemver.g:4898:2: ( ruleVersionRange ) + // InternalSemver.g:4899:3: ruleVersionRange + { + if ( state.backtracking==0 ) { + before(grammarAccess.getVersionRangeSetRequirementAccess().getRangesVersionRangeParserRuleCall_1_1_3_0()); + } + pushFollow(FOLLOW_2); + ruleVersionRange(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getVersionRangeSetRequirementAccess().getRangesVersionRangeParserRuleCall_1_1_3_0()); + } + + } - } + } } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + restoreStackSize(stackSize); } + return ; } - // $ANTLR end synpred4_InternalSemver + // $ANTLR end "rule__VersionRangeSetRequirement__RangesAssignment_1_1_3" - // $ANTLR start synpred5_InternalSemver - public final void synpred5_InternalSemver_fragment() throws RecognitionException { - // InternalSemver.g:821:2: ( ( ( ruleURLVersionRequirement ) ) ) - // InternalSemver.g:821:2: ( ( ruleURLVersionRequirement ) ) - { - // InternalSemver.g:821:2: ( ( ruleURLVersionRequirement ) ) - // InternalSemver.g:822:3: ( ruleURLVersionRequirement ) - { - if ( state.backtracking==0 ) { - before(grammarAccess.getNPMVersionRequirementAccess().getURLVersionRequirementParserRuleCall_1_0_1_0()); - } - // InternalSemver.g:823:3: ( ruleURLVersionRequirement ) - // InternalSemver.g:823:4: ruleURLVersionRequirement - { - pushFollow(FOLLOW_2); - ruleURLVersionRequirement(); - state._fsp--; - if (state.failed) return ; + // $ANTLR start "rule__HyphenVersionRange__FromAssignment_1" + // InternalSemver.g:4908:1: rule__HyphenVersionRange__FromAssignment_1 : ( ruleVersionNumber ) ; + public final void rule__HyphenVersionRange__FromAssignment_1() throws RecognitionException { - } + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:4912:1: ( ( ruleVersionNumber ) ) + // InternalSemver.g:4913:2: ( ruleVersionNumber ) + { + // InternalSemver.g:4913:2: ( ruleVersionNumber ) + // InternalSemver.g:4914:3: ruleVersionNumber + { + if ( state.backtracking==0 ) { + before(grammarAccess.getHyphenVersionRangeAccess().getFromVersionNumberParserRuleCall_1_0()); + } + pushFollow(FOLLOW_2); + ruleVersionNumber(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getHyphenVersionRangeAccess().getFromVersionNumberParserRuleCall_1_0()); + } + } + + + } } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + restoreStackSize(stackSize); } + return ; } - // $ANTLR end synpred5_InternalSemver + // $ANTLR end "rule__HyphenVersionRange__FromAssignment_1" - // $ANTLR start synpred6_InternalSemver - public final void synpred6_InternalSemver_fragment() throws RecognitionException { - // InternalSemver.g:827:2: ( ( ruleGitHubVersionRequirement ) ) - // InternalSemver.g:827:2: ( ruleGitHubVersionRequirement ) - { - // InternalSemver.g:827:2: ( ruleGitHubVersionRequirement ) - // InternalSemver.g:828:3: ruleGitHubVersionRequirement - { - if ( state.backtracking==0 ) { - before(grammarAccess.getNPMVersionRequirementAccess().getGitHubVersionRequirementParserRuleCall_1_0_1_1()); - } - pushFollow(FOLLOW_2); - ruleGitHubVersionRequirement(); - state._fsp--; - if (state.failed) return ; + // $ANTLR start "rule__HyphenVersionRange__ToAssignment_5" + // InternalSemver.g:4923:1: rule__HyphenVersionRange__ToAssignment_5 : ( ruleVersionNumber ) ; + public final void rule__HyphenVersionRange__ToAssignment_5() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:4927:1: ( ( ruleVersionNumber ) ) + // InternalSemver.g:4928:2: ( ruleVersionNumber ) + { + // InternalSemver.g:4928:2: ( ruleVersionNumber ) + // InternalSemver.g:4929:3: ruleVersionNumber + { + if ( state.backtracking==0 ) { + before(grammarAccess.getHyphenVersionRangeAccess().getToVersionNumberParserRuleCall_5_0()); + } + pushFollow(FOLLOW_2); + ruleVersionNumber(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getHyphenVersionRangeAccess().getToVersionNumberParserRuleCall_5_0()); + } + + } + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); } + finally { + restoreStackSize(stackSize); } + return ; } - // $ANTLR end synpred6_InternalSemver + // $ANTLR end "rule__HyphenVersionRange__ToAssignment_5" - // $ANTLR start synpred7_InternalSemver - public final void synpred7_InternalSemver_fragment() throws RecognitionException { - // InternalSemver.g:848:2: ( ( ( rule__URLVersionSpecifier__Group_0__0 ) ) ) - // InternalSemver.g:848:2: ( ( rule__URLVersionSpecifier__Group_0__0 ) ) - { - // InternalSemver.g:848:2: ( ( rule__URLVersionSpecifier__Group_0__0 ) ) - // InternalSemver.g:849:3: ( rule__URLVersionSpecifier__Group_0__0 ) - { - if ( state.backtracking==0 ) { - before(grammarAccess.getURLVersionSpecifierAccess().getGroup_0()); - } - // InternalSemver.g:850:3: ( rule__URLVersionSpecifier__Group_0__0 ) - // InternalSemver.g:850:4: rule__URLVersionSpecifier__Group_0__0 - { - pushFollow(FOLLOW_2); - rule__URLVersionSpecifier__Group_0__0(); - state._fsp--; - if (state.failed) return ; + // $ANTLR start "rule__VersionRangeContraint__VersionConstraintsAssignment_1" + // InternalSemver.g:4938:1: rule__VersionRangeContraint__VersionConstraintsAssignment_1 : ( ruleSimpleVersion ) ; + public final void rule__VersionRangeContraint__VersionConstraintsAssignment_1() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:4942:1: ( ( ruleSimpleVersion ) ) + // InternalSemver.g:4943:2: ( ruleSimpleVersion ) + { + // InternalSemver.g:4943:2: ( ruleSimpleVersion ) + // InternalSemver.g:4944:3: ruleSimpleVersion + { + if ( state.backtracking==0 ) { + before(grammarAccess.getVersionRangeContraintAccess().getVersionConstraintsSimpleVersionParserRuleCall_1_0()); + } + pushFollow(FOLLOW_2); + ruleSimpleVersion(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getVersionRangeContraintAccess().getVersionConstraintsSimpleVersionParserRuleCall_1_0()); + } + + } - } + } } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + restoreStackSize(stackSize); } + return ; } - // $ANTLR end synpred7_InternalSemver + // $ANTLR end "rule__VersionRangeContraint__VersionConstraintsAssignment_1" - // Delegated rules - public final boolean synpred6_InternalSemver() { - state.backtracking++; - int start = input.mark(); + // $ANTLR start "rule__VersionRangeContraint__VersionConstraintsAssignment_2_1" + // InternalSemver.g:4953:1: rule__VersionRangeContraint__VersionConstraintsAssignment_2_1 : ( ruleSimpleVersion ) ; + public final void rule__VersionRangeContraint__VersionConstraintsAssignment_2_1() throws RecognitionException { + + int stackSize = keepStackSize(); + try { - synpred6_InternalSemver_fragment(); // can never throw exception - } catch (RecognitionException re) { - System.err.println("impossible: "+re); + // InternalSemver.g:4957:1: ( ( ruleSimpleVersion ) ) + // InternalSemver.g:4958:2: ( ruleSimpleVersion ) + { + // InternalSemver.g:4958:2: ( ruleSimpleVersion ) + // InternalSemver.g:4959:3: ruleSimpleVersion + { + if ( state.backtracking==0 ) { + before(grammarAccess.getVersionRangeContraintAccess().getVersionConstraintsSimpleVersionParserRuleCall_2_1_0()); + } + pushFollow(FOLLOW_2); + ruleSimpleVersion(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getVersionRangeContraintAccess().getVersionConstraintsSimpleVersionParserRuleCall_2_1_0()); + } + + } + + + } + } - boolean success = !state.failed; - input.rewind(start); - state.backtracking--; - state.failed=false; - return success; + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; } - public final boolean synpred4_InternalSemver() { - state.backtracking++; - int start = input.mark(); + // $ANTLR end "rule__VersionRangeContraint__VersionConstraintsAssignment_2_1" + + + // $ANTLR start "rule__SimpleVersion__ComparatorsAssignment_0_0" + // InternalSemver.g:4968:1: rule__SimpleVersion__ComparatorsAssignment_0_0 : ( ruleVersionComparator ) ; + public final void rule__SimpleVersion__ComparatorsAssignment_0_0() throws RecognitionException { + + int stackSize = keepStackSize(); + try { - synpred4_InternalSemver_fragment(); // can never throw exception - } catch (RecognitionException re) { - System.err.println("impossible: "+re); + // InternalSemver.g:4972:1: ( ( ruleVersionComparator ) ) + // InternalSemver.g:4973:2: ( ruleVersionComparator ) + { + // InternalSemver.g:4973:2: ( ruleVersionComparator ) + // InternalSemver.g:4974:3: ruleVersionComparator + { + if ( state.backtracking==0 ) { + before(grammarAccess.getSimpleVersionAccess().getComparatorsVersionComparatorEnumRuleCall_0_0_0()); + } + pushFollow(FOLLOW_2); + ruleVersionComparator(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getSimpleVersionAccess().getComparatorsVersionComparatorEnumRuleCall_0_0_0()); + } + + } + + + } + } - boolean success = !state.failed; - input.rewind(start); - state.backtracking--; - state.failed=false; - return success; + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; } - public final boolean synpred5_InternalSemver() { - state.backtracking++; - int start = input.mark(); + // $ANTLR end "rule__SimpleVersion__ComparatorsAssignment_0_0" + + + // $ANTLR start "rule__SimpleVersion__WithLetterVAssignment_1" + // InternalSemver.g:4983:1: rule__SimpleVersion__WithLetterVAssignment_1 : ( RULE_LETTER_V ) ; + public final void rule__SimpleVersion__WithLetterVAssignment_1() throws RecognitionException { + + int stackSize = keepStackSize(); + try { - synpred5_InternalSemver_fragment(); // can never throw exception - } catch (RecognitionException re) { - System.err.println("impossible: "+re); + // InternalSemver.g:4987:1: ( ( RULE_LETTER_V ) ) + // InternalSemver.g:4988:2: ( RULE_LETTER_V ) + { + // InternalSemver.g:4988:2: ( RULE_LETTER_V ) + // InternalSemver.g:4989:3: RULE_LETTER_V + { + if ( state.backtracking==0 ) { + before(grammarAccess.getSimpleVersionAccess().getWithLetterVLETTER_VTerminalRuleCall_1_0()); + } + match(input,RULE_LETTER_V,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getSimpleVersionAccess().getWithLetterVLETTER_VTerminalRuleCall_1_0()); + } + + } + + + } + } - boolean success = !state.failed; - input.rewind(start); - state.backtracking--; - state.failed=false; - return success; + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; } - public final boolean synpred7_InternalSemver() { - state.backtracking++; - int start = input.mark(); + // $ANTLR end "rule__SimpleVersion__WithLetterVAssignment_1" + + + // $ANTLR start "rule__SimpleVersion__NumberAssignment_2" + // InternalSemver.g:4998:1: rule__SimpleVersion__NumberAssignment_2 : ( ruleVersionNumber ) ; + public final void rule__SimpleVersion__NumberAssignment_2() throws RecognitionException { + + int stackSize = keepStackSize(); + try { - synpred7_InternalSemver_fragment(); // can never throw exception - } catch (RecognitionException re) { - System.err.println("impossible: "+re); + // InternalSemver.g:5002:1: ( ( ruleVersionNumber ) ) + // InternalSemver.g:5003:2: ( ruleVersionNumber ) + { + // InternalSemver.g:5003:2: ( ruleVersionNumber ) + // InternalSemver.g:5004:3: ruleVersionNumber + { + if ( state.backtracking==0 ) { + before(grammarAccess.getSimpleVersionAccess().getNumberVersionNumberParserRuleCall_2_0()); + } + pushFollow(FOLLOW_2); + ruleVersionNumber(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getSimpleVersionAccess().getNumberVersionNumberParserRuleCall_2_0()); + } + + } + + + } + } - boolean success = !state.failed; - input.rewind(start); - state.backtracking--; - state.failed=false; - return success; + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__SimpleVersion__NumberAssignment_2" + + + // $ANTLR start "rule__VersionNumber__MajorAssignment_0" + // InternalSemver.g:5013:1: rule__VersionNumber__MajorAssignment_0 : ( ruleVersionPart ) ; + public final void rule__VersionNumber__MajorAssignment_0() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:5017:1: ( ( ruleVersionPart ) ) + // InternalSemver.g:5018:2: ( ruleVersionPart ) + { + // InternalSemver.g:5018:2: ( ruleVersionPart ) + // InternalSemver.g:5019:3: ruleVersionPart + { + if ( state.backtracking==0 ) { + before(grammarAccess.getVersionNumberAccess().getMajorVersionPartParserRuleCall_0_0()); + } + pushFollow(FOLLOW_2); + ruleVersionPart(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getVersionNumberAccess().getMajorVersionPartParserRuleCall_0_0()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__VersionNumber__MajorAssignment_0" + + + // $ANTLR start "rule__VersionNumber__MinorAssignment_1_1" + // InternalSemver.g:5028:1: rule__VersionNumber__MinorAssignment_1_1 : ( ruleVersionPart ) ; + public final void rule__VersionNumber__MinorAssignment_1_1() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:5032:1: ( ( ruleVersionPart ) ) + // InternalSemver.g:5033:2: ( ruleVersionPart ) + { + // InternalSemver.g:5033:2: ( ruleVersionPart ) + // InternalSemver.g:5034:3: ruleVersionPart + { + if ( state.backtracking==0 ) { + before(grammarAccess.getVersionNumberAccess().getMinorVersionPartParserRuleCall_1_1_0()); + } + pushFollow(FOLLOW_2); + ruleVersionPart(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getVersionNumberAccess().getMinorVersionPartParserRuleCall_1_1_0()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; } + // $ANTLR end "rule__VersionNumber__MinorAssignment_1_1" + + + // $ANTLR start "rule__VersionNumber__PatchAssignment_1_2_1" + // InternalSemver.g:5043:1: rule__VersionNumber__PatchAssignment_1_2_1 : ( ruleVersionPart ) ; + public final void rule__VersionNumber__PatchAssignment_1_2_1() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:5047:1: ( ( ruleVersionPart ) ) + // InternalSemver.g:5048:2: ( ruleVersionPart ) + { + // InternalSemver.g:5048:2: ( ruleVersionPart ) + // InternalSemver.g:5049:3: ruleVersionPart + { + if ( state.backtracking==0 ) { + before(grammarAccess.getVersionNumberAccess().getPatchVersionPartParserRuleCall_1_2_1_0()); + } + pushFollow(FOLLOW_2); + ruleVersionPart(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getVersionNumberAccess().getPatchVersionPartParserRuleCall_1_2_1_0()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__VersionNumber__PatchAssignment_1_2_1" + + + // $ANTLR start "rule__VersionNumber__ExtendedAssignment_1_2_2_1" + // InternalSemver.g:5058:1: rule__VersionNumber__ExtendedAssignment_1_2_2_1 : ( ruleVersionPart ) ; + public final void rule__VersionNumber__ExtendedAssignment_1_2_2_1() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:5062:1: ( ( ruleVersionPart ) ) + // InternalSemver.g:5063:2: ( ruleVersionPart ) + { + // InternalSemver.g:5063:2: ( ruleVersionPart ) + // InternalSemver.g:5064:3: ruleVersionPart + { + if ( state.backtracking==0 ) { + before(grammarAccess.getVersionNumberAccess().getExtendedVersionPartParserRuleCall_1_2_2_1_0()); + } + pushFollow(FOLLOW_2); + ruleVersionPart(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getVersionNumberAccess().getExtendedVersionPartParserRuleCall_1_2_2_1_0()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__VersionNumber__ExtendedAssignment_1_2_2_1" + + + // $ANTLR start "rule__VersionNumber__QualifierAssignment_2" + // InternalSemver.g:5073:1: rule__VersionNumber__QualifierAssignment_2 : ( ruleQualifier ) ; + public final void rule__VersionNumber__QualifierAssignment_2() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:5077:1: ( ( ruleQualifier ) ) + // InternalSemver.g:5078:2: ( ruleQualifier ) + { + // InternalSemver.g:5078:2: ( ruleQualifier ) + // InternalSemver.g:5079:3: ruleQualifier + { + if ( state.backtracking==0 ) { + before(grammarAccess.getVersionNumberAccess().getQualifierQualifierParserRuleCall_2_0()); + } + pushFollow(FOLLOW_2); + ruleQualifier(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getVersionNumberAccess().getQualifierQualifierParserRuleCall_2_0()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__VersionNumber__QualifierAssignment_2" + + + // $ANTLR start "rule__VersionPart__WildcardAssignment_0" + // InternalSemver.g:5088:1: rule__VersionPart__WildcardAssignment_0 : ( ruleWILDCARD ) ; + public final void rule__VersionPart__WildcardAssignment_0() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:5092:1: ( ( ruleWILDCARD ) ) + // InternalSemver.g:5093:2: ( ruleWILDCARD ) + { + // InternalSemver.g:5093:2: ( ruleWILDCARD ) + // InternalSemver.g:5094:3: ruleWILDCARD + { + if ( state.backtracking==0 ) { + before(grammarAccess.getVersionPartAccess().getWildcardWILDCARDParserRuleCall_0_0()); + } + pushFollow(FOLLOW_2); + ruleWILDCARD(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getVersionPartAccess().getWildcardWILDCARDParserRuleCall_0_0()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__VersionPart__WildcardAssignment_0" + + + // $ANTLR start "rule__VersionPart__NumberRawAssignment_1" + // InternalSemver.g:5103:1: rule__VersionPart__NumberRawAssignment_1 : ( RULE_DIGITS ) ; + public final void rule__VersionPart__NumberRawAssignment_1() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:5107:1: ( ( RULE_DIGITS ) ) + // InternalSemver.g:5108:2: ( RULE_DIGITS ) + { + // InternalSemver.g:5108:2: ( RULE_DIGITS ) + // InternalSemver.g:5109:3: RULE_DIGITS + { + if ( state.backtracking==0 ) { + before(grammarAccess.getVersionPartAccess().getNumberRawDIGITSTerminalRuleCall_1_0()); + } + match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getVersionPartAccess().getNumberRawDIGITSTerminalRuleCall_1_0()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__VersionPart__NumberRawAssignment_1" + + + // $ANTLR start "rule__Qualifier__PreReleaseAssignment_0_1" + // InternalSemver.g:5118:1: rule__Qualifier__PreReleaseAssignment_0_1 : ( ruleQualifierTag ) ; + public final void rule__Qualifier__PreReleaseAssignment_0_1() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:5122:1: ( ( ruleQualifierTag ) ) + // InternalSemver.g:5123:2: ( ruleQualifierTag ) + { + // InternalSemver.g:5123:2: ( ruleQualifierTag ) + // InternalSemver.g:5124:3: ruleQualifierTag + { + if ( state.backtracking==0 ) { + before(grammarAccess.getQualifierAccess().getPreReleaseQualifierTagParserRuleCall_0_1_0()); + } + pushFollow(FOLLOW_2); + ruleQualifierTag(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getQualifierAccess().getPreReleaseQualifierTagParserRuleCall_0_1_0()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__Qualifier__PreReleaseAssignment_0_1" + + + // $ANTLR start "rule__Qualifier__BuildMetadataAssignment_0_2_1" + // InternalSemver.g:5133:1: rule__Qualifier__BuildMetadataAssignment_0_2_1 : ( ruleQualifierTag ) ; + public final void rule__Qualifier__BuildMetadataAssignment_0_2_1() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:5137:1: ( ( ruleQualifierTag ) ) + // InternalSemver.g:5138:2: ( ruleQualifierTag ) + { + // InternalSemver.g:5138:2: ( ruleQualifierTag ) + // InternalSemver.g:5139:3: ruleQualifierTag + { + if ( state.backtracking==0 ) { + before(grammarAccess.getQualifierAccess().getBuildMetadataQualifierTagParserRuleCall_0_2_1_0()); + } + pushFollow(FOLLOW_2); + ruleQualifierTag(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getQualifierAccess().getBuildMetadataQualifierTagParserRuleCall_0_2_1_0()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__Qualifier__BuildMetadataAssignment_0_2_1" + + + // $ANTLR start "rule__Qualifier__BuildMetadataAssignment_1_1" + // InternalSemver.g:5148:1: rule__Qualifier__BuildMetadataAssignment_1_1 : ( ruleQualifierTag ) ; + public final void rule__Qualifier__BuildMetadataAssignment_1_1() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:5152:1: ( ( ruleQualifierTag ) ) + // InternalSemver.g:5153:2: ( ruleQualifierTag ) + { + // InternalSemver.g:5153:2: ( ruleQualifierTag ) + // InternalSemver.g:5154:3: ruleQualifierTag + { + if ( state.backtracking==0 ) { + before(grammarAccess.getQualifierAccess().getBuildMetadataQualifierTagParserRuleCall_1_1_0()); + } + pushFollow(FOLLOW_2); + ruleQualifierTag(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getQualifierAccess().getBuildMetadataQualifierTagParserRuleCall_1_1_0()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__Qualifier__BuildMetadataAssignment_1_1" + + + // $ANTLR start "rule__QualifierTag__PartsAssignment_0" + // InternalSemver.g:5163:1: rule__QualifierTag__PartsAssignment_0 : ( ruleALPHA_NUMERIC_CHARS ) ; + public final void rule__QualifierTag__PartsAssignment_0() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:5167:1: ( ( ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:5168:2: ( ruleALPHA_NUMERIC_CHARS ) + { + // InternalSemver.g:5168:2: ( ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:5169:3: ruleALPHA_NUMERIC_CHARS + { + if ( state.backtracking==0 ) { + before(grammarAccess.getQualifierTagAccess().getPartsALPHA_NUMERIC_CHARSParserRuleCall_0_0()); + } + pushFollow(FOLLOW_2); + ruleALPHA_NUMERIC_CHARS(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getQualifierTagAccess().getPartsALPHA_NUMERIC_CHARSParserRuleCall_0_0()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__QualifierTag__PartsAssignment_0" + + + // $ANTLR start "rule__QualifierTag__PartsAssignment_1_1" + // InternalSemver.g:5178:1: rule__QualifierTag__PartsAssignment_1_1 : ( ruleALPHA_NUMERIC_CHARS ) ; + public final void rule__QualifierTag__PartsAssignment_1_1() throws RecognitionException { + + int stackSize = keepStackSize(); + + try { + // InternalSemver.g:5182:1: ( ( ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:5183:2: ( ruleALPHA_NUMERIC_CHARS ) + { + // InternalSemver.g:5183:2: ( ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:5184:3: ruleALPHA_NUMERIC_CHARS + { + if ( state.backtracking==0 ) { + before(grammarAccess.getQualifierTagAccess().getPartsALPHA_NUMERIC_CHARSParserRuleCall_1_1_0()); + } + pushFollow(FOLLOW_2); + ruleALPHA_NUMERIC_CHARS(); + + state._fsp--; + if (state.failed) return ; + if ( state.backtracking==0 ) { + after(grammarAccess.getQualifierTagAccess().getPartsALPHA_NUMERIC_CHARSParserRuleCall_1_1_0()); + } + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + + restoreStackSize(stackSize); + + } + return ; + } + // $ANTLR end "rule__QualifierTag__PartsAssignment_1_1" + + // $ANTLR start synpred5_InternalSemver + public final void synpred5_InternalSemver_fragment() throws RecognitionException { + // InternalSemver.g:907:2: ( ( ( ruleLocalPathVersionRequirement ) ) ) + // InternalSemver.g:907:2: ( ( ruleLocalPathVersionRequirement ) ) + { + // InternalSemver.g:907:2: ( ( ruleLocalPathVersionRequirement ) ) + // InternalSemver.g:908:3: ( ruleLocalPathVersionRequirement ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getNPMVersionRequirementAccess().getLocalPathVersionRequirementParserRuleCall_1_0_0()); + } + // InternalSemver.g:909:3: ( ruleLocalPathVersionRequirement ) + // InternalSemver.g:909:4: ruleLocalPathVersionRequirement + { + pushFollow(FOLLOW_2); + ruleLocalPathVersionRequirement(); + + state._fsp--; + if (state.failed) return ; + + } + + + } + + + } + } + // $ANTLR end synpred5_InternalSemver + + // $ANTLR start synpred6_InternalSemver + public final void synpred6_InternalSemver_fragment() throws RecognitionException { + // InternalSemver.g:928:2: ( ( ( ruleURLVersionRequirement ) ) ) + // InternalSemver.g:928:2: ( ( ruleURLVersionRequirement ) ) + { + // InternalSemver.g:928:2: ( ( ruleURLVersionRequirement ) ) + // InternalSemver.g:929:3: ( ruleURLVersionRequirement ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getNPMVersionRequirementAccess().getURLVersionRequirementParserRuleCall_1_0_1_0()); + } + // InternalSemver.g:930:3: ( ruleURLVersionRequirement ) + // InternalSemver.g:930:4: ruleURLVersionRequirement + { + pushFollow(FOLLOW_2); + ruleURLVersionRequirement(); + + state._fsp--; + if (state.failed) return ; + + } + + + } + + + } + } + // $ANTLR end synpred6_InternalSemver + + // $ANTLR start synpred7_InternalSemver + public final void synpred7_InternalSemver_fragment() throws RecognitionException { + // InternalSemver.g:949:2: ( ( ( ruleWorkspaceVersionRequirement ) ) ) + // InternalSemver.g:949:2: ( ( ruleWorkspaceVersionRequirement ) ) + { + // InternalSemver.g:949:2: ( ( ruleWorkspaceVersionRequirement ) ) + // InternalSemver.g:950:3: ( ruleWorkspaceVersionRequirement ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getNPMVersionRequirementAccess().getWorkspaceVersionRequirementParserRuleCall_1_0_1_1_0()); + } + // InternalSemver.g:951:3: ( ruleWorkspaceVersionRequirement ) + // InternalSemver.g:951:4: ruleWorkspaceVersionRequirement + { + pushFollow(FOLLOW_2); + ruleWorkspaceVersionRequirement(); + + state._fsp--; + if (state.failed) return ; + + } + + + } + + + } + } + // $ANTLR end synpred7_InternalSemver + + // $ANTLR start synpred8_InternalSemver + public final void synpred8_InternalSemver_fragment() throws RecognitionException { + // InternalSemver.g:955:2: ( ( ruleGitHubVersionRequirement ) ) + // InternalSemver.g:955:2: ( ruleGitHubVersionRequirement ) + { + // InternalSemver.g:955:2: ( ruleGitHubVersionRequirement ) + // InternalSemver.g:956:3: ruleGitHubVersionRequirement + { + if ( state.backtracking==0 ) { + before(grammarAccess.getNPMVersionRequirementAccess().getGitHubVersionRequirementParserRuleCall_1_0_1_1_1()); + } + pushFollow(FOLLOW_2); + ruleGitHubVersionRequirement(); + + state._fsp--; + if (state.failed) return ; + + } + + + } + } + // $ANTLR end synpred8_InternalSemver + + // $ANTLR start synpred9_InternalSemver + public final void synpred9_InternalSemver_fragment() throws RecognitionException { + // InternalSemver.g:976:2: ( ( ( rule__URLVersionSpecifier__Group_0__0 ) ) ) + // InternalSemver.g:976:2: ( ( rule__URLVersionSpecifier__Group_0__0 ) ) + { + // InternalSemver.g:976:2: ( ( rule__URLVersionSpecifier__Group_0__0 ) ) + // InternalSemver.g:977:3: ( rule__URLVersionSpecifier__Group_0__0 ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getURLVersionSpecifierAccess().getGroup_0()); + } + // InternalSemver.g:978:3: ( rule__URLVersionSpecifier__Group_0__0 ) + // InternalSemver.g:978:4: rule__URLVersionSpecifier__Group_0__0 + { + pushFollow(FOLLOW_2); + rule__URLVersionSpecifier__Group_0__0(); + + state._fsp--; + if (state.failed) return ; + + } + + + } + + + } + } + // $ANTLR end synpred9_InternalSemver + + // $ANTLR start synpred11_InternalSemver + public final void synpred11_InternalSemver_fragment() throws RecognitionException { + // InternalSemver.g:1003:2: ( ( ( rule__WorkspaceVersionRequirement__VersionAssignment_1_0 ) ) ) + // InternalSemver.g:1003:2: ( ( rule__WorkspaceVersionRequirement__VersionAssignment_1_0 ) ) + { + // InternalSemver.g:1003:2: ( ( rule__WorkspaceVersionRequirement__VersionAssignment_1_0 ) ) + // InternalSemver.g:1004:3: ( rule__WorkspaceVersionRequirement__VersionAssignment_1_0 ) + { + if ( state.backtracking==0 ) { + before(grammarAccess.getWorkspaceVersionRequirementAccess().getVersionAssignment_1_0()); + } + // InternalSemver.g:1005:3: ( rule__WorkspaceVersionRequirement__VersionAssignment_1_0 ) + // InternalSemver.g:1005:4: rule__WorkspaceVersionRequirement__VersionAssignment_1_0 + { + pushFollow(FOLLOW_2); + rule__WorkspaceVersionRequirement__VersionAssignment_1_0(); + + state._fsp--; + if (state.failed) return ; + + } + + + } + + + } + } + // $ANTLR end synpred11_InternalSemver + + // Delegated rules + + public final boolean synpred6_InternalSemver() { + state.backtracking++; + int start = input.mark(); + try { + synpred6_InternalSemver_fragment(); // can never throw exception + } catch (RecognitionException re) { + System.err.println("impossible: "+re); + } + boolean success = !state.failed; + input.rewind(start); + state.backtracking--; + state.failed=false; + return success; + } + public final boolean synpred9_InternalSemver() { + state.backtracking++; + int start = input.mark(); + try { + synpred9_InternalSemver_fragment(); // can never throw exception + } catch (RecognitionException re) { + System.err.println("impossible: "+re); + } + boolean success = !state.failed; + input.rewind(start); + state.backtracking--; + state.failed=false; + return success; + } + public final boolean synpred11_InternalSemver() { + state.backtracking++; + int start = input.mark(); + try { + synpred11_InternalSemver_fragment(); // can never throw exception + } catch (RecognitionException re) { + System.err.println("impossible: "+re); + } + boolean success = !state.failed; + input.rewind(start); + state.backtracking--; + state.failed=false; + return success; + } + public final boolean synpred5_InternalSemver() { + state.backtracking++; + int start = input.mark(); + try { + synpred5_InternalSemver_fragment(); // can never throw exception + } catch (RecognitionException re) { + System.err.println("impossible: "+re); + } + boolean success = !state.failed; + input.rewind(start); + state.backtracking--; + state.failed=false; + return success; + } + public final boolean synpred7_InternalSemver() { + state.backtracking++; + int start = input.mark(); + try { + synpred7_InternalSemver_fragment(); // can never throw exception + } catch (RecognitionException re) { + System.err.println("impossible: "+re); + } + boolean success = !state.failed; + input.rewind(start); + state.backtracking--; + state.failed=false; + return success; + } + public final boolean synpred8_InternalSemver() { + state.backtracking++; + int start = input.mark(); + try { + synpred8_InternalSemver_fragment(); // can never throw exception + } catch (RecognitionException re) { + System.err.println("impossible: "+re); + } + boolean success = !state.failed; + input.rewind(start); + state.backtracking--; + state.failed=false; + return success; + } + + + protected DFA5 dfa5 = new DFA5(this); + protected DFA6 dfa6 = new DFA6(this); + protected DFA7 dfa7 = new DFA7(this); + protected DFA8 dfa8 = new DFA8(this); + protected DFA9 dfa9 = new DFA9(this); + protected DFA10 dfa10 = new DFA10(this); + static final String dfa_1s = "\36\uffff"; + static final String dfa_2s = "\3\uffff\4\2\27\uffff"; + static final String dfa_3s = "\1\10\1\5\1\uffff\4\5\26\0\1\uffff"; + static final String dfa_4s = "\2\57\1\uffff\3\57\1\67\26\0\1\uffff"; + static final String dfa_5s = "\2\uffff\1\2\32\uffff\1\1"; + static final String dfa_6s = "\7\uffff\1\0\1\4\1\22\1\6\1\12\1\23\1\11\1\21\1\24\1\7\1\5\1\16\1\1\1\14\1\13\1\25\1\10\1\20\1\17\1\2\1\15\1\3\1\uffff}>"; + static final String[] dfa_7s = { + "\3\2\1\1\12\2\26\uffff\1\2\2\uffff\1\2", + "\7\2\1\3\11\2\23\uffff\7\2", + "", + "\11\2\1\4\10\2\22\uffff\7\2", + "\5\2\1\5\14\2\22\uffff\7\2", + "\22\2\22\uffff\5\2\1\6\1\2", + "\1\14\1\16\1\15\1\17\1\20\1\21\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\2\22\uffff\1\7\1\10\1\11\1\12\1\uffff\1\2\1\13\7\uffff\1\2", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "" + }; + + static final short[] dfa_1 = DFA.unpackEncodedString(dfa_1s); + static final short[] dfa_2 = DFA.unpackEncodedString(dfa_2s); + static final char[] dfa_3 = DFA.unpackEncodedStringToUnsignedChars(dfa_3s); + static final char[] dfa_4 = DFA.unpackEncodedStringToUnsignedChars(dfa_4s); + static final short[] dfa_5 = DFA.unpackEncodedString(dfa_5s); + static final short[] dfa_6 = DFA.unpackEncodedString(dfa_6s); + static final short[][] dfa_7 = unpackEncodedStringArray(dfa_7s); + + class DFA5 extends DFA { + + public DFA5(BaseRecognizer recognizer) { + this.recognizer = recognizer; + this.decisionNumber = 5; + this.eot = dfa_1; + this.eof = dfa_2; + this.min = dfa_3; + this.max = dfa_4; + this.accept = dfa_5; + this.special = dfa_6; + this.transition = dfa_7; + } + public String getDescription() { + return "902:1: rule__NPMVersionRequirement__Alternatives_1_0 : ( ( ( ruleLocalPathVersionRequirement ) ) | ( ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) ) );"; + } + public int specialStateTransition(int s, IntStream _input) throws NoViableAltException { + TokenStream input = (TokenStream)_input; + int _s = s; + switch ( s ) { + case 0 : + int LA5_7 = input.LA(1); + + + int index5_7 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_7); + if ( s>=0 ) return s; + break; + case 1 : + int LA5_19 = input.LA(1); + + + int index5_19 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_19); + if ( s>=0 ) return s; + break; + case 2 : + int LA5_26 = input.LA(1); + + + int index5_26 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_26); + if ( s>=0 ) return s; + break; + case 3 : + int LA5_28 = input.LA(1); + + + int index5_28 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_28); + if ( s>=0 ) return s; + break; + case 4 : + int LA5_8 = input.LA(1); + + + int index5_8 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_8); + if ( s>=0 ) return s; + break; + case 5 : + int LA5_17 = input.LA(1); + + + int index5_17 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_17); + if ( s>=0 ) return s; + break; + case 6 : + int LA5_10 = input.LA(1); + + + int index5_10 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_10); + if ( s>=0 ) return s; + break; + case 7 : + int LA5_16 = input.LA(1); + + + int index5_16 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_16); + if ( s>=0 ) return s; + break; + case 8 : + int LA5_23 = input.LA(1); + + + int index5_23 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_23); + if ( s>=0 ) return s; + break; + case 9 : + int LA5_13 = input.LA(1); + + + int index5_13 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_13); + if ( s>=0 ) return s; + break; + case 10 : + int LA5_11 = input.LA(1); + + + int index5_11 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_11); + if ( s>=0 ) return s; + break; + case 11 : + int LA5_21 = input.LA(1); + + + int index5_21 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_21); + if ( s>=0 ) return s; + break; + case 12 : + int LA5_20 = input.LA(1); + + + int index5_20 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_20); + if ( s>=0 ) return s; + break; + case 13 : + int LA5_27 = input.LA(1); + + + int index5_27 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_27); + if ( s>=0 ) return s; + break; + case 14 : + int LA5_18 = input.LA(1); + + + int index5_18 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_18); + if ( s>=0 ) return s; + break; + case 15 : + int LA5_25 = input.LA(1); + + + int index5_25 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_25); + if ( s>=0 ) return s; + break; + case 16 : + int LA5_24 = input.LA(1); + + + int index5_24 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_24); + if ( s>=0 ) return s; + break; + case 17 : + int LA5_14 = input.LA(1); + + + int index5_14 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_14); + if ( s>=0 ) return s; + break; + case 18 : + int LA5_9 = input.LA(1); + + + int index5_9 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_9); + if ( s>=0 ) return s; + break; + case 19 : + int LA5_12 = input.LA(1); + + + int index5_12 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_12); + if ( s>=0 ) return s; + break; + case 20 : + int LA5_15 = input.LA(1); + + + int index5_15 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_15); + if ( s>=0 ) return s; + break; + case 21 : + int LA5_22 = input.LA(1); + + + int index5_22 = input.index(); + input.rewind(); + s = -1; + if ( (synpred5_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index5_22); + if ( s>=0 ) return s; + break; + } + if (state.backtracking>0) {state.failed=true; return -1;} + NoViableAltException nvae = + new NoViableAltException(getDescription(), 5, _s, input); + error(nvae); + throw nvae; + } + } + static final String dfa_8s = "\155\uffff"; + static final String dfa_9s = "\20\uffff\20\17\1\uffff\52\17\4\uffff\32\17\4\uffff"; + static final String dfa_10s = "\1\10\16\5\1\uffff\20\5\1\uffff\52\5\4\0\4\5\26\4\4\0"; + static final String dfa_11s = "\17\57\1\uffff\20\57\1\uffff\1\57\1\67\21\57\1\67\1\57\1\67\1\57\23\67\4\0\4\57\26\67\4\0"; + static final String dfa_12s = "\17\uffff\1\2\20\uffff\1\1\114\uffff"; + static final String dfa_13s = "\113\uffff\1\2\1\4\1\5\1\6\32\uffff\1\3\1\7\1\0\1\1}>"; + static final String[] dfa_14s = { + "\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\11\1\12\1\13\1\14\1\15\1\16\26\uffff\1\17\2\uffff\1\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\41\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "\1\17\1\21\1\20\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\23\uffff\4\17\1\40\2\17", + "", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\63\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\22\17\22\uffff\1\64\3\17\1\uffff\2\17\7\uffff\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\65\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\22\17\22\uffff\1\66\3\17\1\uffff\2\17\7\uffff\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\67\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\117\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\72\1\74\1\73\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111\1\112\1\17\22\uffff\1\113\1\114\1\116\1\70\1\uffff\1\115\1\71\7\uffff\1\17", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\17\1\44\1\43\1\120\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\121\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\122\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\42\1\17", + "\1\17\1\44\1\43\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\17\22\uffff\4\17\1\40\1\123\1\17", + "\23\17\22\uffff\1\124\3\17\1\uffff\12\17", + "\23\17\22\uffff\1\125\3\17\1\uffff\12\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\17\1\130\1\132\1\131\1\133\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\17\22\uffff\1\151\1\152\1\154\1\126\1\uffff\1\153\1\127\10\17", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff" + }; + + static final short[] dfa_8 = DFA.unpackEncodedString(dfa_8s); + static final short[] dfa_9 = DFA.unpackEncodedString(dfa_9s); + static final char[] dfa_10 = DFA.unpackEncodedStringToUnsignedChars(dfa_10s); + static final char[] dfa_11 = DFA.unpackEncodedStringToUnsignedChars(dfa_11s); + static final short[] dfa_12 = DFA.unpackEncodedString(dfa_12s); + static final short[] dfa_13 = DFA.unpackEncodedString(dfa_13s); + static final short[][] dfa_14 = unpackEncodedStringArray(dfa_14s); + + class DFA6 extends DFA { + + public DFA6(BaseRecognizer recognizer) { + this.recognizer = recognizer; + this.decisionNumber = 6; + this.eot = dfa_8; + this.eof = dfa_9; + this.min = dfa_10; + this.max = dfa_11; + this.accept = dfa_12; + this.special = dfa_13; + this.transition = dfa_14; + } + public String getDescription() { + return "923:1: rule__NPMVersionRequirement__Alternatives_1_0_1 : ( ( ( ruleURLVersionRequirement ) ) | ( ( rule__NPMVersionRequirement__Alternatives_1_0_1_1 ) ) );"; + } + public int specialStateTransition(int s, IntStream _input) throws NoViableAltException { + TokenStream input = (TokenStream)_input; + int _s = s; + switch ( s ) { + case 0 : + int LA6_107 = input.LA(1); + + + int index6_107 = input.index(); + input.rewind(); + s = -1; + if ( (synpred6_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index6_107); + if ( s>=0 ) return s; + break; + case 1 : + int LA6_108 = input.LA(1); + + + int index6_108 = input.index(); + input.rewind(); + s = -1; + if ( (synpred6_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index6_108); + if ( s>=0 ) return s; + break; + case 2 : + int LA6_75 = input.LA(1); + + + int index6_75 = input.index(); + input.rewind(); + s = -1; + if ( (synpred6_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index6_75); + if ( s>=0 ) return s; + break; + case 3 : + int LA6_105 = input.LA(1); + + + int index6_105 = input.index(); + input.rewind(); + s = -1; + if ( (synpred6_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index6_105); + if ( s>=0 ) return s; + break; + case 4 : + int LA6_76 = input.LA(1); + + + int index6_76 = input.index(); + input.rewind(); + s = -1; + if ( (synpred6_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index6_76); + if ( s>=0 ) return s; + break; + case 5 : + int LA6_77 = input.LA(1); + + + int index6_77 = input.index(); + input.rewind(); + s = -1; + if ( (synpred6_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index6_77); + if ( s>=0 ) return s; + break; + case 6 : + int LA6_78 = input.LA(1); + + + int index6_78 = input.index(); + input.rewind(); + s = -1; + if ( (synpred6_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + input.seek(index6_78); + if ( s>=0 ) return s; + break; + case 7 : + int LA6_106 = input.LA(1); - protected DFA4 dfa4 = new DFA4(this); - protected DFA5 dfa5 = new DFA5(this); - protected DFA6 dfa6 = new DFA6(this); - protected DFA7 dfa7 = new DFA7(this); - static final String dfa_1s = "\30\uffff"; - static final String dfa_2s = "\3\uffff\4\2\21\uffff"; - static final String dfa_3s = "\1\10\1\4\1\uffff\4\4\20\0\1\uffff"; - static final String dfa_4s = "\1\47\1\51\1\uffff\3\51\1\61\20\0\1\uffff"; - static final String dfa_5s = "\2\uffff\1\2\24\uffff\1\1"; - static final String dfa_6s = "\7\uffff\1\0\1\13\1\16\1\10\1\12\1\4\1\1\1\3\1\15\1\17\1\11\1\14\1\5\1\6\1\2\1\7\1\uffff}>"; - static final String[] dfa_7s = { - "\3\2\1\1\4\2\26\uffff\2\2", - "\2\2\1\uffff\5\2\1\3\3\2\23\uffff\7\2", + + int index6_106 = input.index(); + input.rewind(); + s = -1; + if ( (synpred6_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index6_106); + if ( s>=0 ) return s; + break; + } + if (state.backtracking>0) {state.failed=true; return -1;} + NoViableAltException nvae = + new NoViableAltException(getDescription(), 6, _s, input); + error(nvae); + throw nvae; + } + } + static final String dfa_15s = "\126\uffff"; + static final String dfa_16s = "\20\uffff\45\65\1\uffff\7\65\1\2\30\uffff"; + static final String dfa_17s = "\1\10\1\5\1\uffff\62\5\1\uffff\7\5\1\4\1\uffff\27\0"; + static final String dfa_18s = "\2\57\1\uffff\62\57\1\uffff\7\57\1\67\1\uffff\27\0"; + static final String dfa_19s = "\2\uffff\1\2\62\uffff\1\3\10\uffff\1\1\27\uffff"; + static final String dfa_20s = "\77\uffff\1\23\1\0\1\24\1\4\1\12\1\21\1\1\1\7\1\25\1\5\1\13\1\22\1\2\1\10\1\15\1\26\1\6\1\14\1\17\1\3\1\11\1\16\1\20}>"; + static final String[] dfa_21s = { + "\1\3\1\4\1\5\1\6\1\7\1\10\1\11\1\12\1\13\1\14\1\15\1\16\1\1\1\17\26\uffff\1\2\2\uffff\1\2", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\42\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\42\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\42\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\42\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\42\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\42\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\42\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\42\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\42\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\42\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\42\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\42\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "\1\21\1\23\1\22\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\42\1\35\1\36\1\37\1\40\1\41\23\uffff\4\2\1\uffff\1\2\1\20", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\66\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\67\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\70\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\71\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\72\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\73\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\74\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\2\1\43", + "\1\44\1\46\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64\1\65\22\uffff\4\2\1\uffff\1\75\1\43", + "\1\76\1\101\1\100\1\77\1\110\1\111\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\2\22\uffff\1\102\1\103\1\105\1\106\1\uffff\1\104\1\107\7\76\1\2", "", - "\2\2\1\uffff\6\2\1\4\3\2\22\uffff\7\2", - "\2\2\1\uffff\7\2\1\5\2\2\22\uffff\7\2", - "\2\2\1\uffff\12\2\22\uffff\6\2\1\6", - "\1\14\1\16\1\uffff\1\15\1\17\1\20\1\21\1\22\1\23\1\24\1\25\1\26\1\2\22\uffff\1\7\1\10\1\11\1\12\1\13\1\uffff\1\2\7\uffff\1\2", "\1\uffff", "\1\uffff", "\1\uffff", @@ -16085,814 +18482,995 @@ public final boolean synpred7_InternalSemver() { "\1\uffff", "\1\uffff", "\1\uffff", - "" + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff" }; - static final short[] dfa_1 = DFA.unpackEncodedString(dfa_1s); - static final short[] dfa_2 = DFA.unpackEncodedString(dfa_2s); - static final char[] dfa_3 = DFA.unpackEncodedStringToUnsignedChars(dfa_3s); - static final char[] dfa_4 = DFA.unpackEncodedStringToUnsignedChars(dfa_4s); - static final short[] dfa_5 = DFA.unpackEncodedString(dfa_5s); - static final short[] dfa_6 = DFA.unpackEncodedString(dfa_6s); - static final short[][] dfa_7 = unpackEncodedStringArray(dfa_7s); + static final short[] dfa_15 = DFA.unpackEncodedString(dfa_15s); + static final short[] dfa_16 = DFA.unpackEncodedString(dfa_16s); + static final char[] dfa_17 = DFA.unpackEncodedStringToUnsignedChars(dfa_17s); + static final char[] dfa_18 = DFA.unpackEncodedStringToUnsignedChars(dfa_18s); + static final short[] dfa_19 = DFA.unpackEncodedString(dfa_19s); + static final short[] dfa_20 = DFA.unpackEncodedString(dfa_20s); + static final short[][] dfa_21 = unpackEncodedStringArray(dfa_21s); - class DFA4 extends DFA { + class DFA7 extends DFA { - public DFA4(BaseRecognizer recognizer) { + public DFA7(BaseRecognizer recognizer) { this.recognizer = recognizer; - this.decisionNumber = 4; - this.eot = dfa_1; - this.eof = dfa_2; - this.min = dfa_3; - this.max = dfa_4; - this.accept = dfa_5; - this.special = dfa_6; - this.transition = dfa_7; + this.decisionNumber = 7; + this.eot = dfa_15; + this.eof = dfa_16; + this.min = dfa_17; + this.max = dfa_18; + this.accept = dfa_19; + this.special = dfa_20; + this.transition = dfa_21; } public String getDescription() { - return "795:1: rule__NPMVersionRequirement__Alternatives_1_0 : ( ( ( ruleLocalPathVersionRequirement ) ) | ( ( rule__NPMVersionRequirement__Alternatives_1_0_1 ) ) );"; + return "944:1: rule__NPMVersionRequirement__Alternatives_1_0_1_1 : ( ( ( ruleWorkspaceVersionRequirement ) ) | ( ruleGitHubVersionRequirement ) | ( ruleTagVersionRequirement ) );"; } public int specialStateTransition(int s, IntStream _input) throws NoViableAltException { TokenStream input = (TokenStream)_input; int _s = s; switch ( s ) { case 0 : - int LA4_7 = input.LA(1); + int LA7_64 = input.LA(1); - int index4_7 = input.index(); + int index7_64 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_7); + input.seek(index7_64); if ( s>=0 ) return s; break; case 1 : - int LA4_13 = input.LA(1); + int LA7_69 = input.LA(1); - int index4_13 = input.index(); + int index7_69 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_13); + input.seek(index7_69); if ( s>=0 ) return s; break; case 2 : - int LA4_21 = input.LA(1); + int LA7_75 = input.LA(1); - int index4_21 = input.index(); + int index7_75 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_21); + input.seek(index7_75); if ( s>=0 ) return s; break; case 3 : - int LA4_14 = input.LA(1); + int LA7_82 = input.LA(1); - int index4_14 = input.index(); + int index7_82 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_14); + input.seek(index7_82); if ( s>=0 ) return s; break; case 4 : - int LA4_12 = input.LA(1); + int LA7_66 = input.LA(1); - int index4_12 = input.index(); + int index7_66 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_12); + input.seek(index7_66); if ( s>=0 ) return s; break; case 5 : - int LA4_19 = input.LA(1); + int LA7_72 = input.LA(1); - int index4_19 = input.index(); + int index7_72 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_19); + input.seek(index7_72); if ( s>=0 ) return s; break; case 6 : - int LA4_20 = input.LA(1); + int LA7_79 = input.LA(1); - int index4_20 = input.index(); + int index7_79 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_20); + input.seek(index7_79); if ( s>=0 ) return s; break; case 7 : - int LA4_22 = input.LA(1); + int LA7_70 = input.LA(1); - int index4_22 = input.index(); + int index7_70 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_22); + input.seek(index7_70); if ( s>=0 ) return s; break; case 8 : - int LA4_10 = input.LA(1); + int LA7_76 = input.LA(1); - int index4_10 = input.index(); + int index7_76 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_10); + input.seek(index7_76); if ( s>=0 ) return s; break; case 9 : - int LA4_17 = input.LA(1); + int LA7_83 = input.LA(1); - int index4_17 = input.index(); + int index7_83 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_17); + input.seek(index7_83); if ( s>=0 ) return s; break; case 10 : - int LA4_11 = input.LA(1); + int LA7_67 = input.LA(1); - int index4_11 = input.index(); + int index7_67 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_11); + input.seek(index7_67); if ( s>=0 ) return s; break; case 11 : - int LA4_8 = input.LA(1); + int LA7_73 = input.LA(1); - int index4_8 = input.index(); + int index7_73 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_8); + input.seek(index7_73); if ( s>=0 ) return s; break; case 12 : - int LA4_18 = input.LA(1); + int LA7_80 = input.LA(1); - int index4_18 = input.index(); + int index7_80 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_18); + input.seek(index7_80); if ( s>=0 ) return s; break; case 13 : - int LA4_15 = input.LA(1); + int LA7_77 = input.LA(1); - int index4_15 = input.index(); + int index7_77 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_15); + input.seek(index7_77); if ( s>=0 ) return s; break; case 14 : - int LA4_9 = input.LA(1); + int LA7_84 = input.LA(1); - int index4_9 = input.index(); + int index7_84 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_9); + input.seek(index7_84); if ( s>=0 ) return s; break; case 15 : - int LA4_16 = input.LA(1); + int LA7_81 = input.LA(1); - int index4_16 = input.index(); + int index7_81 = input.index(); input.rewind(); s = -1; - if ( (synpred4_InternalSemver()) ) {s = 23;} + if ( (synpred7_InternalSemver()) ) {s = 62;} - else if ( (true) ) {s = 2;} + else if ( (synpred8_InternalSemver()) ) {s = 2;} + + + input.seek(index7_81); + if ( s>=0 ) return s; + break; + case 16 : + int LA7_85 = input.LA(1); + + + int index7_85 = input.index(); + input.rewind(); + s = -1; + if ( (synpred7_InternalSemver()) ) {s = 62;} + + else if ( (synpred8_InternalSemver()) ) {s = 2;} + + + input.seek(index7_85); + if ( s>=0 ) return s; + break; + case 17 : + int LA7_68 = input.LA(1); + + + int index7_68 = input.index(); + input.rewind(); + s = -1; + if ( (synpred7_InternalSemver()) ) {s = 62;} + + else if ( (synpred8_InternalSemver()) ) {s = 2;} + + + input.seek(index7_68); + if ( s>=0 ) return s; + break; + case 18 : + int LA7_74 = input.LA(1); + + + int index7_74 = input.index(); + input.rewind(); + s = -1; + if ( (synpred7_InternalSemver()) ) {s = 62;} + + else if ( (synpred8_InternalSemver()) ) {s = 2;} + + + input.seek(index7_74); + if ( s>=0 ) return s; + break; + case 19 : + int LA7_63 = input.LA(1); + + + int index7_63 = input.index(); + input.rewind(); + s = -1; + if ( (synpred7_InternalSemver()) ) {s = 62;} + + else if ( (synpred8_InternalSemver()) ) {s = 2;} + + + input.seek(index7_63); + if ( s>=0 ) return s; + break; + case 20 : + int LA7_65 = input.LA(1); + + + int index7_65 = input.index(); + input.rewind(); + s = -1; + if ( (synpred7_InternalSemver()) ) {s = 62;} + + else if ( (synpred8_InternalSemver()) ) {s = 2;} + + + input.seek(index7_65); + if ( s>=0 ) return s; + break; + case 21 : + int LA7_71 = input.LA(1); + + + int index7_71 = input.index(); + input.rewind(); + s = -1; + if ( (synpred7_InternalSemver()) ) {s = 62;} + + else if ( (synpred8_InternalSemver()) ) {s = 2;} + + + input.seek(index7_71); + if ( s>=0 ) return s; + break; + case 22 : + int LA7_78 = input.LA(1); + + + int index7_78 = input.index(); + input.rewind(); + s = -1; + if ( (synpred7_InternalSemver()) ) {s = 62;} + + else if ( (synpred8_InternalSemver()) ) {s = 2;} - input.seek(index4_16); + input.seek(index7_78); if ( s>=0 ) return s; break; } if (state.backtracking>0) {state.failed=true; return -1;} NoViableAltException nvae = - new NoViableAltException(getDescription(), 4, _s, input); + new NoViableAltException(getDescription(), 7, _s, input); error(nvae); throw nvae; } } - static final String dfa_8s = "\102\uffff"; - static final String dfa_9s = "\12\uffff\14\43\1\uffff\14\43\1\uffff\1\11\12\43\2\11\4\uffff\15\11"; - static final String dfa_10s = "\1\10\10\4\1\uffff\14\4\1\uffff\14\4\1\uffff\15\4\4\0\15\4"; - static final String dfa_11s = "\1\47\10\51\1\uffff\14\51\1\uffff\14\51\1\uffff\1\61\12\51\2\61\4\0\15\61"; - static final String dfa_12s = "\11\uffff\1\2\14\uffff\1\1\14\uffff\1\3\36\uffff"; - static final String dfa_13s = "\61\uffff\1\2\1\3\1\0\1\1\15\uffff}>"; - static final String[] dfa_14s = { - "\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\26\uffff\2\11", - "\1\13\1\15\1\uffff\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24\1\25\23\uffff\3\11\1\12\1\11\1\26\1\11", - "\1\13\1\15\1\uffff\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24\1\25\23\uffff\3\11\1\12\1\11\1\26\1\11", - "\1\13\1\15\1\uffff\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24\1\25\23\uffff\3\11\1\12\1\11\1\26\1\11", - "\1\13\1\15\1\uffff\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24\1\25\23\uffff\3\11\1\12\1\11\1\26\1\11", - "\1\13\1\15\1\uffff\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24\1\25\23\uffff\3\11\1\12\1\11\1\26\1\11", - "\1\13\1\15\1\uffff\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24\1\25\23\uffff\3\11\1\12\1\11\1\26\1\11", - "\1\13\1\15\1\uffff\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24\1\25\23\uffff\3\11\1\12\1\11\1\26\1\11", - "\1\13\1\15\1\uffff\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24\1\25\23\uffff\3\11\1\12\1\11\1\26\1\11", - "", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", - "\1\30\1\32\1\uffff\1\31\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\22\uffff\3\11\1\27\1\11\1\uffff\1\11", + static final String dfa_22s = "\17\uffff"; + static final String dfa_23s = "\1\uffff\1\6\1\uffff\1\6\3\uffff\1\6\3\uffff\4\6"; + static final String dfa_24s = "\1\4\1\5\1\uffff\1\4\1\0\1\5\1\uffff\1\5\2\0\1\uffff\4\5"; + static final String dfa_25s = "\1\66\1\57\1\uffff\1\57\1\0\1\57\1\uffff\1\57\2\0\1\uffff\4\57"; + static final String dfa_26s = "\2\uffff\1\1\3\uffff\1\3\3\uffff\1\2\4\uffff"; + static final String dfa_27s = "\4\uffff\1\1\1\0\2\uffff\1\3\1\2\5\uffff}>"; + static final String[] dfa_28s = { + "\1\2\1\5\1\4\1\3\13\6\1\1\2\6\31\uffff\1\6\7\2", + "\5\6\1\7\14\6\30\uffff\1\6", "", - "\2\11\1\uffff\12\11\22\uffff\1\57\4\11\1\uffff\1\11\7\uffff\1\11", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\1\30\1\46\1\uffff\1\45\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\43\22\uffff\3\11\1\27\1\11\1\26\1\44", - "\2\11\1\uffff\12\11\22\uffff\1\60\4\11\1\uffff\1\11\7\uffff\1\11", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11", - "\1\uffff", + "\1\2\1\10\1\11\20\6\30\uffff\1\6", "\1\uffff", + "\21\12\31\uffff\1\12", + "", + "\12\6\1\13\7\6\30\uffff\1\6", "\1\uffff", "\1\uffff", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11", - "\1\67\1\71\1\uffff\1\70\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\11\22\uffff\1\61\1\62\1\64\1\65\1\66\1\uffff\1\63\7\uffff\1\11" + "", + "\2\6\1\14\17\6\30\uffff\1\6", + "\5\6\1\15\14\6\30\uffff\1\6", + "\15\6\1\16\4\6\30\uffff\1\6", + "\22\6\27\uffff\1\2\1\6" }; - static final short[] dfa_8 = DFA.unpackEncodedString(dfa_8s); - static final short[] dfa_9 = DFA.unpackEncodedString(dfa_9s); - static final char[] dfa_10 = DFA.unpackEncodedStringToUnsignedChars(dfa_10s); - static final char[] dfa_11 = DFA.unpackEncodedStringToUnsignedChars(dfa_11s); - static final short[] dfa_12 = DFA.unpackEncodedString(dfa_12s); - static final short[] dfa_13 = DFA.unpackEncodedString(dfa_13s); - static final short[][] dfa_14 = unpackEncodedStringArray(dfa_14s); + static final short[] dfa_22 = DFA.unpackEncodedString(dfa_22s); + static final short[] dfa_23 = DFA.unpackEncodedString(dfa_23s); + static final char[] dfa_24 = DFA.unpackEncodedStringToUnsignedChars(dfa_24s); + static final char[] dfa_25 = DFA.unpackEncodedStringToUnsignedChars(dfa_25s); + static final short[] dfa_26 = DFA.unpackEncodedString(dfa_26s); + static final short[] dfa_27 = DFA.unpackEncodedString(dfa_27s); + static final short[][] dfa_28 = unpackEncodedStringArray(dfa_28s); - class DFA5 extends DFA { + class DFA8 extends DFA { - public DFA5(BaseRecognizer recognizer) { + public DFA8(BaseRecognizer recognizer) { this.recognizer = recognizer; - this.decisionNumber = 5; - this.eot = dfa_8; - this.eof = dfa_9; - this.min = dfa_10; - this.max = dfa_11; - this.accept = dfa_12; - this.special = dfa_13; - this.transition = dfa_14; + this.decisionNumber = 8; + this.eot = dfa_22; + this.eof = dfa_23; + this.min = dfa_24; + this.max = dfa_25; + this.accept = dfa_26; + this.special = dfa_27; + this.transition = dfa_28; } public String getDescription() { - return "816:1: rule__NPMVersionRequirement__Alternatives_1_0_1 : ( ( ( ruleURLVersionRequirement ) ) | ( ruleGitHubVersionRequirement ) | ( ruleTagVersionRequirement ) );"; + return "971:1: rule__URLVersionSpecifier__Alternatives : ( ( ( rule__URLVersionSpecifier__Group_0__0 ) ) | ( ( rule__URLVersionSpecifier__Group_1__0 ) ) | ( ( rule__URLVersionSpecifier__Group_2__0 ) ) );"; } public int specialStateTransition(int s, IntStream _input) throws NoViableAltException { TokenStream input = (TokenStream)_input; int _s = s; switch ( s ) { case 0 : - int LA5_51 = input.LA(1); + int LA8_5 = input.LA(1); - int index5_51 = input.index(); + int index8_5 = input.index(); input.rewind(); s = -1; - if ( (synpred5_InternalSemver()) ) {s = 22;} + if ( ((LA8_5>=RULE_DIGITS && LA8_5<=RULE_LETTER_OTHER)||LA8_5==47) ) {s = 10;} - else if ( (synpred6_InternalSemver()) ) {s = 9;} + else if ( (synpred9_InternalSemver()) ) {s = 2;} + + else if ( (true) ) {s = 6;} - input.seek(index5_51); + input.seek(index8_5); if ( s>=0 ) return s; break; case 1 : - int LA5_52 = input.LA(1); + int LA8_4 = input.LA(1); - int index5_52 = input.index(); + int index8_4 = input.index(); input.rewind(); s = -1; - if ( (synpred5_InternalSemver()) ) {s = 22;} + if ( (synpred9_InternalSemver()) ) {s = 2;} - else if ( (synpred6_InternalSemver()) ) {s = 9;} + else if ( (true) ) {s = 6;} - input.seek(index5_52); + input.seek(index8_4); if ( s>=0 ) return s; break; case 2 : - int LA5_49 = input.LA(1); + int LA8_9 = input.LA(1); - int index5_49 = input.index(); + int index8_9 = input.index(); input.rewind(); s = -1; - if ( (synpred5_InternalSemver()) ) {s = 22;} + if ( (synpred9_InternalSemver()) ) {s = 2;} - else if ( (synpred6_InternalSemver()) ) {s = 9;} + else if ( (true) ) {s = 6;} - input.seek(index5_49); + input.seek(index8_9); if ( s>=0 ) return s; break; case 3 : - int LA5_50 = input.LA(1); + int LA8_8 = input.LA(1); - int index5_50 = input.index(); + int index8_8 = input.index(); input.rewind(); s = -1; - if ( (synpred5_InternalSemver()) ) {s = 22;} + if ( (synpred9_InternalSemver()) ) {s = 2;} - else if ( (synpred6_InternalSemver()) ) {s = 9;} + else if ( (true) ) {s = 6;} - input.seek(index5_50); + input.seek(index8_8); if ( s>=0 ) return s; break; } if (state.backtracking>0) {state.failed=true; return -1;} NoViableAltException nvae = - new NoViableAltException(getDescription(), 5, _s, input); + new NoViableAltException(getDescription(), 8, _s, input); error(nvae); throw nvae; } } - static final String dfa_15s = "\17\uffff"; - static final String dfa_16s = "\1\uffff\1\6\1\uffff\1\6\3\uffff\1\6\3\uffff\4\6"; - static final String dfa_17s = "\2\4\1\uffff\1\4\1\0\1\4\1\uffff\1\4\2\0\1\uffff\4\4"; - static final String dfa_18s = "\1\60\1\46\1\uffff\1\46\1\0\1\46\1\uffff\1\46\2\0\1\uffff\3\46\1\51"; - static final String dfa_19s = "\2\uffff\1\1\3\uffff\1\3\3\uffff\1\2\4\uffff"; - static final String dfa_20s = "\4\uffff\1\2\1\0\2\uffff\1\3\1\1\5\uffff}>"; - static final String[] dfa_21s = { - "\1\5\1\4\1\2\1\3\1\1\7\6\26\uffff\1\6\3\uffff\7\2", - "\2\6\1\uffff\7\6\1\7\2\6\25\uffff\1\6", - "", - "\1\11\1\10\1\2\12\6\25\uffff\1\6", + static final String dfa_29s = "\32\uffff"; + static final String dfa_30s = "\1\uffff\10\14\4\uffff\7\14\2\uffff\1\14\1\uffff\1\14\1\uffff"; + static final String dfa_31s = "\11\4\3\0\1\uffff\7\4\2\0\1\4\1\0\1\4\1\uffff"; + static final String dfa_32s = "\11\66\3\0\1\uffff\7\66\2\0\1\66\1\0\1\66\1\uffff"; + static final String dfa_33s = "\14\uffff\1\2\14\uffff\1\1"; + static final String dfa_34s = "\11\uffff\1\4\1\5\1\2\10\uffff\1\0\1\1\1\uffff\1\3\2\uffff}>"; + static final String[] dfa_35s = { + "\1\12\1\13\1\11\1\10\16\14\23\uffff\4\14\1\uffff\2\14\1\1\1\2\1\3\1\4\1\5\1\6\1\7", + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\24\1\25\1\27\20\14\22\uffff\4\14\1\uffff\11\14", "\1\uffff", - "\2\12\1\uffff\11\12\26\uffff\1\12", - "", - "\2\6\1\uffff\2\6\1\13\7\6\25\uffff\1\6", "\1\uffff", "\1\uffff", "", - "\2\6\1\uffff\1\14\11\6\25\uffff\1\6", - "\2\6\1\uffff\7\6\1\15\2\6\25\uffff\1\6", - "\2\6\1\uffff\3\6\1\16\6\6\25\uffff\1\6", - "\2\6\1\uffff\12\6\25\uffff\1\6\2\uffff\1\2" + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\24\1\25\1\27\1\26\16\14\1\30\22\uffff\4\14\1\uffff\2\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23", + "\1\uffff", + "\1\uffff", + "\1\24\1\25\1\27\20\14\22\uffff\4\14\1\uffff\11\14", + "\1\uffff", + "\4\31\50\uffff\7\31", + "" }; - static final short[] dfa_15 = DFA.unpackEncodedString(dfa_15s); - static final short[] dfa_16 = DFA.unpackEncodedString(dfa_16s); - static final char[] dfa_17 = DFA.unpackEncodedStringToUnsignedChars(dfa_17s); - static final char[] dfa_18 = DFA.unpackEncodedStringToUnsignedChars(dfa_18s); - static final short[] dfa_19 = DFA.unpackEncodedString(dfa_19s); - static final short[] dfa_20 = DFA.unpackEncodedString(dfa_20s); - static final short[][] dfa_21 = unpackEncodedStringArray(dfa_21s); + static final short[] dfa_29 = DFA.unpackEncodedString(dfa_29s); + static final short[] dfa_30 = DFA.unpackEncodedString(dfa_30s); + static final char[] dfa_31 = DFA.unpackEncodedStringToUnsignedChars(dfa_31s); + static final char[] dfa_32 = DFA.unpackEncodedStringToUnsignedChars(dfa_32s); + static final short[] dfa_33 = DFA.unpackEncodedString(dfa_33s); + static final short[] dfa_34 = DFA.unpackEncodedString(dfa_34s); + static final short[][] dfa_35 = unpackEncodedStringArray(dfa_35s); - class DFA6 extends DFA { + class DFA9 extends DFA { - public DFA6(BaseRecognizer recognizer) { + public DFA9(BaseRecognizer recognizer) { this.recognizer = recognizer; - this.decisionNumber = 6; - this.eot = dfa_15; - this.eof = dfa_16; - this.min = dfa_17; - this.max = dfa_18; - this.accept = dfa_19; - this.special = dfa_20; - this.transition = dfa_21; + this.decisionNumber = 9; + this.eot = dfa_29; + this.eof = dfa_30; + this.min = dfa_31; + this.max = dfa_32; + this.accept = dfa_33; + this.special = dfa_34; + this.transition = dfa_35; } public String getDescription() { - return "843:1: rule__URLVersionSpecifier__Alternatives : ( ( ( rule__URLVersionSpecifier__Group_0__0 ) ) | ( ( rule__URLVersionSpecifier__Group_1__0 ) ) | ( ( rule__URLVersionSpecifier__Group_2__0 ) ) );"; + return "998:1: rule__WorkspaceVersionRequirement__Alternatives_1 : ( ( ( rule__WorkspaceVersionRequirement__VersionAssignment_1_0 ) ) | ( ( rule__WorkspaceVersionRequirement__OtherVersionAssignment_1_1 ) ) );"; } public int specialStateTransition(int s, IntStream _input) throws NoViableAltException { TokenStream input = (TokenStream)_input; int _s = s; switch ( s ) { case 0 : - int LA6_5 = input.LA(1); + int LA9_20 = input.LA(1); - int index6_5 = input.index(); + int index9_20 = input.index(); input.rewind(); s = -1; - if ( ((LA6_5>=RULE_DIGITS && LA6_5<=RULE_LETTER_X)||(LA6_5>=RULE_LETTER_V && LA6_5<=RULE_LETTER_OTHER)||LA6_5==38) ) {s = 10;} + if ( (synpred11_InternalSemver()) ) {s = 25;} - else if ( (synpred7_InternalSemver()) ) {s = 2;} - - else if ( (true) ) {s = 6;} + else if ( (true) ) {s = 12;} - input.seek(index6_5); + input.seek(index9_20); if ( s>=0 ) return s; break; case 1 : - int LA6_9 = input.LA(1); + int LA9_21 = input.LA(1); - int index6_9 = input.index(); + int index9_21 = input.index(); input.rewind(); s = -1; - if ( (synpred7_InternalSemver()) ) {s = 2;} + if ( (synpred11_InternalSemver()) ) {s = 25;} - else if ( (true) ) {s = 6;} + else if ( (true) ) {s = 12;} - input.seek(index6_9); + input.seek(index9_21); if ( s>=0 ) return s; break; case 2 : - int LA6_4 = input.LA(1); + int LA9_11 = input.LA(1); - int index6_4 = input.index(); + int index9_11 = input.index(); input.rewind(); s = -1; - if ( (synpred7_InternalSemver()) ) {s = 2;} + if ( (synpred11_InternalSemver()) ) {s = 25;} - else if ( (true) ) {s = 6;} + else if ( (true) ) {s = 12;} - input.seek(index6_4); + input.seek(index9_11); if ( s>=0 ) return s; break; case 3 : - int LA6_8 = input.LA(1); + int LA9_23 = input.LA(1); - int index6_8 = input.index(); + int index9_23 = input.index(); input.rewind(); s = -1; - if ( (synpred7_InternalSemver()) ) {s = 2;} + if ( (synpred11_InternalSemver()) ) {s = 25;} - else if ( (true) ) {s = 6;} + else if ( (true) ) {s = 12;} + + + input.seek(index9_23); + if ( s>=0 ) return s; + break; + case 4 : + int LA9_9 = input.LA(1); + + + int index9_9 = input.index(); + input.rewind(); + s = -1; + if ( (synpred11_InternalSemver()) ) {s = 25;} + + else if ( (true) ) {s = 12;} + + + input.seek(index9_9); + if ( s>=0 ) return s; + break; + case 5 : + int LA9_10 = input.LA(1); - input.seek(index6_8); + int index9_10 = input.index(); + input.rewind(); + s = -1; + if ( (synpred11_InternalSemver()) ) {s = 25;} + + else if ( (true) ) {s = 12;} + + + input.seek(index9_10); if ( s>=0 ) return s; break; } if (state.backtracking>0) {state.failed=true; return -1;} NoViableAltException nvae = - new NoViableAltException(getDescription(), 6, _s, input); + new NoViableAltException(getDescription(), 9, _s, input); error(nvae); throw nvae; } } - static final String dfa_22s = "\u00a9\uffff"; - static final String dfa_23s = "\2\uffff\3\1\3\uffff\34\1\2\uffff\14\1\2\uffff\14\1\1\uffff\47\1\1\uffff\30\1\1\uffff\47\1"; - static final String dfa_24s = "\1\4\1\uffff\3\20\4\4\3\20\30\4\1\uffff\34\4\3\20\112\4\3\20\30\4"; - static final String dfa_25s = "\1\60\1\uffff\3\62\1\6\2\46\34\62\1\uffff\1\6\14\62\2\46\14\62\1\46\47\62\1\6\30\62\1\46\47\62"; - static final String dfa_26s = "\1\uffff\1\1\42\uffff\1\2\u0084\uffff"; - static final String dfa_27s = "\u00a9\uffff}>"; - static final String[] dfa_28s = { - "\1\4\1\2\1\3\1\1\42\uffff\7\1", + static final String dfa_36s = "\u00f1\uffff"; + static final String dfa_37s = "\2\uffff\3\1\3\uffff\50\1\2\uffff\22\1\2\uffff\22\1\1\uffff\71\1\1\uffff\44\1\1\uffff\71\1"; + static final String dfa_38s = "\1\4\1\uffff\3\26\1\4\2\5\1\4\3\26\44\5\1\uffff\1\4\47\5\3\26\66\5\1\4\67\5\3\26\44\5"; + static final String dfa_39s = "\1\66\1\uffff\3\70\1\6\2\57\50\70\1\uffff\1\6\22\70\2\57\22\70\1\57\71\70\1\6\44\70\1\57\71\70"; + static final String dfa_40s = "\1\uffff\1\1\56\uffff\1\2\u00c0\uffff"; + static final String dfa_41s = "\u00f1\uffff}>"; + static final String[] dfa_42s = { + "\1\3\1\4\1\2\1\1\50\uffff\7\1", "", - "\1\10\23\uffff\1\5\1\uffff\1\6\1\uffff\1\7\11\uffff\1\1", - "\1\10\23\uffff\1\5\1\uffff\1\6\1\uffff\1\7\11\uffff\1\1", - "\1\10\23\uffff\1\5\1\uffff\1\6\1\uffff\1\7\11\uffff\1\1", - "\1\13\1\11\1\12", - "\1\15\1\17\1\uffff\1\16\1\20\1\21\1\22\1\23\1\24\1\25\1\26\1\27\26\uffff\1\14", - "\1\31\1\33\1\uffff\1\32\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\26\uffff\1\30", - "\4\1\36\uffff\1\44\3\uffff\7\1\1\uffff\1\1", - "\1\10\23\uffff\1\45\1\uffff\1\6\1\uffff\1\7\11\uffff\1\1", - "\1\10\23\uffff\1\45\1\uffff\1\6\1\uffff\1\7\11\uffff\1\1", - "\1\10\23\uffff\1\45\1\uffff\1\6\1\uffff\1\7\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", + "\1\10\23\uffff\1\5\2\uffff\1\7\1\uffff\1\6\10\uffff\1\1", + "\1\10\23\uffff\1\5\2\uffff\1\7\1\uffff\1\6\10\uffff\1\1", + "\1\10\23\uffff\1\5\2\uffff\1\7\1\uffff\1\6\10\uffff\1\1", + "\1\12\1\13\1\11", + "\1\15\1\17\1\16\1\20\1\21\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\31\uffff\1\14", + "\1\37\1\41\1\40\1\42\1\43\1\44\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57\31\uffff\1\36", + "\4\1\47\uffff\1\60\7\1\1\uffff\1\1", + "\1\10\23\uffff\1\61\2\uffff\1\7\1\uffff\1\6\10\uffff\1\1", + "\1\10\23\uffff\1\61\2\uffff\1\7\1\uffff\1\6\10\uffff\1\1", + "\1\10\23\uffff\1\61\2\uffff\1\7\1\uffff\1\6\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", "", - "\1\103\1\101\1\102", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\47\1\51\1\uffff\1\50\1\52\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\10\23\uffff\1\62\1\uffff\1\46\1\uffff\1\63\11\uffff\1\1", - "\1\105\1\107\1\uffff\1\106\1\110\1\111\1\112\1\113\1\114\1\115\1\116\1\117\26\uffff\1\104", - "\1\121\1\123\1\uffff\1\122\1\124\1\125\1\126\1\127\1\130\1\131\1\132\1\133\26\uffff\1\120", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\65\1\67\1\uffff\1\66\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\10\23\uffff\1\100\1\uffff\1\64\13\uffff\1\1", - "\1\135\1\137\1\uffff\1\136\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\26\uffff\1\134", - "\1\10\23\uffff\1\150\1\uffff\1\6\1\uffff\1\7\11\uffff\1\1", - "\1\10\23\uffff\1\150\1\uffff\1\6\1\uffff\1\7\11\uffff\1\1", - "\1\10\23\uffff\1\150\1\uffff\1\6\1\uffff\1\7\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0090\1\u008e\1\u008f", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\152\1\154\1\uffff\1\153\1\155\1\156\1\157\1\160\1\161\1\162\1\163\1\164\1\10\23\uffff\1\62\1\uffff\1\151\1\uffff\1\63\11\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\166\1\170\1\uffff\1\167\1\171\1\172\1\173\1\174\1\175\1\176\1\177\1\u0080\1\10\23\uffff\1\u0081\1\uffff\1\165\13\uffff\1\1", - "\1\u0092\1\u0094\1\uffff\1\u0093\1\u0095\1\u0096\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\26\uffff\1\u0091", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\u0083\1\u0085\1\uffff\1\u0084\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\10\23\uffff\1\100\1\uffff\1\u0082\13\uffff\1\1", - "\1\10\23\uffff\1\150\1\uffff\1\6\1\uffff\1\7\11\uffff\1\1", - "\1\10\23\uffff\1\150\1\uffff\1\6\1\uffff\1\7\11\uffff\1\1", - "\1\10\23\uffff\1\150\1\uffff\1\6\1\uffff\1\7\11\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1", - "\1\u009e\1\u00a0\1\uffff\1\u009f\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\u00a5\1\u00a6\1\u00a7\1\u00a8\1\10\23\uffff\1\u0081\1\uffff\1\u009d\13\uffff\1\1" + "\1\132\1\133\1\131", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\63\1\65\1\64\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\62\10\uffff\1\1", + "\1\135\1\137\1\136\1\140\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\151\1\152\1\153\1\154\1\155\31\uffff\1\134", + "\1\157\1\161\1\160\1\162\1\163\1\164\1\165\1\166\1\167\1\170\1\171\1\172\1\173\1\174\1\175\1\176\1\177\31\uffff\1\156", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\107\1\111\1\110\1\112\1\113\1\114\1\115\1\116\1\117\1\120\1\121\1\122\1\123\1\124\1\125\1\126\1\127\1\10\23\uffff\1\130\4\uffff\1\106\10\uffff\1\1", + "\1\u0081\1\u0083\1\u0082\1\u0084\1\u0085\1\u0086\1\u0087\1\u0088\1\u0089\1\u008a\1\u008b\1\u008c\1\u008d\1\u008e\1\u008f\1\u0090\1\u0091\31\uffff\1\u0080", + "\1\10\23\uffff\1\u0092\2\uffff\1\7\1\uffff\1\6\10\uffff\1\1", + "\1\10\23\uffff\1\u0092\2\uffff\1\7\1\uffff\1\6\10\uffff\1\1", + "\1\10\23\uffff\1\u0092\2\uffff\1\7\1\uffff\1\6\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00cb\1\u00cc\1\u00ca", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u0094\1\u0096\1\u0095\1\u0097\1\u0098\1\u0099\1\u009a\1\u009b\1\u009c\1\u009d\1\u009e\1\u009f\1\u00a0\1\u00a1\1\u00a2\1\u00a3\1\u00a4\1\10\23\uffff\1\104\2\uffff\1\105\1\uffff\1\u0093\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00a6\1\u00a8\1\u00a7\1\u00a9\1\u00aa\1\u00ab\1\u00ac\1\u00ad\1\u00ae\1\u00af\1\u00b0\1\u00b1\1\u00b2\1\u00b3\1\u00b4\1\u00b5\1\u00b6\1\10\23\uffff\1\u00b7\4\uffff\1\u00a5\10\uffff\1\1", + "\1\u00ce\1\u00d0\1\u00cf\1\u00d1\1\u00d2\1\u00d3\1\u00d4\1\u00d5\1\u00d6\1\u00d7\1\u00d8\1\u00d9\1\u00da\1\u00db\1\u00dc\1\u00dd\1\u00de\31\uffff\1\u00cd", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\u00b9\1\u00bb\1\u00ba\1\u00bc\1\u00bd\1\u00be\1\u00bf\1\u00c0\1\u00c1\1\u00c2\1\u00c3\1\u00c4\1\u00c5\1\u00c6\1\u00c7\1\u00c8\1\u00c9\1\10\23\uffff\1\130\4\uffff\1\u00b8\10\uffff\1\1", + "\1\10\23\uffff\1\u0092\2\uffff\1\7\1\uffff\1\6\10\uffff\1\1", + "\1\10\23\uffff\1\u0092\2\uffff\1\7\1\uffff\1\6\10\uffff\1\1", + "\1\10\23\uffff\1\u0092\2\uffff\1\7\1\uffff\1\6\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1", + "\1\u00e0\1\u00e2\1\u00e1\1\u00e3\1\u00e4\1\u00e5\1\u00e6\1\u00e7\1\u00e8\1\u00e9\1\u00ea\1\u00eb\1\u00ec\1\u00ed\1\u00ee\1\u00ef\1\u00f0\1\10\23\uffff\1\u00b7\4\uffff\1\u00df\10\uffff\1\1" }; - static final short[] dfa_22 = DFA.unpackEncodedString(dfa_22s); - static final short[] dfa_23 = DFA.unpackEncodedString(dfa_23s); - static final char[] dfa_24 = DFA.unpackEncodedStringToUnsignedChars(dfa_24s); - static final char[] dfa_25 = DFA.unpackEncodedStringToUnsignedChars(dfa_25s); - static final short[] dfa_26 = DFA.unpackEncodedString(dfa_26s); - static final short[] dfa_27 = DFA.unpackEncodedString(dfa_27s); - static final short[][] dfa_28 = unpackEncodedStringArray(dfa_28s); + static final short[] dfa_36 = DFA.unpackEncodedString(dfa_36s); + static final short[] dfa_37 = DFA.unpackEncodedString(dfa_37s); + static final char[] dfa_38 = DFA.unpackEncodedStringToUnsignedChars(dfa_38s); + static final char[] dfa_39 = DFA.unpackEncodedStringToUnsignedChars(dfa_39s); + static final short[] dfa_40 = DFA.unpackEncodedString(dfa_40s); + static final short[] dfa_41 = DFA.unpackEncodedString(dfa_41s); + static final short[][] dfa_42 = unpackEncodedStringArray(dfa_42s); - class DFA7 extends DFA { + class DFA10 extends DFA { - public DFA7(BaseRecognizer recognizer) { + public DFA10(BaseRecognizer recognizer) { this.recognizer = recognizer; - this.decisionNumber = 7; - this.eot = dfa_22; - this.eof = dfa_23; - this.min = dfa_24; - this.max = dfa_25; - this.accept = dfa_26; - this.special = dfa_27; - this.transition = dfa_28; + this.decisionNumber = 10; + this.eot = dfa_36; + this.eof = dfa_37; + this.min = dfa_38; + this.max = dfa_39; + this.accept = dfa_40; + this.special = dfa_41; + this.transition = dfa_42; } public String getDescription() { - return "870:1: rule__VersionRange__Alternatives : ( ( ruleVersionRangeContraint ) | ( ruleHyphenVersionRange ) );"; + return "1019:1: rule__VersionRange__Alternatives : ( ( ruleVersionRangeContraint ) | ( ruleHyphenVersionRange ) );"; } } public static final BitSet FOLLOW_1 = new BitSet(new long[]{0x0000000000000000L}); public static final BitSet FOLLOW_2 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_3 = new BitSet(new long[]{0x000000F80000FFB2L}); - public static final BitSet FOLLOW_4 = new BitSet(new long[]{0x0001FC00000000F0L}); - public static final BitSet FOLLOW_5 = new BitSet(new long[]{0x0000000000010000L}); - public static final BitSet FOLLOW_6 = new BitSet(new long[]{0x000000F80000FFB0L}); - public static final BitSet FOLLOW_7 = new BitSet(new long[]{0x0000020000000000L}); - public static final BitSet FOLLOW_8 = new BitSet(new long[]{0x000002F80000FFB0L}); - public static final BitSet FOLLOW_9 = new BitSet(new long[]{0x0002000000000000L}); - public static final BitSet FOLLOW_10 = new BitSet(new long[]{0x0000000800000000L}); - public static final BitSet FOLLOW_11 = new BitSet(new long[]{0x0001FCF80000FFF0L}); - public static final BitSet FOLLOW_12 = new BitSet(new long[]{0x0000000000000010L}); - public static final BitSet FOLLOW_13 = new BitSet(new long[]{0x0001FC00000001F0L}); - public static final BitSet FOLLOW_14 = new BitSet(new long[]{0x0004000000010000L}); - public static final BitSet FOLLOW_15 = new BitSet(new long[]{0x0004000000010002L}); - public static final BitSet FOLLOW_16 = new BitSet(new long[]{0x0001FC00000100F0L}); - public static final BitSet FOLLOW_17 = new BitSet(new long[]{0x0000004000000000L}); - public static final BitSet FOLLOW_18 = new BitSet(new long[]{0x0000000000010002L}); - public static final BitSet FOLLOW_19 = new BitSet(new long[]{0x0001FC0000000002L}); - public static final BitSet FOLLOW_20 = new BitSet(new long[]{0x0000015000000000L}); - public static final BitSet FOLLOW_21 = new BitSet(new long[]{0x0000001000000000L}); - public static final BitSet FOLLOW_22 = new BitSet(new long[]{0x0000001000000002L}); - public static final BitSet FOLLOW_23 = new BitSet(new long[]{0x0000010000000000L}); - public static final BitSet FOLLOW_24 = new BitSet(new long[]{0x0000000000001000L}); - public static final BitSet FOLLOW_25 = new BitSet(new long[]{0x0000000000002000L}); - public static final BitSet FOLLOW_26 = new BitSet(new long[]{0x0000000000004000L}); - public static final BitSet FOLLOW_27 = new BitSet(new long[]{0x0000000000000200L}); - public static final BitSet FOLLOW_28 = new BitSet(new long[]{0x0000000000000080L}); - public static final BitSet FOLLOW_29 = new BitSet(new long[]{0x0000000000000400L}); - public static final BitSet FOLLOW_30 = new BitSet(new long[]{0x000001F80000FFB0L}); - public static final BitSet FOLLOW_31 = new BitSet(new long[]{0x000001F80000FFB2L}); - public static final BitSet FOLLOW_32 = new BitSet(new long[]{0x000002F80000FFB2L}); + public static final BitSet FOLLOW_3 = new BitSet(new long[]{0x00009E00003FFFE2L}); + public static final BitSet FOLLOW_4 = new BitSet(new long[]{0x007FDE00003FFFF2L}); + public static final BitSet FOLLOW_5 = new BitSet(new long[]{0x007F0000000000F0L}); + public static final BitSet FOLLOW_6 = new BitSet(new long[]{0x0000000000400000L}); + public static final BitSet FOLLOW_7 = new BitSet(new long[]{0x00009E00003FFFE0L}); + public static final BitSet FOLLOW_8 = new BitSet(new long[]{0x0000400000000000L}); + public static final BitSet FOLLOW_9 = new BitSet(new long[]{0x0000DE00003FFFE0L}); + public static final BitSet FOLLOW_10 = new BitSet(new long[]{0x0080000000000000L}); + public static final BitSet FOLLOW_11 = new BitSet(new long[]{0x0000020000000000L}); + public static final BitSet FOLLOW_12 = new BitSet(new long[]{0x007F9E00003FFFF0L}); + public static final BitSet FOLLOW_13 = new BitSet(new long[]{0x0000000000000020L}); + public static final BitSet FOLLOW_14 = new BitSet(new long[]{0x007F0000000800F0L}); + public static final BitSet FOLLOW_15 = new BitSet(new long[]{0x007FDE00003FFFF0L}); + public static final BitSet FOLLOW_16 = new BitSet(new long[]{0x0100000000400000L}); + public static final BitSet FOLLOW_17 = new BitSet(new long[]{0x0100000000400002L}); + public static final BitSet FOLLOW_18 = new BitSet(new long[]{0x007F0000004000F0L}); + public static final BitSet FOLLOW_19 = new BitSet(new long[]{0x0000800000000000L}); + public static final BitSet FOLLOW_20 = new BitSet(new long[]{0x0000000000400002L}); + public static final BitSet FOLLOW_21 = new BitSet(new long[]{0x007F000000000002L}); + public static final BitSet FOLLOW_22 = new BitSet(new long[]{0x0000A40000000000L}); + public static final BitSet FOLLOW_23 = new BitSet(new long[]{0x0000040000000000L}); + public static final BitSet FOLLOW_24 = new BitSet(new long[]{0x0000040000000002L}); + public static final BitSet FOLLOW_25 = new BitSet(new long[]{0x0000200000000000L}); + public static final BitSet FOLLOW_26 = new BitSet(new long[]{0x0000000000001000L}); + public static final BitSet FOLLOW_27 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_28 = new BitSet(new long[]{0x0000000000000400L}); + public static final BitSet FOLLOW_29 = new BitSet(new long[]{0x0000000000008000L}); + public static final BitSet FOLLOW_30 = new BitSet(new long[]{0x0000000000000080L}); + public static final BitSet FOLLOW_31 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_32 = new BitSet(new long[]{0x0000000000010000L}); + public static final BitSet FOLLOW_33 = new BitSet(new long[]{0x0000000000002000L}); + public static final BitSet FOLLOW_34 = new BitSet(new long[]{0x0000000000080000L}); + public static final BitSet FOLLOW_35 = new BitSet(new long[]{0x0000000000020000L}); + public static final BitSet FOLLOW_36 = new BitSet(new long[]{0x0000000000000100L}); + public static final BitSet FOLLOW_37 = new BitSet(new long[]{0x0000000000000200L}); + public static final BitSet FOLLOW_38 = new BitSet(new long[]{0x0000BE00003FFFE0L}); + public static final BitSet FOLLOW_39 = new BitSet(new long[]{0x0000BE00003FFFE2L}); + public static final BitSet FOLLOW_40 = new BitSet(new long[]{0x0000DE00003FFFE2L}); } \ No newline at end of file diff --git a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/SemverFactory.java b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/SemverFactory.java index 9664852aba..4a4822be02 100644 --- a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/SemverFactory.java +++ b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/SemverFactory.java @@ -56,6 +56,15 @@ public interface SemverFactory extends EFactory { */ URLCommitISH createURLCommitISH(); + /** + * Returns a new object of class 'Workspace Version Requirement'. + * + * + * @return a new object of class 'Workspace Version Requirement'. + * @generated + */ + WorkspaceVersionRequirement createWorkspaceVersionRequirement(); + /** * Returns a new object of class 'Git Hub Version Requirement'. * diff --git a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/SemverPackage.java b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/SemverPackage.java index 194521efe4..372093469e 100644 --- a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/SemverPackage.java +++ b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/SemverPackage.java @@ -370,6 +370,61 @@ public interface SemverPackage extends EPackage { */ int URL_COMMIT_ISH_OPERATION_COUNT = URL_VERSION_SPECIFIER_OPERATION_COUNT + 0; + /** + * The meta object id for the '{@link org.eclipse.n4js.semver.Semver.impl.WorkspaceVersionRequirementImpl Workspace Version Requirement}' class. + * + * + * @see org.eclipse.n4js.semver.Semver.impl.WorkspaceVersionRequirementImpl + * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getWorkspaceVersionRequirement() + * @generated + */ + int WORKSPACE_VERSION_REQUIREMENT = 6; + + /** + * The feature id for the 'Version' containment reference. + * + * + * @generated + * @ordered + */ + int WORKSPACE_VERSION_REQUIREMENT__VERSION = NPM_VERSION_REQUIREMENT_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Other Version' attribute. + * + * + * @generated + * @ordered + */ + int WORKSPACE_VERSION_REQUIREMENT__OTHER_VERSION = NPM_VERSION_REQUIREMENT_FEATURE_COUNT + 1; + + /** + * The number of structural features of the 'Workspace Version Requirement' class. + * + * + * @generated + * @ordered + */ + int WORKSPACE_VERSION_REQUIREMENT_FEATURE_COUNT = NPM_VERSION_REQUIREMENT_FEATURE_COUNT + 2; + + /** + * The operation id for the 'To String' operation. + * + * + * @generated + * @ordered + */ + int WORKSPACE_VERSION_REQUIREMENT___TO_STRING = NPM_VERSION_REQUIREMENT___TO_STRING; + + /** + * The number of operations of the 'Workspace Version Requirement' class. + * + * + * @generated + * @ordered + */ + int WORKSPACE_VERSION_REQUIREMENT_OPERATION_COUNT = NPM_VERSION_REQUIREMENT_OPERATION_COUNT + 0; + /** * The meta object id for the '{@link org.eclipse.n4js.semver.Semver.impl.GitHubVersionRequirementImpl Git Hub Version Requirement}' class. * @@ -378,7 +433,7 @@ public interface SemverPackage extends EPackage { * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getGitHubVersionRequirement() * @generated */ - int GIT_HUB_VERSION_REQUIREMENT = 6; + int GIT_HUB_VERSION_REQUIREMENT = 7; /** * The feature id for the 'Github Url' attribute. @@ -433,7 +488,7 @@ public interface SemverPackage extends EPackage { * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getLocalPathVersionRequirement() * @generated */ - int LOCAL_PATH_VERSION_REQUIREMENT = 7; + int LOCAL_PATH_VERSION_REQUIREMENT = 8; /** * The feature id for the 'Local Path' attribute. @@ -479,7 +534,7 @@ public interface SemverPackage extends EPackage { * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getTagVersionRequirement() * @generated */ - int TAG_VERSION_REQUIREMENT = 8; + int TAG_VERSION_REQUIREMENT = 9; /** * The feature id for the 'Tag Name' attribute. @@ -525,7 +580,7 @@ public interface SemverPackage extends EPackage { * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getVersionRangeSetRequirement() * @generated */ - int VERSION_RANGE_SET_REQUIREMENT = 9; + int VERSION_RANGE_SET_REQUIREMENT = 10; /** * The feature id for the 'Ranges' containment reference list. @@ -571,7 +626,7 @@ public interface SemverPackage extends EPackage { * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getVersionRange() * @generated */ - int VERSION_RANGE = 10; + int VERSION_RANGE = 11; /** * The number of structural features of the 'Version Range' class. @@ -608,7 +663,7 @@ public interface SemverPackage extends EPackage { * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getHyphenVersionRange() * @generated */ - int HYPHEN_VERSION_RANGE = 11; + int HYPHEN_VERSION_RANGE = 12; /** * The feature id for the 'From' containment reference. @@ -663,7 +718,7 @@ public interface SemverPackage extends EPackage { * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getVersionRangeConstraint() * @generated */ - int VERSION_RANGE_CONSTRAINT = 12; + int VERSION_RANGE_CONSTRAINT = 13; /** * The feature id for the 'Version Constraints' containment reference list. @@ -709,7 +764,7 @@ public interface SemverPackage extends EPackage { * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getSimpleVersion() * @generated */ - int SIMPLE_VERSION = 13; + int SIMPLE_VERSION = 14; /** * The feature id for the 'Number' containment reference. @@ -845,7 +900,7 @@ public interface SemverPackage extends EPackage { * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getVersionNumber() * @generated */ - int VERSION_NUMBER = 14; + int VERSION_NUMBER = 15; /** * The feature id for the 'Major' containment reference. @@ -981,7 +1036,7 @@ public interface SemverPackage extends EPackage { * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getVersionPart() * @generated */ - int VERSION_PART = 15; + int VERSION_PART = 16; /** * The feature id for the 'Wildcard' attribute. @@ -1054,7 +1109,7 @@ public interface SemverPackage extends EPackage { * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getQualifier() * @generated */ - int QUALIFIER = 16; + int QUALIFIER = 17; /** * The feature id for the 'Pre Release' containment reference. @@ -1118,7 +1173,7 @@ public interface SemverPackage extends EPackage { * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getQualifierTag() * @generated */ - int QUALIFIER_TAG = 17; + int QUALIFIER_TAG = 18; /** * The feature id for the 'Parts' attribute list. @@ -1173,7 +1228,7 @@ public interface SemverPackage extends EPackage { * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getVersionComparator() * @generated */ - int VERSION_COMPARATOR = 18; + int VERSION_COMPARATOR = 19; /** @@ -1332,6 +1387,38 @@ public interface SemverPackage extends EPackage { */ EAttribute getURLCommitISH_CommitISH(); + /** + * Returns the meta object for class '{@link org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement Workspace Version Requirement}'. + * + * + * @return the meta object for class 'Workspace Version Requirement'. + * @see org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement + * @generated + */ + EClass getWorkspaceVersionRequirement(); + + /** + * Returns the meta object for the containment reference '{@link org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement#getVersion Version}'. + * + * + * @return the meta object for the containment reference 'Version'. + * @see org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement#getVersion() + * @see #getWorkspaceVersionRequirement() + * @generated + */ + EReference getWorkspaceVersionRequirement_Version(); + + /** + * Returns the meta object for the attribute '{@link org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement#getOtherVersion Other Version}'. + * + * + * @return the meta object for the attribute 'Other Version'. + * @see org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement#getOtherVersion() + * @see #getWorkspaceVersionRequirement() + * @generated + */ + EAttribute getWorkspaceVersionRequirement_OtherVersion(); + /** * Returns the meta object for class '{@link org.eclipse.n4js.semver.Semver.GitHubVersionRequirement Git Hub Version Requirement}'. * @@ -2028,6 +2115,32 @@ interface Literals { */ EAttribute URL_COMMIT_ISH__COMMIT_ISH = eINSTANCE.getURLCommitISH_CommitISH(); + /** + * The meta object literal for the '{@link org.eclipse.n4js.semver.Semver.impl.WorkspaceVersionRequirementImpl Workspace Version Requirement}' class. + * + * + * @see org.eclipse.n4js.semver.Semver.impl.WorkspaceVersionRequirementImpl + * @see org.eclipse.n4js.semver.Semver.impl.SemverPackageImpl#getWorkspaceVersionRequirement() + * @generated + */ + EClass WORKSPACE_VERSION_REQUIREMENT = eINSTANCE.getWorkspaceVersionRequirement(); + + /** + * The meta object literal for the 'Version' containment reference feature. + * + * + * @generated + */ + EReference WORKSPACE_VERSION_REQUIREMENT__VERSION = eINSTANCE.getWorkspaceVersionRequirement_Version(); + + /** + * The meta object literal for the 'Other Version' attribute feature. + * + * + * @generated + */ + EAttribute WORKSPACE_VERSION_REQUIREMENT__OTHER_VERSION = eINSTANCE.getWorkspaceVersionRequirement_OtherVersion(); + /** * The meta object literal for the '{@link org.eclipse.n4js.semver.Semver.impl.GitHubVersionRequirementImpl Git Hub Version Requirement}' class. * diff --git a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/WorkspaceVersionRequirement.java b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/WorkspaceVersionRequirement.java new file mode 100644 index 0000000000..d17968e394 --- /dev/null +++ b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/WorkspaceVersionRequirement.java @@ -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.semver.Semver; + + +/** + * + * A representation of the model object 'Workspace Version Requirement'. + * + * + *

+ * The following features are supported: + *

+ *
    + *
  • {@link org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement#getVersion Version}
  • + *
  • {@link org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement#getOtherVersion Other Version}
  • + *
+ * + * @see org.eclipse.n4js.semver.Semver.SemverPackage#getWorkspaceVersionRequirement() + * @model + * @generated + */ +public interface WorkspaceVersionRequirement extends NPMVersionRequirement { + /** + * Returns the value of the 'Version' containment reference. + * + * + * @return the value of the 'Version' containment reference. + * @see #setVersion(SimpleVersion) + * @see org.eclipse.n4js.semver.Semver.SemverPackage#getWorkspaceVersionRequirement_Version() + * @model containment="true" + * @generated + */ + SimpleVersion getVersion(); + + /** + * Sets the value of the '{@link org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement#getVersion Version}' containment reference. + * + * + * @param value the new value of the 'Version' containment reference. + * @see #getVersion() + * @generated + */ + void setVersion(SimpleVersion value); + + /** + * Returns the value of the 'Other Version' attribute. + * + * + * @return the value of the 'Other Version' attribute. + * @see #setOtherVersion(String) + * @see org.eclipse.n4js.semver.Semver.SemverPackage#getWorkspaceVersionRequirement_OtherVersion() + * @model unique="false" + * @generated + */ + String getOtherVersion(); + + /** + * Sets the value of the '{@link org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement#getOtherVersion Other Version}' attribute. + * + * + * @param value the new value of the 'Other Version' attribute. + * @see #getOtherVersion() + * @generated + */ + void setOtherVersion(String value); + +} // WorkspaceVersionRequirement diff --git a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/impl/SemverFactoryImpl.java b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/impl/SemverFactoryImpl.java index 0d75ede9cd..3185b1a3e0 100644 --- a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/impl/SemverFactoryImpl.java +++ b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/impl/SemverFactoryImpl.java @@ -68,6 +68,7 @@ public EObject create(EClass eClass) { case SemverPackage.URL_VERSION_REQUIREMENT: return createURLVersionRequirement(); case SemverPackage.URL_SEMVER: return createURLSemver(); case SemverPackage.URL_COMMIT_ISH: return createURLCommitISH(); + case SemverPackage.WORKSPACE_VERSION_REQUIREMENT: return createWorkspaceVersionRequirement(); case SemverPackage.GIT_HUB_VERSION_REQUIREMENT: return createGitHubVersionRequirement(); case SemverPackage.LOCAL_PATH_VERSION_REQUIREMENT: return createLocalPathVersionRequirement(); case SemverPackage.TAG_VERSION_REQUIREMENT: return createTagVersionRequirement(); @@ -147,6 +148,17 @@ public URLCommitISH createURLCommitISH() { return urlCommitISH; } + /** + * + * + * @generated + */ + @Override + public WorkspaceVersionRequirement createWorkspaceVersionRequirement() { + WorkspaceVersionRequirementImpl workspaceVersionRequirement = new WorkspaceVersionRequirementImpl(); + return workspaceVersionRequirement; + } + /** * * diff --git a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/impl/SemverPackageImpl.java b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/impl/SemverPackageImpl.java index 691afb8012..f472ea593c 100644 --- a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/impl/SemverPackageImpl.java +++ b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/impl/SemverPackageImpl.java @@ -41,6 +41,7 @@ import org.eclipse.n4js.semver.Semver.VersionRange; import org.eclipse.n4js.semver.Semver.VersionRangeConstraint; import org.eclipse.n4js.semver.Semver.VersionRangeSetRequirement; +import org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement; /** * @@ -91,6 +92,13 @@ public class SemverPackageImpl extends EPackageImpl implements SemverPackage { */ private EClass urlCommitISHEClass = null; + /** + * + * + * @generated + */ + private EClass workspaceVersionRequirementEClass = null; + /** * * @@ -396,6 +404,36 @@ public EAttribute getURLCommitISH_CommitISH() { return (EAttribute)urlCommitISHEClass.getEStructuralFeatures().get(0); } + /** + * + * + * @generated + */ + @Override + public EClass getWorkspaceVersionRequirement() { + return workspaceVersionRequirementEClass; + } + + /** + * + * + * @generated + */ + @Override + public EReference getWorkspaceVersionRequirement_Version() { + return (EReference)workspaceVersionRequirementEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + @Override + public EAttribute getWorkspaceVersionRequirement_OtherVersion() { + return (EAttribute)workspaceVersionRequirementEClass.getEStructuralFeatures().get(1); + } + /** * * @@ -966,6 +1004,10 @@ public void createPackageContents() { urlCommitISHEClass = createEClass(URL_COMMIT_ISH); createEAttribute(urlCommitISHEClass, URL_COMMIT_ISH__COMMIT_ISH); + workspaceVersionRequirementEClass = createEClass(WORKSPACE_VERSION_REQUIREMENT); + createEReference(workspaceVersionRequirementEClass, WORKSPACE_VERSION_REQUIREMENT__VERSION); + createEAttribute(workspaceVersionRequirementEClass, WORKSPACE_VERSION_REQUIREMENT__OTHER_VERSION); + gitHubVersionRequirementEClass = createEClass(GIT_HUB_VERSION_REQUIREMENT); createEAttribute(gitHubVersionRequirementEClass, GIT_HUB_VERSION_REQUIREMENT__GITHUB_URL); createEAttribute(gitHubVersionRequirementEClass, GIT_HUB_VERSION_REQUIREMENT__COMMIT_ISH); @@ -1069,6 +1111,7 @@ public void initializePackageContents() { urlVersionSpecifierEClass.getESuperTypes().add(this.getSemverToStringable()); urlSemverEClass.getESuperTypes().add(this.getURLVersionSpecifier()); urlCommitISHEClass.getESuperTypes().add(this.getURLVersionSpecifier()); + workspaceVersionRequirementEClass.getESuperTypes().add(this.getNPMVersionRequirement()); gitHubVersionRequirementEClass.getESuperTypes().add(this.getNPMVersionRequirement()); localPathVersionRequirementEClass.getESuperTypes().add(this.getNPMVersionRequirement()); tagVersionRequirementEClass.getESuperTypes().add(this.getNPMVersionRequirement()); @@ -1107,6 +1150,10 @@ public void initializePackageContents() { initEClass(urlCommitISHEClass, URLCommitISH.class, "URLCommitISH", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getURLCommitISH_CommitISH(), theEcorePackage.getEString(), "commitISH", null, 0, 1, URLCommitISH.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEClass(workspaceVersionRequirementEClass, WorkspaceVersionRequirement.class, "WorkspaceVersionRequirement", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getWorkspaceVersionRequirement_Version(), this.getSimpleVersion(), null, "version", null, 0, 1, WorkspaceVersionRequirement.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getWorkspaceVersionRequirement_OtherVersion(), theEcorePackage.getEString(), "otherVersion", null, 0, 1, WorkspaceVersionRequirement.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEClass(gitHubVersionRequirementEClass, GitHubVersionRequirement.class, "GitHubVersionRequirement", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getGitHubVersionRequirement_GithubUrl(), theEcorePackage.getEString(), "githubUrl", null, 0, 1, GitHubVersionRequirement.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getGitHubVersionRequirement_CommitISH(), theEcorePackage.getEString(), "commitISH", null, 0, 1, GitHubVersionRequirement.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED); diff --git a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/impl/WorkspaceVersionRequirementImpl.java b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/impl/WorkspaceVersionRequirementImpl.java new file mode 100644 index 0000000000..7ddbc1f3d2 --- /dev/null +++ b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/impl/WorkspaceVersionRequirementImpl.java @@ -0,0 +1,254 @@ +/** + * 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.semver.Semver.impl; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +import org.eclipse.n4js.semver.Semver.SemverPackage; +import org.eclipse.n4js.semver.Semver.SimpleVersion; +import org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement; + +/** + * + * An implementation of the model object 'Workspace Version Requirement'. + * + *

+ * The following features are implemented: + *

+ *
    + *
  • {@link org.eclipse.n4js.semver.Semver.impl.WorkspaceVersionRequirementImpl#getVersion Version}
  • + *
  • {@link org.eclipse.n4js.semver.Semver.impl.WorkspaceVersionRequirementImpl#getOtherVersion Other Version}
  • + *
+ * + * @generated + */ +public class WorkspaceVersionRequirementImpl extends NPMVersionRequirementImpl implements WorkspaceVersionRequirement { + /** + * The cached value of the '{@link #getVersion() Version}' containment reference. + * + * + * @see #getVersion() + * @generated + * @ordered + */ + protected SimpleVersion version; + + /** + * The default value of the '{@link #getOtherVersion() Other Version}' attribute. + * + * + * @see #getOtherVersion() + * @generated + * @ordered + */ + protected static final String OTHER_VERSION_EDEFAULT = null; + /** + * The cached value of the '{@link #getOtherVersion() Other Version}' attribute. + * + * + * @see #getOtherVersion() + * @generated + * @ordered + */ + protected String otherVersion = OTHER_VERSION_EDEFAULT; + + /** + * + * + * @generated + */ + protected WorkspaceVersionRequirementImpl() { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() { + return SemverPackage.Literals.WORKSPACE_VERSION_REQUIREMENT; + } + + /** + * + * + * @generated + */ + @Override + public SimpleVersion getVersion() { + return version; + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetVersion(SimpleVersion newVersion, NotificationChain msgs) { + SimpleVersion oldVersion = version; + version = newVersion; + if (eNotificationRequired()) { + ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, SemverPackage.WORKSPACE_VERSION_REQUIREMENT__VERSION, oldVersion, newVersion); + if (msgs == null) msgs = notification; else msgs.add(notification); + } + return msgs; + } + + /** + * + * + * @generated + */ + @Override + public void setVersion(SimpleVersion newVersion) { + if (newVersion != version) { + NotificationChain msgs = null; + if (version != null) + msgs = ((InternalEObject)version).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - SemverPackage.WORKSPACE_VERSION_REQUIREMENT__VERSION, null, msgs); + if (newVersion != null) + msgs = ((InternalEObject)newVersion).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - SemverPackage.WORKSPACE_VERSION_REQUIREMENT__VERSION, null, msgs); + msgs = basicSetVersion(newVersion, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, SemverPackage.WORKSPACE_VERSION_REQUIREMENT__VERSION, newVersion, newVersion)); + } + + /** + * + * + * @generated + */ + @Override + public String getOtherVersion() { + return otherVersion; + } + + /** + * + * + * @generated + */ + @Override + public void setOtherVersion(String newOtherVersion) { + String oldOtherVersion = otherVersion; + otherVersion = newOtherVersion; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, SemverPackage.WORKSPACE_VERSION_REQUIREMENT__OTHER_VERSION, oldOtherVersion, otherVersion)); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case SemverPackage.WORKSPACE_VERSION_REQUIREMENT__VERSION: + return basicSetVersion(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case SemverPackage.WORKSPACE_VERSION_REQUIREMENT__VERSION: + return getVersion(); + case SemverPackage.WORKSPACE_VERSION_REQUIREMENT__OTHER_VERSION: + return getOtherVersion(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case SemverPackage.WORKSPACE_VERSION_REQUIREMENT__VERSION: + setVersion((SimpleVersion)newValue); + return; + case SemverPackage.WORKSPACE_VERSION_REQUIREMENT__OTHER_VERSION: + setOtherVersion((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) { + switch (featureID) { + case SemverPackage.WORKSPACE_VERSION_REQUIREMENT__VERSION: + setVersion((SimpleVersion)null); + return; + case SemverPackage.WORKSPACE_VERSION_REQUIREMENT__OTHER_VERSION: + setOtherVersion(OTHER_VERSION_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case SemverPackage.WORKSPACE_VERSION_REQUIREMENT__VERSION: + return version != null; + case SemverPackage.WORKSPACE_VERSION_REQUIREMENT__OTHER_VERSION: + return OTHER_VERSION_EDEFAULT == null ? otherVersion != null : !OTHER_VERSION_EDEFAULT.equals(otherVersion); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + @Override + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuilder result = new StringBuilder(super.toString()); + result.append(" (otherVersion: "); + result.append(otherVersion); + result.append(')'); + return result.toString(); + } + +} //WorkspaceVersionRequirementImpl diff --git a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/util/SemverAdapterFactory.java b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/util/SemverAdapterFactory.java index 0ec8afd8b2..5bc6de8f1f 100644 --- a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/util/SemverAdapterFactory.java +++ b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/util/SemverAdapterFactory.java @@ -100,6 +100,10 @@ public Adapter caseURLCommitISH(URLCommitISH object) { return createURLCommitISHAdapter(); } @Override + public Adapter caseWorkspaceVersionRequirement(WorkspaceVersionRequirement object) { + return createWorkspaceVersionRequirementAdapter(); + } + @Override public Adapter caseGitHubVersionRequirement(GitHubVersionRequirement object) { return createGitHubVersionRequirementAdapter(); } @@ -251,6 +255,20 @@ public Adapter createURLCommitISHAdapter() { return null; } + /** + * Creates a new adapter for an object of class '{@link org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement Workspace Version Requirement}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement + * @generated + */ + public Adapter createWorkspaceVersionRequirementAdapter() { + return null; + } + /** * Creates a new adapter for an object of class '{@link org.eclipse.n4js.semver.Semver.GitHubVersionRequirement Git Hub Version Requirement}'. * diff --git a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/util/SemverSwitch.java b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/util/SemverSwitch.java index 9c09e48fd6..0f1643d507 100644 --- a/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/util/SemverSwitch.java +++ b/plugins/org.eclipse.n4js.semver.model/emf-gen/org/eclipse/n4js/semver/Semver/util/SemverSwitch.java @@ -118,6 +118,14 @@ protected T doSwitch(int classifierID, EObject theEObject) { if (result == null) result = defaultCase(theEObject); return result; } + case SemverPackage.WORKSPACE_VERSION_REQUIREMENT: { + WorkspaceVersionRequirement workspaceVersionRequirement = (WorkspaceVersionRequirement)theEObject; + T result = caseWorkspaceVersionRequirement(workspaceVersionRequirement); + if (result == null) result = caseNPMVersionRequirement(workspaceVersionRequirement); + if (result == null) result = caseSemverToStringable(workspaceVersionRequirement); + if (result == null) result = defaultCase(theEObject); + return result; + } case SemverPackage.GIT_HUB_VERSION_REQUIREMENT: { GitHubVersionRequirement gitHubVersionRequirement = (GitHubVersionRequirement)theEObject; T result = caseGitHubVersionRequirement(gitHubVersionRequirement); @@ -302,6 +310,21 @@ public T caseURLCommitISH(URLCommitISH object) { return null; } + /** + * Returns the result of interpreting the object as an instance of 'Workspace Version Requirement'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Workspace Version Requirement'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseWorkspaceVersionRequirement(WorkspaceVersionRequirement object) { + return null; + } + /** * Returns the result of interpreting the object as an instance of 'Git Hub Version Requirement'. * diff --git a/plugins/org.eclipse.n4js.semver.model/model/Semver.xcore b/plugins/org.eclipse.n4js.semver.model/model/Semver.xcore index 6bb843fdb7..bc833ab9ba 100644 --- a/plugins/org.eclipse.n4js.semver.model/model/Semver.xcore +++ b/plugins/org.eclipse.n4js.semver.model/model/Semver.xcore @@ -67,6 +67,11 @@ class URLCommitISH extends URLVersionSpecifier { String commitISH } +class WorkspaceVersionRequirement extends NPMVersionRequirement { + contains SimpleVersion version + String otherVersion +} + class GitHubVersionRequirement extends NPMVersionRequirement { String githubUrl String commitISH diff --git a/plugins/org.eclipse.n4js.semver.model/src/org/eclipse/n4js/semver/model/SemverSerializer.java b/plugins/org.eclipse.n4js.semver.model/src/org/eclipse/n4js/semver/model/SemverSerializer.java index 46a1ba63c1..aa1c4b5721 100644 --- a/plugins/org.eclipse.n4js.semver.model/src/org/eclipse/n4js/semver/model/SemverSerializer.java +++ b/plugins/org.eclipse.n4js.semver.model/src/org/eclipse/n4js/semver/model/SemverSerializer.java @@ -22,6 +22,7 @@ import org.eclipse.n4js.semver.Semver.VersionRange; import org.eclipse.n4js.semver.Semver.VersionRangeConstraint; import org.eclipse.n4js.semver.Semver.VersionRangeSetRequirement; +import org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement; import org.eclipse.xtext.resource.SaveOptions; import org.eclipse.xtext.serializer.ISerializer; import org.eclipse.xtext.util.ReplaceRegion; @@ -85,6 +86,18 @@ static public String serialize(TagVersionRequirement tv) { return tv.getTagName(); } + /** @return string representation of {@link TagVersionRequirement} */ + static public String serialize(WorkspaceVersionRequirement wv) { + if (wv == null) + return ""; + + if (wv.getVersion() != null) { + return "workspace:" + serialize(wv.getVersion()); + } + + return "workspace:" + wv.getOtherVersion(); + } + /** @return string representation of {@link GitHubVersionRequirement} */ static public String serialize(GitHubVersionRequirement ghv) { if (ghv == null) @@ -261,6 +274,9 @@ static public String serialize(SemverToStringable obj) { if (obj instanceof TagVersionRequirement) { return serialize((TagVersionRequirement) obj); } + if (obj instanceof WorkspaceVersionRequirement) { + return serialize((WorkspaceVersionRequirement) obj); + } if (obj instanceof GitHubVersionRequirement) { return serialize((GitHubVersionRequirement) obj); } diff --git a/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/Semver.xtextbin b/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/Semver.xtextbin index 7955fc1c7a111fd78d18fb2c0c3bf6b5c907f52d..0ec78b45fcb3be58f1c94818fd7f91966f9ff787 100644 GIT binary patch delta 3841 zcmZvfd0^WOJ6 z_nh@^?EJl60wxed*y1+wXT6zsGraX^%(8#AeKA*ha zJYJ0W>xnNQpVvG?yhN0j3Z5SdMj}B$mbplYMwY{RoVXNvint6&xgd)|K^si8D;yoT z#^4n$Ss`RGUkGO<86JN&c(ldfm9A-(m<(Qxj4a|RXbZ_dUIT7z4i_+Zoy%RMxr^bq zhlwx2ML>hE09c&^1`V!p!Amu`9{w0{Ei|aPI&d3uIMd*bF1JZ@m%%?ud^yzA+!Z#! z`W&#$;45A5Dh<98K%96pv`vFogKNm)It*@fxhBmu!#_d11=^vx7I3XDXGcQ@2V8Kg z27>?+#3nSPK?bN?FxqKwo6EIpt^@u_;t;e`bDiM2a=5U;VVASJHP{0nN!$w!Yp@Ss zBnRv^xZec_G&czUH1RdiZq022H;t^<{=3?MRbGSi+$6Rh)b8-0h67Pl%YHk9Yoe)sgfnEmTh{6Jzbm1w1mva)( zF5+ouEAbxa2yqI!m3Rg^Mx2H+@ho(l_&TT}-V5DL{Ay@B@jmDj@%2<-dp%vmufdHy z#QUK=#IJ>>i4Q;{#JWqf#0T-apZImqeZ)6Fw-LV{dOh)t&>>Vue*b978k>wwrS&g; z5C8ES$nWt~%es9d%yupDo2c09o3>Kv8J|(pn9pxUV+tLD-vWQL_z%HfL;O~;7wwvj zCq_DBX=}tvTRx9aZv*AkL%f~*;=jr9zvKV=->LmQ&MR zOguRiNKVb9Q&xOxF4gzIbR-M&dlB*G%*poBRfq8kZ!pYTWZ!(BWRuUgP?4A4pS{f= z$oM-d>{}(WcQlop)cJo9p-xDHKI9DiVdO76?MIy7w~5_IC$;%@$LyrdAI)a%DUN)`EJ?2D?-U(E75JG#|N_g>5c7~ji+LG>jrZ17Qcy5A=zAAb&}4aA>^))U_km1+L~w3_%qG-flBzEAT?QV%EgCEi12lXfHQSy2g4qK^__>`51r}xRH&&Q7;Tpck!iyoPdUx02Q{vtF= z{3Qe|(mlbDU)BxziZn#J@Iu5pH3yy$>C%|C-x1* zc@m$!{@zfuyEhyO2g0)Ze$%c0gl^KeU@Ry8wqz?A8hjErmJ)vl8P#Mn;qQt!kDtP= z&BWh>N)g{DTVD|WKoZECO=ZXaAtF32W9P}(20!Bt`6C_X#~2EW@+VHwrvOON{8K5{ z%Rh6%{~Rhk`UO;m{UvmZ*iL5y4Yfd0RfXA#)IwBLtSbs6Cnw|S zwmun8Ey5BSp1Xk-t0IY{iZcV<)wVi+K2^0?$8-*UN+0~3U0N;GkCtJ$lDXj|_VROM z;}AH%x#QidGQ1yEt{0SAA+4$yOr|Dgrmf-FfPL=1qAHvLE<`<*b#<=$95dyqN}btC zRJ2NB7Y&AcJNmj?0@=++t#-?+5@(^(N5@f8YmsM{O==x3q~#Yu8%SLYl~;8MG(t)r z87oOuB2M%TTpc{PG!C;LLB`bDSXY_S6RH*`j26JeHEVY~!n= zpKp}sYLirOfm?yhr@ppum!U3mtGGP7X%wp~Fn%4WdT1@FE3^5itDsv*=|g3dls;58 zlDZoA50Gkr?jY3&ZI*(YaM47nSycXPAcfb0x3kYTm&0+`z4@xQin^#5>L7JZhfegn8OLV;(XOn0Jzg{tM7w$dv#9 delta 3063 zcmZWrdwf%88Qzl9C3tIk%X$p=3*%lBSz% zNH(0hF`c@jvb!?TsoQ=(k?C&8@QU+-Q|Aqpp-u(wcy~JI`+Vml>3-`UeUk4y&-*^_ z`@P?nbMwQr_d)vf{w})U&;wmp7}RJV2{rhA)}!P%J?rhIp_WClRC+w=vmV3BZX)Y( zsxhr6>=mJ=>L;;wm8?C5wZrz=P`y1Bs;CR^m`S9keb(pYxv_qO5RQQGw0%pc#dj2< zu0y9o2aSU1nLC!qji)9P=~RBFr`_~&6&`mGSCh}Q&JfQRi!i{2#b7p&;R(3R5rZ4c ztR=!S__c5}O}rF1Lh{E=&^6D}4I121*0pNgdEjS=mjMU0?sd>DFX;-=xYVG}-5sH7|K#ag%)f)w%V zfqh!|1_;;95)K&LSrYOawQfE5Y2ppQ0j=wTu6vd)Y;aFm*Q<3Q@RP)ajrb7O!b>0w zi?Fz9k(k16TV*kexRn(&3F1CrFYzYeC~-e9L_7c-BOU~9Bpw2e6GwoT5Dx<e^8eR6LFtiFM8Jl4ww-&r32yM*N9yFrrT?g6eLz8AQT_a@%<>i6Gr&M z;(1OwJC;ZfC-U2M`5ysmzoamSdt=Jr2Xy$jzDz$#rbn(|KOaDdAo0h5GEW}|_7Fb^ zl+>R9#)&^E!Ei-?3PEdh?MVBO6z=7RrEsbC5y`d4?j2fa&mXL|yM`Lx8zXY-JX-F+XLXxC2VyPpV~$^gA9wQe6Y$mU z_~0jn>*c4g)Jc38C?(++$rCJy%OhgIJCk#AKaB`SCAU{{8~lZG$}j3LUqY%j)8sEh zFD>{AP+IU+5uydh91Fx>lj2Q&#!dHipmgvXK(X;nU=PV{^(`l2fRDS>Z@biIUFvrn zDt{L!8NUaVjL*3lzwc&5x%`9Tnf@VIt;9dF?~By?ehkhD`*5T_@Dr4@$KapZCnHNn zf2OzSBn4hMn;w21ic`{vIns!cWaipr&fuTB+Fy8#bBwvcVCj*Z(O>HRynr+Mt0GMd z{o1~AcyZx3h;~|{RgQ!Qw}zw6NS`Tp_qU?<^Y1`wApSkDoA?jFX5v2z;&=T|?)smB z%ZbmTNIl}jf01phnoeb=(#fsK+;l2CsfX#WkoFhvm%m9GgZ~bb|8PzI6SY+9S~g}g znN+@SM2YWz;mC{?7j&q9BkPNH@8-4w|EFyIzdGhi$RqpzKW7%b{IauM>Kx~R#1wV$ zY$y*z$`B*UTQowX%vWVqKIn>fHuhLmkl$x2zjU+Ses-j;(og{>gqmYNGtyG1)UoFx z)I=)3eP(ovGu&#Pgi=-Rp1SWss=8E(nlD0A)nFvlxvu>Mz&I(qTFF@>wa`5QYLUyR zbs2TSkPfIqJ*ZNtT8ty08t^nlka4-2Pc@J zFqW8bhbfxeF_X$AGs($3dDVpy(w|RE3?(v2%!XQp7^|hVUR>5{O}VKT>D{;(32RBM zb;m>LH!P_IuUDvH9SBp!`M@@J&i*msJNOYk!KYM*@>{oC`}hXyUh9B$+iRHI~ yPxF30#79+?TFsUGqIH66xRx8ZnU`}1ui + { + newCompositeNode(grammarAccess.getNPMVersionRequirementAccess().getWorkspaceVersionRequirementParserRuleCall_1_0_1_1_0()); + } + this_WorkspaceVersionRequirement_4=ruleWorkspaceVersionRequirement + { + $current = $this_WorkspaceVersionRequirement_4.current; + afterParserOrEnumRuleCall(); + } + ) + | + { + newCompositeNode(grammarAccess.getNPMVersionRequirementAccess().getGitHubVersionRequirementParserRuleCall_1_0_1_1_1()); + } + this_GitHubVersionRequirement_5=ruleGitHubVersionRequirement + { + $current = $this_GitHubVersionRequirement_5.current; + afterParserOrEnumRuleCall(); + } + | + { + newCompositeNode(grammarAccess.getNPMVersionRequirementAccess().getTagVersionRequirementParserRuleCall_1_0_1_1_2()); + } + this_TagVersionRequirement_6=ruleTagVersionRequirement + { + $current = $this_TagVersionRequirement_6.current; + afterParserOrEnumRuleCall(); + } + ) ) ) ( - this_WS_6=RULE_WS + this_WS_7=RULE_WS { - newLeafNode(this_WS_6, grammarAccess.getNPMVersionRequirementAccess().getWSTerminalRuleCall_1_1()); + newLeafNode(this_WS_7, grammarAccess.getNPMVersionRequirementAccess().getWSTerminalRuleCall_1_1()); } )? ) @@ -451,15 +465,15 @@ ruleURLSemver returns [EObject current=null] ) ; -// Entry rule entryRuleTagVersionRequirement -entryRuleTagVersionRequirement returns [EObject current=null]: - { newCompositeNode(grammarAccess.getTagVersionRequirementRule()); } - iv_ruleTagVersionRequirement=ruleTagVersionRequirement - { $current=$iv_ruleTagVersionRequirement.current; } +// Entry rule entryRuleWorkspaceVersionRequirement +entryRuleWorkspaceVersionRequirement returns [EObject current=null]: + { newCompositeNode(grammarAccess.getWorkspaceVersionRequirementRule()); } + iv_ruleWorkspaceVersionRequirement=ruleWorkspaceVersionRequirement + { $current=$iv_ruleWorkspaceVersionRequirement.current; } EOF; -// Rule TagVersionRequirement -ruleTagVersionRequirement returns [EObject current=null] +// Rule WorkspaceVersionRequirement +ruleWorkspaceVersionRequirement returns [EObject current=null] @init { enterRule(); } @@ -467,22 +481,57 @@ ruleTagVersionRequirement returns [EObject current=null] leaveRule(); }: ( + { + newCompositeNode(grammarAccess.getWorkspaceVersionRequirementAccess().getWORKSPACE_TAGParserRuleCall_0()); + } + ruleWORKSPACE_TAG + { + afterParserOrEnumRuleCall(); + } ( - { - newCompositeNode(grammarAccess.getTagVersionRequirementAccess().getTagNameTAGParserRuleCall_0()); - } - lv_tagName_0_0=ruleTAG - { - if ($current==null) { - $current = createModelElementForParent(grammarAccess.getTagVersionRequirementRule()); - } - set( - $current, - "tagName", - lv_tagName_0_0, - "org.eclipse.n4js.semver.Semver.TAG"); - afterParserOrEnumRuleCall(); - } + ( + (( + ruleSimpleVersion + ) + )=> + ( + { + newCompositeNode(grammarAccess.getWorkspaceVersionRequirementAccess().getVersionSimpleVersionParserRuleCall_1_0_0()); + } + lv_version_1_0=ruleSimpleVersion + { + if ($current==null) { + $current = createModelElementForParent(grammarAccess.getWorkspaceVersionRequirementRule()); + } + set( + $current, + "version", + lv_version_1_0, + "org.eclipse.n4js.semver.Semver.SimpleVersion"); + afterParserOrEnumRuleCall(); + } + ) + ) + | + ( + ( + { + newCompositeNode(grammarAccess.getWorkspaceVersionRequirementAccess().getOtherVersionWORKSPACE_VERSIONParserRuleCall_1_1_0()); + } + lv_otherVersion_2_0=ruleWORKSPACE_VERSION + { + if ($current==null) { + $current = createModelElementForParent(grammarAccess.getWorkspaceVersionRequirementRule()); + } + set( + $current, + "otherVersion", + lv_otherVersion_2_0, + "org.eclipse.n4js.semver.Semver.WORKSPACE_VERSION"); + afterParserOrEnumRuleCall(); + } + ) + ) ) ) ; @@ -550,6 +599,42 @@ ruleGitHubVersionRequirement returns [EObject current=null] ) ; +// Entry rule entryRuleTagVersionRequirement +entryRuleTagVersionRequirement returns [EObject current=null]: + { newCompositeNode(grammarAccess.getTagVersionRequirementRule()); } + iv_ruleTagVersionRequirement=ruleTagVersionRequirement + { $current=$iv_ruleTagVersionRequirement.current; } + EOF; + +// Rule TagVersionRequirement +ruleTagVersionRequirement returns [EObject current=null] +@init { + enterRule(); +} +@after { + leaveRule(); +}: + ( + ( + { + newCompositeNode(grammarAccess.getTagVersionRequirementAccess().getTagNameTAGParserRuleCall_0()); + } + lv_tagName_0_0=ruleTAG + { + if ($current==null) { + $current = createModelElementForParent(grammarAccess.getTagVersionRequirementRule()); + } + set( + $current, + "tagName", + lv_tagName_0_0, + "org.eclipse.n4js.semver.Semver.TAG"); + afterParserOrEnumRuleCall(); + } + ) + ) +; + // Entry rule entryRuleVersionRangeSetRequirement entryRuleVersionRangeSetRequirement returns [EObject current=null]: { newCompositeNode(grammarAccess.getVersionRangeSetRequirementRule()); } @@ -1370,6 +1455,93 @@ ruleSEMVER_TAG returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToke ) ; +// Entry rule entryRuleWORKSPACE_TAG +entryRuleWORKSPACE_TAG returns [String current=null]: + { newCompositeNode(grammarAccess.getWORKSPACE_TAGRule()); } + iv_ruleWORKSPACE_TAG=ruleWORKSPACE_TAG + { $current=$iv_ruleWORKSPACE_TAG.current.getText(); } + EOF; + +// Rule WORKSPACE_TAG +ruleWORKSPACE_TAG returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] +@init { + enterRule(); +} +@after { + leaveRule(); +}: + ( + this_LETTER_W_0=RULE_LETTER_W + { + $current.merge(this_LETTER_W_0); + } + { + newLeafNode(this_LETTER_W_0, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_WTerminalRuleCall_0()); + } + this_LETTER_O_1=RULE_LETTER_O + { + $current.merge(this_LETTER_O_1); + } + { + newLeafNode(this_LETTER_O_1, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_OTerminalRuleCall_1()); + } + this_LETTER_R_2=RULE_LETTER_R + { + $current.merge(this_LETTER_R_2); + } + { + newLeafNode(this_LETTER_R_2, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_RTerminalRuleCall_2()); + } + this_LETTER_K_3=RULE_LETTER_K + { + $current.merge(this_LETTER_K_3); + } + { + newLeafNode(this_LETTER_K_3, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_KTerminalRuleCall_3()); + } + this_LETTER_S_4=RULE_LETTER_S + { + $current.merge(this_LETTER_S_4); + } + { + newLeafNode(this_LETTER_S_4, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_STerminalRuleCall_4()); + } + this_LETTER_P_5=RULE_LETTER_P + { + $current.merge(this_LETTER_P_5); + } + { + newLeafNode(this_LETTER_P_5, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_PTerminalRuleCall_5()); + } + this_LETTER_A_6=RULE_LETTER_A + { + $current.merge(this_LETTER_A_6); + } + { + newLeafNode(this_LETTER_A_6, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_ATerminalRuleCall_6()); + } + this_LETTER_C_7=RULE_LETTER_C + { + $current.merge(this_LETTER_C_7); + } + { + newLeafNode(this_LETTER_C_7, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_CTerminalRuleCall_7()); + } + this_LETTER_E_8=RULE_LETTER_E + { + $current.merge(this_LETTER_E_8); + } + { + newLeafNode(this_LETTER_E_8, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_ETerminalRuleCall_8()); + } + kw=':' + { + $current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_TAGAccess().getColonKeyword_9()); + } + ) +; + // Entry rule entryRulePATH entryRulePATH returns [String current=null]: { newCompositeNode(grammarAccess.getPATHRule()); } @@ -1404,32 +1576,18 @@ rulePATH returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] newLeafNode(kw, grammarAccess.getPATHAccess().getCommercialAtKeyword_2()); } | - kw='-' - { - $current.merge(kw); - newLeafNode(kw, grammarAccess.getPATHAccess().getHyphenMinusKeyword_3()); - } - | kw='_' { $current.merge(kw); - newLeafNode(kw, grammarAccess.getPATHAccess().get_Keyword_4()); - } - | - this_DIGITS_5=RULE_DIGITS - { - $current.merge(this_DIGITS_5); - } - { - newLeafNode(this_DIGITS_5, grammarAccess.getPATHAccess().getDIGITSTerminalRuleCall_5()); + newLeafNode(kw, grammarAccess.getPATHAccess().get_Keyword_3()); } | { - newCompositeNode(grammarAccess.getPATHAccess().getLETTERParserRuleCall_6()); + newCompositeNode(grammarAccess.getPATHAccess().getALPHA_NUMERIC_CHARParserRuleCall_4()); } - this_LETTER_6=ruleLETTER + this_ALPHA_NUMERIC_CHAR_4=ruleALPHA_NUMERIC_CHAR { - $current.merge(this_LETTER_6); + $current.merge(this_ALPHA_NUMERIC_CHAR_4); } { afterParserOrEnumRuleCall(); @@ -1501,32 +1659,18 @@ ruleURL returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] }: ( ( - kw='-' - { - $current.merge(kw); - newLeafNode(kw, grammarAccess.getURLAccess().getHyphenMinusKeyword_0_0()); - } - | kw='_' { $current.merge(kw); - newLeafNode(kw, grammarAccess.getURLAccess().get_Keyword_0_1()); + newLeafNode(kw, grammarAccess.getURLAccess().get_Keyword_0_0()); } | - this_DIGITS_2=RULE_DIGITS - { - $current.merge(this_DIGITS_2); - } { - newLeafNode(this_DIGITS_2, grammarAccess.getURLAccess().getDIGITSTerminalRuleCall_0_2()); + newCompositeNode(grammarAccess.getURLAccess().getALPHA_NUMERIC_CHARParserRuleCall_0_1()); } - | + this_ALPHA_NUMERIC_CHAR_1=ruleALPHA_NUMERIC_CHAR { - newCompositeNode(grammarAccess.getURLAccess().getLETTERParserRuleCall_0_3()); - } - this_LETTER_3=ruleLETTER - { - $current.merge(this_LETTER_3); + $current.merge(this_ALPHA_NUMERIC_CHAR_1); } { afterParserOrEnumRuleCall(); @@ -1582,32 +1726,18 @@ ruleURL returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] newLeafNode(kw, grammarAccess.getURLAccess().getCommercialAtKeyword_2_3()); } | - kw='-' - { - $current.merge(kw); - newLeafNode(kw, grammarAccess.getURLAccess().getHyphenMinusKeyword_2_4()); - } - | kw='_' { $current.merge(kw); - newLeafNode(kw, grammarAccess.getURLAccess().get_Keyword_2_5()); - } - | - this_DIGITS_14=RULE_DIGITS - { - $current.merge(this_DIGITS_14); - } - { - newLeafNode(this_DIGITS_14, grammarAccess.getURLAccess().getDIGITSTerminalRuleCall_2_6()); + newLeafNode(kw, grammarAccess.getURLAccess().get_Keyword_2_4()); } | { - newCompositeNode(grammarAccess.getURLAccess().getLETTERParserRuleCall_2_7()); + newCompositeNode(grammarAccess.getURLAccess().getALPHA_NUMERIC_CHARParserRuleCall_2_5()); } - this_LETTER_15=ruleLETTER + this_ALPHA_NUMERIC_CHAR_11=ruleALPHA_NUMERIC_CHAR { - $current.merge(this_LETTER_15); + $current.merge(this_ALPHA_NUMERIC_CHAR_11); } { afterParserOrEnumRuleCall(); @@ -1633,16 +1763,16 @@ ruleURL_NO_VX returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken }: ( ( - kw='-' + kw='_' { $current.merge(kw); - newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_0_0()); + newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().get_Keyword_0_0()); } | - kw='_' + kw='-' { $current.merge(kw); - newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().get_Keyword_0_1()); + newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_0_1()); } | { @@ -1657,32 +1787,18 @@ ruleURL_NO_VX returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken } ) ( - kw='-' - { - $current.merge(kw); - newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_1_0()); - } - | kw='_' { $current.merge(kw); - newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().get_Keyword_1_1()); - } - | - this_DIGITS_5=RULE_DIGITS - { - $current.merge(this_DIGITS_5); - } - { - newLeafNode(this_DIGITS_5, grammarAccess.getURL_NO_VXAccess().getDIGITSTerminalRuleCall_1_2()); + newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().get_Keyword_1_0()); } | { - newCompositeNode(grammarAccess.getURL_NO_VXAccess().getLETTERParserRuleCall_1_3()); + newCompositeNode(grammarAccess.getURL_NO_VXAccess().getALPHA_NUMERIC_CHARParserRuleCall_1_1()); } - this_LETTER_6=ruleLETTER + this_ALPHA_NUMERIC_CHAR_4=ruleALPHA_NUMERIC_CHAR { - $current.merge(this_LETTER_6); + $current.merge(this_ALPHA_NUMERIC_CHAR_4); } { afterParserOrEnumRuleCall(); @@ -1738,32 +1854,18 @@ ruleURL_NO_VX returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().getCommercialAtKeyword_3_3()); } | - kw='-' - { - $current.merge(kw); - newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_3_4()); - } - | kw='_' { $current.merge(kw); - newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().get_Keyword_3_5()); + newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().get_Keyword_3_4()); } | - this_DIGITS_17=RULE_DIGITS { - $current.merge(this_DIGITS_17); + newCompositeNode(grammarAccess.getURL_NO_VXAccess().getALPHA_NUMERIC_CHARParserRuleCall_3_5()); } + this_ALPHA_NUMERIC_CHAR_14=ruleALPHA_NUMERIC_CHAR { - newLeafNode(this_DIGITS_17, grammarAccess.getURL_NO_VXAccess().getDIGITSTerminalRuleCall_3_6()); - } - | - { - newCompositeNode(grammarAccess.getURL_NO_VXAccess().getLETTERParserRuleCall_3_7()); - } - this_LETTER_18=ruleLETTER - { - $current.merge(this_LETTER_18); + $current.merge(this_ALPHA_NUMERIC_CHAR_14); } { afterParserOrEnumRuleCall(); @@ -1798,44 +1900,28 @@ ruleTAG returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] { afterParserOrEnumRuleCall(); } - ( - kw='-' - { - $current.merge(kw); - newLeafNode(kw, grammarAccess.getTAGAccess().getHyphenMinusKeyword_1_0()); - } - | - this_DIGITS_2=RULE_DIGITS - { - $current.merge(this_DIGITS_2); - } - { - newLeafNode(this_DIGITS_2, grammarAccess.getTAGAccess().getDIGITSTerminalRuleCall_1_1()); - } - | - { - newCompositeNode(grammarAccess.getTAGAccess().getLETTERParserRuleCall_1_2()); - } - this_LETTER_3=ruleLETTER - { - $current.merge(this_LETTER_3); - } - { - afterParserOrEnumRuleCall(); - } - )+ + { + newCompositeNode(grammarAccess.getTAGAccess().getALPHA_NUMERIC_CHARSParserRuleCall_1()); + } + this_ALPHA_NUMERIC_CHARS_1=ruleALPHA_NUMERIC_CHARS + { + $current.merge(this_ALPHA_NUMERIC_CHARS_1); + } + { + afterParserOrEnumRuleCall(); + } ) ; -// Entry rule entryRuleALPHA_NUMERIC_CHARS -entryRuleALPHA_NUMERIC_CHARS returns [String current=null]: - { newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARSRule()); } - iv_ruleALPHA_NUMERIC_CHARS=ruleALPHA_NUMERIC_CHARS - { $current=$iv_ruleALPHA_NUMERIC_CHARS.current.getText(); } +// Entry rule entryRuleWORKSPACE_VERSION +entryRuleWORKSPACE_VERSION returns [String current=null]: + { newCompositeNode(grammarAccess.getWORKSPACE_VERSIONRule()); } + iv_ruleWORKSPACE_VERSION=ruleWORKSPACE_VERSION + { $current=$iv_ruleWORKSPACE_VERSION.current.getText(); } EOF; -// Rule ALPHA_NUMERIC_CHARS -ruleALPHA_NUMERIC_CHARS returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] +// Rule WORKSPACE_VERSION +ruleWORKSPACE_VERSION returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] @init { enterRule(); } @@ -1843,26 +1929,92 @@ ruleALPHA_NUMERIC_CHARS returns [AntlrDatatypeRuleToken current=new AntlrDatatyp leaveRule(); }: ( - kw='-' + kw='/' { $current.merge(kw); - newLeafNode(kw, grammarAccess.getALPHA_NUMERIC_CHARSAccess().getHyphenMinusKeyword_0()); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getSolidusKeyword_0()); } | - this_DIGITS_1=RULE_DIGITS + kw='.' { - $current.merge(this_DIGITS_1); + $current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getFullStopKeyword_1()); } + | + kw=':' { - newLeafNode(this_DIGITS_1, grammarAccess.getALPHA_NUMERIC_CHARSAccess().getDIGITSTerminalRuleCall_1()); + $current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getColonKeyword_2()); } | + kw='@' { - newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getLETTERParserRuleCall_2()); + $current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getCommercialAtKeyword_3()); } - this_LETTER_2=ruleLETTER + | + kw='_' { - $current.merge(this_LETTER_2); + $current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().get_Keyword_4()); + } + | + kw='=' + { + $current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getEqualsSignKeyword_5()); + } + | + kw='~' + { + $current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getTildeKeyword_6()); + } + | + kw='^' + { + $current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getCircumflexAccentKeyword_7()); + } + | + kw='<' + { + $current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getLessThanSignKeyword_8()); + } + | + kw='>' + { + $current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getGreaterThanSignKeyword_9()); + } + | + kw='<=' + { + $current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getLessThanSignEqualsSignKeyword_10()); + } + | + kw='>=' + { + $current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getGreaterThanSignEqualsSignKeyword_11()); + } + | + this_ASTERIX_12=RULE_ASTERIX + { + $current.merge(this_ASTERIX_12); + } + { + newLeafNode(this_ASTERIX_12, grammarAccess.getWORKSPACE_VERSIONAccess().getASTERIXTerminalRuleCall_12()); + } + | + { + newCompositeNode(grammarAccess.getWORKSPACE_VERSIONAccess().getALPHA_NUMERIC_CHARParserRuleCall_13()); + } + this_ALPHA_NUMERIC_CHAR_13=ruleALPHA_NUMERIC_CHAR + { + $current.merge(this_ALPHA_NUMERIC_CHAR_13); } { afterParserOrEnumRuleCall(); @@ -1893,32 +2045,88 @@ ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS returns [AntlrDatatypeRuleToken curren { newLeafNode(this_DIGITS_0, grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getDIGITSTerminalRuleCall_0()); } - ( - kw='-' - { - $current.merge(kw); - newLeafNode(kw, grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getHyphenMinusKeyword_1_0()); - } - | - this_DIGITS_2=RULE_DIGITS - { - $current.merge(this_DIGITS_2); - } - { - newLeafNode(this_DIGITS_2, grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getDIGITSTerminalRuleCall_1_1()); - } - | - { - newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getLETTERParserRuleCall_1_2()); - } - this_LETTER_3=ruleLETTER - { - $current.merge(this_LETTER_3); - } - { - afterParserOrEnumRuleCall(); - } - )+ + { + newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getALPHA_NUMERIC_CHARSParserRuleCall_1()); + } + this_ALPHA_NUMERIC_CHARS_1=ruleALPHA_NUMERIC_CHARS + { + $current.merge(this_ALPHA_NUMERIC_CHARS_1); + } + { + afterParserOrEnumRuleCall(); + } + ) +; + +// Entry rule entryRuleALPHA_NUMERIC_CHARS +entryRuleALPHA_NUMERIC_CHARS returns [String current=null]: + { newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARSRule()); } + iv_ruleALPHA_NUMERIC_CHARS=ruleALPHA_NUMERIC_CHARS + { $current=$iv_ruleALPHA_NUMERIC_CHARS.current.getText(); } + EOF; + +// Rule ALPHA_NUMERIC_CHARS +ruleALPHA_NUMERIC_CHARS returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] +@init { + enterRule(); +} +@after { + leaveRule(); +}: + ( + { + newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getALPHA_NUMERIC_CHARParserRuleCall()); + } + this_ALPHA_NUMERIC_CHAR_0=ruleALPHA_NUMERIC_CHAR + { + $current.merge(this_ALPHA_NUMERIC_CHAR_0); + } + { + afterParserOrEnumRuleCall(); + } + )+ +; + +// Entry rule entryRuleALPHA_NUMERIC_CHAR +entryRuleALPHA_NUMERIC_CHAR returns [String current=null]: + { newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARRule()); } + iv_ruleALPHA_NUMERIC_CHAR=ruleALPHA_NUMERIC_CHAR + { $current=$iv_ruleALPHA_NUMERIC_CHAR.current.getText(); } + EOF; + +// Rule ALPHA_NUMERIC_CHAR +ruleALPHA_NUMERIC_CHAR returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] +@init { + enterRule(); +} +@after { + leaveRule(); +}: + ( + kw='-' + { + $current.merge(kw); + newLeafNode(kw, grammarAccess.getALPHA_NUMERIC_CHARAccess().getHyphenMinusKeyword_0()); + } + | + this_DIGITS_1=RULE_DIGITS + { + $current.merge(this_DIGITS_1); + } + { + newLeafNode(this_DIGITS_1, grammarAccess.getALPHA_NUMERIC_CHARAccess().getDIGITSTerminalRuleCall_1()); + } + | + { + newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARAccess().getLETTERParserRuleCall_2()); + } + this_LETTER_2=ruleLETTER + { + $current.merge(this_LETTER_2); + } + { + afterParserOrEnumRuleCall(); + } ) ; @@ -2005,28 +2213,28 @@ ruleLETTER_NO_VX returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleTo leaveRule(); }: ( - this_LETTER_S_0=RULE_LETTER_S + this_LETTER_A_0=RULE_LETTER_A { - $current.merge(this_LETTER_S_0); + $current.merge(this_LETTER_A_0); } { - newLeafNode(this_LETTER_S_0, grammarAccess.getLETTER_NO_VXAccess().getLETTER_STerminalRuleCall_0()); + newLeafNode(this_LETTER_A_0, grammarAccess.getLETTER_NO_VXAccess().getLETTER_ATerminalRuleCall_0()); } | - this_LETTER_M_1=RULE_LETTER_M + this_LETTER_C_1=RULE_LETTER_C { - $current.merge(this_LETTER_M_1); + $current.merge(this_LETTER_C_1); } { - newLeafNode(this_LETTER_M_1, grammarAccess.getLETTER_NO_VXAccess().getLETTER_MTerminalRuleCall_1()); + newLeafNode(this_LETTER_C_1, grammarAccess.getLETTER_NO_VXAccess().getLETTER_CTerminalRuleCall_1()); } | - this_LETTER_R_2=RULE_LETTER_R + this_LETTER_E_2=RULE_LETTER_E { - $current.merge(this_LETTER_R_2); + $current.merge(this_LETTER_E_2); } { - newLeafNode(this_LETTER_R_2, grammarAccess.getLETTER_NO_VXAccess().getLETTER_RTerminalRuleCall_2()); + newLeafNode(this_LETTER_E_2, grammarAccess.getLETTER_NO_VXAccess().getLETTER_ETerminalRuleCall_2()); } | this_LETTER_F_3=RULE_LETTER_F @@ -2045,28 +2253,76 @@ ruleLETTER_NO_VX returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleTo newLeafNode(this_LETTER_I_4, grammarAccess.getLETTER_NO_VXAccess().getLETTER_ITerminalRuleCall_4()); } | - this_LETTER_L_5=RULE_LETTER_L + this_LETTER_K_5=RULE_LETTER_K + { + $current.merge(this_LETTER_K_5); + } + { + newLeafNode(this_LETTER_K_5, grammarAccess.getLETTER_NO_VXAccess().getLETTER_KTerminalRuleCall_5()); + } + | + this_LETTER_L_6=RULE_LETTER_L + { + $current.merge(this_LETTER_L_6); + } + { + newLeafNode(this_LETTER_L_6, grammarAccess.getLETTER_NO_VXAccess().getLETTER_LTerminalRuleCall_6()); + } + | + this_LETTER_M_7=RULE_LETTER_M + { + $current.merge(this_LETTER_M_7); + } + { + newLeafNode(this_LETTER_M_7, grammarAccess.getLETTER_NO_VXAccess().getLETTER_MTerminalRuleCall_7()); + } + | + this_LETTER_O_8=RULE_LETTER_O + { + $current.merge(this_LETTER_O_8); + } + { + newLeafNode(this_LETTER_O_8, grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTerminalRuleCall_8()); + } + | + this_LETTER_P_9=RULE_LETTER_P + { + $current.merge(this_LETTER_P_9); + } + { + newLeafNode(this_LETTER_P_9, grammarAccess.getLETTER_NO_VXAccess().getLETTER_PTerminalRuleCall_9()); + } + | + this_LETTER_R_10=RULE_LETTER_R + { + $current.merge(this_LETTER_R_10); + } + { + newLeafNode(this_LETTER_R_10, grammarAccess.getLETTER_NO_VXAccess().getLETTER_RTerminalRuleCall_10()); + } + | + this_LETTER_S_11=RULE_LETTER_S { - $current.merge(this_LETTER_L_5); + $current.merge(this_LETTER_S_11); } { - newLeafNode(this_LETTER_L_5, grammarAccess.getLETTER_NO_VXAccess().getLETTER_LTerminalRuleCall_5()); + newLeafNode(this_LETTER_S_11, grammarAccess.getLETTER_NO_VXAccess().getLETTER_STerminalRuleCall_11()); } | - this_LETTER_E_6=RULE_LETTER_E + this_LETTER_W_12=RULE_LETTER_W { - $current.merge(this_LETTER_E_6); + $current.merge(this_LETTER_W_12); } { - newLeafNode(this_LETTER_E_6, grammarAccess.getLETTER_NO_VXAccess().getLETTER_ETerminalRuleCall_6()); + newLeafNode(this_LETTER_W_12, grammarAccess.getLETTER_NO_VXAccess().getLETTER_WTerminalRuleCall_12()); } | - this_LETTER_OTHER_7=RULE_LETTER_OTHER + this_LETTER_OTHER_13=RULE_LETTER_OTHER { - $current.merge(this_LETTER_OTHER_7); + $current.merge(this_LETTER_OTHER_13); } { - newLeafNode(this_LETTER_OTHER_7, grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTHERTerminalRuleCall_7()); + newLeafNode(this_LETTER_OTHER_13, grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTHERTerminalRuleCall_13()); } ) ; @@ -2089,42 +2345,42 @@ ruleVersionComparator returns [Enumerator current=null] ) | ( - enumLiteral_1='<' + enumLiteral_1='~' { - $current = grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_1().getEnumLiteral().getInstance(); - newLeafNode(enumLiteral_1, grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_1()); + $current = grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_1().getEnumLiteral().getInstance(); + newLeafNode(enumLiteral_1, grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_1()); } ) | ( - enumLiteral_2='~' + enumLiteral_2='^' { - $current = grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_2().getEnumLiteral().getInstance(); - newLeafNode(enumLiteral_2, grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_2()); + $current = grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_2().getEnumLiteral().getInstance(); + newLeafNode(enumLiteral_2, grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_2()); } ) | ( - enumLiteral_3='^' + enumLiteral_3='<' { - $current = grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_3().getEnumLiteral().getInstance(); - newLeafNode(enumLiteral_3, grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_3()); + $current = grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_3().getEnumLiteral().getInstance(); + newLeafNode(enumLiteral_3, grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_3()); } ) | ( - enumLiteral_4='<=' + enumLiteral_4='>' { - $current = grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_4().getEnumLiteral().getInstance(); - newLeafNode(enumLiteral_4, grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_4()); + $current = grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_4().getEnumLiteral().getInstance(); + newLeafNode(enumLiteral_4, grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_4()); } ) | ( - enumLiteral_5='>' + enumLiteral_5='<=' { - $current = grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_5().getEnumLiteral().getInstance(); - newLeafNode(enumLiteral_5, grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_5()); + $current = grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_5().getEnumLiteral().getInstance(); + newLeafNode(enumLiteral_5, grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_5()); } ) | @@ -2138,25 +2394,37 @@ ruleVersionComparator returns [Enumerator current=null] ) ; -RULE_LETTER_S : ('s'|'S'); +RULE_LETTER_A : ('a'|'A'); -RULE_LETTER_M : ('m'|'M'); +RULE_LETTER_C : ('c'|'C'); -RULE_LETTER_R : ('r'|'R'); +RULE_LETTER_E : ('e'|'E'); RULE_LETTER_F : ('f'|'F'); RULE_LETTER_I : ('i'|'I'); +RULE_LETTER_K : ('k'|'K'); + RULE_LETTER_L : ('l'|'L'); -RULE_LETTER_E : ('e'|'E'); +RULE_LETTER_M : ('m'|'M'); + +RULE_LETTER_O : ('o'|'O'); + +RULE_LETTER_P : ('p'|'P'); + +RULE_LETTER_R : ('r'|'R'); + +RULE_LETTER_S : ('s'|'S'); RULE_LETTER_V : ('v'|'V'); +RULE_LETTER_W : ('w'|'W'); + RULE_LETTER_X : ('x'|'X'); -RULE_LETTER_OTHER : ('a'|'A'|'b'|'B'|'c'|'C'|'d'|'D'|'g'|'G'|'h'|'H'|'j'|'J'|'k'|'K'|'n'|'N'|'o'|'O'|'p'|'P'|'q'|'Q'|'t'|'T'|'u'|'U'|'w'|'W'|'y'|'Y'|'z'|'Z'); +RULE_LETTER_OTHER : ('b'|'B'|'d'|'D'|'g'|'G'|'h'|'H'|'j'|'J'|'n'|'N'|'q'|'Q'|'t'|'T'|'u'|'U'|'y'|'Y'|'z'|'Z'); RULE_ASTERIX : '*'; diff --git a/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/parser/antlr/internal/InternalSemver.tokens b/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/parser/antlr/internal/InternalSemver.tokens index 91f9b667db..3cb6edcbab 100644 --- a/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/parser/antlr/internal/InternalSemver.tokens +++ b/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/parser/antlr/internal/InternalSemver.tokens @@ -1,56 +1,56 @@ -'#'=37 -'+'=41 -'-'=39 -'.'=40 -'/'=36 -':'=35 -'<'=45 -'<='=48 -'='=44 -'>'=49 -'>='=50 -'@'=42 -'^'=47 -'_'=43 -'||'=38 -'~'=46 -RULE_ANY_OTHER=34 -RULE_ASTERIX=15 -RULE_BOM=25 -RULE_DECIMAL_DIGIT_FRAGMENT=20 -RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT=22 +'#'=43 +'+'=47 +'-'=45 +'.'=46 +'/'=42 +':'=41 +'<'=53 +'<='=55 +'='=50 +'>'=54 +'>='=56 +'@'=48 +'^'=52 +'_'=49 +'||'=44 +'~'=51 +RULE_ANY_OTHER=40 +RULE_ASTERIX=20 +RULE_BOM=31 +RULE_DECIMAL_DIGIT_FRAGMENT=26 +RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT=28 RULE_DIGITS=6 -RULE_EOL=19 -RULE_HEX_DIGIT=21 +RULE_EOL=25 +RULE_HEX_DIGIT=27 +RULE_LETTER_A=18 +RULE_LETTER_C=19 RULE_LETTER_E=10 RULE_LETTER_F=7 RULE_LETTER_I=8 +RULE_LETTER_K=16 RULE_LETTER_L=9 RULE_LETTER_M=12 -RULE_LETTER_OTHER=16 +RULE_LETTER_O=15 +RULE_LETTER_OTHER=22 +RULE_LETTER_P=17 RULE_LETTER_R=13 RULE_LETTER_S=11 RULE_LETTER_V=5 -RULE_LETTER_X=14 -RULE_LINE_TERMINATOR_FRAGMENT=27 -RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT=18 -RULE_ML_COMMENT_FRAGMENT=29 -RULE_SL_COMMENT_FRAGMENT=28 -RULE_UNICODE_COMBINING_MARK_FRAGMENT=30 -RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT=32 -RULE_UNICODE_DIGIT_FRAGMENT=31 -RULE_UNICODE_LETTER_FRAGMENT=33 -RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT=26 -RULE_WHITESPACE_FRAGMENT=17 +RULE_LETTER_W=14 +RULE_LETTER_X=21 +RULE_LINE_TERMINATOR_FRAGMENT=33 +RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT=24 +RULE_ML_COMMENT_FRAGMENT=35 +RULE_SL_COMMENT_FRAGMENT=34 +RULE_UNICODE_COMBINING_MARK_FRAGMENT=36 +RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT=38 +RULE_UNICODE_DIGIT_FRAGMENT=37 +RULE_UNICODE_LETTER_FRAGMENT=39 +RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT=32 +RULE_WHITESPACE_FRAGMENT=23 RULE_WS=4 -RULE_ZWJ=23 -RULE_ZWNJ=24 -T__35=35 -T__36=36 -T__37=37 -T__38=38 -T__39=39 -T__40=40 +RULE_ZWJ=29 +RULE_ZWNJ=30 T__41=41 T__42=42 T__43=43 @@ -61,3 +61,9 @@ T__47=47 T__48=48 T__49=49 T__50=50 +T__51=51 +T__52=52 +T__53=53 +T__54=54 +T__55=55 +T__56=56 diff --git a/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/parser/antlr/internal/InternalSemverLexer.java b/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/parser/antlr/internal/InternalSemverLexer.java index eae308a30c..0c3b09d2ea 100644 --- a/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/parser/antlr/internal/InternalSemverLexer.java +++ b/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/parser/antlr/internal/InternalSemverLexer.java @@ -13,50 +13,56 @@ @SuppressWarnings("all") public class InternalSemverLexer extends Lexer { public static final int T__50=50; - public static final int RULE_WHITESPACE_FRAGMENT=17; - public static final int RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT=18; - public static final int RULE_EOL=19; - public static final int RULE_LETTER_OTHER=16; - public static final int RULE_UNICODE_COMBINING_MARK_FRAGMENT=30; - public static final int RULE_ZWNJ=24; - public static final int RULE_ASTERIX=15; + public static final int RULE_WHITESPACE_FRAGMENT=23; + public static final int T__55=55; + public static final int T__56=56; + public static final int T__51=51; + public static final int T__52=52; + public static final int T__53=53; + public static final int T__54=54; + public static final int RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT=24; + public static final int RULE_EOL=25; + public static final int RULE_LETTER_OTHER=22; + public static final int RULE_UNICODE_COMBINING_MARK_FRAGMENT=36; + public static final int RULE_ZWNJ=30; + public static final int RULE_LETTER_A=18; + public static final int RULE_LETTER_C=19; + public static final int RULE_ASTERIX=20; public static final int RULE_LETTER_E=10; - public static final int RULE_ML_COMMENT_FRAGMENT=29; + public static final int RULE_ML_COMMENT_FRAGMENT=35; public static final int RULE_DIGITS=6; - public static final int RULE_ZWJ=23; - public static final int RULE_SL_COMMENT_FRAGMENT=28; - public static final int RULE_UNICODE_DIGIT_FRAGMENT=31; - public static final int T__37=37; + public static final int RULE_LETTER_O=15; + public static final int RULE_ZWJ=29; + public static final int RULE_SL_COMMENT_FRAGMENT=34; + public static final int RULE_LETTER_P=17; + public static final int RULE_UNICODE_DIGIT_FRAGMENT=37; public static final int RULE_LETTER_R=13; - public static final int T__38=38; public static final int RULE_LETTER_S=11; - public static final int T__39=39; public static final int RULE_LETTER_F=7; - public static final int RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT=26; - public static final int T__35=35; - public static final int T__36=36; + public static final int RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT=32; public static final int RULE_LETTER_I=8; public static final int EOF=-1; + public static final int RULE_LETTER_K=16; public static final int RULE_LETTER_L=9; public static final int RULE_LETTER_M=12; public static final int RULE_WS=4; - public static final int RULE_BOM=25; + public static final int RULE_BOM=31; public static final int RULE_LETTER_V=5; - public static final int RULE_LETTER_X=14; - public static final int RULE_ANY_OTHER=34; - public static final int RULE_LINE_TERMINATOR_FRAGMENT=27; - public static final int RULE_UNICODE_LETTER_FRAGMENT=33; - public static final int RULE_DECIMAL_DIGIT_FRAGMENT=20; + public static final int RULE_LETTER_W=14; + public static final int RULE_LETTER_X=21; + public static final int RULE_ANY_OTHER=40; + public static final int RULE_LINE_TERMINATOR_FRAGMENT=33; + public static final int RULE_UNICODE_LETTER_FRAGMENT=39; + public static final int RULE_DECIMAL_DIGIT_FRAGMENT=26; public static final int T__48=48; public static final int T__49=49; public static final int T__44=44; public static final int T__45=45; - public static final int RULE_HEX_DIGIT=21; - public static final int RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT=22; - public static final int RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT=32; + public static final int RULE_HEX_DIGIT=27; + public static final int RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT=28; + public static final int RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT=38; public static final int T__46=46; public static final int T__47=47; - public static final int T__40=40; public static final int T__41=41; public static final int T__42=42; public static final int T__43=43; @@ -74,10 +80,10 @@ public InternalSemverLexer(CharStream input, RecognizerSharedState state) { } public String getGrammarFileName() { return "InternalSemver.g"; } - // $ANTLR start "T__35" - public final void mT__35() throws RecognitionException { + // $ANTLR start "T__41" + public final void mT__41() throws RecognitionException { try { - int _type = T__35; + int _type = T__41; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:11:7: ( ':' ) // InternalSemver.g:11:9: ':' @@ -92,12 +98,12 @@ public final void mT__35() throws RecognitionException { finally { } } - // $ANTLR end "T__35" + // $ANTLR end "T__41" - // $ANTLR start "T__36" - public final void mT__36() throws RecognitionException { + // $ANTLR start "T__42" + public final void mT__42() throws RecognitionException { try { - int _type = T__36; + int _type = T__42; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:12:7: ( '/' ) // InternalSemver.g:12:9: '/' @@ -112,12 +118,12 @@ public final void mT__36() throws RecognitionException { finally { } } - // $ANTLR end "T__36" + // $ANTLR end "T__42" - // $ANTLR start "T__37" - public final void mT__37() throws RecognitionException { + // $ANTLR start "T__43" + public final void mT__43() throws RecognitionException { try { - int _type = T__37; + int _type = T__43; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:13:7: ( '#' ) // InternalSemver.g:13:9: '#' @@ -132,12 +138,12 @@ public final void mT__37() throws RecognitionException { finally { } } - // $ANTLR end "T__37" + // $ANTLR end "T__43" - // $ANTLR start "T__38" - public final void mT__38() throws RecognitionException { + // $ANTLR start "T__44" + public final void mT__44() throws RecognitionException { try { - int _type = T__38; + int _type = T__44; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:14:7: ( '||' ) // InternalSemver.g:14:9: '||' @@ -153,12 +159,12 @@ public final void mT__38() throws RecognitionException { finally { } } - // $ANTLR end "T__38" + // $ANTLR end "T__44" - // $ANTLR start "T__39" - public final void mT__39() throws RecognitionException { + // $ANTLR start "T__45" + public final void mT__45() throws RecognitionException { try { - int _type = T__39; + int _type = T__45; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:15:7: ( '-' ) // InternalSemver.g:15:9: '-' @@ -173,12 +179,12 @@ public final void mT__39() throws RecognitionException { finally { } } - // $ANTLR end "T__39" + // $ANTLR end "T__45" - // $ANTLR start "T__40" - public final void mT__40() throws RecognitionException { + // $ANTLR start "T__46" + public final void mT__46() throws RecognitionException { try { - int _type = T__40; + int _type = T__46; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:16:7: ( '.' ) // InternalSemver.g:16:9: '.' @@ -193,12 +199,12 @@ public final void mT__40() throws RecognitionException { finally { } } - // $ANTLR end "T__40" + // $ANTLR end "T__46" - // $ANTLR start "T__41" - public final void mT__41() throws RecognitionException { + // $ANTLR start "T__47" + public final void mT__47() throws RecognitionException { try { - int _type = T__41; + int _type = T__47; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:17:7: ( '+' ) // InternalSemver.g:17:9: '+' @@ -213,12 +219,12 @@ public final void mT__41() throws RecognitionException { finally { } } - // $ANTLR end "T__41" + // $ANTLR end "T__47" - // $ANTLR start "T__42" - public final void mT__42() throws RecognitionException { + // $ANTLR start "T__48" + public final void mT__48() throws RecognitionException { try { - int _type = T__42; + int _type = T__48; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:18:7: ( '@' ) // InternalSemver.g:18:9: '@' @@ -233,12 +239,12 @@ public final void mT__42() throws RecognitionException { finally { } } - // $ANTLR end "T__42" + // $ANTLR end "T__48" - // $ANTLR start "T__43" - public final void mT__43() throws RecognitionException { + // $ANTLR start "T__49" + public final void mT__49() throws RecognitionException { try { - int _type = T__43; + int _type = T__49; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:19:7: ( '_' ) // InternalSemver.g:19:9: '_' @@ -253,12 +259,12 @@ public final void mT__43() throws RecognitionException { finally { } } - // $ANTLR end "T__43" + // $ANTLR end "T__49" - // $ANTLR start "T__44" - public final void mT__44() throws RecognitionException { + // $ANTLR start "T__50" + public final void mT__50() throws RecognitionException { try { - int _type = T__44; + int _type = T__50; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:20:7: ( '=' ) // InternalSemver.g:20:9: '=' @@ -273,17 +279,17 @@ public final void mT__44() throws RecognitionException { finally { } } - // $ANTLR end "T__44" + // $ANTLR end "T__50" - // $ANTLR start "T__45" - public final void mT__45() throws RecognitionException { + // $ANTLR start "T__51" + public final void mT__51() throws RecognitionException { try { - int _type = T__45; + int _type = T__51; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:21:7: ( '<' ) - // InternalSemver.g:21:9: '<' + // InternalSemver.g:21:7: ( '~' ) + // InternalSemver.g:21:9: '~' { - match('<'); + match('~'); } @@ -293,17 +299,17 @@ public final void mT__45() throws RecognitionException { finally { } } - // $ANTLR end "T__45" + // $ANTLR end "T__51" - // $ANTLR start "T__46" - public final void mT__46() throws RecognitionException { + // $ANTLR start "T__52" + public final void mT__52() throws RecognitionException { try { - int _type = T__46; + int _type = T__52; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:22:7: ( '~' ) - // InternalSemver.g:22:9: '~' + // InternalSemver.g:22:7: ( '^' ) + // InternalSemver.g:22:9: '^' { - match('~'); + match('^'); } @@ -313,17 +319,17 @@ public final void mT__46() throws RecognitionException { finally { } } - // $ANTLR end "T__46" + // $ANTLR end "T__52" - // $ANTLR start "T__47" - public final void mT__47() throws RecognitionException { + // $ANTLR start "T__53" + public final void mT__53() throws RecognitionException { try { - int _type = T__47; + int _type = T__53; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:23:7: ( '^' ) - // InternalSemver.g:23:9: '^' + // InternalSemver.g:23:7: ( '<' ) + // InternalSemver.g:23:9: '<' { - match('^'); + match('<'); } @@ -333,18 +339,17 @@ public final void mT__47() throws RecognitionException { finally { } } - // $ANTLR end "T__47" + // $ANTLR end "T__53" - // $ANTLR start "T__48" - public final void mT__48() throws RecognitionException { + // $ANTLR start "T__54" + public final void mT__54() throws RecognitionException { try { - int _type = T__48; + int _type = T__54; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:24:7: ( '<=' ) - // InternalSemver.g:24:9: '<=' + // InternalSemver.g:24:7: ( '>' ) + // InternalSemver.g:24:9: '>' { - match("<="); - + match('>'); } @@ -354,17 +359,18 @@ public final void mT__48() throws RecognitionException { finally { } } - // $ANTLR end "T__48" + // $ANTLR end "T__54" - // $ANTLR start "T__49" - public final void mT__49() throws RecognitionException { + // $ANTLR start "T__55" + public final void mT__55() throws RecognitionException { try { - int _type = T__49; + int _type = T__55; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:25:7: ( '>' ) - // InternalSemver.g:25:9: '>' + // InternalSemver.g:25:7: ( '<=' ) + // InternalSemver.g:25:9: '<=' { - match('>'); + match("<="); + } @@ -374,12 +380,12 @@ public final void mT__49() throws RecognitionException { finally { } } - // $ANTLR end "T__49" + // $ANTLR end "T__55" - // $ANTLR start "T__50" - public final void mT__50() throws RecognitionException { + // $ANTLR start "T__56" + public final void mT__56() throws RecognitionException { try { - int _type = T__50; + int _type = T__56; int _channel = DEFAULT_TOKEN_CHANNEL; // InternalSemver.g:26:7: ( '>=' ) // InternalSemver.g:26:9: '>=' @@ -395,17 +401,17 @@ public final void mT__50() throws RecognitionException { finally { } } - // $ANTLR end "T__50" + // $ANTLR end "T__56" - // $ANTLR start "RULE_LETTER_S" - public final void mRULE_LETTER_S() throws RecognitionException { + // $ANTLR start "RULE_LETTER_A" + public final void mRULE_LETTER_A() throws RecognitionException { try { - int _type = RULE_LETTER_S; + int _type = RULE_LETTER_A; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2141:15: ( ( 's' | 'S' ) ) - // InternalSemver.g:2141:17: ( 's' | 'S' ) + // InternalSemver.g:2397:15: ( ( 'a' | 'A' ) ) + // InternalSemver.g:2397:17: ( 'a' | 'A' ) { - if ( input.LA(1)=='S'||input.LA(1)=='s' ) { + if ( input.LA(1)=='A'||input.LA(1)=='a' ) { input.consume(); } @@ -423,17 +429,17 @@ public final void mRULE_LETTER_S() throws RecognitionException { finally { } } - // $ANTLR end "RULE_LETTER_S" + // $ANTLR end "RULE_LETTER_A" - // $ANTLR start "RULE_LETTER_M" - public final void mRULE_LETTER_M() throws RecognitionException { + // $ANTLR start "RULE_LETTER_C" + public final void mRULE_LETTER_C() throws RecognitionException { try { - int _type = RULE_LETTER_M; + int _type = RULE_LETTER_C; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2143:15: ( ( 'm' | 'M' ) ) - // InternalSemver.g:2143:17: ( 'm' | 'M' ) + // InternalSemver.g:2399:15: ( ( 'c' | 'C' ) ) + // InternalSemver.g:2399:17: ( 'c' | 'C' ) { - if ( input.LA(1)=='M'||input.LA(1)=='m' ) { + if ( input.LA(1)=='C'||input.LA(1)=='c' ) { input.consume(); } @@ -451,17 +457,17 @@ public final void mRULE_LETTER_M() throws RecognitionException { finally { } } - // $ANTLR end "RULE_LETTER_M" + // $ANTLR end "RULE_LETTER_C" - // $ANTLR start "RULE_LETTER_R" - public final void mRULE_LETTER_R() throws RecognitionException { + // $ANTLR start "RULE_LETTER_E" + public final void mRULE_LETTER_E() throws RecognitionException { try { - int _type = RULE_LETTER_R; + int _type = RULE_LETTER_E; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2145:15: ( ( 'r' | 'R' ) ) - // InternalSemver.g:2145:17: ( 'r' | 'R' ) + // InternalSemver.g:2401:15: ( ( 'e' | 'E' ) ) + // InternalSemver.g:2401:17: ( 'e' | 'E' ) { - if ( input.LA(1)=='R'||input.LA(1)=='r' ) { + if ( input.LA(1)=='E'||input.LA(1)=='e' ) { input.consume(); } @@ -479,15 +485,15 @@ public final void mRULE_LETTER_R() throws RecognitionException { finally { } } - // $ANTLR end "RULE_LETTER_R" + // $ANTLR end "RULE_LETTER_E" // $ANTLR start "RULE_LETTER_F" public final void mRULE_LETTER_F() throws RecognitionException { try { int _type = RULE_LETTER_F; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2147:15: ( ( 'f' | 'F' ) ) - // InternalSemver.g:2147:17: ( 'f' | 'F' ) + // InternalSemver.g:2403:15: ( ( 'f' | 'F' ) ) + // InternalSemver.g:2403:17: ( 'f' | 'F' ) { if ( input.LA(1)=='F'||input.LA(1)=='f' ) { input.consume(); @@ -514,8 +520,8 @@ public final void mRULE_LETTER_I() throws RecognitionException { try { int _type = RULE_LETTER_I; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2149:15: ( ( 'i' | 'I' ) ) - // InternalSemver.g:2149:17: ( 'i' | 'I' ) + // InternalSemver.g:2405:15: ( ( 'i' | 'I' ) ) + // InternalSemver.g:2405:17: ( 'i' | 'I' ) { if ( input.LA(1)=='I'||input.LA(1)=='i' ) { input.consume(); @@ -537,13 +543,41 @@ public final void mRULE_LETTER_I() throws RecognitionException { } // $ANTLR end "RULE_LETTER_I" + // $ANTLR start "RULE_LETTER_K" + public final void mRULE_LETTER_K() throws RecognitionException { + try { + int _type = RULE_LETTER_K; + int _channel = DEFAULT_TOKEN_CHANNEL; + // InternalSemver.g:2407:15: ( ( 'k' | 'K' ) ) + // InternalSemver.g:2407:17: ( 'k' | 'K' ) + { + if ( input.LA(1)=='K'||input.LA(1)=='k' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "RULE_LETTER_K" + // $ANTLR start "RULE_LETTER_L" public final void mRULE_LETTER_L() throws RecognitionException { try { int _type = RULE_LETTER_L; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2151:15: ( ( 'l' | 'L' ) ) - // InternalSemver.g:2151:17: ( 'l' | 'L' ) + // InternalSemver.g:2409:15: ( ( 'l' | 'L' ) ) + // InternalSemver.g:2409:17: ( 'l' | 'L' ) { if ( input.LA(1)=='L'||input.LA(1)=='l' ) { input.consume(); @@ -565,15 +599,15 @@ public final void mRULE_LETTER_L() throws RecognitionException { } // $ANTLR end "RULE_LETTER_L" - // $ANTLR start "RULE_LETTER_E" - public final void mRULE_LETTER_E() throws RecognitionException { + // $ANTLR start "RULE_LETTER_M" + public final void mRULE_LETTER_M() throws RecognitionException { try { - int _type = RULE_LETTER_E; + int _type = RULE_LETTER_M; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2153:15: ( ( 'e' | 'E' ) ) - // InternalSemver.g:2153:17: ( 'e' | 'E' ) + // InternalSemver.g:2411:15: ( ( 'm' | 'M' ) ) + // InternalSemver.g:2411:17: ( 'm' | 'M' ) { - if ( input.LA(1)=='E'||input.LA(1)=='e' ) { + if ( input.LA(1)=='M'||input.LA(1)=='m' ) { input.consume(); } @@ -591,15 +625,127 @@ public final void mRULE_LETTER_E() throws RecognitionException { finally { } } - // $ANTLR end "RULE_LETTER_E" + // $ANTLR end "RULE_LETTER_M" + + // $ANTLR start "RULE_LETTER_O" + public final void mRULE_LETTER_O() throws RecognitionException { + try { + int _type = RULE_LETTER_O; + int _channel = DEFAULT_TOKEN_CHANNEL; + // InternalSemver.g:2413:15: ( ( 'o' | 'O' ) ) + // InternalSemver.g:2413:17: ( 'o' | 'O' ) + { + if ( input.LA(1)=='O'||input.LA(1)=='o' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "RULE_LETTER_O" + + // $ANTLR start "RULE_LETTER_P" + public final void mRULE_LETTER_P() throws RecognitionException { + try { + int _type = RULE_LETTER_P; + int _channel = DEFAULT_TOKEN_CHANNEL; + // InternalSemver.g:2415:15: ( ( 'p' | 'P' ) ) + // InternalSemver.g:2415:17: ( 'p' | 'P' ) + { + if ( input.LA(1)=='P'||input.LA(1)=='p' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "RULE_LETTER_P" + + // $ANTLR start "RULE_LETTER_R" + public final void mRULE_LETTER_R() throws RecognitionException { + try { + int _type = RULE_LETTER_R; + int _channel = DEFAULT_TOKEN_CHANNEL; + // InternalSemver.g:2417:15: ( ( 'r' | 'R' ) ) + // InternalSemver.g:2417:17: ( 'r' | 'R' ) + { + if ( input.LA(1)=='R'||input.LA(1)=='r' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "RULE_LETTER_R" + + // $ANTLR start "RULE_LETTER_S" + public final void mRULE_LETTER_S() throws RecognitionException { + try { + int _type = RULE_LETTER_S; + int _channel = DEFAULT_TOKEN_CHANNEL; + // InternalSemver.g:2419:15: ( ( 's' | 'S' ) ) + // InternalSemver.g:2419:17: ( 's' | 'S' ) + { + if ( input.LA(1)=='S'||input.LA(1)=='s' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "RULE_LETTER_S" // $ANTLR start "RULE_LETTER_V" public final void mRULE_LETTER_V() throws RecognitionException { try { int _type = RULE_LETTER_V; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2155:15: ( ( 'v' | 'V' ) ) - // InternalSemver.g:2155:17: ( 'v' | 'V' ) + // InternalSemver.g:2421:15: ( ( 'v' | 'V' ) ) + // InternalSemver.g:2421:17: ( 'v' | 'V' ) { if ( input.LA(1)=='V'||input.LA(1)=='v' ) { input.consume(); @@ -621,13 +767,41 @@ public final void mRULE_LETTER_V() throws RecognitionException { } // $ANTLR end "RULE_LETTER_V" + // $ANTLR start "RULE_LETTER_W" + public final void mRULE_LETTER_W() throws RecognitionException { + try { + int _type = RULE_LETTER_W; + int _channel = DEFAULT_TOKEN_CHANNEL; + // InternalSemver.g:2423:15: ( ( 'w' | 'W' ) ) + // InternalSemver.g:2423:17: ( 'w' | 'W' ) + { + if ( input.LA(1)=='W'||input.LA(1)=='w' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "RULE_LETTER_W" + // $ANTLR start "RULE_LETTER_X" public final void mRULE_LETTER_X() throws RecognitionException { try { int _type = RULE_LETTER_X; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2157:15: ( ( 'x' | 'X' ) ) - // InternalSemver.g:2157:17: ( 'x' | 'X' ) + // InternalSemver.g:2425:15: ( ( 'x' | 'X' ) ) + // InternalSemver.g:2425:17: ( 'x' | 'X' ) { if ( input.LA(1)=='X'||input.LA(1)=='x' ) { input.consume(); @@ -654,10 +828,10 @@ public final void mRULE_LETTER_OTHER() throws RecognitionException { try { int _type = RULE_LETTER_OTHER; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2159:19: ( ( 'a' | 'A' | 'b' | 'B' | 'c' | 'C' | 'd' | 'D' | 'g' | 'G' | 'h' | 'H' | 'j' | 'J' | 'k' | 'K' | 'n' | 'N' | 'o' | 'O' | 'p' | 'P' | 'q' | 'Q' | 't' | 'T' | 'u' | 'U' | 'w' | 'W' | 'y' | 'Y' | 'z' | 'Z' ) ) - // InternalSemver.g:2159:21: ( 'a' | 'A' | 'b' | 'B' | 'c' | 'C' | 'd' | 'D' | 'g' | 'G' | 'h' | 'H' | 'j' | 'J' | 'k' | 'K' | 'n' | 'N' | 'o' | 'O' | 'p' | 'P' | 'q' | 'Q' | 't' | 'T' | 'u' | 'U' | 'w' | 'W' | 'y' | 'Y' | 'z' | 'Z' ) + // InternalSemver.g:2427:19: ( ( 'b' | 'B' | 'd' | 'D' | 'g' | 'G' | 'h' | 'H' | 'j' | 'J' | 'n' | 'N' | 'q' | 'Q' | 't' | 'T' | 'u' | 'U' | 'y' | 'Y' | 'z' | 'Z' ) ) + // InternalSemver.g:2427:21: ( 'b' | 'B' | 'd' | 'D' | 'g' | 'G' | 'h' | 'H' | 'j' | 'J' | 'n' | 'N' | 'q' | 'Q' | 't' | 'T' | 'u' | 'U' | 'y' | 'Y' | 'z' | 'Z' ) { - if ( (input.LA(1)>='A' && input.LA(1)<='D')||(input.LA(1)>='G' && input.LA(1)<='H')||(input.LA(1)>='J' && input.LA(1)<='K')||(input.LA(1)>='N' && input.LA(1)<='Q')||(input.LA(1)>='T' && input.LA(1)<='U')||input.LA(1)=='W'||(input.LA(1)>='Y' && input.LA(1)<='Z')||(input.LA(1)>='a' && input.LA(1)<='d')||(input.LA(1)>='g' && input.LA(1)<='h')||(input.LA(1)>='j' && input.LA(1)<='k')||(input.LA(1)>='n' && input.LA(1)<='q')||(input.LA(1)>='t' && input.LA(1)<='u')||input.LA(1)=='w'||(input.LA(1)>='y' && input.LA(1)<='z') ) { + if ( input.LA(1)=='B'||input.LA(1)=='D'||(input.LA(1)>='G' && input.LA(1)<='H')||input.LA(1)=='J'||input.LA(1)=='N'||input.LA(1)=='Q'||(input.LA(1)>='T' && input.LA(1)<='U')||(input.LA(1)>='Y' && input.LA(1)<='Z')||input.LA(1)=='b'||input.LA(1)=='d'||(input.LA(1)>='g' && input.LA(1)<='h')||input.LA(1)=='j'||input.LA(1)=='n'||input.LA(1)=='q'||(input.LA(1)>='t' && input.LA(1)<='u')||(input.LA(1)>='y' && input.LA(1)<='z') ) { input.consume(); } @@ -682,8 +856,8 @@ public final void mRULE_ASTERIX() throws RecognitionException { try { int _type = RULE_ASTERIX; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2161:14: ( '*' ) - // InternalSemver.g:2161:16: '*' + // InternalSemver.g:2429:14: ( '*' ) + // InternalSemver.g:2429:16: '*' { match('*'); @@ -702,10 +876,10 @@ public final void mRULE_DIGITS() throws RecognitionException { try { int _type = RULE_DIGITS; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2163:13: ( ( '0' .. '9' )+ ) - // InternalSemver.g:2163:15: ( '0' .. '9' )+ + // InternalSemver.g:2431:13: ( ( '0' .. '9' )+ ) + // InternalSemver.g:2431:15: ( '0' .. '9' )+ { - // InternalSemver.g:2163:15: ( '0' .. '9' )+ + // InternalSemver.g:2431:15: ( '0' .. '9' )+ int cnt1=0; loop1: do { @@ -719,7 +893,7 @@ public final void mRULE_DIGITS() throws RecognitionException { switch (alt1) { case 1 : - // InternalSemver.g:2163:16: '0' .. '9' + // InternalSemver.g:2431:16: '0' .. '9' { matchRange('0','9'); @@ -751,10 +925,10 @@ public final void mRULE_WS() throws RecognitionException { try { int _type = RULE_WS; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2165:9: ( ( RULE_WHITESPACE_FRAGMENT )+ ) - // InternalSemver.g:2165:11: ( RULE_WHITESPACE_FRAGMENT )+ + // InternalSemver.g:2433:9: ( ( RULE_WHITESPACE_FRAGMENT )+ ) + // InternalSemver.g:2433:11: ( RULE_WHITESPACE_FRAGMENT )+ { - // InternalSemver.g:2165:11: ( RULE_WHITESPACE_FRAGMENT )+ + // InternalSemver.g:2433:11: ( RULE_WHITESPACE_FRAGMENT )+ int cnt2=0; loop2: do { @@ -768,7 +942,7 @@ public final void mRULE_WS() throws RecognitionException { switch (alt2) { case 1 : - // InternalSemver.g:2165:11: RULE_WHITESPACE_FRAGMENT + // InternalSemver.g:2433:11: RULE_WHITESPACE_FRAGMENT { mRULE_WHITESPACE_FRAGMENT(); @@ -800,8 +974,8 @@ public final void mRULE_EOL() throws RecognitionException { try { int _type = RULE_EOL; int _channel = DEFAULT_TOKEN_CHANNEL; - // InternalSemver.g:2167:10: ( RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT ) - // InternalSemver.g:2167:12: RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT + // InternalSemver.g:2435:10: ( RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT ) + // InternalSemver.g:2435:12: RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT { mRULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT(); @@ -818,8 +992,8 @@ public final void mRULE_EOL() throws RecognitionException { // $ANTLR start "RULE_HEX_DIGIT" public final void mRULE_HEX_DIGIT() throws RecognitionException { try { - // InternalSemver.g:2169:25: ( ( RULE_DECIMAL_DIGIT_FRAGMENT | 'a' .. 'f' | 'A' .. 'F' ) ) - // InternalSemver.g:2169:27: ( RULE_DECIMAL_DIGIT_FRAGMENT | 'a' .. 'f' | 'A' .. 'F' ) + // InternalSemver.g:2437:25: ( ( RULE_DECIMAL_DIGIT_FRAGMENT | 'a' .. 'f' | 'A' .. 'F' ) ) + // InternalSemver.g:2437:27: ( RULE_DECIMAL_DIGIT_FRAGMENT | 'a' .. 'f' | 'A' .. 'F' ) { if ( (input.LA(1)>='0' && input.LA(1)<='9')||(input.LA(1)>='A' && input.LA(1)<='F')||(input.LA(1)>='a' && input.LA(1)<='f') ) { input.consume(); @@ -842,10 +1016,10 @@ public final void mRULE_HEX_DIGIT() throws RecognitionException { // $ANTLR start "RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT" public final void mRULE_DECIMAL_INTEGER_LITERAL_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:2171:48: ( ( '0' | '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* ) ) - // InternalSemver.g:2171:50: ( '0' | '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* ) + // InternalSemver.g:2439:48: ( ( '0' | '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* ) ) + // InternalSemver.g:2439:50: ( '0' | '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* ) { - // InternalSemver.g:2171:50: ( '0' | '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* ) + // InternalSemver.g:2439:50: ( '0' | '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* ) int alt4=2; int LA4_0 = input.LA(1); @@ -863,17 +1037,17 @@ else if ( ((LA4_0>='1' && LA4_0<='9')) ) { } switch (alt4) { case 1 : - // InternalSemver.g:2171:51: '0' + // InternalSemver.g:2439:51: '0' { match('0'); } break; case 2 : - // InternalSemver.g:2171:55: '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* + // InternalSemver.g:2439:55: '1' .. '9' ( RULE_DECIMAL_DIGIT_FRAGMENT )* { matchRange('1','9'); - // InternalSemver.g:2171:64: ( RULE_DECIMAL_DIGIT_FRAGMENT )* + // InternalSemver.g:2439:64: ( RULE_DECIMAL_DIGIT_FRAGMENT )* loop3: do { int alt3=2; @@ -886,7 +1060,7 @@ else if ( ((LA4_0>='1' && LA4_0<='9')) ) { switch (alt3) { case 1 : - // InternalSemver.g:2171:64: RULE_DECIMAL_DIGIT_FRAGMENT + // InternalSemver.g:2439:64: RULE_DECIMAL_DIGIT_FRAGMENT { mRULE_DECIMAL_DIGIT_FRAGMENT(); @@ -916,8 +1090,8 @@ else if ( ((LA4_0>='1' && LA4_0<='9')) ) { // $ANTLR start "RULE_DECIMAL_DIGIT_FRAGMENT" public final void mRULE_DECIMAL_DIGIT_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:2173:38: ( '0' .. '9' ) - // InternalSemver.g:2173:40: '0' .. '9' + // InternalSemver.g:2441:38: ( '0' .. '9' ) + // InternalSemver.g:2441:40: '0' .. '9' { matchRange('0','9'); @@ -932,8 +1106,8 @@ public final void mRULE_DECIMAL_DIGIT_FRAGMENT() throws RecognitionException { // $ANTLR start "RULE_ZWJ" public final void mRULE_ZWJ() throws RecognitionException { try { - // InternalSemver.g:2175:19: ( '\\u200D' ) - // InternalSemver.g:2175:21: '\\u200D' + // InternalSemver.g:2443:19: ( '\\u200D' ) + // InternalSemver.g:2443:21: '\\u200D' { match('\u200D'); @@ -948,8 +1122,8 @@ public final void mRULE_ZWJ() throws RecognitionException { // $ANTLR start "RULE_ZWNJ" public final void mRULE_ZWNJ() throws RecognitionException { try { - // InternalSemver.g:2177:20: ( '\\u200C' ) - // InternalSemver.g:2177:22: '\\u200C' + // InternalSemver.g:2445:20: ( '\\u200C' ) + // InternalSemver.g:2445:22: '\\u200C' { match('\u200C'); @@ -964,8 +1138,8 @@ public final void mRULE_ZWNJ() throws RecognitionException { // $ANTLR start "RULE_BOM" public final void mRULE_BOM() throws RecognitionException { try { - // InternalSemver.g:2179:19: ( '\\uFEFF' ) - // InternalSemver.g:2179:21: '\\uFEFF' + // InternalSemver.g:2447:19: ( '\\uFEFF' ) + // InternalSemver.g:2447:21: '\\uFEFF' { match('\uFEFF'); @@ -980,8 +1154,8 @@ public final void mRULE_BOM() throws RecognitionException { // $ANTLR start "RULE_WHITESPACE_FRAGMENT" public final void mRULE_WHITESPACE_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:2181:35: ( ( '\\t' | '\\u000B' | '\\f' | ' ' | '\\u00A0' | RULE_BOM | RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT ) ) - // InternalSemver.g:2181:37: ( '\\t' | '\\u000B' | '\\f' | ' ' | '\\u00A0' | RULE_BOM | RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT ) + // InternalSemver.g:2449:35: ( ( '\\t' | '\\u000B' | '\\f' | ' ' | '\\u00A0' | RULE_BOM | RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT ) ) + // InternalSemver.g:2449:37: ( '\\t' | '\\u000B' | '\\f' | ' ' | '\\u00A0' | RULE_BOM | RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT ) { if ( input.LA(1)=='\t'||(input.LA(1)>='\u000B' && input.LA(1)<='\f')||input.LA(1)==' '||input.LA(1)=='\u00A0'||input.LA(1)=='\u1680'||(input.LA(1)>='\u2000' && input.LA(1)<='\u200A')||input.LA(1)=='\u202F'||input.LA(1)=='\u205F'||input.LA(1)=='\u3000'||input.LA(1)=='\uFEFF' ) { input.consume(); @@ -1004,8 +1178,8 @@ public final void mRULE_WHITESPACE_FRAGMENT() throws RecognitionException { // $ANTLR start "RULE_LINE_TERMINATOR_FRAGMENT" public final void mRULE_LINE_TERMINATOR_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:2183:40: ( ( '\\n' | '\\r' | '\\u2028' | '\\u2029' ) ) - // InternalSemver.g:2183:42: ( '\\n' | '\\r' | '\\u2028' | '\\u2029' ) + // InternalSemver.g:2451:40: ( ( '\\n' | '\\r' | '\\u2028' | '\\u2029' ) ) + // InternalSemver.g:2451:42: ( '\\n' | '\\r' | '\\u2028' | '\\u2029' ) { if ( input.LA(1)=='\n'||input.LA(1)=='\r'||(input.LA(1)>='\u2028' && input.LA(1)<='\u2029') ) { input.consume(); @@ -1028,10 +1202,10 @@ public final void mRULE_LINE_TERMINATOR_FRAGMENT() throws RecognitionException { // $ANTLR start "RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT" public final void mRULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:2185:49: ( ( '\\n' | '\\r' ( '\\n' )? | '\\u2028' | '\\u2029' ) ) - // InternalSemver.g:2185:51: ( '\\n' | '\\r' ( '\\n' )? | '\\u2028' | '\\u2029' ) + // InternalSemver.g:2453:49: ( ( '\\n' | '\\r' ( '\\n' )? | '\\u2028' | '\\u2029' ) ) + // InternalSemver.g:2453:51: ( '\\n' | '\\r' ( '\\n' )? | '\\u2028' | '\\u2029' ) { - // InternalSemver.g:2185:51: ( '\\n' | '\\r' ( '\\n' )? | '\\u2028' | '\\u2029' ) + // InternalSemver.g:2453:51: ( '\\n' | '\\r' ( '\\n' )? | '\\u2028' | '\\u2029' ) int alt6=4; switch ( input.LA(1) ) { case '\n': @@ -1063,17 +1237,17 @@ public final void mRULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT() throws RecognitionEx switch (alt6) { case 1 : - // InternalSemver.g:2185:52: '\\n' + // InternalSemver.g:2453:52: '\\n' { match('\n'); } break; case 2 : - // InternalSemver.g:2185:57: '\\r' ( '\\n' )? + // InternalSemver.g:2453:57: '\\r' ( '\\n' )? { match('\r'); - // InternalSemver.g:2185:62: ( '\\n' )? + // InternalSemver.g:2453:62: ( '\\n' )? int alt5=2; int LA5_0 = input.LA(1); @@ -1082,7 +1256,7 @@ public final void mRULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT() throws RecognitionEx } switch (alt5) { case 1 : - // InternalSemver.g:2185:62: '\\n' + // InternalSemver.g:2453:62: '\\n' { match('\n'); @@ -1095,14 +1269,14 @@ public final void mRULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT() throws RecognitionEx } break; case 3 : - // InternalSemver.g:2185:68: '\\u2028' + // InternalSemver.g:2453:68: '\\u2028' { match('\u2028'); } break; case 4 : - // InternalSemver.g:2185:77: '\\u2029' + // InternalSemver.g:2453:77: '\\u2029' { match('\u2029'); @@ -1123,12 +1297,12 @@ public final void mRULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT() throws RecognitionEx // $ANTLR start "RULE_SL_COMMENT_FRAGMENT" public final void mRULE_SL_COMMENT_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:2187:35: ( '//' (~ ( RULE_LINE_TERMINATOR_FRAGMENT ) )* ) - // InternalSemver.g:2187:37: '//' (~ ( RULE_LINE_TERMINATOR_FRAGMENT ) )* + // InternalSemver.g:2455:35: ( '//' (~ ( RULE_LINE_TERMINATOR_FRAGMENT ) )* ) + // InternalSemver.g:2455:37: '//' (~ ( RULE_LINE_TERMINATOR_FRAGMENT ) )* { match("//"); - // InternalSemver.g:2187:42: (~ ( RULE_LINE_TERMINATOR_FRAGMENT ) )* + // InternalSemver.g:2455:42: (~ ( RULE_LINE_TERMINATOR_FRAGMENT ) )* loop7: do { int alt7=2; @@ -1141,7 +1315,7 @@ public final void mRULE_SL_COMMENT_FRAGMENT() throws RecognitionException { switch (alt7) { case 1 : - // InternalSemver.g:2187:42: ~ ( RULE_LINE_TERMINATOR_FRAGMENT ) + // InternalSemver.g:2455:42: ~ ( RULE_LINE_TERMINATOR_FRAGMENT ) { if ( (input.LA(1)>='\u0000' && input.LA(1)<='\t')||(input.LA(1)>='\u000B' && input.LA(1)<='\f')||(input.LA(1)>='\u000E' && input.LA(1)<='\u2027')||(input.LA(1)>='\u202A' && input.LA(1)<='\uFFFF') ) { input.consume(); @@ -1173,12 +1347,12 @@ public final void mRULE_SL_COMMENT_FRAGMENT() throws RecognitionException { // $ANTLR start "RULE_ML_COMMENT_FRAGMENT" public final void mRULE_ML_COMMENT_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:2189:35: ( '/*' ( options {greedy=false; } : . )* '*/' ) - // InternalSemver.g:2189:37: '/*' ( options {greedy=false; } : . )* '*/' + // InternalSemver.g:2457:35: ( '/*' ( options {greedy=false; } : . )* '*/' ) + // InternalSemver.g:2457:37: '/*' ( options {greedy=false; } : . )* '*/' { match("/*"); - // InternalSemver.g:2189:42: ( options {greedy=false; } : . )* + // InternalSemver.g:2457:42: ( options {greedy=false; } : . )* loop8: do { int alt8=2; @@ -1203,7 +1377,7 @@ else if ( ((LA8_0>='\u0000' && LA8_0<=')')||(LA8_0>='+' && LA8_0<='\uFFFF')) ) { switch (alt8) { case 1 : - // InternalSemver.g:2189:70: . + // InternalSemver.g:2457:70: . { matchAny(); @@ -1229,8 +1403,8 @@ else if ( ((LA8_0>='\u0000' && LA8_0<=')')||(LA8_0>='+' && LA8_0<='\uFFFF')) ) { // $ANTLR start "RULE_UNICODE_COMBINING_MARK_FRAGMENT" public final void mRULE_UNICODE_COMBINING_MARK_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:2191:47: ( ( '\\u0300' .. '\\u036F' | '\\u0483' .. '\\u0487' | '\\u0591' .. '\\u05BD' | '\\u05BF' | '\\u05C1' .. '\\u05C2' | '\\u05C4' .. '\\u05C5' | '\\u05C7' | '\\u0610' .. '\\u061A' | '\\u064B' .. '\\u065F' | '\\u0670' | '\\u06D6' .. '\\u06DC' | '\\u06DF' .. '\\u06E4' | '\\u06E7' .. '\\u06E8' | '\\u06EA' .. '\\u06ED' | '\\u0711' | '\\u0730' .. '\\u074A' | '\\u07A6' .. '\\u07B0' | '\\u07EB' .. '\\u07F3' | '\\u0816' .. '\\u0819' | '\\u081B' .. '\\u0823' | '\\u0825' .. '\\u0827' | '\\u0829' .. '\\u082D' | '\\u0859' .. '\\u085B' | '\\u08E3' .. '\\u0903' | '\\u093A' .. '\\u093C' | '\\u093E' .. '\\u094F' | '\\u0951' .. '\\u0957' | '\\u0962' .. '\\u0963' | '\\u0981' .. '\\u0983' | '\\u09BC' | '\\u09BE' .. '\\u09C4' | '\\u09C7' .. '\\u09C8' | '\\u09CB' .. '\\u09CD' | '\\u09D7' | '\\u09E2' .. '\\u09E3' | '\\u0A01' .. '\\u0A03' | '\\u0A3C' | '\\u0A3E' .. '\\u0A42' | '\\u0A47' .. '\\u0A48' | '\\u0A4B' .. '\\u0A4D' | '\\u0A51' | '\\u0A70' .. '\\u0A71' | '\\u0A75' | '\\u0A81' .. '\\u0A83' | '\\u0ABC' | '\\u0ABE' .. '\\u0AC5' | '\\u0AC7' .. '\\u0AC9' | '\\u0ACB' .. '\\u0ACD' | '\\u0AE2' .. '\\u0AE3' | '\\u0B01' .. '\\u0B03' | '\\u0B3C' | '\\u0B3E' .. '\\u0B44' | '\\u0B47' .. '\\u0B48' | '\\u0B4B' .. '\\u0B4D' | '\\u0B56' .. '\\u0B57' | '\\u0B62' .. '\\u0B63' | '\\u0B82' | '\\u0BBE' .. '\\u0BC2' | '\\u0BC6' .. '\\u0BC8' | '\\u0BCA' .. '\\u0BCD' | '\\u0BD7' | '\\u0C00' .. '\\u0C03' | '\\u0C3E' .. '\\u0C44' | '\\u0C46' .. '\\u0C48' | '\\u0C4A' .. '\\u0C4D' | '\\u0C55' .. '\\u0C56' | '\\u0C62' .. '\\u0C63' | '\\u0C81' .. '\\u0C83' | '\\u0CBC' | '\\u0CBE' .. '\\u0CC4' | '\\u0CC6' .. '\\u0CC8' | '\\u0CCA' .. '\\u0CCD' | '\\u0CD5' .. '\\u0CD6' | '\\u0CE2' .. '\\u0CE3' | '\\u0D01' .. '\\u0D03' | '\\u0D3E' .. '\\u0D44' | '\\u0D46' .. '\\u0D48' | '\\u0D4A' .. '\\u0D4D' | '\\u0D57' | '\\u0D62' .. '\\u0D63' | '\\u0D82' .. '\\u0D83' | '\\u0DCA' | '\\u0DCF' .. '\\u0DD4' | '\\u0DD6' | '\\u0DD8' .. '\\u0DDF' | '\\u0DF2' .. '\\u0DF3' | '\\u0E31' | '\\u0E34' .. '\\u0E3A' | '\\u0E47' .. '\\u0E4E' | '\\u0EB1' | '\\u0EB4' .. '\\u0EB9' | '\\u0EBB' .. '\\u0EBC' | '\\u0EC8' .. '\\u0ECD' | '\\u0F18' .. '\\u0F19' | '\\u0F35' | '\\u0F37' | '\\u0F39' | '\\u0F3E' .. '\\u0F3F' | '\\u0F71' .. '\\u0F84' | '\\u0F86' .. '\\u0F87' | '\\u0F8D' .. '\\u0F97' | '\\u0F99' .. '\\u0FBC' | '\\u0FC6' | '\\u102B' .. '\\u103E' | '\\u1056' .. '\\u1059' | '\\u105E' .. '\\u1060' | '\\u1062' .. '\\u1064' | '\\u1067' .. '\\u106D' | '\\u1071' .. '\\u1074' | '\\u1082' .. '\\u108D' | '\\u108F' | '\\u109A' .. '\\u109D' | '\\u135D' .. '\\u135F' | '\\u1712' .. '\\u1714' | '\\u1732' .. '\\u1734' | '\\u1752' .. '\\u1753' | '\\u1772' .. '\\u1773' | '\\u17B4' .. '\\u17D3' | '\\u17DD' | '\\u180B' .. '\\u180D' | '\\u18A9' | '\\u1920' .. '\\u192B' | '\\u1930' .. '\\u193B' | '\\u1A17' .. '\\u1A1B' | '\\u1A55' .. '\\u1A5E' | '\\u1A60' .. '\\u1A7C' | '\\u1A7F' | '\\u1AB0' .. '\\u1ABD' | '\\u1B00' .. '\\u1B04' | '\\u1B34' .. '\\u1B44' | '\\u1B6B' .. '\\u1B73' | '\\u1B80' .. '\\u1B82' | '\\u1BA1' .. '\\u1BAD' | '\\u1BE6' .. '\\u1BF3' | '\\u1C24' .. '\\u1C37' | '\\u1CD0' .. '\\u1CD2' | '\\u1CD4' .. '\\u1CE8' | '\\u1CED' | '\\u1CF2' .. '\\u1CF4' | '\\u1CF8' .. '\\u1CF9' | '\\u1DC0' .. '\\u1DF5' | '\\u1DFC' .. '\\u1DFF' | '\\u20D0' .. '\\u20DC' | '\\u20E1' | '\\u20E5' .. '\\u20F0' | '\\u2CEF' .. '\\u2CF1' | '\\u2D7F' | '\\u2DE0' .. '\\u2DFF' | '\\u302A' .. '\\u302F' | '\\u3099' .. '\\u309A' | '\\uA66F' | '\\uA674' .. '\\uA67D' | '\\uA69E' .. '\\uA69F' | '\\uA6F0' .. '\\uA6F1' | '\\uA802' | '\\uA806' | '\\uA80B' | '\\uA823' .. '\\uA827' | '\\uA880' .. '\\uA881' | '\\uA8B4' .. '\\uA8C4' | '\\uA8E0' .. '\\uA8F1' | '\\uA926' .. '\\uA92D' | '\\uA947' .. '\\uA953' | '\\uA980' .. '\\uA983' | '\\uA9B3' .. '\\uA9C0' | '\\uA9E5' | '\\uAA29' .. '\\uAA36' | '\\uAA43' | '\\uAA4C' .. '\\uAA4D' | '\\uAA7B' .. '\\uAA7D' | '\\uAAB0' | '\\uAAB2' .. '\\uAAB4' | '\\uAAB7' .. '\\uAAB8' | '\\uAABE' .. '\\uAABF' | '\\uAAC1' | '\\uAAEB' .. '\\uAAEF' | '\\uAAF5' .. '\\uAAF6' | '\\uABE3' .. '\\uABEA' | '\\uABEC' .. '\\uABED' | '\\uFB1E' | '\\uFE00' .. '\\uFE0F' | '\\uFE20' .. '\\uFE2F' ) ) - // InternalSemver.g:2191:49: ( '\\u0300' .. '\\u036F' | '\\u0483' .. '\\u0487' | '\\u0591' .. '\\u05BD' | '\\u05BF' | '\\u05C1' .. '\\u05C2' | '\\u05C4' .. '\\u05C5' | '\\u05C7' | '\\u0610' .. '\\u061A' | '\\u064B' .. '\\u065F' | '\\u0670' | '\\u06D6' .. '\\u06DC' | '\\u06DF' .. '\\u06E4' | '\\u06E7' .. '\\u06E8' | '\\u06EA' .. '\\u06ED' | '\\u0711' | '\\u0730' .. '\\u074A' | '\\u07A6' .. '\\u07B0' | '\\u07EB' .. '\\u07F3' | '\\u0816' .. '\\u0819' | '\\u081B' .. '\\u0823' | '\\u0825' .. '\\u0827' | '\\u0829' .. '\\u082D' | '\\u0859' .. '\\u085B' | '\\u08E3' .. '\\u0903' | '\\u093A' .. '\\u093C' | '\\u093E' .. '\\u094F' | '\\u0951' .. '\\u0957' | '\\u0962' .. '\\u0963' | '\\u0981' .. '\\u0983' | '\\u09BC' | '\\u09BE' .. '\\u09C4' | '\\u09C7' .. '\\u09C8' | '\\u09CB' .. '\\u09CD' | '\\u09D7' | '\\u09E2' .. '\\u09E3' | '\\u0A01' .. '\\u0A03' | '\\u0A3C' | '\\u0A3E' .. '\\u0A42' | '\\u0A47' .. '\\u0A48' | '\\u0A4B' .. '\\u0A4D' | '\\u0A51' | '\\u0A70' .. '\\u0A71' | '\\u0A75' | '\\u0A81' .. '\\u0A83' | '\\u0ABC' | '\\u0ABE' .. '\\u0AC5' | '\\u0AC7' .. '\\u0AC9' | '\\u0ACB' .. '\\u0ACD' | '\\u0AE2' .. '\\u0AE3' | '\\u0B01' .. '\\u0B03' | '\\u0B3C' | '\\u0B3E' .. '\\u0B44' | '\\u0B47' .. '\\u0B48' | '\\u0B4B' .. '\\u0B4D' | '\\u0B56' .. '\\u0B57' | '\\u0B62' .. '\\u0B63' | '\\u0B82' | '\\u0BBE' .. '\\u0BC2' | '\\u0BC6' .. '\\u0BC8' | '\\u0BCA' .. '\\u0BCD' | '\\u0BD7' | '\\u0C00' .. '\\u0C03' | '\\u0C3E' .. '\\u0C44' | '\\u0C46' .. '\\u0C48' | '\\u0C4A' .. '\\u0C4D' | '\\u0C55' .. '\\u0C56' | '\\u0C62' .. '\\u0C63' | '\\u0C81' .. '\\u0C83' | '\\u0CBC' | '\\u0CBE' .. '\\u0CC4' | '\\u0CC6' .. '\\u0CC8' | '\\u0CCA' .. '\\u0CCD' | '\\u0CD5' .. '\\u0CD6' | '\\u0CE2' .. '\\u0CE3' | '\\u0D01' .. '\\u0D03' | '\\u0D3E' .. '\\u0D44' | '\\u0D46' .. '\\u0D48' | '\\u0D4A' .. '\\u0D4D' | '\\u0D57' | '\\u0D62' .. '\\u0D63' | '\\u0D82' .. '\\u0D83' | '\\u0DCA' | '\\u0DCF' .. '\\u0DD4' | '\\u0DD6' | '\\u0DD8' .. '\\u0DDF' | '\\u0DF2' .. '\\u0DF3' | '\\u0E31' | '\\u0E34' .. '\\u0E3A' | '\\u0E47' .. '\\u0E4E' | '\\u0EB1' | '\\u0EB4' .. '\\u0EB9' | '\\u0EBB' .. '\\u0EBC' | '\\u0EC8' .. '\\u0ECD' | '\\u0F18' .. '\\u0F19' | '\\u0F35' | '\\u0F37' | '\\u0F39' | '\\u0F3E' .. '\\u0F3F' | '\\u0F71' .. '\\u0F84' | '\\u0F86' .. '\\u0F87' | '\\u0F8D' .. '\\u0F97' | '\\u0F99' .. '\\u0FBC' | '\\u0FC6' | '\\u102B' .. '\\u103E' | '\\u1056' .. '\\u1059' | '\\u105E' .. '\\u1060' | '\\u1062' .. '\\u1064' | '\\u1067' .. '\\u106D' | '\\u1071' .. '\\u1074' | '\\u1082' .. '\\u108D' | '\\u108F' | '\\u109A' .. '\\u109D' | '\\u135D' .. '\\u135F' | '\\u1712' .. '\\u1714' | '\\u1732' .. '\\u1734' | '\\u1752' .. '\\u1753' | '\\u1772' .. '\\u1773' | '\\u17B4' .. '\\u17D3' | '\\u17DD' | '\\u180B' .. '\\u180D' | '\\u18A9' | '\\u1920' .. '\\u192B' | '\\u1930' .. '\\u193B' | '\\u1A17' .. '\\u1A1B' | '\\u1A55' .. '\\u1A5E' | '\\u1A60' .. '\\u1A7C' | '\\u1A7F' | '\\u1AB0' .. '\\u1ABD' | '\\u1B00' .. '\\u1B04' | '\\u1B34' .. '\\u1B44' | '\\u1B6B' .. '\\u1B73' | '\\u1B80' .. '\\u1B82' | '\\u1BA1' .. '\\u1BAD' | '\\u1BE6' .. '\\u1BF3' | '\\u1C24' .. '\\u1C37' | '\\u1CD0' .. '\\u1CD2' | '\\u1CD4' .. '\\u1CE8' | '\\u1CED' | '\\u1CF2' .. '\\u1CF4' | '\\u1CF8' .. '\\u1CF9' | '\\u1DC0' .. '\\u1DF5' | '\\u1DFC' .. '\\u1DFF' | '\\u20D0' .. '\\u20DC' | '\\u20E1' | '\\u20E5' .. '\\u20F0' | '\\u2CEF' .. '\\u2CF1' | '\\u2D7F' | '\\u2DE0' .. '\\u2DFF' | '\\u302A' .. '\\u302F' | '\\u3099' .. '\\u309A' | '\\uA66F' | '\\uA674' .. '\\uA67D' | '\\uA69E' .. '\\uA69F' | '\\uA6F0' .. '\\uA6F1' | '\\uA802' | '\\uA806' | '\\uA80B' | '\\uA823' .. '\\uA827' | '\\uA880' .. '\\uA881' | '\\uA8B4' .. '\\uA8C4' | '\\uA8E0' .. '\\uA8F1' | '\\uA926' .. '\\uA92D' | '\\uA947' .. '\\uA953' | '\\uA980' .. '\\uA983' | '\\uA9B3' .. '\\uA9C0' | '\\uA9E5' | '\\uAA29' .. '\\uAA36' | '\\uAA43' | '\\uAA4C' .. '\\uAA4D' | '\\uAA7B' .. '\\uAA7D' | '\\uAAB0' | '\\uAAB2' .. '\\uAAB4' | '\\uAAB7' .. '\\uAAB8' | '\\uAABE' .. '\\uAABF' | '\\uAAC1' | '\\uAAEB' .. '\\uAAEF' | '\\uAAF5' .. '\\uAAF6' | '\\uABE3' .. '\\uABEA' | '\\uABEC' .. '\\uABED' | '\\uFB1E' | '\\uFE00' .. '\\uFE0F' | '\\uFE20' .. '\\uFE2F' ) + // InternalSemver.g:2459:47: ( ( '\\u0300' .. '\\u036F' | '\\u0483' .. '\\u0487' | '\\u0591' .. '\\u05BD' | '\\u05BF' | '\\u05C1' .. '\\u05C2' | '\\u05C4' .. '\\u05C5' | '\\u05C7' | '\\u0610' .. '\\u061A' | '\\u064B' .. '\\u065F' | '\\u0670' | '\\u06D6' .. '\\u06DC' | '\\u06DF' .. '\\u06E4' | '\\u06E7' .. '\\u06E8' | '\\u06EA' .. '\\u06ED' | '\\u0711' | '\\u0730' .. '\\u074A' | '\\u07A6' .. '\\u07B0' | '\\u07EB' .. '\\u07F3' | '\\u0816' .. '\\u0819' | '\\u081B' .. '\\u0823' | '\\u0825' .. '\\u0827' | '\\u0829' .. '\\u082D' | '\\u0859' .. '\\u085B' | '\\u08E3' .. '\\u0903' | '\\u093A' .. '\\u093C' | '\\u093E' .. '\\u094F' | '\\u0951' .. '\\u0957' | '\\u0962' .. '\\u0963' | '\\u0981' .. '\\u0983' | '\\u09BC' | '\\u09BE' .. '\\u09C4' | '\\u09C7' .. '\\u09C8' | '\\u09CB' .. '\\u09CD' | '\\u09D7' | '\\u09E2' .. '\\u09E3' | '\\u0A01' .. '\\u0A03' | '\\u0A3C' | '\\u0A3E' .. '\\u0A42' | '\\u0A47' .. '\\u0A48' | '\\u0A4B' .. '\\u0A4D' | '\\u0A51' | '\\u0A70' .. '\\u0A71' | '\\u0A75' | '\\u0A81' .. '\\u0A83' | '\\u0ABC' | '\\u0ABE' .. '\\u0AC5' | '\\u0AC7' .. '\\u0AC9' | '\\u0ACB' .. '\\u0ACD' | '\\u0AE2' .. '\\u0AE3' | '\\u0B01' .. '\\u0B03' | '\\u0B3C' | '\\u0B3E' .. '\\u0B44' | '\\u0B47' .. '\\u0B48' | '\\u0B4B' .. '\\u0B4D' | '\\u0B56' .. '\\u0B57' | '\\u0B62' .. '\\u0B63' | '\\u0B82' | '\\u0BBE' .. '\\u0BC2' | '\\u0BC6' .. '\\u0BC8' | '\\u0BCA' .. '\\u0BCD' | '\\u0BD7' | '\\u0C00' .. '\\u0C03' | '\\u0C3E' .. '\\u0C44' | '\\u0C46' .. '\\u0C48' | '\\u0C4A' .. '\\u0C4D' | '\\u0C55' .. '\\u0C56' | '\\u0C62' .. '\\u0C63' | '\\u0C81' .. '\\u0C83' | '\\u0CBC' | '\\u0CBE' .. '\\u0CC4' | '\\u0CC6' .. '\\u0CC8' | '\\u0CCA' .. '\\u0CCD' | '\\u0CD5' .. '\\u0CD6' | '\\u0CE2' .. '\\u0CE3' | '\\u0D01' .. '\\u0D03' | '\\u0D3E' .. '\\u0D44' | '\\u0D46' .. '\\u0D48' | '\\u0D4A' .. '\\u0D4D' | '\\u0D57' | '\\u0D62' .. '\\u0D63' | '\\u0D82' .. '\\u0D83' | '\\u0DCA' | '\\u0DCF' .. '\\u0DD4' | '\\u0DD6' | '\\u0DD8' .. '\\u0DDF' | '\\u0DF2' .. '\\u0DF3' | '\\u0E31' | '\\u0E34' .. '\\u0E3A' | '\\u0E47' .. '\\u0E4E' | '\\u0EB1' | '\\u0EB4' .. '\\u0EB9' | '\\u0EBB' .. '\\u0EBC' | '\\u0EC8' .. '\\u0ECD' | '\\u0F18' .. '\\u0F19' | '\\u0F35' | '\\u0F37' | '\\u0F39' | '\\u0F3E' .. '\\u0F3F' | '\\u0F71' .. '\\u0F84' | '\\u0F86' .. '\\u0F87' | '\\u0F8D' .. '\\u0F97' | '\\u0F99' .. '\\u0FBC' | '\\u0FC6' | '\\u102B' .. '\\u103E' | '\\u1056' .. '\\u1059' | '\\u105E' .. '\\u1060' | '\\u1062' .. '\\u1064' | '\\u1067' .. '\\u106D' | '\\u1071' .. '\\u1074' | '\\u1082' .. '\\u108D' | '\\u108F' | '\\u109A' .. '\\u109D' | '\\u135D' .. '\\u135F' | '\\u1712' .. '\\u1714' | '\\u1732' .. '\\u1734' | '\\u1752' .. '\\u1753' | '\\u1772' .. '\\u1773' | '\\u17B4' .. '\\u17D3' | '\\u17DD' | '\\u180B' .. '\\u180D' | '\\u18A9' | '\\u1920' .. '\\u192B' | '\\u1930' .. '\\u193B' | '\\u1A17' .. '\\u1A1B' | '\\u1A55' .. '\\u1A5E' | '\\u1A60' .. '\\u1A7C' | '\\u1A7F' | '\\u1AB0' .. '\\u1ABD' | '\\u1B00' .. '\\u1B04' | '\\u1B34' .. '\\u1B44' | '\\u1B6B' .. '\\u1B73' | '\\u1B80' .. '\\u1B82' | '\\u1BA1' .. '\\u1BAD' | '\\u1BE6' .. '\\u1BF3' | '\\u1C24' .. '\\u1C37' | '\\u1CD0' .. '\\u1CD2' | '\\u1CD4' .. '\\u1CE8' | '\\u1CED' | '\\u1CF2' .. '\\u1CF4' | '\\u1CF8' .. '\\u1CF9' | '\\u1DC0' .. '\\u1DF5' | '\\u1DFC' .. '\\u1DFF' | '\\u20D0' .. '\\u20DC' | '\\u20E1' | '\\u20E5' .. '\\u20F0' | '\\u2CEF' .. '\\u2CF1' | '\\u2D7F' | '\\u2DE0' .. '\\u2DFF' | '\\u302A' .. '\\u302F' | '\\u3099' .. '\\u309A' | '\\uA66F' | '\\uA674' .. '\\uA67D' | '\\uA69E' .. '\\uA69F' | '\\uA6F0' .. '\\uA6F1' | '\\uA802' | '\\uA806' | '\\uA80B' | '\\uA823' .. '\\uA827' | '\\uA880' .. '\\uA881' | '\\uA8B4' .. '\\uA8C4' | '\\uA8E0' .. '\\uA8F1' | '\\uA926' .. '\\uA92D' | '\\uA947' .. '\\uA953' | '\\uA980' .. '\\uA983' | '\\uA9B3' .. '\\uA9C0' | '\\uA9E5' | '\\uAA29' .. '\\uAA36' | '\\uAA43' | '\\uAA4C' .. '\\uAA4D' | '\\uAA7B' .. '\\uAA7D' | '\\uAAB0' | '\\uAAB2' .. '\\uAAB4' | '\\uAAB7' .. '\\uAAB8' | '\\uAABE' .. '\\uAABF' | '\\uAAC1' | '\\uAAEB' .. '\\uAAEF' | '\\uAAF5' .. '\\uAAF6' | '\\uABE3' .. '\\uABEA' | '\\uABEC' .. '\\uABED' | '\\uFB1E' | '\\uFE00' .. '\\uFE0F' | '\\uFE20' .. '\\uFE2F' ) ) + // InternalSemver.g:2459:49: ( '\\u0300' .. '\\u036F' | '\\u0483' .. '\\u0487' | '\\u0591' .. '\\u05BD' | '\\u05BF' | '\\u05C1' .. '\\u05C2' | '\\u05C4' .. '\\u05C5' | '\\u05C7' | '\\u0610' .. '\\u061A' | '\\u064B' .. '\\u065F' | '\\u0670' | '\\u06D6' .. '\\u06DC' | '\\u06DF' .. '\\u06E4' | '\\u06E7' .. '\\u06E8' | '\\u06EA' .. '\\u06ED' | '\\u0711' | '\\u0730' .. '\\u074A' | '\\u07A6' .. '\\u07B0' | '\\u07EB' .. '\\u07F3' | '\\u0816' .. '\\u0819' | '\\u081B' .. '\\u0823' | '\\u0825' .. '\\u0827' | '\\u0829' .. '\\u082D' | '\\u0859' .. '\\u085B' | '\\u08E3' .. '\\u0903' | '\\u093A' .. '\\u093C' | '\\u093E' .. '\\u094F' | '\\u0951' .. '\\u0957' | '\\u0962' .. '\\u0963' | '\\u0981' .. '\\u0983' | '\\u09BC' | '\\u09BE' .. '\\u09C4' | '\\u09C7' .. '\\u09C8' | '\\u09CB' .. '\\u09CD' | '\\u09D7' | '\\u09E2' .. '\\u09E3' | '\\u0A01' .. '\\u0A03' | '\\u0A3C' | '\\u0A3E' .. '\\u0A42' | '\\u0A47' .. '\\u0A48' | '\\u0A4B' .. '\\u0A4D' | '\\u0A51' | '\\u0A70' .. '\\u0A71' | '\\u0A75' | '\\u0A81' .. '\\u0A83' | '\\u0ABC' | '\\u0ABE' .. '\\u0AC5' | '\\u0AC7' .. '\\u0AC9' | '\\u0ACB' .. '\\u0ACD' | '\\u0AE2' .. '\\u0AE3' | '\\u0B01' .. '\\u0B03' | '\\u0B3C' | '\\u0B3E' .. '\\u0B44' | '\\u0B47' .. '\\u0B48' | '\\u0B4B' .. '\\u0B4D' | '\\u0B56' .. '\\u0B57' | '\\u0B62' .. '\\u0B63' | '\\u0B82' | '\\u0BBE' .. '\\u0BC2' | '\\u0BC6' .. '\\u0BC8' | '\\u0BCA' .. '\\u0BCD' | '\\u0BD7' | '\\u0C00' .. '\\u0C03' | '\\u0C3E' .. '\\u0C44' | '\\u0C46' .. '\\u0C48' | '\\u0C4A' .. '\\u0C4D' | '\\u0C55' .. '\\u0C56' | '\\u0C62' .. '\\u0C63' | '\\u0C81' .. '\\u0C83' | '\\u0CBC' | '\\u0CBE' .. '\\u0CC4' | '\\u0CC6' .. '\\u0CC8' | '\\u0CCA' .. '\\u0CCD' | '\\u0CD5' .. '\\u0CD6' | '\\u0CE2' .. '\\u0CE3' | '\\u0D01' .. '\\u0D03' | '\\u0D3E' .. '\\u0D44' | '\\u0D46' .. '\\u0D48' | '\\u0D4A' .. '\\u0D4D' | '\\u0D57' | '\\u0D62' .. '\\u0D63' | '\\u0D82' .. '\\u0D83' | '\\u0DCA' | '\\u0DCF' .. '\\u0DD4' | '\\u0DD6' | '\\u0DD8' .. '\\u0DDF' | '\\u0DF2' .. '\\u0DF3' | '\\u0E31' | '\\u0E34' .. '\\u0E3A' | '\\u0E47' .. '\\u0E4E' | '\\u0EB1' | '\\u0EB4' .. '\\u0EB9' | '\\u0EBB' .. '\\u0EBC' | '\\u0EC8' .. '\\u0ECD' | '\\u0F18' .. '\\u0F19' | '\\u0F35' | '\\u0F37' | '\\u0F39' | '\\u0F3E' .. '\\u0F3F' | '\\u0F71' .. '\\u0F84' | '\\u0F86' .. '\\u0F87' | '\\u0F8D' .. '\\u0F97' | '\\u0F99' .. '\\u0FBC' | '\\u0FC6' | '\\u102B' .. '\\u103E' | '\\u1056' .. '\\u1059' | '\\u105E' .. '\\u1060' | '\\u1062' .. '\\u1064' | '\\u1067' .. '\\u106D' | '\\u1071' .. '\\u1074' | '\\u1082' .. '\\u108D' | '\\u108F' | '\\u109A' .. '\\u109D' | '\\u135D' .. '\\u135F' | '\\u1712' .. '\\u1714' | '\\u1732' .. '\\u1734' | '\\u1752' .. '\\u1753' | '\\u1772' .. '\\u1773' | '\\u17B4' .. '\\u17D3' | '\\u17DD' | '\\u180B' .. '\\u180D' | '\\u18A9' | '\\u1920' .. '\\u192B' | '\\u1930' .. '\\u193B' | '\\u1A17' .. '\\u1A1B' | '\\u1A55' .. '\\u1A5E' | '\\u1A60' .. '\\u1A7C' | '\\u1A7F' | '\\u1AB0' .. '\\u1ABD' | '\\u1B00' .. '\\u1B04' | '\\u1B34' .. '\\u1B44' | '\\u1B6B' .. '\\u1B73' | '\\u1B80' .. '\\u1B82' | '\\u1BA1' .. '\\u1BAD' | '\\u1BE6' .. '\\u1BF3' | '\\u1C24' .. '\\u1C37' | '\\u1CD0' .. '\\u1CD2' | '\\u1CD4' .. '\\u1CE8' | '\\u1CED' | '\\u1CF2' .. '\\u1CF4' | '\\u1CF8' .. '\\u1CF9' | '\\u1DC0' .. '\\u1DF5' | '\\u1DFC' .. '\\u1DFF' | '\\u20D0' .. '\\u20DC' | '\\u20E1' | '\\u20E5' .. '\\u20F0' | '\\u2CEF' .. '\\u2CF1' | '\\u2D7F' | '\\u2DE0' .. '\\u2DFF' | '\\u302A' .. '\\u302F' | '\\u3099' .. '\\u309A' | '\\uA66F' | '\\uA674' .. '\\uA67D' | '\\uA69E' .. '\\uA69F' | '\\uA6F0' .. '\\uA6F1' | '\\uA802' | '\\uA806' | '\\uA80B' | '\\uA823' .. '\\uA827' | '\\uA880' .. '\\uA881' | '\\uA8B4' .. '\\uA8C4' | '\\uA8E0' .. '\\uA8F1' | '\\uA926' .. '\\uA92D' | '\\uA947' .. '\\uA953' | '\\uA980' .. '\\uA983' | '\\uA9B3' .. '\\uA9C0' | '\\uA9E5' | '\\uAA29' .. '\\uAA36' | '\\uAA43' | '\\uAA4C' .. '\\uAA4D' | '\\uAA7B' .. '\\uAA7D' | '\\uAAB0' | '\\uAAB2' .. '\\uAAB4' | '\\uAAB7' .. '\\uAAB8' | '\\uAABE' .. '\\uAABF' | '\\uAAC1' | '\\uAAEB' .. '\\uAAEF' | '\\uAAF5' .. '\\uAAF6' | '\\uABE3' .. '\\uABEA' | '\\uABEC' .. '\\uABED' | '\\uFB1E' | '\\uFE00' .. '\\uFE0F' | '\\uFE20' .. '\\uFE2F' ) { if ( (input.LA(1)>='\u0300' && input.LA(1)<='\u036F')||(input.LA(1)>='\u0483' && input.LA(1)<='\u0487')||(input.LA(1)>='\u0591' && input.LA(1)<='\u05BD')||input.LA(1)=='\u05BF'||(input.LA(1)>='\u05C1' && input.LA(1)<='\u05C2')||(input.LA(1)>='\u05C4' && input.LA(1)<='\u05C5')||input.LA(1)=='\u05C7'||(input.LA(1)>='\u0610' && input.LA(1)<='\u061A')||(input.LA(1)>='\u064B' && input.LA(1)<='\u065F')||input.LA(1)=='\u0670'||(input.LA(1)>='\u06D6' && input.LA(1)<='\u06DC')||(input.LA(1)>='\u06DF' && input.LA(1)<='\u06E4')||(input.LA(1)>='\u06E7' && input.LA(1)<='\u06E8')||(input.LA(1)>='\u06EA' && input.LA(1)<='\u06ED')||input.LA(1)=='\u0711'||(input.LA(1)>='\u0730' && input.LA(1)<='\u074A')||(input.LA(1)>='\u07A6' && input.LA(1)<='\u07B0')||(input.LA(1)>='\u07EB' && input.LA(1)<='\u07F3')||(input.LA(1)>='\u0816' && input.LA(1)<='\u0819')||(input.LA(1)>='\u081B' && input.LA(1)<='\u0823')||(input.LA(1)>='\u0825' && input.LA(1)<='\u0827')||(input.LA(1)>='\u0829' && input.LA(1)<='\u082D')||(input.LA(1)>='\u0859' && input.LA(1)<='\u085B')||(input.LA(1)>='\u08E3' && input.LA(1)<='\u0903')||(input.LA(1)>='\u093A' && input.LA(1)<='\u093C')||(input.LA(1)>='\u093E' && input.LA(1)<='\u094F')||(input.LA(1)>='\u0951' && input.LA(1)<='\u0957')||(input.LA(1)>='\u0962' && input.LA(1)<='\u0963')||(input.LA(1)>='\u0981' && input.LA(1)<='\u0983')||input.LA(1)=='\u09BC'||(input.LA(1)>='\u09BE' && input.LA(1)<='\u09C4')||(input.LA(1)>='\u09C7' && input.LA(1)<='\u09C8')||(input.LA(1)>='\u09CB' && input.LA(1)<='\u09CD')||input.LA(1)=='\u09D7'||(input.LA(1)>='\u09E2' && input.LA(1)<='\u09E3')||(input.LA(1)>='\u0A01' && input.LA(1)<='\u0A03')||input.LA(1)=='\u0A3C'||(input.LA(1)>='\u0A3E' && input.LA(1)<='\u0A42')||(input.LA(1)>='\u0A47' && input.LA(1)<='\u0A48')||(input.LA(1)>='\u0A4B' && input.LA(1)<='\u0A4D')||input.LA(1)=='\u0A51'||(input.LA(1)>='\u0A70' && input.LA(1)<='\u0A71')||input.LA(1)=='\u0A75'||(input.LA(1)>='\u0A81' && input.LA(1)<='\u0A83')||input.LA(1)=='\u0ABC'||(input.LA(1)>='\u0ABE' && input.LA(1)<='\u0AC5')||(input.LA(1)>='\u0AC7' && input.LA(1)<='\u0AC9')||(input.LA(1)>='\u0ACB' && input.LA(1)<='\u0ACD')||(input.LA(1)>='\u0AE2' && input.LA(1)<='\u0AE3')||(input.LA(1)>='\u0B01' && input.LA(1)<='\u0B03')||input.LA(1)=='\u0B3C'||(input.LA(1)>='\u0B3E' && input.LA(1)<='\u0B44')||(input.LA(1)>='\u0B47' && input.LA(1)<='\u0B48')||(input.LA(1)>='\u0B4B' && input.LA(1)<='\u0B4D')||(input.LA(1)>='\u0B56' && input.LA(1)<='\u0B57')||(input.LA(1)>='\u0B62' && input.LA(1)<='\u0B63')||input.LA(1)=='\u0B82'||(input.LA(1)>='\u0BBE' && input.LA(1)<='\u0BC2')||(input.LA(1)>='\u0BC6' && input.LA(1)<='\u0BC8')||(input.LA(1)>='\u0BCA' && input.LA(1)<='\u0BCD')||input.LA(1)=='\u0BD7'||(input.LA(1)>='\u0C00' && input.LA(1)<='\u0C03')||(input.LA(1)>='\u0C3E' && input.LA(1)<='\u0C44')||(input.LA(1)>='\u0C46' && input.LA(1)<='\u0C48')||(input.LA(1)>='\u0C4A' && input.LA(1)<='\u0C4D')||(input.LA(1)>='\u0C55' && input.LA(1)<='\u0C56')||(input.LA(1)>='\u0C62' && input.LA(1)<='\u0C63')||(input.LA(1)>='\u0C81' && input.LA(1)<='\u0C83')||input.LA(1)=='\u0CBC'||(input.LA(1)>='\u0CBE' && input.LA(1)<='\u0CC4')||(input.LA(1)>='\u0CC6' && input.LA(1)<='\u0CC8')||(input.LA(1)>='\u0CCA' && input.LA(1)<='\u0CCD')||(input.LA(1)>='\u0CD5' && input.LA(1)<='\u0CD6')||(input.LA(1)>='\u0CE2' && input.LA(1)<='\u0CE3')||(input.LA(1)>='\u0D01' && input.LA(1)<='\u0D03')||(input.LA(1)>='\u0D3E' && input.LA(1)<='\u0D44')||(input.LA(1)>='\u0D46' && input.LA(1)<='\u0D48')||(input.LA(1)>='\u0D4A' && input.LA(1)<='\u0D4D')||input.LA(1)=='\u0D57'||(input.LA(1)>='\u0D62' && input.LA(1)<='\u0D63')||(input.LA(1)>='\u0D82' && input.LA(1)<='\u0D83')||input.LA(1)=='\u0DCA'||(input.LA(1)>='\u0DCF' && input.LA(1)<='\u0DD4')||input.LA(1)=='\u0DD6'||(input.LA(1)>='\u0DD8' && input.LA(1)<='\u0DDF')||(input.LA(1)>='\u0DF2' && input.LA(1)<='\u0DF3')||input.LA(1)=='\u0E31'||(input.LA(1)>='\u0E34' && input.LA(1)<='\u0E3A')||(input.LA(1)>='\u0E47' && input.LA(1)<='\u0E4E')||input.LA(1)=='\u0EB1'||(input.LA(1)>='\u0EB4' && input.LA(1)<='\u0EB9')||(input.LA(1)>='\u0EBB' && input.LA(1)<='\u0EBC')||(input.LA(1)>='\u0EC8' && input.LA(1)<='\u0ECD')||(input.LA(1)>='\u0F18' && input.LA(1)<='\u0F19')||input.LA(1)=='\u0F35'||input.LA(1)=='\u0F37'||input.LA(1)=='\u0F39'||(input.LA(1)>='\u0F3E' && input.LA(1)<='\u0F3F')||(input.LA(1)>='\u0F71' && input.LA(1)<='\u0F84')||(input.LA(1)>='\u0F86' && input.LA(1)<='\u0F87')||(input.LA(1)>='\u0F8D' && input.LA(1)<='\u0F97')||(input.LA(1)>='\u0F99' && input.LA(1)<='\u0FBC')||input.LA(1)=='\u0FC6'||(input.LA(1)>='\u102B' && input.LA(1)<='\u103E')||(input.LA(1)>='\u1056' && input.LA(1)<='\u1059')||(input.LA(1)>='\u105E' && input.LA(1)<='\u1060')||(input.LA(1)>='\u1062' && input.LA(1)<='\u1064')||(input.LA(1)>='\u1067' && input.LA(1)<='\u106D')||(input.LA(1)>='\u1071' && input.LA(1)<='\u1074')||(input.LA(1)>='\u1082' && input.LA(1)<='\u108D')||input.LA(1)=='\u108F'||(input.LA(1)>='\u109A' && input.LA(1)<='\u109D')||(input.LA(1)>='\u135D' && input.LA(1)<='\u135F')||(input.LA(1)>='\u1712' && input.LA(1)<='\u1714')||(input.LA(1)>='\u1732' && input.LA(1)<='\u1734')||(input.LA(1)>='\u1752' && input.LA(1)<='\u1753')||(input.LA(1)>='\u1772' && input.LA(1)<='\u1773')||(input.LA(1)>='\u17B4' && input.LA(1)<='\u17D3')||input.LA(1)=='\u17DD'||(input.LA(1)>='\u180B' && input.LA(1)<='\u180D')||input.LA(1)=='\u18A9'||(input.LA(1)>='\u1920' && input.LA(1)<='\u192B')||(input.LA(1)>='\u1930' && input.LA(1)<='\u193B')||(input.LA(1)>='\u1A17' && input.LA(1)<='\u1A1B')||(input.LA(1)>='\u1A55' && input.LA(1)<='\u1A5E')||(input.LA(1)>='\u1A60' && input.LA(1)<='\u1A7C')||input.LA(1)=='\u1A7F'||(input.LA(1)>='\u1AB0' && input.LA(1)<='\u1ABD')||(input.LA(1)>='\u1B00' && input.LA(1)<='\u1B04')||(input.LA(1)>='\u1B34' && input.LA(1)<='\u1B44')||(input.LA(1)>='\u1B6B' && input.LA(1)<='\u1B73')||(input.LA(1)>='\u1B80' && input.LA(1)<='\u1B82')||(input.LA(1)>='\u1BA1' && input.LA(1)<='\u1BAD')||(input.LA(1)>='\u1BE6' && input.LA(1)<='\u1BF3')||(input.LA(1)>='\u1C24' && input.LA(1)<='\u1C37')||(input.LA(1)>='\u1CD0' && input.LA(1)<='\u1CD2')||(input.LA(1)>='\u1CD4' && input.LA(1)<='\u1CE8')||input.LA(1)=='\u1CED'||(input.LA(1)>='\u1CF2' && input.LA(1)<='\u1CF4')||(input.LA(1)>='\u1CF8' && input.LA(1)<='\u1CF9')||(input.LA(1)>='\u1DC0' && input.LA(1)<='\u1DF5')||(input.LA(1)>='\u1DFC' && input.LA(1)<='\u1DFF')||(input.LA(1)>='\u20D0' && input.LA(1)<='\u20DC')||input.LA(1)=='\u20E1'||(input.LA(1)>='\u20E5' && input.LA(1)<='\u20F0')||(input.LA(1)>='\u2CEF' && input.LA(1)<='\u2CF1')||input.LA(1)=='\u2D7F'||(input.LA(1)>='\u2DE0' && input.LA(1)<='\u2DFF')||(input.LA(1)>='\u302A' && input.LA(1)<='\u302F')||(input.LA(1)>='\u3099' && input.LA(1)<='\u309A')||input.LA(1)=='\uA66F'||(input.LA(1)>='\uA674' && input.LA(1)<='\uA67D')||(input.LA(1)>='\uA69E' && input.LA(1)<='\uA69F')||(input.LA(1)>='\uA6F0' && input.LA(1)<='\uA6F1')||input.LA(1)=='\uA802'||input.LA(1)=='\uA806'||input.LA(1)=='\uA80B'||(input.LA(1)>='\uA823' && input.LA(1)<='\uA827')||(input.LA(1)>='\uA880' && input.LA(1)<='\uA881')||(input.LA(1)>='\uA8B4' && input.LA(1)<='\uA8C4')||(input.LA(1)>='\uA8E0' && input.LA(1)<='\uA8F1')||(input.LA(1)>='\uA926' && input.LA(1)<='\uA92D')||(input.LA(1)>='\uA947' && input.LA(1)<='\uA953')||(input.LA(1)>='\uA980' && input.LA(1)<='\uA983')||(input.LA(1)>='\uA9B3' && input.LA(1)<='\uA9C0')||input.LA(1)=='\uA9E5'||(input.LA(1)>='\uAA29' && input.LA(1)<='\uAA36')||input.LA(1)=='\uAA43'||(input.LA(1)>='\uAA4C' && input.LA(1)<='\uAA4D')||(input.LA(1)>='\uAA7B' && input.LA(1)<='\uAA7D')||input.LA(1)=='\uAAB0'||(input.LA(1)>='\uAAB2' && input.LA(1)<='\uAAB4')||(input.LA(1)>='\uAAB7' && input.LA(1)<='\uAAB8')||(input.LA(1)>='\uAABE' && input.LA(1)<='\uAABF')||input.LA(1)=='\uAAC1'||(input.LA(1)>='\uAAEB' && input.LA(1)<='\uAAEF')||(input.LA(1)>='\uAAF5' && input.LA(1)<='\uAAF6')||(input.LA(1)>='\uABE3' && input.LA(1)<='\uABEA')||(input.LA(1)>='\uABEC' && input.LA(1)<='\uABED')||input.LA(1)=='\uFB1E'||(input.LA(1)>='\uFE00' && input.LA(1)<='\uFE0F')||(input.LA(1)>='\uFE20' && input.LA(1)<='\uFE2F') ) { input.consume(); @@ -1253,8 +1427,8 @@ public final void mRULE_UNICODE_COMBINING_MARK_FRAGMENT() throws RecognitionExce // $ANTLR start "RULE_UNICODE_DIGIT_FRAGMENT" public final void mRULE_UNICODE_DIGIT_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:2193:38: ( ( '0' .. '9' | '\\u0660' .. '\\u0669' | '\\u06F0' .. '\\u06F9' | '\\u07C0' .. '\\u07C9' | '\\u0966' .. '\\u096F' | '\\u09E6' .. '\\u09EF' | '\\u0A66' .. '\\u0A6F' | '\\u0AE6' .. '\\u0AEF' | '\\u0B66' .. '\\u0B6F' | '\\u0BE6' .. '\\u0BEF' | '\\u0C66' .. '\\u0C6F' | '\\u0CE6' .. '\\u0CEF' | '\\u0D66' .. '\\u0D6F' | '\\u0DE6' .. '\\u0DEF' | '\\u0E50' .. '\\u0E59' | '\\u0ED0' .. '\\u0ED9' | '\\u0F20' .. '\\u0F29' | '\\u1040' .. '\\u1049' | '\\u1090' .. '\\u1099' | '\\u17E0' .. '\\u17E9' | '\\u1810' .. '\\u1819' | '\\u1946' .. '\\u194F' | '\\u19D0' .. '\\u19D9' | '\\u1A80' .. '\\u1A89' | '\\u1A90' .. '\\u1A99' | '\\u1B50' .. '\\u1B59' | '\\u1BB0' .. '\\u1BB9' | '\\u1C40' .. '\\u1C49' | '\\u1C50' .. '\\u1C59' | '\\uA620' .. '\\uA629' | '\\uA8D0' .. '\\uA8D9' | '\\uA900' .. '\\uA909' | '\\uA9D0' .. '\\uA9D9' | '\\uA9F0' .. '\\uA9F9' | '\\uAA50' .. '\\uAA59' | '\\uABF0' .. '\\uABF9' | '\\uFF10' .. '\\uFF19' ) ) - // InternalSemver.g:2193:40: ( '0' .. '9' | '\\u0660' .. '\\u0669' | '\\u06F0' .. '\\u06F9' | '\\u07C0' .. '\\u07C9' | '\\u0966' .. '\\u096F' | '\\u09E6' .. '\\u09EF' | '\\u0A66' .. '\\u0A6F' | '\\u0AE6' .. '\\u0AEF' | '\\u0B66' .. '\\u0B6F' | '\\u0BE6' .. '\\u0BEF' | '\\u0C66' .. '\\u0C6F' | '\\u0CE6' .. '\\u0CEF' | '\\u0D66' .. '\\u0D6F' | '\\u0DE6' .. '\\u0DEF' | '\\u0E50' .. '\\u0E59' | '\\u0ED0' .. '\\u0ED9' | '\\u0F20' .. '\\u0F29' | '\\u1040' .. '\\u1049' | '\\u1090' .. '\\u1099' | '\\u17E0' .. '\\u17E9' | '\\u1810' .. '\\u1819' | '\\u1946' .. '\\u194F' | '\\u19D0' .. '\\u19D9' | '\\u1A80' .. '\\u1A89' | '\\u1A90' .. '\\u1A99' | '\\u1B50' .. '\\u1B59' | '\\u1BB0' .. '\\u1BB9' | '\\u1C40' .. '\\u1C49' | '\\u1C50' .. '\\u1C59' | '\\uA620' .. '\\uA629' | '\\uA8D0' .. '\\uA8D9' | '\\uA900' .. '\\uA909' | '\\uA9D0' .. '\\uA9D9' | '\\uA9F0' .. '\\uA9F9' | '\\uAA50' .. '\\uAA59' | '\\uABF0' .. '\\uABF9' | '\\uFF10' .. '\\uFF19' ) + // InternalSemver.g:2461:38: ( ( '0' .. '9' | '\\u0660' .. '\\u0669' | '\\u06F0' .. '\\u06F9' | '\\u07C0' .. '\\u07C9' | '\\u0966' .. '\\u096F' | '\\u09E6' .. '\\u09EF' | '\\u0A66' .. '\\u0A6F' | '\\u0AE6' .. '\\u0AEF' | '\\u0B66' .. '\\u0B6F' | '\\u0BE6' .. '\\u0BEF' | '\\u0C66' .. '\\u0C6F' | '\\u0CE6' .. '\\u0CEF' | '\\u0D66' .. '\\u0D6F' | '\\u0DE6' .. '\\u0DEF' | '\\u0E50' .. '\\u0E59' | '\\u0ED0' .. '\\u0ED9' | '\\u0F20' .. '\\u0F29' | '\\u1040' .. '\\u1049' | '\\u1090' .. '\\u1099' | '\\u17E0' .. '\\u17E9' | '\\u1810' .. '\\u1819' | '\\u1946' .. '\\u194F' | '\\u19D0' .. '\\u19D9' | '\\u1A80' .. '\\u1A89' | '\\u1A90' .. '\\u1A99' | '\\u1B50' .. '\\u1B59' | '\\u1BB0' .. '\\u1BB9' | '\\u1C40' .. '\\u1C49' | '\\u1C50' .. '\\u1C59' | '\\uA620' .. '\\uA629' | '\\uA8D0' .. '\\uA8D9' | '\\uA900' .. '\\uA909' | '\\uA9D0' .. '\\uA9D9' | '\\uA9F0' .. '\\uA9F9' | '\\uAA50' .. '\\uAA59' | '\\uABF0' .. '\\uABF9' | '\\uFF10' .. '\\uFF19' ) ) + // InternalSemver.g:2461:40: ( '0' .. '9' | '\\u0660' .. '\\u0669' | '\\u06F0' .. '\\u06F9' | '\\u07C0' .. '\\u07C9' | '\\u0966' .. '\\u096F' | '\\u09E6' .. '\\u09EF' | '\\u0A66' .. '\\u0A6F' | '\\u0AE6' .. '\\u0AEF' | '\\u0B66' .. '\\u0B6F' | '\\u0BE6' .. '\\u0BEF' | '\\u0C66' .. '\\u0C6F' | '\\u0CE6' .. '\\u0CEF' | '\\u0D66' .. '\\u0D6F' | '\\u0DE6' .. '\\u0DEF' | '\\u0E50' .. '\\u0E59' | '\\u0ED0' .. '\\u0ED9' | '\\u0F20' .. '\\u0F29' | '\\u1040' .. '\\u1049' | '\\u1090' .. '\\u1099' | '\\u17E0' .. '\\u17E9' | '\\u1810' .. '\\u1819' | '\\u1946' .. '\\u194F' | '\\u19D0' .. '\\u19D9' | '\\u1A80' .. '\\u1A89' | '\\u1A90' .. '\\u1A99' | '\\u1B50' .. '\\u1B59' | '\\u1BB0' .. '\\u1BB9' | '\\u1C40' .. '\\u1C49' | '\\u1C50' .. '\\u1C59' | '\\uA620' .. '\\uA629' | '\\uA8D0' .. '\\uA8D9' | '\\uA900' .. '\\uA909' | '\\uA9D0' .. '\\uA9D9' | '\\uA9F0' .. '\\uA9F9' | '\\uAA50' .. '\\uAA59' | '\\uABF0' .. '\\uABF9' | '\\uFF10' .. '\\uFF19' ) { if ( (input.LA(1)>='0' && input.LA(1)<='9')||(input.LA(1)>='\u0660' && input.LA(1)<='\u0669')||(input.LA(1)>='\u06F0' && input.LA(1)<='\u06F9')||(input.LA(1)>='\u07C0' && input.LA(1)<='\u07C9')||(input.LA(1)>='\u0966' && input.LA(1)<='\u096F')||(input.LA(1)>='\u09E6' && input.LA(1)<='\u09EF')||(input.LA(1)>='\u0A66' && input.LA(1)<='\u0A6F')||(input.LA(1)>='\u0AE6' && input.LA(1)<='\u0AEF')||(input.LA(1)>='\u0B66' && input.LA(1)<='\u0B6F')||(input.LA(1)>='\u0BE6' && input.LA(1)<='\u0BEF')||(input.LA(1)>='\u0C66' && input.LA(1)<='\u0C6F')||(input.LA(1)>='\u0CE6' && input.LA(1)<='\u0CEF')||(input.LA(1)>='\u0D66' && input.LA(1)<='\u0D6F')||(input.LA(1)>='\u0DE6' && input.LA(1)<='\u0DEF')||(input.LA(1)>='\u0E50' && input.LA(1)<='\u0E59')||(input.LA(1)>='\u0ED0' && input.LA(1)<='\u0ED9')||(input.LA(1)>='\u0F20' && input.LA(1)<='\u0F29')||(input.LA(1)>='\u1040' && input.LA(1)<='\u1049')||(input.LA(1)>='\u1090' && input.LA(1)<='\u1099')||(input.LA(1)>='\u17E0' && input.LA(1)<='\u17E9')||(input.LA(1)>='\u1810' && input.LA(1)<='\u1819')||(input.LA(1)>='\u1946' && input.LA(1)<='\u194F')||(input.LA(1)>='\u19D0' && input.LA(1)<='\u19D9')||(input.LA(1)>='\u1A80' && input.LA(1)<='\u1A89')||(input.LA(1)>='\u1A90' && input.LA(1)<='\u1A99')||(input.LA(1)>='\u1B50' && input.LA(1)<='\u1B59')||(input.LA(1)>='\u1BB0' && input.LA(1)<='\u1BB9')||(input.LA(1)>='\u1C40' && input.LA(1)<='\u1C49')||(input.LA(1)>='\u1C50' && input.LA(1)<='\u1C59')||(input.LA(1)>='\uA620' && input.LA(1)<='\uA629')||(input.LA(1)>='\uA8D0' && input.LA(1)<='\uA8D9')||(input.LA(1)>='\uA900' && input.LA(1)<='\uA909')||(input.LA(1)>='\uA9D0' && input.LA(1)<='\uA9D9')||(input.LA(1)>='\uA9F0' && input.LA(1)<='\uA9F9')||(input.LA(1)>='\uAA50' && input.LA(1)<='\uAA59')||(input.LA(1)>='\uABF0' && input.LA(1)<='\uABF9')||(input.LA(1)>='\uFF10' && input.LA(1)<='\uFF19') ) { input.consume(); @@ -1277,8 +1451,8 @@ public final void mRULE_UNICODE_DIGIT_FRAGMENT() throws RecognitionException { // $ANTLR start "RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT" public final void mRULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:2195:54: ( ( '_' | '\\u203F' .. '\\u2040' | '\\u2054' | '\\uFE33' .. '\\uFE34' | '\\uFE4D' .. '\\uFE4F' | '\\uFF3F' ) ) - // InternalSemver.g:2195:56: ( '_' | '\\u203F' .. '\\u2040' | '\\u2054' | '\\uFE33' .. '\\uFE34' | '\\uFE4D' .. '\\uFE4F' | '\\uFF3F' ) + // InternalSemver.g:2463:54: ( ( '_' | '\\u203F' .. '\\u2040' | '\\u2054' | '\\uFE33' .. '\\uFE34' | '\\uFE4D' .. '\\uFE4F' | '\\uFF3F' ) ) + // InternalSemver.g:2463:56: ( '_' | '\\u203F' .. '\\u2040' | '\\u2054' | '\\uFE33' .. '\\uFE34' | '\\uFE4D' .. '\\uFE4F' | '\\uFF3F' ) { if ( input.LA(1)=='_'||(input.LA(1)>='\u203F' && input.LA(1)<='\u2040')||input.LA(1)=='\u2054'||(input.LA(1)>='\uFE33' && input.LA(1)<='\uFE34')||(input.LA(1)>='\uFE4D' && input.LA(1)<='\uFE4F')||input.LA(1)=='\uFF3F' ) { input.consume(); @@ -1301,8 +1475,8 @@ public final void mRULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT() throws Recognit // $ANTLR start "RULE_UNICODE_LETTER_FRAGMENT" public final void mRULE_UNICODE_LETTER_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:2197:39: ( ( 'A' .. 'Z' | 'a' .. 'z' | '\\u00AA' | '\\u00B5' | '\\u00BA' | '\\u00C0' .. '\\u00D6' | '\\u00D8' .. '\\u00F6' | '\\u00F8' .. '\\u02C1' | '\\u02C6' .. '\\u02D1' | '\\u02E0' .. '\\u02E4' | '\\u02EC' | '\\u02EE' | '\\u0370' .. '\\u0374' | '\\u0376' .. '\\u0377' | '\\u037A' .. '\\u037D' | '\\u037F' | '\\u0386' | '\\u0388' .. '\\u038A' | '\\u038C' | '\\u038E' .. '\\u03A1' | '\\u03A3' .. '\\u03F5' | '\\u03F7' .. '\\u0481' | '\\u048A' .. '\\u052F' | '\\u0531' .. '\\u0556' | '\\u0559' | '\\u0561' .. '\\u0587' | '\\u05D0' .. '\\u05EA' | '\\u05F0' .. '\\u05F2' | '\\u0620' .. '\\u064A' | '\\u066E' .. '\\u066F' | '\\u0671' .. '\\u06D3' | '\\u06D5' | '\\u06E5' .. '\\u06E6' | '\\u06EE' .. '\\u06EF' | '\\u06FA' .. '\\u06FC' | '\\u06FF' | '\\u0710' | '\\u0712' .. '\\u072F' | '\\u074D' .. '\\u07A5' | '\\u07B1' | '\\u07CA' .. '\\u07EA' | '\\u07F4' .. '\\u07F5' | '\\u07FA' | '\\u0800' .. '\\u0815' | '\\u081A' | '\\u0824' | '\\u0828' | '\\u0840' .. '\\u0858' | '\\u08A0' .. '\\u08B4' | '\\u0904' .. '\\u0939' | '\\u093D' | '\\u0950' | '\\u0958' .. '\\u0961' | '\\u0971' .. '\\u0980' | '\\u0985' .. '\\u098C' | '\\u098F' .. '\\u0990' | '\\u0993' .. '\\u09A8' | '\\u09AA' .. '\\u09B0' | '\\u09B2' | '\\u09B6' .. '\\u09B9' | '\\u09BD' | '\\u09CE' | '\\u09DC' .. '\\u09DD' | '\\u09DF' .. '\\u09E1' | '\\u09F0' .. '\\u09F1' | '\\u0A05' .. '\\u0A0A' | '\\u0A0F' .. '\\u0A10' | '\\u0A13' .. '\\u0A28' | '\\u0A2A' .. '\\u0A30' | '\\u0A32' .. '\\u0A33' | '\\u0A35' .. '\\u0A36' | '\\u0A38' .. '\\u0A39' | '\\u0A59' .. '\\u0A5C' | '\\u0A5E' | '\\u0A72' .. '\\u0A74' | '\\u0A85' .. '\\u0A8D' | '\\u0A8F' .. '\\u0A91' | '\\u0A93' .. '\\u0AA8' | '\\u0AAA' .. '\\u0AB0' | '\\u0AB2' .. '\\u0AB3' | '\\u0AB5' .. '\\u0AB9' | '\\u0ABD' | '\\u0AD0' | '\\u0AE0' .. '\\u0AE1' | '\\u0AF9' | '\\u0B05' .. '\\u0B0C' | '\\u0B0F' .. '\\u0B10' | '\\u0B13' .. '\\u0B28' | '\\u0B2A' .. '\\u0B30' | '\\u0B32' .. '\\u0B33' | '\\u0B35' .. '\\u0B39' | '\\u0B3D' | '\\u0B5C' .. '\\u0B5D' | '\\u0B5F' .. '\\u0B61' | '\\u0B71' | '\\u0B83' | '\\u0B85' .. '\\u0B8A' | '\\u0B8E' .. '\\u0B90' | '\\u0B92' .. '\\u0B95' | '\\u0B99' .. '\\u0B9A' | '\\u0B9C' | '\\u0B9E' .. '\\u0B9F' | '\\u0BA3' .. '\\u0BA4' | '\\u0BA8' .. '\\u0BAA' | '\\u0BAE' .. '\\u0BB9' | '\\u0BD0' | '\\u0C05' .. '\\u0C0C' | '\\u0C0E' .. '\\u0C10' | '\\u0C12' .. '\\u0C28' | '\\u0C2A' .. '\\u0C39' | '\\u0C3D' | '\\u0C58' .. '\\u0C5A' | '\\u0C60' .. '\\u0C61' | '\\u0C85' .. '\\u0C8C' | '\\u0C8E' .. '\\u0C90' | '\\u0C92' .. '\\u0CA8' | '\\u0CAA' .. '\\u0CB3' | '\\u0CB5' .. '\\u0CB9' | '\\u0CBD' | '\\u0CDE' | '\\u0CE0' .. '\\u0CE1' | '\\u0CF1' .. '\\u0CF2' | '\\u0D05' .. '\\u0D0C' | '\\u0D0E' .. '\\u0D10' | '\\u0D12' .. '\\u0D3A' | '\\u0D3D' | '\\u0D4E' | '\\u0D5F' .. '\\u0D61' | '\\u0D7A' .. '\\u0D7F' | '\\u0D85' .. '\\u0D96' | '\\u0D9A' .. '\\u0DB1' | '\\u0DB3' .. '\\u0DBB' | '\\u0DBD' | '\\u0DC0' .. '\\u0DC6' | '\\u0E01' .. '\\u0E30' | '\\u0E32' .. '\\u0E33' | '\\u0E40' .. '\\u0E46' | '\\u0E81' .. '\\u0E82' | '\\u0E84' | '\\u0E87' .. '\\u0E88' | '\\u0E8A' | '\\u0E8D' | '\\u0E94' .. '\\u0E97' | '\\u0E99' .. '\\u0E9F' | '\\u0EA1' .. '\\u0EA3' | '\\u0EA5' | '\\u0EA7' | '\\u0EAA' .. '\\u0EAB' | '\\u0EAD' .. '\\u0EB0' | '\\u0EB2' .. '\\u0EB3' | '\\u0EBD' | '\\u0EC0' .. '\\u0EC4' | '\\u0EC6' | '\\u0EDC' .. '\\u0EDF' | '\\u0F00' | '\\u0F40' .. '\\u0F47' | '\\u0F49' .. '\\u0F6C' | '\\u0F88' .. '\\u0F8C' | '\\u1000' .. '\\u102A' | '\\u103F' | '\\u1050' .. '\\u1055' | '\\u105A' .. '\\u105D' | '\\u1061' | '\\u1065' .. '\\u1066' | '\\u106E' .. '\\u1070' | '\\u1075' .. '\\u1081' | '\\u108E' | '\\u10A0' .. '\\u10C5' | '\\u10C7' | '\\u10CD' | '\\u10D0' .. '\\u10FA' | '\\u10FC' .. '\\u1248' | '\\u124A' .. '\\u124D' | '\\u1250' .. '\\u1256' | '\\u1258' | '\\u125A' .. '\\u125D' | '\\u1260' .. '\\u1288' | '\\u128A' .. '\\u128D' | '\\u1290' .. '\\u12B0' | '\\u12B2' .. '\\u12B5' | '\\u12B8' .. '\\u12BE' | '\\u12C0' | '\\u12C2' .. '\\u12C5' | '\\u12C8' .. '\\u12D6' | '\\u12D8' .. '\\u1310' | '\\u1312' .. '\\u1315' | '\\u1318' .. '\\u135A' | '\\u1380' .. '\\u138F' | '\\u13A0' .. '\\u13F5' | '\\u13F8' .. '\\u13FD' | '\\u1401' .. '\\u166C' | '\\u166F' .. '\\u167F' | '\\u1681' .. '\\u169A' | '\\u16A0' .. '\\u16EA' | '\\u16EE' .. '\\u16F8' | '\\u1700' .. '\\u170C' | '\\u170E' .. '\\u1711' | '\\u1720' .. '\\u1731' | '\\u1740' .. '\\u1751' | '\\u1760' .. '\\u176C' | '\\u176E' .. '\\u1770' | '\\u1780' .. '\\u17B3' | '\\u17D7' | '\\u17DC' | '\\u1820' .. '\\u1877' | '\\u1880' .. '\\u18A8' | '\\u18AA' | '\\u18B0' .. '\\u18F5' | '\\u1900' .. '\\u191E' | '\\u1950' .. '\\u196D' | '\\u1970' .. '\\u1974' | '\\u1980' .. '\\u19AB' | '\\u19B0' .. '\\u19C9' | '\\u1A00' .. '\\u1A16' | '\\u1A20' .. '\\u1A54' | '\\u1AA7' | '\\u1B05' .. '\\u1B33' | '\\u1B45' .. '\\u1B4B' | '\\u1B83' .. '\\u1BA0' | '\\u1BAE' .. '\\u1BAF' | '\\u1BBA' .. '\\u1BE5' | '\\u1C00' .. '\\u1C23' | '\\u1C4D' .. '\\u1C4F' | '\\u1C5A' .. '\\u1C7D' | '\\u1CE9' .. '\\u1CEC' | '\\u1CEE' .. '\\u1CF1' | '\\u1CF5' .. '\\u1CF6' | '\\u1D00' .. '\\u1DBF' | '\\u1E00' .. '\\u1F15' | '\\u1F18' .. '\\u1F1D' | '\\u1F20' .. '\\u1F45' | '\\u1F48' .. '\\u1F4D' | '\\u1F50' .. '\\u1F57' | '\\u1F59' | '\\u1F5B' | '\\u1F5D' | '\\u1F5F' .. '\\u1F7D' | '\\u1F80' .. '\\u1FB4' | '\\u1FB6' .. '\\u1FBC' | '\\u1FBE' | '\\u1FC2' .. '\\u1FC4' | '\\u1FC6' .. '\\u1FCC' | '\\u1FD0' .. '\\u1FD3' | '\\u1FD6' .. '\\u1FDB' | '\\u1FE0' .. '\\u1FEC' | '\\u1FF2' .. '\\u1FF4' | '\\u1FF6' .. '\\u1FFC' | '\\u2071' | '\\u207F' | '\\u2090' .. '\\u209C' | '\\u2102' | '\\u2107' | '\\u210A' .. '\\u2113' | '\\u2115' | '\\u2119' .. '\\u211D' | '\\u2124' | '\\u2126' | '\\u2128' | '\\u212A' .. '\\u212D' | '\\u212F' .. '\\u2139' | '\\u213C' .. '\\u213F' | '\\u2145' .. '\\u2149' | '\\u214E' | '\\u2160' .. '\\u2188' | '\\u2C00' .. '\\u2C2E' | '\\u2C30' .. '\\u2C5E' | '\\u2C60' .. '\\u2CE4' | '\\u2CEB' .. '\\u2CEE' | '\\u2CF2' .. '\\u2CF3' | '\\u2D00' .. '\\u2D25' | '\\u2D27' | '\\u2D2D' | '\\u2D30' .. '\\u2D67' | '\\u2D6F' | '\\u2D80' .. '\\u2D96' | '\\u2DA0' .. '\\u2DA6' | '\\u2DA8' .. '\\u2DAE' | '\\u2DB0' .. '\\u2DB6' | '\\u2DB8' .. '\\u2DBE' | '\\u2DC0' .. '\\u2DC6' | '\\u2DC8' .. '\\u2DCE' | '\\u2DD0' .. '\\u2DD6' | '\\u2DD8' .. '\\u2DDE' | '\\u2E2F' | '\\u3005' .. '\\u3007' | '\\u3021' .. '\\u3029' | '\\u3031' .. '\\u3035' | '\\u3038' .. '\\u303C' | '\\u3041' .. '\\u3096' | '\\u309D' .. '\\u309F' | '\\u30A1' .. '\\u30FA' | '\\u30FC' .. '\\u30FF' | '\\u3105' .. '\\u312D' | '\\u3131' .. '\\u318E' | '\\u31A0' .. '\\u31BA' | '\\u31F0' .. '\\u31FF' | '\\u3400' .. '\\u4DB5' | '\\u4E00' .. '\\u9FD5' | '\\uA000' .. '\\uA48C' | '\\uA4D0' .. '\\uA4FD' | '\\uA500' .. '\\uA60C' | '\\uA610' .. '\\uA61F' | '\\uA62A' .. '\\uA62B' | '\\uA640' .. '\\uA66E' | '\\uA67F' .. '\\uA69D' | '\\uA6A0' .. '\\uA6EF' | '\\uA717' .. '\\uA71F' | '\\uA722' .. '\\uA788' | '\\uA78B' .. '\\uA7AD' | '\\uA7B0' .. '\\uA7B7' | '\\uA7F7' .. '\\uA801' | '\\uA803' .. '\\uA805' | '\\uA807' .. '\\uA80A' | '\\uA80C' .. '\\uA822' | '\\uA840' .. '\\uA873' | '\\uA882' .. '\\uA8B3' | '\\uA8F2' .. '\\uA8F7' | '\\uA8FB' | '\\uA8FD' | '\\uA90A' .. '\\uA925' | '\\uA930' .. '\\uA946' | '\\uA960' .. '\\uA97C' | '\\uA984' .. '\\uA9B2' | '\\uA9CF' | '\\uA9E0' .. '\\uA9E4' | '\\uA9E6' .. '\\uA9EF' | '\\uA9FA' .. '\\uA9FE' | '\\uAA00' .. '\\uAA28' | '\\uAA40' .. '\\uAA42' | '\\uAA44' .. '\\uAA4B' | '\\uAA60' .. '\\uAA76' | '\\uAA7A' | '\\uAA7E' .. '\\uAAAF' | '\\uAAB1' | '\\uAAB5' .. '\\uAAB6' | '\\uAAB9' .. '\\uAABD' | '\\uAAC0' | '\\uAAC2' | '\\uAADB' .. '\\uAADD' | '\\uAAE0' .. '\\uAAEA' | '\\uAAF2' .. '\\uAAF4' | '\\uAB01' .. '\\uAB06' | '\\uAB09' .. '\\uAB0E' | '\\uAB11' .. '\\uAB16' | '\\uAB20' .. '\\uAB26' | '\\uAB28' .. '\\uAB2E' | '\\uAB30' .. '\\uAB5A' | '\\uAB5C' .. '\\uAB65' | '\\uAB70' .. '\\uABE2' | '\\uAC00' .. '\\uD7A3' | '\\uD7B0' .. '\\uD7C6' | '\\uD7CB' .. '\\uD7FB' | '\\uF900' .. '\\uFA6D' | '\\uFA70' .. '\\uFAD9' | '\\uFB00' .. '\\uFB06' | '\\uFB13' .. '\\uFB17' | '\\uFB1D' | '\\uFB1F' .. '\\uFB28' | '\\uFB2A' .. '\\uFB36' | '\\uFB38' .. '\\uFB3C' | '\\uFB3E' | '\\uFB40' .. '\\uFB41' | '\\uFB43' .. '\\uFB44' | '\\uFB46' .. '\\uFBB1' | '\\uFBD3' .. '\\uFD3D' | '\\uFD50' .. '\\uFD8F' | '\\uFD92' .. '\\uFDC7' | '\\uFDF0' .. '\\uFDFB' | '\\uFE70' .. '\\uFE74' | '\\uFE76' .. '\\uFEFC' | '\\uFF21' .. '\\uFF3A' | '\\uFF41' .. '\\uFF5A' | '\\uFF66' .. '\\uFFBE' | '\\uFFC2' .. '\\uFFC7' | '\\uFFCA' .. '\\uFFCF' | '\\uFFD2' .. '\\uFFD7' | '\\uFFDA' .. '\\uFFDC' ) ) - // InternalSemver.g:2197:41: ( 'A' .. 'Z' | 'a' .. 'z' | '\\u00AA' | '\\u00B5' | '\\u00BA' | '\\u00C0' .. '\\u00D6' | '\\u00D8' .. '\\u00F6' | '\\u00F8' .. '\\u02C1' | '\\u02C6' .. '\\u02D1' | '\\u02E0' .. '\\u02E4' | '\\u02EC' | '\\u02EE' | '\\u0370' .. '\\u0374' | '\\u0376' .. '\\u0377' | '\\u037A' .. '\\u037D' | '\\u037F' | '\\u0386' | '\\u0388' .. '\\u038A' | '\\u038C' | '\\u038E' .. '\\u03A1' | '\\u03A3' .. '\\u03F5' | '\\u03F7' .. '\\u0481' | '\\u048A' .. '\\u052F' | '\\u0531' .. '\\u0556' | '\\u0559' | '\\u0561' .. '\\u0587' | '\\u05D0' .. '\\u05EA' | '\\u05F0' .. '\\u05F2' | '\\u0620' .. '\\u064A' | '\\u066E' .. '\\u066F' | '\\u0671' .. '\\u06D3' | '\\u06D5' | '\\u06E5' .. '\\u06E6' | '\\u06EE' .. '\\u06EF' | '\\u06FA' .. '\\u06FC' | '\\u06FF' | '\\u0710' | '\\u0712' .. '\\u072F' | '\\u074D' .. '\\u07A5' | '\\u07B1' | '\\u07CA' .. '\\u07EA' | '\\u07F4' .. '\\u07F5' | '\\u07FA' | '\\u0800' .. '\\u0815' | '\\u081A' | '\\u0824' | '\\u0828' | '\\u0840' .. '\\u0858' | '\\u08A0' .. '\\u08B4' | '\\u0904' .. '\\u0939' | '\\u093D' | '\\u0950' | '\\u0958' .. '\\u0961' | '\\u0971' .. '\\u0980' | '\\u0985' .. '\\u098C' | '\\u098F' .. '\\u0990' | '\\u0993' .. '\\u09A8' | '\\u09AA' .. '\\u09B0' | '\\u09B2' | '\\u09B6' .. '\\u09B9' | '\\u09BD' | '\\u09CE' | '\\u09DC' .. '\\u09DD' | '\\u09DF' .. '\\u09E1' | '\\u09F0' .. '\\u09F1' | '\\u0A05' .. '\\u0A0A' | '\\u0A0F' .. '\\u0A10' | '\\u0A13' .. '\\u0A28' | '\\u0A2A' .. '\\u0A30' | '\\u0A32' .. '\\u0A33' | '\\u0A35' .. '\\u0A36' | '\\u0A38' .. '\\u0A39' | '\\u0A59' .. '\\u0A5C' | '\\u0A5E' | '\\u0A72' .. '\\u0A74' | '\\u0A85' .. '\\u0A8D' | '\\u0A8F' .. '\\u0A91' | '\\u0A93' .. '\\u0AA8' | '\\u0AAA' .. '\\u0AB0' | '\\u0AB2' .. '\\u0AB3' | '\\u0AB5' .. '\\u0AB9' | '\\u0ABD' | '\\u0AD0' | '\\u0AE0' .. '\\u0AE1' | '\\u0AF9' | '\\u0B05' .. '\\u0B0C' | '\\u0B0F' .. '\\u0B10' | '\\u0B13' .. '\\u0B28' | '\\u0B2A' .. '\\u0B30' | '\\u0B32' .. '\\u0B33' | '\\u0B35' .. '\\u0B39' | '\\u0B3D' | '\\u0B5C' .. '\\u0B5D' | '\\u0B5F' .. '\\u0B61' | '\\u0B71' | '\\u0B83' | '\\u0B85' .. '\\u0B8A' | '\\u0B8E' .. '\\u0B90' | '\\u0B92' .. '\\u0B95' | '\\u0B99' .. '\\u0B9A' | '\\u0B9C' | '\\u0B9E' .. '\\u0B9F' | '\\u0BA3' .. '\\u0BA4' | '\\u0BA8' .. '\\u0BAA' | '\\u0BAE' .. '\\u0BB9' | '\\u0BD0' | '\\u0C05' .. '\\u0C0C' | '\\u0C0E' .. '\\u0C10' | '\\u0C12' .. '\\u0C28' | '\\u0C2A' .. '\\u0C39' | '\\u0C3D' | '\\u0C58' .. '\\u0C5A' | '\\u0C60' .. '\\u0C61' | '\\u0C85' .. '\\u0C8C' | '\\u0C8E' .. '\\u0C90' | '\\u0C92' .. '\\u0CA8' | '\\u0CAA' .. '\\u0CB3' | '\\u0CB5' .. '\\u0CB9' | '\\u0CBD' | '\\u0CDE' | '\\u0CE0' .. '\\u0CE1' | '\\u0CF1' .. '\\u0CF2' | '\\u0D05' .. '\\u0D0C' | '\\u0D0E' .. '\\u0D10' | '\\u0D12' .. '\\u0D3A' | '\\u0D3D' | '\\u0D4E' | '\\u0D5F' .. '\\u0D61' | '\\u0D7A' .. '\\u0D7F' | '\\u0D85' .. '\\u0D96' | '\\u0D9A' .. '\\u0DB1' | '\\u0DB3' .. '\\u0DBB' | '\\u0DBD' | '\\u0DC0' .. '\\u0DC6' | '\\u0E01' .. '\\u0E30' | '\\u0E32' .. '\\u0E33' | '\\u0E40' .. '\\u0E46' | '\\u0E81' .. '\\u0E82' | '\\u0E84' | '\\u0E87' .. '\\u0E88' | '\\u0E8A' | '\\u0E8D' | '\\u0E94' .. '\\u0E97' | '\\u0E99' .. '\\u0E9F' | '\\u0EA1' .. '\\u0EA3' | '\\u0EA5' | '\\u0EA7' | '\\u0EAA' .. '\\u0EAB' | '\\u0EAD' .. '\\u0EB0' | '\\u0EB2' .. '\\u0EB3' | '\\u0EBD' | '\\u0EC0' .. '\\u0EC4' | '\\u0EC6' | '\\u0EDC' .. '\\u0EDF' | '\\u0F00' | '\\u0F40' .. '\\u0F47' | '\\u0F49' .. '\\u0F6C' | '\\u0F88' .. '\\u0F8C' | '\\u1000' .. '\\u102A' | '\\u103F' | '\\u1050' .. '\\u1055' | '\\u105A' .. '\\u105D' | '\\u1061' | '\\u1065' .. '\\u1066' | '\\u106E' .. '\\u1070' | '\\u1075' .. '\\u1081' | '\\u108E' | '\\u10A0' .. '\\u10C5' | '\\u10C7' | '\\u10CD' | '\\u10D0' .. '\\u10FA' | '\\u10FC' .. '\\u1248' | '\\u124A' .. '\\u124D' | '\\u1250' .. '\\u1256' | '\\u1258' | '\\u125A' .. '\\u125D' | '\\u1260' .. '\\u1288' | '\\u128A' .. '\\u128D' | '\\u1290' .. '\\u12B0' | '\\u12B2' .. '\\u12B5' | '\\u12B8' .. '\\u12BE' | '\\u12C0' | '\\u12C2' .. '\\u12C5' | '\\u12C8' .. '\\u12D6' | '\\u12D8' .. '\\u1310' | '\\u1312' .. '\\u1315' | '\\u1318' .. '\\u135A' | '\\u1380' .. '\\u138F' | '\\u13A0' .. '\\u13F5' | '\\u13F8' .. '\\u13FD' | '\\u1401' .. '\\u166C' | '\\u166F' .. '\\u167F' | '\\u1681' .. '\\u169A' | '\\u16A0' .. '\\u16EA' | '\\u16EE' .. '\\u16F8' | '\\u1700' .. '\\u170C' | '\\u170E' .. '\\u1711' | '\\u1720' .. '\\u1731' | '\\u1740' .. '\\u1751' | '\\u1760' .. '\\u176C' | '\\u176E' .. '\\u1770' | '\\u1780' .. '\\u17B3' | '\\u17D7' | '\\u17DC' | '\\u1820' .. '\\u1877' | '\\u1880' .. '\\u18A8' | '\\u18AA' | '\\u18B0' .. '\\u18F5' | '\\u1900' .. '\\u191E' | '\\u1950' .. '\\u196D' | '\\u1970' .. '\\u1974' | '\\u1980' .. '\\u19AB' | '\\u19B0' .. '\\u19C9' | '\\u1A00' .. '\\u1A16' | '\\u1A20' .. '\\u1A54' | '\\u1AA7' | '\\u1B05' .. '\\u1B33' | '\\u1B45' .. '\\u1B4B' | '\\u1B83' .. '\\u1BA0' | '\\u1BAE' .. '\\u1BAF' | '\\u1BBA' .. '\\u1BE5' | '\\u1C00' .. '\\u1C23' | '\\u1C4D' .. '\\u1C4F' | '\\u1C5A' .. '\\u1C7D' | '\\u1CE9' .. '\\u1CEC' | '\\u1CEE' .. '\\u1CF1' | '\\u1CF5' .. '\\u1CF6' | '\\u1D00' .. '\\u1DBF' | '\\u1E00' .. '\\u1F15' | '\\u1F18' .. '\\u1F1D' | '\\u1F20' .. '\\u1F45' | '\\u1F48' .. '\\u1F4D' | '\\u1F50' .. '\\u1F57' | '\\u1F59' | '\\u1F5B' | '\\u1F5D' | '\\u1F5F' .. '\\u1F7D' | '\\u1F80' .. '\\u1FB4' | '\\u1FB6' .. '\\u1FBC' | '\\u1FBE' | '\\u1FC2' .. '\\u1FC4' | '\\u1FC6' .. '\\u1FCC' | '\\u1FD0' .. '\\u1FD3' | '\\u1FD6' .. '\\u1FDB' | '\\u1FE0' .. '\\u1FEC' | '\\u1FF2' .. '\\u1FF4' | '\\u1FF6' .. '\\u1FFC' | '\\u2071' | '\\u207F' | '\\u2090' .. '\\u209C' | '\\u2102' | '\\u2107' | '\\u210A' .. '\\u2113' | '\\u2115' | '\\u2119' .. '\\u211D' | '\\u2124' | '\\u2126' | '\\u2128' | '\\u212A' .. '\\u212D' | '\\u212F' .. '\\u2139' | '\\u213C' .. '\\u213F' | '\\u2145' .. '\\u2149' | '\\u214E' | '\\u2160' .. '\\u2188' | '\\u2C00' .. '\\u2C2E' | '\\u2C30' .. '\\u2C5E' | '\\u2C60' .. '\\u2CE4' | '\\u2CEB' .. '\\u2CEE' | '\\u2CF2' .. '\\u2CF3' | '\\u2D00' .. '\\u2D25' | '\\u2D27' | '\\u2D2D' | '\\u2D30' .. '\\u2D67' | '\\u2D6F' | '\\u2D80' .. '\\u2D96' | '\\u2DA0' .. '\\u2DA6' | '\\u2DA8' .. '\\u2DAE' | '\\u2DB0' .. '\\u2DB6' | '\\u2DB8' .. '\\u2DBE' | '\\u2DC0' .. '\\u2DC6' | '\\u2DC8' .. '\\u2DCE' | '\\u2DD0' .. '\\u2DD6' | '\\u2DD8' .. '\\u2DDE' | '\\u2E2F' | '\\u3005' .. '\\u3007' | '\\u3021' .. '\\u3029' | '\\u3031' .. '\\u3035' | '\\u3038' .. '\\u303C' | '\\u3041' .. '\\u3096' | '\\u309D' .. '\\u309F' | '\\u30A1' .. '\\u30FA' | '\\u30FC' .. '\\u30FF' | '\\u3105' .. '\\u312D' | '\\u3131' .. '\\u318E' | '\\u31A0' .. '\\u31BA' | '\\u31F0' .. '\\u31FF' | '\\u3400' .. '\\u4DB5' | '\\u4E00' .. '\\u9FD5' | '\\uA000' .. '\\uA48C' | '\\uA4D0' .. '\\uA4FD' | '\\uA500' .. '\\uA60C' | '\\uA610' .. '\\uA61F' | '\\uA62A' .. '\\uA62B' | '\\uA640' .. '\\uA66E' | '\\uA67F' .. '\\uA69D' | '\\uA6A0' .. '\\uA6EF' | '\\uA717' .. '\\uA71F' | '\\uA722' .. '\\uA788' | '\\uA78B' .. '\\uA7AD' | '\\uA7B0' .. '\\uA7B7' | '\\uA7F7' .. '\\uA801' | '\\uA803' .. '\\uA805' | '\\uA807' .. '\\uA80A' | '\\uA80C' .. '\\uA822' | '\\uA840' .. '\\uA873' | '\\uA882' .. '\\uA8B3' | '\\uA8F2' .. '\\uA8F7' | '\\uA8FB' | '\\uA8FD' | '\\uA90A' .. '\\uA925' | '\\uA930' .. '\\uA946' | '\\uA960' .. '\\uA97C' | '\\uA984' .. '\\uA9B2' | '\\uA9CF' | '\\uA9E0' .. '\\uA9E4' | '\\uA9E6' .. '\\uA9EF' | '\\uA9FA' .. '\\uA9FE' | '\\uAA00' .. '\\uAA28' | '\\uAA40' .. '\\uAA42' | '\\uAA44' .. '\\uAA4B' | '\\uAA60' .. '\\uAA76' | '\\uAA7A' | '\\uAA7E' .. '\\uAAAF' | '\\uAAB1' | '\\uAAB5' .. '\\uAAB6' | '\\uAAB9' .. '\\uAABD' | '\\uAAC0' | '\\uAAC2' | '\\uAADB' .. '\\uAADD' | '\\uAAE0' .. '\\uAAEA' | '\\uAAF2' .. '\\uAAF4' | '\\uAB01' .. '\\uAB06' | '\\uAB09' .. '\\uAB0E' | '\\uAB11' .. '\\uAB16' | '\\uAB20' .. '\\uAB26' | '\\uAB28' .. '\\uAB2E' | '\\uAB30' .. '\\uAB5A' | '\\uAB5C' .. '\\uAB65' | '\\uAB70' .. '\\uABE2' | '\\uAC00' .. '\\uD7A3' | '\\uD7B0' .. '\\uD7C6' | '\\uD7CB' .. '\\uD7FB' | '\\uF900' .. '\\uFA6D' | '\\uFA70' .. '\\uFAD9' | '\\uFB00' .. '\\uFB06' | '\\uFB13' .. '\\uFB17' | '\\uFB1D' | '\\uFB1F' .. '\\uFB28' | '\\uFB2A' .. '\\uFB36' | '\\uFB38' .. '\\uFB3C' | '\\uFB3E' | '\\uFB40' .. '\\uFB41' | '\\uFB43' .. '\\uFB44' | '\\uFB46' .. '\\uFBB1' | '\\uFBD3' .. '\\uFD3D' | '\\uFD50' .. '\\uFD8F' | '\\uFD92' .. '\\uFDC7' | '\\uFDF0' .. '\\uFDFB' | '\\uFE70' .. '\\uFE74' | '\\uFE76' .. '\\uFEFC' | '\\uFF21' .. '\\uFF3A' | '\\uFF41' .. '\\uFF5A' | '\\uFF66' .. '\\uFFBE' | '\\uFFC2' .. '\\uFFC7' | '\\uFFCA' .. '\\uFFCF' | '\\uFFD2' .. '\\uFFD7' | '\\uFFDA' .. '\\uFFDC' ) + // InternalSemver.g:2465:39: ( ( 'A' .. 'Z' | 'a' .. 'z' | '\\u00AA' | '\\u00B5' | '\\u00BA' | '\\u00C0' .. '\\u00D6' | '\\u00D8' .. '\\u00F6' | '\\u00F8' .. '\\u02C1' | '\\u02C6' .. '\\u02D1' | '\\u02E0' .. '\\u02E4' | '\\u02EC' | '\\u02EE' | '\\u0370' .. '\\u0374' | '\\u0376' .. '\\u0377' | '\\u037A' .. '\\u037D' | '\\u037F' | '\\u0386' | '\\u0388' .. '\\u038A' | '\\u038C' | '\\u038E' .. '\\u03A1' | '\\u03A3' .. '\\u03F5' | '\\u03F7' .. '\\u0481' | '\\u048A' .. '\\u052F' | '\\u0531' .. '\\u0556' | '\\u0559' | '\\u0561' .. '\\u0587' | '\\u05D0' .. '\\u05EA' | '\\u05F0' .. '\\u05F2' | '\\u0620' .. '\\u064A' | '\\u066E' .. '\\u066F' | '\\u0671' .. '\\u06D3' | '\\u06D5' | '\\u06E5' .. '\\u06E6' | '\\u06EE' .. '\\u06EF' | '\\u06FA' .. '\\u06FC' | '\\u06FF' | '\\u0710' | '\\u0712' .. '\\u072F' | '\\u074D' .. '\\u07A5' | '\\u07B1' | '\\u07CA' .. '\\u07EA' | '\\u07F4' .. '\\u07F5' | '\\u07FA' | '\\u0800' .. '\\u0815' | '\\u081A' | '\\u0824' | '\\u0828' | '\\u0840' .. '\\u0858' | '\\u08A0' .. '\\u08B4' | '\\u0904' .. '\\u0939' | '\\u093D' | '\\u0950' | '\\u0958' .. '\\u0961' | '\\u0971' .. '\\u0980' | '\\u0985' .. '\\u098C' | '\\u098F' .. '\\u0990' | '\\u0993' .. '\\u09A8' | '\\u09AA' .. '\\u09B0' | '\\u09B2' | '\\u09B6' .. '\\u09B9' | '\\u09BD' | '\\u09CE' | '\\u09DC' .. '\\u09DD' | '\\u09DF' .. '\\u09E1' | '\\u09F0' .. '\\u09F1' | '\\u0A05' .. '\\u0A0A' | '\\u0A0F' .. '\\u0A10' | '\\u0A13' .. '\\u0A28' | '\\u0A2A' .. '\\u0A30' | '\\u0A32' .. '\\u0A33' | '\\u0A35' .. '\\u0A36' | '\\u0A38' .. '\\u0A39' | '\\u0A59' .. '\\u0A5C' | '\\u0A5E' | '\\u0A72' .. '\\u0A74' | '\\u0A85' .. '\\u0A8D' | '\\u0A8F' .. '\\u0A91' | '\\u0A93' .. '\\u0AA8' | '\\u0AAA' .. '\\u0AB0' | '\\u0AB2' .. '\\u0AB3' | '\\u0AB5' .. '\\u0AB9' | '\\u0ABD' | '\\u0AD0' | '\\u0AE0' .. '\\u0AE1' | '\\u0AF9' | '\\u0B05' .. '\\u0B0C' | '\\u0B0F' .. '\\u0B10' | '\\u0B13' .. '\\u0B28' | '\\u0B2A' .. '\\u0B30' | '\\u0B32' .. '\\u0B33' | '\\u0B35' .. '\\u0B39' | '\\u0B3D' | '\\u0B5C' .. '\\u0B5D' | '\\u0B5F' .. '\\u0B61' | '\\u0B71' | '\\u0B83' | '\\u0B85' .. '\\u0B8A' | '\\u0B8E' .. '\\u0B90' | '\\u0B92' .. '\\u0B95' | '\\u0B99' .. '\\u0B9A' | '\\u0B9C' | '\\u0B9E' .. '\\u0B9F' | '\\u0BA3' .. '\\u0BA4' | '\\u0BA8' .. '\\u0BAA' | '\\u0BAE' .. '\\u0BB9' | '\\u0BD0' | '\\u0C05' .. '\\u0C0C' | '\\u0C0E' .. '\\u0C10' | '\\u0C12' .. '\\u0C28' | '\\u0C2A' .. '\\u0C39' | '\\u0C3D' | '\\u0C58' .. '\\u0C5A' | '\\u0C60' .. '\\u0C61' | '\\u0C85' .. '\\u0C8C' | '\\u0C8E' .. '\\u0C90' | '\\u0C92' .. '\\u0CA8' | '\\u0CAA' .. '\\u0CB3' | '\\u0CB5' .. '\\u0CB9' | '\\u0CBD' | '\\u0CDE' | '\\u0CE0' .. '\\u0CE1' | '\\u0CF1' .. '\\u0CF2' | '\\u0D05' .. '\\u0D0C' | '\\u0D0E' .. '\\u0D10' | '\\u0D12' .. '\\u0D3A' | '\\u0D3D' | '\\u0D4E' | '\\u0D5F' .. '\\u0D61' | '\\u0D7A' .. '\\u0D7F' | '\\u0D85' .. '\\u0D96' | '\\u0D9A' .. '\\u0DB1' | '\\u0DB3' .. '\\u0DBB' | '\\u0DBD' | '\\u0DC0' .. '\\u0DC6' | '\\u0E01' .. '\\u0E30' | '\\u0E32' .. '\\u0E33' | '\\u0E40' .. '\\u0E46' | '\\u0E81' .. '\\u0E82' | '\\u0E84' | '\\u0E87' .. '\\u0E88' | '\\u0E8A' | '\\u0E8D' | '\\u0E94' .. '\\u0E97' | '\\u0E99' .. '\\u0E9F' | '\\u0EA1' .. '\\u0EA3' | '\\u0EA5' | '\\u0EA7' | '\\u0EAA' .. '\\u0EAB' | '\\u0EAD' .. '\\u0EB0' | '\\u0EB2' .. '\\u0EB3' | '\\u0EBD' | '\\u0EC0' .. '\\u0EC4' | '\\u0EC6' | '\\u0EDC' .. '\\u0EDF' | '\\u0F00' | '\\u0F40' .. '\\u0F47' | '\\u0F49' .. '\\u0F6C' | '\\u0F88' .. '\\u0F8C' | '\\u1000' .. '\\u102A' | '\\u103F' | '\\u1050' .. '\\u1055' | '\\u105A' .. '\\u105D' | '\\u1061' | '\\u1065' .. '\\u1066' | '\\u106E' .. '\\u1070' | '\\u1075' .. '\\u1081' | '\\u108E' | '\\u10A0' .. '\\u10C5' | '\\u10C7' | '\\u10CD' | '\\u10D0' .. '\\u10FA' | '\\u10FC' .. '\\u1248' | '\\u124A' .. '\\u124D' | '\\u1250' .. '\\u1256' | '\\u1258' | '\\u125A' .. '\\u125D' | '\\u1260' .. '\\u1288' | '\\u128A' .. '\\u128D' | '\\u1290' .. '\\u12B0' | '\\u12B2' .. '\\u12B5' | '\\u12B8' .. '\\u12BE' | '\\u12C0' | '\\u12C2' .. '\\u12C5' | '\\u12C8' .. '\\u12D6' | '\\u12D8' .. '\\u1310' | '\\u1312' .. '\\u1315' | '\\u1318' .. '\\u135A' | '\\u1380' .. '\\u138F' | '\\u13A0' .. '\\u13F5' | '\\u13F8' .. '\\u13FD' | '\\u1401' .. '\\u166C' | '\\u166F' .. '\\u167F' | '\\u1681' .. '\\u169A' | '\\u16A0' .. '\\u16EA' | '\\u16EE' .. '\\u16F8' | '\\u1700' .. '\\u170C' | '\\u170E' .. '\\u1711' | '\\u1720' .. '\\u1731' | '\\u1740' .. '\\u1751' | '\\u1760' .. '\\u176C' | '\\u176E' .. '\\u1770' | '\\u1780' .. '\\u17B3' | '\\u17D7' | '\\u17DC' | '\\u1820' .. '\\u1877' | '\\u1880' .. '\\u18A8' | '\\u18AA' | '\\u18B0' .. '\\u18F5' | '\\u1900' .. '\\u191E' | '\\u1950' .. '\\u196D' | '\\u1970' .. '\\u1974' | '\\u1980' .. '\\u19AB' | '\\u19B0' .. '\\u19C9' | '\\u1A00' .. '\\u1A16' | '\\u1A20' .. '\\u1A54' | '\\u1AA7' | '\\u1B05' .. '\\u1B33' | '\\u1B45' .. '\\u1B4B' | '\\u1B83' .. '\\u1BA0' | '\\u1BAE' .. '\\u1BAF' | '\\u1BBA' .. '\\u1BE5' | '\\u1C00' .. '\\u1C23' | '\\u1C4D' .. '\\u1C4F' | '\\u1C5A' .. '\\u1C7D' | '\\u1CE9' .. '\\u1CEC' | '\\u1CEE' .. '\\u1CF1' | '\\u1CF5' .. '\\u1CF6' | '\\u1D00' .. '\\u1DBF' | '\\u1E00' .. '\\u1F15' | '\\u1F18' .. '\\u1F1D' | '\\u1F20' .. '\\u1F45' | '\\u1F48' .. '\\u1F4D' | '\\u1F50' .. '\\u1F57' | '\\u1F59' | '\\u1F5B' | '\\u1F5D' | '\\u1F5F' .. '\\u1F7D' | '\\u1F80' .. '\\u1FB4' | '\\u1FB6' .. '\\u1FBC' | '\\u1FBE' | '\\u1FC2' .. '\\u1FC4' | '\\u1FC6' .. '\\u1FCC' | '\\u1FD0' .. '\\u1FD3' | '\\u1FD6' .. '\\u1FDB' | '\\u1FE0' .. '\\u1FEC' | '\\u1FF2' .. '\\u1FF4' | '\\u1FF6' .. '\\u1FFC' | '\\u2071' | '\\u207F' | '\\u2090' .. '\\u209C' | '\\u2102' | '\\u2107' | '\\u210A' .. '\\u2113' | '\\u2115' | '\\u2119' .. '\\u211D' | '\\u2124' | '\\u2126' | '\\u2128' | '\\u212A' .. '\\u212D' | '\\u212F' .. '\\u2139' | '\\u213C' .. '\\u213F' | '\\u2145' .. '\\u2149' | '\\u214E' | '\\u2160' .. '\\u2188' | '\\u2C00' .. '\\u2C2E' | '\\u2C30' .. '\\u2C5E' | '\\u2C60' .. '\\u2CE4' | '\\u2CEB' .. '\\u2CEE' | '\\u2CF2' .. '\\u2CF3' | '\\u2D00' .. '\\u2D25' | '\\u2D27' | '\\u2D2D' | '\\u2D30' .. '\\u2D67' | '\\u2D6F' | '\\u2D80' .. '\\u2D96' | '\\u2DA0' .. '\\u2DA6' | '\\u2DA8' .. '\\u2DAE' | '\\u2DB0' .. '\\u2DB6' | '\\u2DB8' .. '\\u2DBE' | '\\u2DC0' .. '\\u2DC6' | '\\u2DC8' .. '\\u2DCE' | '\\u2DD0' .. '\\u2DD6' | '\\u2DD8' .. '\\u2DDE' | '\\u2E2F' | '\\u3005' .. '\\u3007' | '\\u3021' .. '\\u3029' | '\\u3031' .. '\\u3035' | '\\u3038' .. '\\u303C' | '\\u3041' .. '\\u3096' | '\\u309D' .. '\\u309F' | '\\u30A1' .. '\\u30FA' | '\\u30FC' .. '\\u30FF' | '\\u3105' .. '\\u312D' | '\\u3131' .. '\\u318E' | '\\u31A0' .. '\\u31BA' | '\\u31F0' .. '\\u31FF' | '\\u3400' .. '\\u4DB5' | '\\u4E00' .. '\\u9FD5' | '\\uA000' .. '\\uA48C' | '\\uA4D0' .. '\\uA4FD' | '\\uA500' .. '\\uA60C' | '\\uA610' .. '\\uA61F' | '\\uA62A' .. '\\uA62B' | '\\uA640' .. '\\uA66E' | '\\uA67F' .. '\\uA69D' | '\\uA6A0' .. '\\uA6EF' | '\\uA717' .. '\\uA71F' | '\\uA722' .. '\\uA788' | '\\uA78B' .. '\\uA7AD' | '\\uA7B0' .. '\\uA7B7' | '\\uA7F7' .. '\\uA801' | '\\uA803' .. '\\uA805' | '\\uA807' .. '\\uA80A' | '\\uA80C' .. '\\uA822' | '\\uA840' .. '\\uA873' | '\\uA882' .. '\\uA8B3' | '\\uA8F2' .. '\\uA8F7' | '\\uA8FB' | '\\uA8FD' | '\\uA90A' .. '\\uA925' | '\\uA930' .. '\\uA946' | '\\uA960' .. '\\uA97C' | '\\uA984' .. '\\uA9B2' | '\\uA9CF' | '\\uA9E0' .. '\\uA9E4' | '\\uA9E6' .. '\\uA9EF' | '\\uA9FA' .. '\\uA9FE' | '\\uAA00' .. '\\uAA28' | '\\uAA40' .. '\\uAA42' | '\\uAA44' .. '\\uAA4B' | '\\uAA60' .. '\\uAA76' | '\\uAA7A' | '\\uAA7E' .. '\\uAAAF' | '\\uAAB1' | '\\uAAB5' .. '\\uAAB6' | '\\uAAB9' .. '\\uAABD' | '\\uAAC0' | '\\uAAC2' | '\\uAADB' .. '\\uAADD' | '\\uAAE0' .. '\\uAAEA' | '\\uAAF2' .. '\\uAAF4' | '\\uAB01' .. '\\uAB06' | '\\uAB09' .. '\\uAB0E' | '\\uAB11' .. '\\uAB16' | '\\uAB20' .. '\\uAB26' | '\\uAB28' .. '\\uAB2E' | '\\uAB30' .. '\\uAB5A' | '\\uAB5C' .. '\\uAB65' | '\\uAB70' .. '\\uABE2' | '\\uAC00' .. '\\uD7A3' | '\\uD7B0' .. '\\uD7C6' | '\\uD7CB' .. '\\uD7FB' | '\\uF900' .. '\\uFA6D' | '\\uFA70' .. '\\uFAD9' | '\\uFB00' .. '\\uFB06' | '\\uFB13' .. '\\uFB17' | '\\uFB1D' | '\\uFB1F' .. '\\uFB28' | '\\uFB2A' .. '\\uFB36' | '\\uFB38' .. '\\uFB3C' | '\\uFB3E' | '\\uFB40' .. '\\uFB41' | '\\uFB43' .. '\\uFB44' | '\\uFB46' .. '\\uFBB1' | '\\uFBD3' .. '\\uFD3D' | '\\uFD50' .. '\\uFD8F' | '\\uFD92' .. '\\uFDC7' | '\\uFDF0' .. '\\uFDFB' | '\\uFE70' .. '\\uFE74' | '\\uFE76' .. '\\uFEFC' | '\\uFF21' .. '\\uFF3A' | '\\uFF41' .. '\\uFF5A' | '\\uFF66' .. '\\uFFBE' | '\\uFFC2' .. '\\uFFC7' | '\\uFFCA' .. '\\uFFCF' | '\\uFFD2' .. '\\uFFD7' | '\\uFFDA' .. '\\uFFDC' ) ) + // InternalSemver.g:2465:41: ( 'A' .. 'Z' | 'a' .. 'z' | '\\u00AA' | '\\u00B5' | '\\u00BA' | '\\u00C0' .. '\\u00D6' | '\\u00D8' .. '\\u00F6' | '\\u00F8' .. '\\u02C1' | '\\u02C6' .. '\\u02D1' | '\\u02E0' .. '\\u02E4' | '\\u02EC' | '\\u02EE' | '\\u0370' .. '\\u0374' | '\\u0376' .. '\\u0377' | '\\u037A' .. '\\u037D' | '\\u037F' | '\\u0386' | '\\u0388' .. '\\u038A' | '\\u038C' | '\\u038E' .. '\\u03A1' | '\\u03A3' .. '\\u03F5' | '\\u03F7' .. '\\u0481' | '\\u048A' .. '\\u052F' | '\\u0531' .. '\\u0556' | '\\u0559' | '\\u0561' .. '\\u0587' | '\\u05D0' .. '\\u05EA' | '\\u05F0' .. '\\u05F2' | '\\u0620' .. '\\u064A' | '\\u066E' .. '\\u066F' | '\\u0671' .. '\\u06D3' | '\\u06D5' | '\\u06E5' .. '\\u06E6' | '\\u06EE' .. '\\u06EF' | '\\u06FA' .. '\\u06FC' | '\\u06FF' | '\\u0710' | '\\u0712' .. '\\u072F' | '\\u074D' .. '\\u07A5' | '\\u07B1' | '\\u07CA' .. '\\u07EA' | '\\u07F4' .. '\\u07F5' | '\\u07FA' | '\\u0800' .. '\\u0815' | '\\u081A' | '\\u0824' | '\\u0828' | '\\u0840' .. '\\u0858' | '\\u08A0' .. '\\u08B4' | '\\u0904' .. '\\u0939' | '\\u093D' | '\\u0950' | '\\u0958' .. '\\u0961' | '\\u0971' .. '\\u0980' | '\\u0985' .. '\\u098C' | '\\u098F' .. '\\u0990' | '\\u0993' .. '\\u09A8' | '\\u09AA' .. '\\u09B0' | '\\u09B2' | '\\u09B6' .. '\\u09B9' | '\\u09BD' | '\\u09CE' | '\\u09DC' .. '\\u09DD' | '\\u09DF' .. '\\u09E1' | '\\u09F0' .. '\\u09F1' | '\\u0A05' .. '\\u0A0A' | '\\u0A0F' .. '\\u0A10' | '\\u0A13' .. '\\u0A28' | '\\u0A2A' .. '\\u0A30' | '\\u0A32' .. '\\u0A33' | '\\u0A35' .. '\\u0A36' | '\\u0A38' .. '\\u0A39' | '\\u0A59' .. '\\u0A5C' | '\\u0A5E' | '\\u0A72' .. '\\u0A74' | '\\u0A85' .. '\\u0A8D' | '\\u0A8F' .. '\\u0A91' | '\\u0A93' .. '\\u0AA8' | '\\u0AAA' .. '\\u0AB0' | '\\u0AB2' .. '\\u0AB3' | '\\u0AB5' .. '\\u0AB9' | '\\u0ABD' | '\\u0AD0' | '\\u0AE0' .. '\\u0AE1' | '\\u0AF9' | '\\u0B05' .. '\\u0B0C' | '\\u0B0F' .. '\\u0B10' | '\\u0B13' .. '\\u0B28' | '\\u0B2A' .. '\\u0B30' | '\\u0B32' .. '\\u0B33' | '\\u0B35' .. '\\u0B39' | '\\u0B3D' | '\\u0B5C' .. '\\u0B5D' | '\\u0B5F' .. '\\u0B61' | '\\u0B71' | '\\u0B83' | '\\u0B85' .. '\\u0B8A' | '\\u0B8E' .. '\\u0B90' | '\\u0B92' .. '\\u0B95' | '\\u0B99' .. '\\u0B9A' | '\\u0B9C' | '\\u0B9E' .. '\\u0B9F' | '\\u0BA3' .. '\\u0BA4' | '\\u0BA8' .. '\\u0BAA' | '\\u0BAE' .. '\\u0BB9' | '\\u0BD0' | '\\u0C05' .. '\\u0C0C' | '\\u0C0E' .. '\\u0C10' | '\\u0C12' .. '\\u0C28' | '\\u0C2A' .. '\\u0C39' | '\\u0C3D' | '\\u0C58' .. '\\u0C5A' | '\\u0C60' .. '\\u0C61' | '\\u0C85' .. '\\u0C8C' | '\\u0C8E' .. '\\u0C90' | '\\u0C92' .. '\\u0CA8' | '\\u0CAA' .. '\\u0CB3' | '\\u0CB5' .. '\\u0CB9' | '\\u0CBD' | '\\u0CDE' | '\\u0CE0' .. '\\u0CE1' | '\\u0CF1' .. '\\u0CF2' | '\\u0D05' .. '\\u0D0C' | '\\u0D0E' .. '\\u0D10' | '\\u0D12' .. '\\u0D3A' | '\\u0D3D' | '\\u0D4E' | '\\u0D5F' .. '\\u0D61' | '\\u0D7A' .. '\\u0D7F' | '\\u0D85' .. '\\u0D96' | '\\u0D9A' .. '\\u0DB1' | '\\u0DB3' .. '\\u0DBB' | '\\u0DBD' | '\\u0DC0' .. '\\u0DC6' | '\\u0E01' .. '\\u0E30' | '\\u0E32' .. '\\u0E33' | '\\u0E40' .. '\\u0E46' | '\\u0E81' .. '\\u0E82' | '\\u0E84' | '\\u0E87' .. '\\u0E88' | '\\u0E8A' | '\\u0E8D' | '\\u0E94' .. '\\u0E97' | '\\u0E99' .. '\\u0E9F' | '\\u0EA1' .. '\\u0EA3' | '\\u0EA5' | '\\u0EA7' | '\\u0EAA' .. '\\u0EAB' | '\\u0EAD' .. '\\u0EB0' | '\\u0EB2' .. '\\u0EB3' | '\\u0EBD' | '\\u0EC0' .. '\\u0EC4' | '\\u0EC6' | '\\u0EDC' .. '\\u0EDF' | '\\u0F00' | '\\u0F40' .. '\\u0F47' | '\\u0F49' .. '\\u0F6C' | '\\u0F88' .. '\\u0F8C' | '\\u1000' .. '\\u102A' | '\\u103F' | '\\u1050' .. '\\u1055' | '\\u105A' .. '\\u105D' | '\\u1061' | '\\u1065' .. '\\u1066' | '\\u106E' .. '\\u1070' | '\\u1075' .. '\\u1081' | '\\u108E' | '\\u10A0' .. '\\u10C5' | '\\u10C7' | '\\u10CD' | '\\u10D0' .. '\\u10FA' | '\\u10FC' .. '\\u1248' | '\\u124A' .. '\\u124D' | '\\u1250' .. '\\u1256' | '\\u1258' | '\\u125A' .. '\\u125D' | '\\u1260' .. '\\u1288' | '\\u128A' .. '\\u128D' | '\\u1290' .. '\\u12B0' | '\\u12B2' .. '\\u12B5' | '\\u12B8' .. '\\u12BE' | '\\u12C0' | '\\u12C2' .. '\\u12C5' | '\\u12C8' .. '\\u12D6' | '\\u12D8' .. '\\u1310' | '\\u1312' .. '\\u1315' | '\\u1318' .. '\\u135A' | '\\u1380' .. '\\u138F' | '\\u13A0' .. '\\u13F5' | '\\u13F8' .. '\\u13FD' | '\\u1401' .. '\\u166C' | '\\u166F' .. '\\u167F' | '\\u1681' .. '\\u169A' | '\\u16A0' .. '\\u16EA' | '\\u16EE' .. '\\u16F8' | '\\u1700' .. '\\u170C' | '\\u170E' .. '\\u1711' | '\\u1720' .. '\\u1731' | '\\u1740' .. '\\u1751' | '\\u1760' .. '\\u176C' | '\\u176E' .. '\\u1770' | '\\u1780' .. '\\u17B3' | '\\u17D7' | '\\u17DC' | '\\u1820' .. '\\u1877' | '\\u1880' .. '\\u18A8' | '\\u18AA' | '\\u18B0' .. '\\u18F5' | '\\u1900' .. '\\u191E' | '\\u1950' .. '\\u196D' | '\\u1970' .. '\\u1974' | '\\u1980' .. '\\u19AB' | '\\u19B0' .. '\\u19C9' | '\\u1A00' .. '\\u1A16' | '\\u1A20' .. '\\u1A54' | '\\u1AA7' | '\\u1B05' .. '\\u1B33' | '\\u1B45' .. '\\u1B4B' | '\\u1B83' .. '\\u1BA0' | '\\u1BAE' .. '\\u1BAF' | '\\u1BBA' .. '\\u1BE5' | '\\u1C00' .. '\\u1C23' | '\\u1C4D' .. '\\u1C4F' | '\\u1C5A' .. '\\u1C7D' | '\\u1CE9' .. '\\u1CEC' | '\\u1CEE' .. '\\u1CF1' | '\\u1CF5' .. '\\u1CF6' | '\\u1D00' .. '\\u1DBF' | '\\u1E00' .. '\\u1F15' | '\\u1F18' .. '\\u1F1D' | '\\u1F20' .. '\\u1F45' | '\\u1F48' .. '\\u1F4D' | '\\u1F50' .. '\\u1F57' | '\\u1F59' | '\\u1F5B' | '\\u1F5D' | '\\u1F5F' .. '\\u1F7D' | '\\u1F80' .. '\\u1FB4' | '\\u1FB6' .. '\\u1FBC' | '\\u1FBE' | '\\u1FC2' .. '\\u1FC4' | '\\u1FC6' .. '\\u1FCC' | '\\u1FD0' .. '\\u1FD3' | '\\u1FD6' .. '\\u1FDB' | '\\u1FE0' .. '\\u1FEC' | '\\u1FF2' .. '\\u1FF4' | '\\u1FF6' .. '\\u1FFC' | '\\u2071' | '\\u207F' | '\\u2090' .. '\\u209C' | '\\u2102' | '\\u2107' | '\\u210A' .. '\\u2113' | '\\u2115' | '\\u2119' .. '\\u211D' | '\\u2124' | '\\u2126' | '\\u2128' | '\\u212A' .. '\\u212D' | '\\u212F' .. '\\u2139' | '\\u213C' .. '\\u213F' | '\\u2145' .. '\\u2149' | '\\u214E' | '\\u2160' .. '\\u2188' | '\\u2C00' .. '\\u2C2E' | '\\u2C30' .. '\\u2C5E' | '\\u2C60' .. '\\u2CE4' | '\\u2CEB' .. '\\u2CEE' | '\\u2CF2' .. '\\u2CF3' | '\\u2D00' .. '\\u2D25' | '\\u2D27' | '\\u2D2D' | '\\u2D30' .. '\\u2D67' | '\\u2D6F' | '\\u2D80' .. '\\u2D96' | '\\u2DA0' .. '\\u2DA6' | '\\u2DA8' .. '\\u2DAE' | '\\u2DB0' .. '\\u2DB6' | '\\u2DB8' .. '\\u2DBE' | '\\u2DC0' .. '\\u2DC6' | '\\u2DC8' .. '\\u2DCE' | '\\u2DD0' .. '\\u2DD6' | '\\u2DD8' .. '\\u2DDE' | '\\u2E2F' | '\\u3005' .. '\\u3007' | '\\u3021' .. '\\u3029' | '\\u3031' .. '\\u3035' | '\\u3038' .. '\\u303C' | '\\u3041' .. '\\u3096' | '\\u309D' .. '\\u309F' | '\\u30A1' .. '\\u30FA' | '\\u30FC' .. '\\u30FF' | '\\u3105' .. '\\u312D' | '\\u3131' .. '\\u318E' | '\\u31A0' .. '\\u31BA' | '\\u31F0' .. '\\u31FF' | '\\u3400' .. '\\u4DB5' | '\\u4E00' .. '\\u9FD5' | '\\uA000' .. '\\uA48C' | '\\uA4D0' .. '\\uA4FD' | '\\uA500' .. '\\uA60C' | '\\uA610' .. '\\uA61F' | '\\uA62A' .. '\\uA62B' | '\\uA640' .. '\\uA66E' | '\\uA67F' .. '\\uA69D' | '\\uA6A0' .. '\\uA6EF' | '\\uA717' .. '\\uA71F' | '\\uA722' .. '\\uA788' | '\\uA78B' .. '\\uA7AD' | '\\uA7B0' .. '\\uA7B7' | '\\uA7F7' .. '\\uA801' | '\\uA803' .. '\\uA805' | '\\uA807' .. '\\uA80A' | '\\uA80C' .. '\\uA822' | '\\uA840' .. '\\uA873' | '\\uA882' .. '\\uA8B3' | '\\uA8F2' .. '\\uA8F7' | '\\uA8FB' | '\\uA8FD' | '\\uA90A' .. '\\uA925' | '\\uA930' .. '\\uA946' | '\\uA960' .. '\\uA97C' | '\\uA984' .. '\\uA9B2' | '\\uA9CF' | '\\uA9E0' .. '\\uA9E4' | '\\uA9E6' .. '\\uA9EF' | '\\uA9FA' .. '\\uA9FE' | '\\uAA00' .. '\\uAA28' | '\\uAA40' .. '\\uAA42' | '\\uAA44' .. '\\uAA4B' | '\\uAA60' .. '\\uAA76' | '\\uAA7A' | '\\uAA7E' .. '\\uAAAF' | '\\uAAB1' | '\\uAAB5' .. '\\uAAB6' | '\\uAAB9' .. '\\uAABD' | '\\uAAC0' | '\\uAAC2' | '\\uAADB' .. '\\uAADD' | '\\uAAE0' .. '\\uAAEA' | '\\uAAF2' .. '\\uAAF4' | '\\uAB01' .. '\\uAB06' | '\\uAB09' .. '\\uAB0E' | '\\uAB11' .. '\\uAB16' | '\\uAB20' .. '\\uAB26' | '\\uAB28' .. '\\uAB2E' | '\\uAB30' .. '\\uAB5A' | '\\uAB5C' .. '\\uAB65' | '\\uAB70' .. '\\uABE2' | '\\uAC00' .. '\\uD7A3' | '\\uD7B0' .. '\\uD7C6' | '\\uD7CB' .. '\\uD7FB' | '\\uF900' .. '\\uFA6D' | '\\uFA70' .. '\\uFAD9' | '\\uFB00' .. '\\uFB06' | '\\uFB13' .. '\\uFB17' | '\\uFB1D' | '\\uFB1F' .. '\\uFB28' | '\\uFB2A' .. '\\uFB36' | '\\uFB38' .. '\\uFB3C' | '\\uFB3E' | '\\uFB40' .. '\\uFB41' | '\\uFB43' .. '\\uFB44' | '\\uFB46' .. '\\uFBB1' | '\\uFBD3' .. '\\uFD3D' | '\\uFD50' .. '\\uFD8F' | '\\uFD92' .. '\\uFDC7' | '\\uFDF0' .. '\\uFDFB' | '\\uFE70' .. '\\uFE74' | '\\uFE76' .. '\\uFEFC' | '\\uFF21' .. '\\uFF3A' | '\\uFF41' .. '\\uFF5A' | '\\uFF66' .. '\\uFFBE' | '\\uFFC2' .. '\\uFFC7' | '\\uFFCA' .. '\\uFFCF' | '\\uFFD2' .. '\\uFFD7' | '\\uFFDA' .. '\\uFFDC' ) { if ( (input.LA(1)>='A' && input.LA(1)<='Z')||(input.LA(1)>='a' && input.LA(1)<='z')||input.LA(1)=='\u00AA'||input.LA(1)=='\u00B5'||input.LA(1)=='\u00BA'||(input.LA(1)>='\u00C0' && input.LA(1)<='\u00D6')||(input.LA(1)>='\u00D8' && input.LA(1)<='\u00F6')||(input.LA(1)>='\u00F8' && input.LA(1)<='\u02C1')||(input.LA(1)>='\u02C6' && input.LA(1)<='\u02D1')||(input.LA(1)>='\u02E0' && input.LA(1)<='\u02E4')||input.LA(1)=='\u02EC'||input.LA(1)=='\u02EE'||(input.LA(1)>='\u0370' && input.LA(1)<='\u0374')||(input.LA(1)>='\u0376' && input.LA(1)<='\u0377')||(input.LA(1)>='\u037A' && input.LA(1)<='\u037D')||input.LA(1)=='\u037F'||input.LA(1)=='\u0386'||(input.LA(1)>='\u0388' && input.LA(1)<='\u038A')||input.LA(1)=='\u038C'||(input.LA(1)>='\u038E' && input.LA(1)<='\u03A1')||(input.LA(1)>='\u03A3' && input.LA(1)<='\u03F5')||(input.LA(1)>='\u03F7' && input.LA(1)<='\u0481')||(input.LA(1)>='\u048A' && input.LA(1)<='\u052F')||(input.LA(1)>='\u0531' && input.LA(1)<='\u0556')||input.LA(1)=='\u0559'||(input.LA(1)>='\u0561' && input.LA(1)<='\u0587')||(input.LA(1)>='\u05D0' && input.LA(1)<='\u05EA')||(input.LA(1)>='\u05F0' && input.LA(1)<='\u05F2')||(input.LA(1)>='\u0620' && input.LA(1)<='\u064A')||(input.LA(1)>='\u066E' && input.LA(1)<='\u066F')||(input.LA(1)>='\u0671' && input.LA(1)<='\u06D3')||input.LA(1)=='\u06D5'||(input.LA(1)>='\u06E5' && input.LA(1)<='\u06E6')||(input.LA(1)>='\u06EE' && input.LA(1)<='\u06EF')||(input.LA(1)>='\u06FA' && input.LA(1)<='\u06FC')||input.LA(1)=='\u06FF'||input.LA(1)=='\u0710'||(input.LA(1)>='\u0712' && input.LA(1)<='\u072F')||(input.LA(1)>='\u074D' && input.LA(1)<='\u07A5')||input.LA(1)=='\u07B1'||(input.LA(1)>='\u07CA' && input.LA(1)<='\u07EA')||(input.LA(1)>='\u07F4' && input.LA(1)<='\u07F5')||input.LA(1)=='\u07FA'||(input.LA(1)>='\u0800' && input.LA(1)<='\u0815')||input.LA(1)=='\u081A'||input.LA(1)=='\u0824'||input.LA(1)=='\u0828'||(input.LA(1)>='\u0840' && input.LA(1)<='\u0858')||(input.LA(1)>='\u08A0' && input.LA(1)<='\u08B4')||(input.LA(1)>='\u0904' && input.LA(1)<='\u0939')||input.LA(1)=='\u093D'||input.LA(1)=='\u0950'||(input.LA(1)>='\u0958' && input.LA(1)<='\u0961')||(input.LA(1)>='\u0971' && input.LA(1)<='\u0980')||(input.LA(1)>='\u0985' && input.LA(1)<='\u098C')||(input.LA(1)>='\u098F' && input.LA(1)<='\u0990')||(input.LA(1)>='\u0993' && input.LA(1)<='\u09A8')||(input.LA(1)>='\u09AA' && input.LA(1)<='\u09B0')||input.LA(1)=='\u09B2'||(input.LA(1)>='\u09B6' && input.LA(1)<='\u09B9')||input.LA(1)=='\u09BD'||input.LA(1)=='\u09CE'||(input.LA(1)>='\u09DC' && input.LA(1)<='\u09DD')||(input.LA(1)>='\u09DF' && input.LA(1)<='\u09E1')||(input.LA(1)>='\u09F0' && input.LA(1)<='\u09F1')||(input.LA(1)>='\u0A05' && input.LA(1)<='\u0A0A')||(input.LA(1)>='\u0A0F' && input.LA(1)<='\u0A10')||(input.LA(1)>='\u0A13' && input.LA(1)<='\u0A28')||(input.LA(1)>='\u0A2A' && input.LA(1)<='\u0A30')||(input.LA(1)>='\u0A32' && input.LA(1)<='\u0A33')||(input.LA(1)>='\u0A35' && input.LA(1)<='\u0A36')||(input.LA(1)>='\u0A38' && input.LA(1)<='\u0A39')||(input.LA(1)>='\u0A59' && input.LA(1)<='\u0A5C')||input.LA(1)=='\u0A5E'||(input.LA(1)>='\u0A72' && input.LA(1)<='\u0A74')||(input.LA(1)>='\u0A85' && input.LA(1)<='\u0A8D')||(input.LA(1)>='\u0A8F' && input.LA(1)<='\u0A91')||(input.LA(1)>='\u0A93' && input.LA(1)<='\u0AA8')||(input.LA(1)>='\u0AAA' && input.LA(1)<='\u0AB0')||(input.LA(1)>='\u0AB2' && input.LA(1)<='\u0AB3')||(input.LA(1)>='\u0AB5' && input.LA(1)<='\u0AB9')||input.LA(1)=='\u0ABD'||input.LA(1)=='\u0AD0'||(input.LA(1)>='\u0AE0' && input.LA(1)<='\u0AE1')||input.LA(1)=='\u0AF9'||(input.LA(1)>='\u0B05' && input.LA(1)<='\u0B0C')||(input.LA(1)>='\u0B0F' && input.LA(1)<='\u0B10')||(input.LA(1)>='\u0B13' && input.LA(1)<='\u0B28')||(input.LA(1)>='\u0B2A' && input.LA(1)<='\u0B30')||(input.LA(1)>='\u0B32' && input.LA(1)<='\u0B33')||(input.LA(1)>='\u0B35' && input.LA(1)<='\u0B39')||input.LA(1)=='\u0B3D'||(input.LA(1)>='\u0B5C' && input.LA(1)<='\u0B5D')||(input.LA(1)>='\u0B5F' && input.LA(1)<='\u0B61')||input.LA(1)=='\u0B71'||input.LA(1)=='\u0B83'||(input.LA(1)>='\u0B85' && input.LA(1)<='\u0B8A')||(input.LA(1)>='\u0B8E' && input.LA(1)<='\u0B90')||(input.LA(1)>='\u0B92' && input.LA(1)<='\u0B95')||(input.LA(1)>='\u0B99' && input.LA(1)<='\u0B9A')||input.LA(1)=='\u0B9C'||(input.LA(1)>='\u0B9E' && input.LA(1)<='\u0B9F')||(input.LA(1)>='\u0BA3' && input.LA(1)<='\u0BA4')||(input.LA(1)>='\u0BA8' && input.LA(1)<='\u0BAA')||(input.LA(1)>='\u0BAE' && input.LA(1)<='\u0BB9')||input.LA(1)=='\u0BD0'||(input.LA(1)>='\u0C05' && input.LA(1)<='\u0C0C')||(input.LA(1)>='\u0C0E' && input.LA(1)<='\u0C10')||(input.LA(1)>='\u0C12' && input.LA(1)<='\u0C28')||(input.LA(1)>='\u0C2A' && input.LA(1)<='\u0C39')||input.LA(1)=='\u0C3D'||(input.LA(1)>='\u0C58' && input.LA(1)<='\u0C5A')||(input.LA(1)>='\u0C60' && input.LA(1)<='\u0C61')||(input.LA(1)>='\u0C85' && input.LA(1)<='\u0C8C')||(input.LA(1)>='\u0C8E' && input.LA(1)<='\u0C90')||(input.LA(1)>='\u0C92' && input.LA(1)<='\u0CA8')||(input.LA(1)>='\u0CAA' && input.LA(1)<='\u0CB3')||(input.LA(1)>='\u0CB5' && input.LA(1)<='\u0CB9')||input.LA(1)=='\u0CBD'||input.LA(1)=='\u0CDE'||(input.LA(1)>='\u0CE0' && input.LA(1)<='\u0CE1')||(input.LA(1)>='\u0CF1' && input.LA(1)<='\u0CF2')||(input.LA(1)>='\u0D05' && input.LA(1)<='\u0D0C')||(input.LA(1)>='\u0D0E' && input.LA(1)<='\u0D10')||(input.LA(1)>='\u0D12' && input.LA(1)<='\u0D3A')||input.LA(1)=='\u0D3D'||input.LA(1)=='\u0D4E'||(input.LA(1)>='\u0D5F' && input.LA(1)<='\u0D61')||(input.LA(1)>='\u0D7A' && input.LA(1)<='\u0D7F')||(input.LA(1)>='\u0D85' && input.LA(1)<='\u0D96')||(input.LA(1)>='\u0D9A' && input.LA(1)<='\u0DB1')||(input.LA(1)>='\u0DB3' && input.LA(1)<='\u0DBB')||input.LA(1)=='\u0DBD'||(input.LA(1)>='\u0DC0' && input.LA(1)<='\u0DC6')||(input.LA(1)>='\u0E01' && input.LA(1)<='\u0E30')||(input.LA(1)>='\u0E32' && input.LA(1)<='\u0E33')||(input.LA(1)>='\u0E40' && input.LA(1)<='\u0E46')||(input.LA(1)>='\u0E81' && input.LA(1)<='\u0E82')||input.LA(1)=='\u0E84'||(input.LA(1)>='\u0E87' && input.LA(1)<='\u0E88')||input.LA(1)=='\u0E8A'||input.LA(1)=='\u0E8D'||(input.LA(1)>='\u0E94' && input.LA(1)<='\u0E97')||(input.LA(1)>='\u0E99' && input.LA(1)<='\u0E9F')||(input.LA(1)>='\u0EA1' && input.LA(1)<='\u0EA3')||input.LA(1)=='\u0EA5'||input.LA(1)=='\u0EA7'||(input.LA(1)>='\u0EAA' && input.LA(1)<='\u0EAB')||(input.LA(1)>='\u0EAD' && input.LA(1)<='\u0EB0')||(input.LA(1)>='\u0EB2' && input.LA(1)<='\u0EB3')||input.LA(1)=='\u0EBD'||(input.LA(1)>='\u0EC0' && input.LA(1)<='\u0EC4')||input.LA(1)=='\u0EC6'||(input.LA(1)>='\u0EDC' && input.LA(1)<='\u0EDF')||input.LA(1)=='\u0F00'||(input.LA(1)>='\u0F40' && input.LA(1)<='\u0F47')||(input.LA(1)>='\u0F49' && input.LA(1)<='\u0F6C')||(input.LA(1)>='\u0F88' && input.LA(1)<='\u0F8C')||(input.LA(1)>='\u1000' && input.LA(1)<='\u102A')||input.LA(1)=='\u103F'||(input.LA(1)>='\u1050' && input.LA(1)<='\u1055')||(input.LA(1)>='\u105A' && input.LA(1)<='\u105D')||input.LA(1)=='\u1061'||(input.LA(1)>='\u1065' && input.LA(1)<='\u1066')||(input.LA(1)>='\u106E' && input.LA(1)<='\u1070')||(input.LA(1)>='\u1075' && input.LA(1)<='\u1081')||input.LA(1)=='\u108E'||(input.LA(1)>='\u10A0' && input.LA(1)<='\u10C5')||input.LA(1)=='\u10C7'||input.LA(1)=='\u10CD'||(input.LA(1)>='\u10D0' && input.LA(1)<='\u10FA')||(input.LA(1)>='\u10FC' && input.LA(1)<='\u1248')||(input.LA(1)>='\u124A' && input.LA(1)<='\u124D')||(input.LA(1)>='\u1250' && input.LA(1)<='\u1256')||input.LA(1)=='\u1258'||(input.LA(1)>='\u125A' && input.LA(1)<='\u125D')||(input.LA(1)>='\u1260' && input.LA(1)<='\u1288')||(input.LA(1)>='\u128A' && input.LA(1)<='\u128D')||(input.LA(1)>='\u1290' && input.LA(1)<='\u12B0')||(input.LA(1)>='\u12B2' && input.LA(1)<='\u12B5')||(input.LA(1)>='\u12B8' && input.LA(1)<='\u12BE')||input.LA(1)=='\u12C0'||(input.LA(1)>='\u12C2' && input.LA(1)<='\u12C5')||(input.LA(1)>='\u12C8' && input.LA(1)<='\u12D6')||(input.LA(1)>='\u12D8' && input.LA(1)<='\u1310')||(input.LA(1)>='\u1312' && input.LA(1)<='\u1315')||(input.LA(1)>='\u1318' && input.LA(1)<='\u135A')||(input.LA(1)>='\u1380' && input.LA(1)<='\u138F')||(input.LA(1)>='\u13A0' && input.LA(1)<='\u13F5')||(input.LA(1)>='\u13F8' && input.LA(1)<='\u13FD')||(input.LA(1)>='\u1401' && input.LA(1)<='\u166C')||(input.LA(1)>='\u166F' && input.LA(1)<='\u167F')||(input.LA(1)>='\u1681' && input.LA(1)<='\u169A')||(input.LA(1)>='\u16A0' && input.LA(1)<='\u16EA')||(input.LA(1)>='\u16EE' && input.LA(1)<='\u16F8')||(input.LA(1)>='\u1700' && input.LA(1)<='\u170C')||(input.LA(1)>='\u170E' && input.LA(1)<='\u1711')||(input.LA(1)>='\u1720' && input.LA(1)<='\u1731')||(input.LA(1)>='\u1740' && input.LA(1)<='\u1751')||(input.LA(1)>='\u1760' && input.LA(1)<='\u176C')||(input.LA(1)>='\u176E' && input.LA(1)<='\u1770')||(input.LA(1)>='\u1780' && input.LA(1)<='\u17B3')||input.LA(1)=='\u17D7'||input.LA(1)=='\u17DC'||(input.LA(1)>='\u1820' && input.LA(1)<='\u1877')||(input.LA(1)>='\u1880' && input.LA(1)<='\u18A8')||input.LA(1)=='\u18AA'||(input.LA(1)>='\u18B0' && input.LA(1)<='\u18F5')||(input.LA(1)>='\u1900' && input.LA(1)<='\u191E')||(input.LA(1)>='\u1950' && input.LA(1)<='\u196D')||(input.LA(1)>='\u1970' && input.LA(1)<='\u1974')||(input.LA(1)>='\u1980' && input.LA(1)<='\u19AB')||(input.LA(1)>='\u19B0' && input.LA(1)<='\u19C9')||(input.LA(1)>='\u1A00' && input.LA(1)<='\u1A16')||(input.LA(1)>='\u1A20' && input.LA(1)<='\u1A54')||input.LA(1)=='\u1AA7'||(input.LA(1)>='\u1B05' && input.LA(1)<='\u1B33')||(input.LA(1)>='\u1B45' && input.LA(1)<='\u1B4B')||(input.LA(1)>='\u1B83' && input.LA(1)<='\u1BA0')||(input.LA(1)>='\u1BAE' && input.LA(1)<='\u1BAF')||(input.LA(1)>='\u1BBA' && input.LA(1)<='\u1BE5')||(input.LA(1)>='\u1C00' && input.LA(1)<='\u1C23')||(input.LA(1)>='\u1C4D' && input.LA(1)<='\u1C4F')||(input.LA(1)>='\u1C5A' && input.LA(1)<='\u1C7D')||(input.LA(1)>='\u1CE9' && input.LA(1)<='\u1CEC')||(input.LA(1)>='\u1CEE' && input.LA(1)<='\u1CF1')||(input.LA(1)>='\u1CF5' && input.LA(1)<='\u1CF6')||(input.LA(1)>='\u1D00' && input.LA(1)<='\u1DBF')||(input.LA(1)>='\u1E00' && input.LA(1)<='\u1F15')||(input.LA(1)>='\u1F18' && input.LA(1)<='\u1F1D')||(input.LA(1)>='\u1F20' && input.LA(1)<='\u1F45')||(input.LA(1)>='\u1F48' && input.LA(1)<='\u1F4D')||(input.LA(1)>='\u1F50' && input.LA(1)<='\u1F57')||input.LA(1)=='\u1F59'||input.LA(1)=='\u1F5B'||input.LA(1)=='\u1F5D'||(input.LA(1)>='\u1F5F' && input.LA(1)<='\u1F7D')||(input.LA(1)>='\u1F80' && input.LA(1)<='\u1FB4')||(input.LA(1)>='\u1FB6' && input.LA(1)<='\u1FBC')||input.LA(1)=='\u1FBE'||(input.LA(1)>='\u1FC2' && input.LA(1)<='\u1FC4')||(input.LA(1)>='\u1FC6' && input.LA(1)<='\u1FCC')||(input.LA(1)>='\u1FD0' && input.LA(1)<='\u1FD3')||(input.LA(1)>='\u1FD6' && input.LA(1)<='\u1FDB')||(input.LA(1)>='\u1FE0' && input.LA(1)<='\u1FEC')||(input.LA(1)>='\u1FF2' && input.LA(1)<='\u1FF4')||(input.LA(1)>='\u1FF6' && input.LA(1)<='\u1FFC')||input.LA(1)=='\u2071'||input.LA(1)=='\u207F'||(input.LA(1)>='\u2090' && input.LA(1)<='\u209C')||input.LA(1)=='\u2102'||input.LA(1)=='\u2107'||(input.LA(1)>='\u210A' && input.LA(1)<='\u2113')||input.LA(1)=='\u2115'||(input.LA(1)>='\u2119' && input.LA(1)<='\u211D')||input.LA(1)=='\u2124'||input.LA(1)=='\u2126'||input.LA(1)=='\u2128'||(input.LA(1)>='\u212A' && input.LA(1)<='\u212D')||(input.LA(1)>='\u212F' && input.LA(1)<='\u2139')||(input.LA(1)>='\u213C' && input.LA(1)<='\u213F')||(input.LA(1)>='\u2145' && input.LA(1)<='\u2149')||input.LA(1)=='\u214E'||(input.LA(1)>='\u2160' && input.LA(1)<='\u2188')||(input.LA(1)>='\u2C00' && input.LA(1)<='\u2C2E')||(input.LA(1)>='\u2C30' && input.LA(1)<='\u2C5E')||(input.LA(1)>='\u2C60' && input.LA(1)<='\u2CE4')||(input.LA(1)>='\u2CEB' && input.LA(1)<='\u2CEE')||(input.LA(1)>='\u2CF2' && input.LA(1)<='\u2CF3')||(input.LA(1)>='\u2D00' && input.LA(1)<='\u2D25')||input.LA(1)=='\u2D27'||input.LA(1)=='\u2D2D'||(input.LA(1)>='\u2D30' && input.LA(1)<='\u2D67')||input.LA(1)=='\u2D6F'||(input.LA(1)>='\u2D80' && input.LA(1)<='\u2D96')||(input.LA(1)>='\u2DA0' && input.LA(1)<='\u2DA6')||(input.LA(1)>='\u2DA8' && input.LA(1)<='\u2DAE')||(input.LA(1)>='\u2DB0' && input.LA(1)<='\u2DB6')||(input.LA(1)>='\u2DB8' && input.LA(1)<='\u2DBE')||(input.LA(1)>='\u2DC0' && input.LA(1)<='\u2DC6')||(input.LA(1)>='\u2DC8' && input.LA(1)<='\u2DCE')||(input.LA(1)>='\u2DD0' && input.LA(1)<='\u2DD6')||(input.LA(1)>='\u2DD8' && input.LA(1)<='\u2DDE')||input.LA(1)=='\u2E2F'||(input.LA(1)>='\u3005' && input.LA(1)<='\u3007')||(input.LA(1)>='\u3021' && input.LA(1)<='\u3029')||(input.LA(1)>='\u3031' && input.LA(1)<='\u3035')||(input.LA(1)>='\u3038' && input.LA(1)<='\u303C')||(input.LA(1)>='\u3041' && input.LA(1)<='\u3096')||(input.LA(1)>='\u309D' && input.LA(1)<='\u309F')||(input.LA(1)>='\u30A1' && input.LA(1)<='\u30FA')||(input.LA(1)>='\u30FC' && input.LA(1)<='\u30FF')||(input.LA(1)>='\u3105' && input.LA(1)<='\u312D')||(input.LA(1)>='\u3131' && input.LA(1)<='\u318E')||(input.LA(1)>='\u31A0' && input.LA(1)<='\u31BA')||(input.LA(1)>='\u31F0' && input.LA(1)<='\u31FF')||(input.LA(1)>='\u3400' && input.LA(1)<='\u4DB5')||(input.LA(1)>='\u4E00' && input.LA(1)<='\u9FD5')||(input.LA(1)>='\uA000' && input.LA(1)<='\uA48C')||(input.LA(1)>='\uA4D0' && input.LA(1)<='\uA4FD')||(input.LA(1)>='\uA500' && input.LA(1)<='\uA60C')||(input.LA(1)>='\uA610' && input.LA(1)<='\uA61F')||(input.LA(1)>='\uA62A' && input.LA(1)<='\uA62B')||(input.LA(1)>='\uA640' && input.LA(1)<='\uA66E')||(input.LA(1)>='\uA67F' && input.LA(1)<='\uA69D')||(input.LA(1)>='\uA6A0' && input.LA(1)<='\uA6EF')||(input.LA(1)>='\uA717' && input.LA(1)<='\uA71F')||(input.LA(1)>='\uA722' && input.LA(1)<='\uA788')||(input.LA(1)>='\uA78B' && input.LA(1)<='\uA7AD')||(input.LA(1)>='\uA7B0' && input.LA(1)<='\uA7B7')||(input.LA(1)>='\uA7F7' && input.LA(1)<='\uA801')||(input.LA(1)>='\uA803' && input.LA(1)<='\uA805')||(input.LA(1)>='\uA807' && input.LA(1)<='\uA80A')||(input.LA(1)>='\uA80C' && input.LA(1)<='\uA822')||(input.LA(1)>='\uA840' && input.LA(1)<='\uA873')||(input.LA(1)>='\uA882' && input.LA(1)<='\uA8B3')||(input.LA(1)>='\uA8F2' && input.LA(1)<='\uA8F7')||input.LA(1)=='\uA8FB'||input.LA(1)=='\uA8FD'||(input.LA(1)>='\uA90A' && input.LA(1)<='\uA925')||(input.LA(1)>='\uA930' && input.LA(1)<='\uA946')||(input.LA(1)>='\uA960' && input.LA(1)<='\uA97C')||(input.LA(1)>='\uA984' && input.LA(1)<='\uA9B2')||input.LA(1)=='\uA9CF'||(input.LA(1)>='\uA9E0' && input.LA(1)<='\uA9E4')||(input.LA(1)>='\uA9E6' && input.LA(1)<='\uA9EF')||(input.LA(1)>='\uA9FA' && input.LA(1)<='\uA9FE')||(input.LA(1)>='\uAA00' && input.LA(1)<='\uAA28')||(input.LA(1)>='\uAA40' && input.LA(1)<='\uAA42')||(input.LA(1)>='\uAA44' && input.LA(1)<='\uAA4B')||(input.LA(1)>='\uAA60' && input.LA(1)<='\uAA76')||input.LA(1)=='\uAA7A'||(input.LA(1)>='\uAA7E' && input.LA(1)<='\uAAAF')||input.LA(1)=='\uAAB1'||(input.LA(1)>='\uAAB5' && input.LA(1)<='\uAAB6')||(input.LA(1)>='\uAAB9' && input.LA(1)<='\uAABD')||input.LA(1)=='\uAAC0'||input.LA(1)=='\uAAC2'||(input.LA(1)>='\uAADB' && input.LA(1)<='\uAADD')||(input.LA(1)>='\uAAE0' && input.LA(1)<='\uAAEA')||(input.LA(1)>='\uAAF2' && input.LA(1)<='\uAAF4')||(input.LA(1)>='\uAB01' && input.LA(1)<='\uAB06')||(input.LA(1)>='\uAB09' && input.LA(1)<='\uAB0E')||(input.LA(1)>='\uAB11' && input.LA(1)<='\uAB16')||(input.LA(1)>='\uAB20' && input.LA(1)<='\uAB26')||(input.LA(1)>='\uAB28' && input.LA(1)<='\uAB2E')||(input.LA(1)>='\uAB30' && input.LA(1)<='\uAB5A')||(input.LA(1)>='\uAB5C' && input.LA(1)<='\uAB65')||(input.LA(1)>='\uAB70' && input.LA(1)<='\uABE2')||(input.LA(1)>='\uAC00' && input.LA(1)<='\uD7A3')||(input.LA(1)>='\uD7B0' && input.LA(1)<='\uD7C6')||(input.LA(1)>='\uD7CB' && input.LA(1)<='\uD7FB')||(input.LA(1)>='\uF900' && input.LA(1)<='\uFA6D')||(input.LA(1)>='\uFA70' && input.LA(1)<='\uFAD9')||(input.LA(1)>='\uFB00' && input.LA(1)<='\uFB06')||(input.LA(1)>='\uFB13' && input.LA(1)<='\uFB17')||input.LA(1)=='\uFB1D'||(input.LA(1)>='\uFB1F' && input.LA(1)<='\uFB28')||(input.LA(1)>='\uFB2A' && input.LA(1)<='\uFB36')||(input.LA(1)>='\uFB38' && input.LA(1)<='\uFB3C')||input.LA(1)=='\uFB3E'||(input.LA(1)>='\uFB40' && input.LA(1)<='\uFB41')||(input.LA(1)>='\uFB43' && input.LA(1)<='\uFB44')||(input.LA(1)>='\uFB46' && input.LA(1)<='\uFBB1')||(input.LA(1)>='\uFBD3' && input.LA(1)<='\uFD3D')||(input.LA(1)>='\uFD50' && input.LA(1)<='\uFD8F')||(input.LA(1)>='\uFD92' && input.LA(1)<='\uFDC7')||(input.LA(1)>='\uFDF0' && input.LA(1)<='\uFDFB')||(input.LA(1)>='\uFE70' && input.LA(1)<='\uFE74')||(input.LA(1)>='\uFE76' && input.LA(1)<='\uFEFC')||(input.LA(1)>='\uFF21' && input.LA(1)<='\uFF3A')||(input.LA(1)>='\uFF41' && input.LA(1)<='\uFF5A')||(input.LA(1)>='\uFF66' && input.LA(1)<='\uFFBE')||(input.LA(1)>='\uFFC2' && input.LA(1)<='\uFFC7')||(input.LA(1)>='\uFFCA' && input.LA(1)<='\uFFCF')||(input.LA(1)>='\uFFD2' && input.LA(1)<='\uFFD7')||(input.LA(1)>='\uFFDA' && input.LA(1)<='\uFFDC') ) { input.consume(); @@ -1325,8 +1499,8 @@ public final void mRULE_UNICODE_LETTER_FRAGMENT() throws RecognitionException { // $ANTLR start "RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT" public final void mRULE_UNICODE_SPACE_SEPARATOR_FRAGMENT() throws RecognitionException { try { - // InternalSemver.g:2199:48: ( ( ' ' | '\\u00A0' | '\\u1680' | '\\u2000' .. '\\u200A' | '\\u202F' | '\\u205F' | '\\u3000' ) ) - // InternalSemver.g:2199:50: ( ' ' | '\\u00A0' | '\\u1680' | '\\u2000' .. '\\u200A' | '\\u202F' | '\\u205F' | '\\u3000' ) + // InternalSemver.g:2467:48: ( ( ' ' | '\\u00A0' | '\\u1680' | '\\u2000' .. '\\u200A' | '\\u202F' | '\\u205F' | '\\u3000' ) ) + // InternalSemver.g:2467:50: ( ' ' | '\\u00A0' | '\\u1680' | '\\u2000' .. '\\u200A' | '\\u202F' | '\\u205F' | '\\u3000' ) { if ( input.LA(1)==' '||input.LA(1)=='\u00A0'||input.LA(1)=='\u1680'||(input.LA(1)>='\u2000' && input.LA(1)<='\u200A')||input.LA(1)=='\u202F'||input.LA(1)=='\u205F'||input.LA(1)=='\u3000' ) { input.consume(); @@ -1349,8 +1523,8 @@ public final void mRULE_UNICODE_SPACE_SEPARATOR_FRAGMENT() throws RecognitionExc // $ANTLR start "RULE_ANY_OTHER" public final void mRULE_ANY_OTHER() throws RecognitionException { try { - // InternalSemver.g:2201:25: ( . ) - // InternalSemver.g:2201:27: . + // InternalSemver.g:2469:25: ( . ) + // InternalSemver.g:2469:27: . { matchAny(); @@ -1363,140 +1537,140 @@ public final void mRULE_ANY_OTHER() throws RecognitionException { // $ANTLR end "RULE_ANY_OTHER" public void mTokens() throws RecognitionException { - // InternalSemver.g:1:8: ( T__35 | T__36 | T__37 | T__38 | T__39 | T__40 | T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | RULE_LETTER_S | RULE_LETTER_M | RULE_LETTER_R | RULE_LETTER_F | RULE_LETTER_I | RULE_LETTER_L | RULE_LETTER_E | RULE_LETTER_V | RULE_LETTER_X | RULE_LETTER_OTHER | RULE_ASTERIX | RULE_DIGITS | RULE_WS | RULE_EOL ) - int alt9=30; + // InternalSemver.g:1:8: ( T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | T__51 | T__52 | T__53 | T__54 | T__55 | T__56 | RULE_LETTER_A | RULE_LETTER_C | RULE_LETTER_E | RULE_LETTER_F | RULE_LETTER_I | RULE_LETTER_K | RULE_LETTER_L | RULE_LETTER_M | RULE_LETTER_O | RULE_LETTER_P | RULE_LETTER_R | RULE_LETTER_S | RULE_LETTER_V | RULE_LETTER_W | RULE_LETTER_X | RULE_LETTER_OTHER | RULE_ASTERIX | RULE_DIGITS | RULE_WS | RULE_EOL ) + int alt9=36; alt9 = dfa9.predict(input); switch (alt9) { case 1 : - // InternalSemver.g:1:10: T__35 + // InternalSemver.g:1:10: T__41 { - mT__35(); + mT__41(); } break; case 2 : - // InternalSemver.g:1:16: T__36 + // InternalSemver.g:1:16: T__42 { - mT__36(); + mT__42(); } break; case 3 : - // InternalSemver.g:1:22: T__37 + // InternalSemver.g:1:22: T__43 { - mT__37(); + mT__43(); } break; case 4 : - // InternalSemver.g:1:28: T__38 + // InternalSemver.g:1:28: T__44 { - mT__38(); + mT__44(); } break; case 5 : - // InternalSemver.g:1:34: T__39 + // InternalSemver.g:1:34: T__45 { - mT__39(); + mT__45(); } break; case 6 : - // InternalSemver.g:1:40: T__40 + // InternalSemver.g:1:40: T__46 { - mT__40(); + mT__46(); } break; case 7 : - // InternalSemver.g:1:46: T__41 + // InternalSemver.g:1:46: T__47 { - mT__41(); + mT__47(); } break; case 8 : - // InternalSemver.g:1:52: T__42 + // InternalSemver.g:1:52: T__48 { - mT__42(); + mT__48(); } break; case 9 : - // InternalSemver.g:1:58: T__43 + // InternalSemver.g:1:58: T__49 { - mT__43(); + mT__49(); } break; case 10 : - // InternalSemver.g:1:64: T__44 + // InternalSemver.g:1:64: T__50 { - mT__44(); + mT__50(); } break; case 11 : - // InternalSemver.g:1:70: T__45 + // InternalSemver.g:1:70: T__51 { - mT__45(); + mT__51(); } break; case 12 : - // InternalSemver.g:1:76: T__46 + // InternalSemver.g:1:76: T__52 { - mT__46(); + mT__52(); } break; case 13 : - // InternalSemver.g:1:82: T__47 + // InternalSemver.g:1:82: T__53 { - mT__47(); + mT__53(); } break; case 14 : - // InternalSemver.g:1:88: T__48 + // InternalSemver.g:1:88: T__54 { - mT__48(); + mT__54(); } break; case 15 : - // InternalSemver.g:1:94: T__49 + // InternalSemver.g:1:94: T__55 { - mT__49(); + mT__55(); } break; case 16 : - // InternalSemver.g:1:100: T__50 + // InternalSemver.g:1:100: T__56 { - mT__50(); + mT__56(); } break; case 17 : - // InternalSemver.g:1:106: RULE_LETTER_S + // InternalSemver.g:1:106: RULE_LETTER_A { - mRULE_LETTER_S(); + mRULE_LETTER_A(); } break; case 18 : - // InternalSemver.g:1:120: RULE_LETTER_M + // InternalSemver.g:1:120: RULE_LETTER_C { - mRULE_LETTER_M(); + mRULE_LETTER_C(); } break; case 19 : - // InternalSemver.g:1:134: RULE_LETTER_R + // InternalSemver.g:1:134: RULE_LETTER_E { - mRULE_LETTER_R(); + mRULE_LETTER_E(); } break; @@ -1515,63 +1689,105 @@ public void mTokens() throws RecognitionException { } break; case 22 : - // InternalSemver.g:1:176: RULE_LETTER_L + // InternalSemver.g:1:176: RULE_LETTER_K { - mRULE_LETTER_L(); + mRULE_LETTER_K(); } break; case 23 : - // InternalSemver.g:1:190: RULE_LETTER_E + // InternalSemver.g:1:190: RULE_LETTER_L { - mRULE_LETTER_E(); + mRULE_LETTER_L(); } break; case 24 : - // InternalSemver.g:1:204: RULE_LETTER_V + // InternalSemver.g:1:204: RULE_LETTER_M { - mRULE_LETTER_V(); + mRULE_LETTER_M(); } break; case 25 : - // InternalSemver.g:1:218: RULE_LETTER_X + // InternalSemver.g:1:218: RULE_LETTER_O { - mRULE_LETTER_X(); + mRULE_LETTER_O(); } break; case 26 : - // InternalSemver.g:1:232: RULE_LETTER_OTHER + // InternalSemver.g:1:232: RULE_LETTER_P { - mRULE_LETTER_OTHER(); + mRULE_LETTER_P(); } break; case 27 : - // InternalSemver.g:1:250: RULE_ASTERIX + // InternalSemver.g:1:246: RULE_LETTER_R { - mRULE_ASTERIX(); + mRULE_LETTER_R(); } break; case 28 : - // InternalSemver.g:1:263: RULE_DIGITS + // InternalSemver.g:1:260: RULE_LETTER_S { - mRULE_DIGITS(); + mRULE_LETTER_S(); } break; case 29 : - // InternalSemver.g:1:275: RULE_WS + // InternalSemver.g:1:274: RULE_LETTER_V { - mRULE_WS(); + mRULE_LETTER_V(); } break; case 30 : - // InternalSemver.g:1:283: RULE_EOL + // InternalSemver.g:1:288: RULE_LETTER_W + { + mRULE_LETTER_W(); + + } + break; + case 31 : + // InternalSemver.g:1:302: RULE_LETTER_X + { + mRULE_LETTER_X(); + + } + break; + case 32 : + // InternalSemver.g:1:316: RULE_LETTER_OTHER + { + mRULE_LETTER_OTHER(); + + } + break; + case 33 : + // InternalSemver.g:1:334: RULE_ASTERIX + { + mRULE_ASTERIX(); + + } + break; + case 34 : + // InternalSemver.g:1:347: RULE_DIGITS + { + mRULE_DIGITS(); + + } + break; + case 35 : + // InternalSemver.g:1:359: RULE_WS + { + mRULE_WS(); + + } + break; + case 36 : + // InternalSemver.g:1:367: RULE_EOL { mRULE_EOL(); @@ -1585,33 +1801,39 @@ public void mTokens() throws RecognitionException { protected DFA9 dfa9 = new DFA9(this); static final String DFA9_eotS = - "\13\uffff\1\36\2\uffff\1\40\22\uffff"; + "\15\uffff\1\44\1\46\30\uffff"; static final String DFA9_eofS = - "\41\uffff"; + "\47\uffff"; static final String DFA9_minS = - "\1\11\12\uffff\1\75\2\uffff\1\75\22\uffff"; + "\1\11\14\uffff\2\75\30\uffff"; static final String DFA9_maxS = - "\1\ufeff\12\uffff\1\75\2\uffff\1\75\22\uffff"; + "\1\ufeff\14\uffff\2\75\30\uffff"; static final String DFA9_acceptS = - "\1\uffff\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\11\1\12\1\uffff\1\14\1\15\1\uffff\1\21\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\16\1\13\1\20\1\17"; + "\1\uffff\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\11\1\12\1\13\1\14\2\uffff\1\21\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43\1\44\1\17\1\15\1\20\1\16"; static final String DFA9_specialS = - "\41\uffff}>"; + "\47\uffff}>"; static final String[] DFA9_transitionS = { - "\1\33\1\34\2\33\1\34\22\uffff\1\33\2\uffff\1\3\6\uffff\1\31\1\7\1\uffff\1\5\1\6\1\2\12\32\1\1\1\uffff\1\13\1\12\1\16\1\uffff\1\10\4\30\1\25\1\22\2\30\1\23\2\30\1\24\1\20\4\30\1\21\1\17\2\30\1\26\1\30\1\27\2\30\3\uffff\1\15\1\11\1\uffff\4\30\1\25\1\22\2\30\1\23\2\30\1\24\1\20\4\30\1\21\1\17\2\30\1\26\1\30\1\27\2\30\1\uffff\1\4\1\uffff\1\14\41\uffff\1\33\u15df\uffff\1\33\u097f\uffff\13\33\35\uffff\2\34\5\uffff\1\33\57\uffff\1\33\u0fa0\uffff\1\33\ucefe\uffff\1\33", + "\1\41\1\42\2\41\1\42\22\uffff\1\41\2\uffff\1\3\6\uffff\1\37\1\7\1\uffff\1\5\1\6\1\2\12\40\1\1\1\uffff\1\15\1\12\1\16\1\uffff\1\10\1\17\1\36\1\20\1\36\1\21\1\22\2\36\1\23\1\36\1\24\1\25\1\26\1\36\1\27\1\30\1\36\1\31\1\32\2\36\1\33\1\34\1\35\2\36\3\uffff\1\14\1\11\1\uffff\1\17\1\36\1\20\1\36\1\21\1\22\2\36\1\23\1\36\1\24\1\25\1\26\1\36\1\27\1\30\1\36\1\31\1\32\2\36\1\33\1\34\1\35\2\36\1\uffff\1\4\1\uffff\1\13\41\uffff\1\41\u15df\uffff\1\41\u097f\uffff\13\41\35\uffff\2\42\5\uffff\1\41\57\uffff\1\41\u0fa0\uffff\1\41\ucefe\uffff\1\41", + "", + "", + "", + "", + "", + "", "", "", "", "", "", "", + "\1\43", + "\1\45", "", "", "", "", - "\1\35", "", "", - "\1\37", "", "", "", @@ -1662,7 +1884,7 @@ public DFA9(BaseRecognizer recognizer) { this.transition = DFA9_transition; } public String getDescription() { - return "1:1: Tokens : ( T__35 | T__36 | T__37 | T__38 | T__39 | T__40 | T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | RULE_LETTER_S | RULE_LETTER_M | RULE_LETTER_R | RULE_LETTER_F | RULE_LETTER_I | RULE_LETTER_L | RULE_LETTER_E | RULE_LETTER_V | RULE_LETTER_X | RULE_LETTER_OTHER | RULE_ASTERIX | RULE_DIGITS | RULE_WS | RULE_EOL );"; + return "1:1: Tokens : ( T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | T__51 | T__52 | T__53 | T__54 | T__55 | T__56 | RULE_LETTER_A | RULE_LETTER_C | RULE_LETTER_E | RULE_LETTER_F | RULE_LETTER_I | RULE_LETTER_K | RULE_LETTER_L | RULE_LETTER_M | RULE_LETTER_O | RULE_LETTER_P | RULE_LETTER_R | RULE_LETTER_S | RULE_LETTER_V | RULE_LETTER_W | RULE_LETTER_X | RULE_LETTER_OTHER | RULE_ASTERIX | RULE_DIGITS | RULE_WS | RULE_EOL );"; } } diff --git a/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/parser/antlr/internal/InternalSemverParser.java b/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/parser/antlr/internal/InternalSemverParser.java index 4e94dc56bc..87a12eb941 100644 --- a/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/parser/antlr/internal/InternalSemverParser.java +++ b/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/parser/antlr/internal/InternalSemverParser.java @@ -33,53 +33,59 @@ @SuppressWarnings("all") public class InternalSemverParser extends AbstractInternalAntlrParser { public static final String[] tokenNames = new String[] { - "", "", "", "", "RULE_WS", "RULE_LETTER_V", "RULE_DIGITS", "RULE_LETTER_F", "RULE_LETTER_I", "RULE_LETTER_L", "RULE_LETTER_E", "RULE_LETTER_S", "RULE_LETTER_M", "RULE_LETTER_R", "RULE_LETTER_X", "RULE_ASTERIX", "RULE_LETTER_OTHER", "RULE_WHITESPACE_FRAGMENT", "RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT", "RULE_EOL", "RULE_DECIMAL_DIGIT_FRAGMENT", "RULE_HEX_DIGIT", "RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT", "RULE_ZWJ", "RULE_ZWNJ", "RULE_BOM", "RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT", "RULE_LINE_TERMINATOR_FRAGMENT", "RULE_SL_COMMENT_FRAGMENT", "RULE_ML_COMMENT_FRAGMENT", "RULE_UNICODE_COMBINING_MARK_FRAGMENT", "RULE_UNICODE_DIGIT_FRAGMENT", "RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT", "RULE_UNICODE_LETTER_FRAGMENT", "RULE_ANY_OTHER", "':'", "'/'", "'#'", "'||'", "'-'", "'.'", "'+'", "'@'", "'_'", "'='", "'<'", "'~'", "'^'", "'<='", "'>'", "'>='" + "", "", "", "", "RULE_WS", "RULE_LETTER_V", "RULE_DIGITS", "RULE_LETTER_F", "RULE_LETTER_I", "RULE_LETTER_L", "RULE_LETTER_E", "RULE_LETTER_S", "RULE_LETTER_M", "RULE_LETTER_R", "RULE_LETTER_W", "RULE_LETTER_O", "RULE_LETTER_K", "RULE_LETTER_P", "RULE_LETTER_A", "RULE_LETTER_C", "RULE_ASTERIX", "RULE_LETTER_X", "RULE_LETTER_OTHER", "RULE_WHITESPACE_FRAGMENT", "RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT", "RULE_EOL", "RULE_DECIMAL_DIGIT_FRAGMENT", "RULE_HEX_DIGIT", "RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT", "RULE_ZWJ", "RULE_ZWNJ", "RULE_BOM", "RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT", "RULE_LINE_TERMINATOR_FRAGMENT", "RULE_SL_COMMENT_FRAGMENT", "RULE_ML_COMMENT_FRAGMENT", "RULE_UNICODE_COMBINING_MARK_FRAGMENT", "RULE_UNICODE_DIGIT_FRAGMENT", "RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT", "RULE_UNICODE_LETTER_FRAGMENT", "RULE_ANY_OTHER", "':'", "'/'", "'#'", "'||'", "'-'", "'.'", "'+'", "'@'", "'_'", "'='", "'~'", "'^'", "'<'", "'>'", "'<='", "'>='" }; public static final int T__50=50; - public static final int RULE_WHITESPACE_FRAGMENT=17; - public static final int RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT=18; - public static final int RULE_EOL=19; - public static final int RULE_LETTER_OTHER=16; - public static final int RULE_UNICODE_COMBINING_MARK_FRAGMENT=30; - public static final int RULE_ZWNJ=24; - public static final int RULE_ASTERIX=15; + public static final int RULE_WHITESPACE_FRAGMENT=23; + public static final int T__55=55; + public static final int T__56=56; + public static final int T__51=51; + public static final int T__52=52; + public static final int T__53=53; + public static final int T__54=54; + public static final int RULE_LINE_TERMINATOR_SEQUENCE_FRAGMENT=24; + public static final int RULE_EOL=25; + public static final int RULE_LETTER_OTHER=22; + public static final int RULE_UNICODE_COMBINING_MARK_FRAGMENT=36; + public static final int RULE_ZWNJ=30; + public static final int RULE_LETTER_A=18; + public static final int RULE_LETTER_C=19; + public static final int RULE_ASTERIX=20; public static final int RULE_LETTER_E=10; - public static final int RULE_ML_COMMENT_FRAGMENT=29; + public static final int RULE_ML_COMMENT_FRAGMENT=35; public static final int RULE_DIGITS=6; - public static final int RULE_ZWJ=23; - public static final int RULE_SL_COMMENT_FRAGMENT=28; - public static final int RULE_UNICODE_DIGIT_FRAGMENT=31; - public static final int T__37=37; + public static final int RULE_LETTER_O=15; + public static final int RULE_ZWJ=29; + public static final int RULE_SL_COMMENT_FRAGMENT=34; + public static final int RULE_LETTER_P=17; + public static final int RULE_UNICODE_DIGIT_FRAGMENT=37; public static final int RULE_LETTER_R=13; - public static final int T__38=38; public static final int RULE_LETTER_S=11; - public static final int T__39=39; public static final int RULE_LETTER_F=7; - public static final int RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT=26; - public static final int T__35=35; - public static final int T__36=36; + public static final int RULE_UNICODE_SPACE_SEPARATOR_FRAGMENT=32; public static final int RULE_LETTER_I=8; public static final int EOF=-1; + public static final int RULE_LETTER_K=16; public static final int RULE_LETTER_L=9; public static final int RULE_LETTER_M=12; public static final int RULE_WS=4; - public static final int RULE_BOM=25; + public static final int RULE_BOM=31; public static final int RULE_LETTER_V=5; - public static final int RULE_LETTER_X=14; - public static final int RULE_ANY_OTHER=34; - public static final int RULE_LINE_TERMINATOR_FRAGMENT=27; - public static final int RULE_UNICODE_LETTER_FRAGMENT=33; - public static final int RULE_DECIMAL_DIGIT_FRAGMENT=20; + public static final int RULE_LETTER_W=14; + public static final int RULE_LETTER_X=21; + public static final int RULE_ANY_OTHER=40; + public static final int RULE_LINE_TERMINATOR_FRAGMENT=33; + public static final int RULE_UNICODE_LETTER_FRAGMENT=39; + public static final int RULE_DECIMAL_DIGIT_FRAGMENT=26; public static final int T__48=48; public static final int T__49=49; public static final int T__44=44; public static final int T__45=45; - public static final int RULE_HEX_DIGIT=21; - public static final int RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT=22; - public static final int RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT=32; + public static final int RULE_HEX_DIGIT=27; + public static final int RULE_DECIMAL_INTEGER_LITERAL_FRAGMENT=28; + public static final int RULE_UNICODE_CONNECTOR_PUNCTUATION_FRAGMENT=38; public static final int T__46=46; public static final int T__47=47; - public static final int T__40=40; public static final int T__41=41; public static final int T__42=42; public static final int T__43=43; @@ -164,48 +170,50 @@ public final EObject entryRuleNPMVersionRequirement() throws RecognitionExceptio // $ANTLR start "ruleNPMVersionRequirement" - // InternalSemver.g:79:1: ruleNPMVersionRequirement returns [EObject current=null] : ( ( (this_WS_0= RULE_WS )? this_VersionRangeSetRequirement_1= ruleVersionRangeSetRequirement ) | ( ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | this_GitHubVersionRequirement_4= ruleGitHubVersionRequirement | this_TagVersionRequirement_5= ruleTagVersionRequirement ) ) (this_WS_6= RULE_WS )? ) ) ; + // InternalSemver.g:79:1: ruleNPMVersionRequirement returns [EObject current=null] : ( ( (this_WS_0= RULE_WS )? this_VersionRangeSetRequirement_1= ruleVersionRangeSetRequirement ) | ( ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) ) ) (this_WS_7= RULE_WS )? ) ) ; public final EObject ruleNPMVersionRequirement() throws RecognitionException { EObject current = null; Token this_WS_0=null; - Token this_WS_6=null; + Token this_WS_7=null; EObject this_VersionRangeSetRequirement_1 = null; EObject this_LocalPathVersionRequirement_2 = null; EObject this_URLVersionRequirement_3 = null; - EObject this_GitHubVersionRequirement_4 = null; + EObject this_WorkspaceVersionRequirement_4 = null; + + EObject this_GitHubVersionRequirement_5 = null; - EObject this_TagVersionRequirement_5 = null; + EObject this_TagVersionRequirement_6 = null; enterRule(); try { - // InternalSemver.g:85:2: ( ( ( (this_WS_0= RULE_WS )? this_VersionRangeSetRequirement_1= ruleVersionRangeSetRequirement ) | ( ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | this_GitHubVersionRequirement_4= ruleGitHubVersionRequirement | this_TagVersionRequirement_5= ruleTagVersionRequirement ) ) (this_WS_6= RULE_WS )? ) ) ) - // InternalSemver.g:86:2: ( ( (this_WS_0= RULE_WS )? this_VersionRangeSetRequirement_1= ruleVersionRangeSetRequirement ) | ( ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | this_GitHubVersionRequirement_4= ruleGitHubVersionRequirement | this_TagVersionRequirement_5= ruleTagVersionRequirement ) ) (this_WS_6= RULE_WS )? ) ) + // InternalSemver.g:85:2: ( ( ( (this_WS_0= RULE_WS )? this_VersionRangeSetRequirement_1= ruleVersionRangeSetRequirement ) | ( ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) ) ) (this_WS_7= RULE_WS )? ) ) ) + // InternalSemver.g:86:2: ( ( (this_WS_0= RULE_WS )? this_VersionRangeSetRequirement_1= ruleVersionRangeSetRequirement ) | ( ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) ) ) (this_WS_7= RULE_WS )? ) ) { - // InternalSemver.g:86:2: ( ( (this_WS_0= RULE_WS )? this_VersionRangeSetRequirement_1= ruleVersionRangeSetRequirement ) | ( ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | this_GitHubVersionRequirement_4= ruleGitHubVersionRequirement | this_TagVersionRequirement_5= ruleTagVersionRequirement ) ) (this_WS_6= RULE_WS )? ) ) - int alt5=2; - int LA5_0 = input.LA(1); + // InternalSemver.g:86:2: ( ( (this_WS_0= RULE_WS )? this_VersionRangeSetRequirement_1= ruleVersionRangeSetRequirement ) | ( ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) ) ) (this_WS_7= RULE_WS )? ) ) + int alt6=2; + int LA6_0 = input.LA(1); - if ( (LA5_0==EOF||(LA5_0>=RULE_WS && LA5_0<=RULE_DIGITS)||(LA5_0>=RULE_LETTER_X && LA5_0<=RULE_ASTERIX)||(LA5_0>=44 && LA5_0<=50)) ) { - alt5=1; + if ( (LA6_0==EOF||(LA6_0>=RULE_WS && LA6_0<=RULE_DIGITS)||(LA6_0>=RULE_ASTERIX && LA6_0<=RULE_LETTER_X)||(LA6_0>=50 && LA6_0<=56)) ) { + alt6=1; } - else if ( ((LA5_0>=RULE_LETTER_F && LA5_0<=RULE_LETTER_R)||LA5_0==RULE_LETTER_OTHER||LA5_0==39||LA5_0==43) ) { - alt5=2; + else if ( ((LA6_0>=RULE_LETTER_F && LA6_0<=RULE_LETTER_C)||LA6_0==RULE_LETTER_OTHER||LA6_0==45||LA6_0==49) ) { + alt6=2; } else { if (state.backtracking>0) {state.failed=true; return current;} NoViableAltException nvae = - new NoViableAltException("", 5, 0, input); + new NoViableAltException("", 6, 0, input); throw nvae; } - switch (alt5) { + switch (alt6) { case 1 : // InternalSemver.g:87:3: ( (this_WS_0= RULE_WS )? this_VersionRangeSetRequirement_1= ruleVersionRangeSetRequirement ) { @@ -258,15 +266,15 @@ else if ( ((LA5_0>=RULE_LETTER_F && LA5_0<=RULE_LETTER_R)||LA5_0==RULE_LETTER_OT } break; case 2 : - // InternalSemver.g:104:3: ( ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | this_GitHubVersionRequirement_4= ruleGitHubVersionRequirement | this_TagVersionRequirement_5= ruleTagVersionRequirement ) ) (this_WS_6= RULE_WS )? ) + // InternalSemver.g:104:3: ( ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) ) ) (this_WS_7= RULE_WS )? ) { - // InternalSemver.g:104:3: ( ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | this_GitHubVersionRequirement_4= ruleGitHubVersionRequirement | this_TagVersionRequirement_5= ruleTagVersionRequirement ) ) (this_WS_6= RULE_WS )? ) - // InternalSemver.g:105:4: ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | this_GitHubVersionRequirement_4= ruleGitHubVersionRequirement | this_TagVersionRequirement_5= ruleTagVersionRequirement ) ) (this_WS_6= RULE_WS )? + // InternalSemver.g:104:3: ( ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) ) ) (this_WS_7= RULE_WS )? ) + // InternalSemver.g:105:4: ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) ) ) (this_WS_7= RULE_WS )? { - // InternalSemver.g:105:4: ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | this_GitHubVersionRequirement_4= ruleGitHubVersionRequirement | this_TagVersionRequirement_5= ruleTagVersionRequirement ) ) - int alt3=2; - alt3 = dfa3.predict(input); - switch (alt3) { + // InternalSemver.g:105:4: ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) ) ) + int alt4=2; + alt4 = dfa4.predict(input); + switch (alt4) { case 1 : // InternalSemver.g:106:5: ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) { @@ -296,12 +304,12 @@ else if ( ((LA5_0>=RULE_LETTER_F && LA5_0<=RULE_LETTER_R)||LA5_0==RULE_LETTER_OT } break; case 2 : - // InternalSemver.g:118:5: ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | this_GitHubVersionRequirement_4= ruleGitHubVersionRequirement | this_TagVersionRequirement_5= ruleTagVersionRequirement ) + // InternalSemver.g:118:5: ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) ) { - // InternalSemver.g:118:5: ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | this_GitHubVersionRequirement_4= ruleGitHubVersionRequirement | this_TagVersionRequirement_5= ruleTagVersionRequirement ) - int alt2=3; - alt2 = dfa2.predict(input); - switch (alt2) { + // InternalSemver.g:118:5: ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) ) + int alt3=2; + alt3 = dfa3.predict(input); + switch (alt3) { case 1 : // InternalSemver.g:119:6: ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) { @@ -331,46 +339,87 @@ else if ( ((LA5_0>=RULE_LETTER_F && LA5_0<=RULE_LETTER_R)||LA5_0==RULE_LETTER_OT } break; case 2 : - // InternalSemver.g:131:6: this_GitHubVersionRequirement_4= ruleGitHubVersionRequirement - { - if ( state.backtracking==0 ) { - - newCompositeNode(grammarAccess.getNPMVersionRequirementAccess().getGitHubVersionRequirementParserRuleCall_1_0_1_1()); - - } - pushFollow(FOLLOW_4); - this_GitHubVersionRequirement_4=ruleGitHubVersionRequirement(); - - state._fsp--; - if (state.failed) return current; - if ( state.backtracking==0 ) { - - current = this_GitHubVersionRequirement_4; - afterParserOrEnumRuleCall(); - - } - - } - break; - case 3 : - // InternalSemver.g:140:6: this_TagVersionRequirement_5= ruleTagVersionRequirement + // InternalSemver.g:131:6: ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) { - if ( state.backtracking==0 ) { + // InternalSemver.g:131:6: ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) + int alt2=3; + alt2 = dfa2.predict(input); + switch (alt2) { + case 1 : + // InternalSemver.g:132:7: ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) + { + // InternalSemver.g:132:7: ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) + // InternalSemver.g:133:8: ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement + { + if ( state.backtracking==0 ) { + + newCompositeNode(grammarAccess.getNPMVersionRequirementAccess().getWorkspaceVersionRequirementParserRuleCall_1_0_1_1_0()); + + } + pushFollow(FOLLOW_4); + this_WorkspaceVersionRequirement_4=ruleWorkspaceVersionRequirement(); + + state._fsp--; + if (state.failed) return current; + if ( state.backtracking==0 ) { + + current = this_WorkspaceVersionRequirement_4; + afterParserOrEnumRuleCall(); + + } + + } + + + } + break; + case 2 : + // InternalSemver.g:144:7: this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement + { + if ( state.backtracking==0 ) { + + newCompositeNode(grammarAccess.getNPMVersionRequirementAccess().getGitHubVersionRequirementParserRuleCall_1_0_1_1_1()); + + } + pushFollow(FOLLOW_4); + this_GitHubVersionRequirement_5=ruleGitHubVersionRequirement(); + + state._fsp--; + if (state.failed) return current; + if ( state.backtracking==0 ) { + + current = this_GitHubVersionRequirement_5; + afterParserOrEnumRuleCall(); + + } + + } + break; + case 3 : + // InternalSemver.g:153:7: this_TagVersionRequirement_6= ruleTagVersionRequirement + { + if ( state.backtracking==0 ) { + + newCompositeNode(grammarAccess.getNPMVersionRequirementAccess().getTagVersionRequirementParserRuleCall_1_0_1_1_2()); + + } + pushFollow(FOLLOW_4); + this_TagVersionRequirement_6=ruleTagVersionRequirement(); + + state._fsp--; + if (state.failed) return current; + if ( state.backtracking==0 ) { + + current = this_TagVersionRequirement_6; + afterParserOrEnumRuleCall(); + + } + + } + break; - newCompositeNode(grammarAccess.getNPMVersionRequirementAccess().getTagVersionRequirementParserRuleCall_1_0_1_2()); - } - pushFollow(FOLLOW_4); - this_TagVersionRequirement_5=ruleTagVersionRequirement(); - state._fsp--; - if (state.failed) return current; - if ( state.backtracking==0 ) { - - current = this_TagVersionRequirement_5; - afterParserOrEnumRuleCall(); - - } } break; @@ -383,21 +432,21 @@ else if ( ((LA5_0>=RULE_LETTER_F && LA5_0<=RULE_LETTER_R)||LA5_0==RULE_LETTER_OT } - // InternalSemver.g:150:4: (this_WS_6= RULE_WS )? - int alt4=2; - int LA4_0 = input.LA(1); + // InternalSemver.g:164:4: (this_WS_7= RULE_WS )? + int alt5=2; + int LA5_0 = input.LA(1); - if ( (LA4_0==RULE_WS) ) { - alt4=1; + if ( (LA5_0==RULE_WS) ) { + alt5=1; } - switch (alt4) { + switch (alt5) { case 1 : - // InternalSemver.g:151:5: this_WS_6= RULE_WS + // InternalSemver.g:165:5: this_WS_7= RULE_WS { - this_WS_6=(Token)match(input,RULE_WS,FOLLOW_2); if (state.failed) return current; + this_WS_7=(Token)match(input,RULE_WS,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { - newLeafNode(this_WS_6, grammarAccess.getNPMVersionRequirementAccess().getWSTerminalRuleCall_1_1()); + newLeafNode(this_WS_7, grammarAccess.getNPMVersionRequirementAccess().getWSTerminalRuleCall_1_1()); } @@ -437,7 +486,7 @@ else if ( ((LA5_0>=RULE_LETTER_F && LA5_0<=RULE_LETTER_R)||LA5_0==RULE_LETTER_OT // $ANTLR start "entryRuleLocalPathVersionRequirement" - // InternalSemver.g:161:1: entryRuleLocalPathVersionRequirement returns [EObject current=null] : iv_ruleLocalPathVersionRequirement= ruleLocalPathVersionRequirement EOF ; + // InternalSemver.g:175:1: entryRuleLocalPathVersionRequirement returns [EObject current=null] : iv_ruleLocalPathVersionRequirement= ruleLocalPathVersionRequirement EOF ; public final EObject entryRuleLocalPathVersionRequirement() throws RecognitionException { EObject current = null; @@ -445,8 +494,8 @@ public final EObject entryRuleLocalPathVersionRequirement() throws RecognitionEx try { - // InternalSemver.g:161:68: (iv_ruleLocalPathVersionRequirement= ruleLocalPathVersionRequirement EOF ) - // InternalSemver.g:162:2: iv_ruleLocalPathVersionRequirement= ruleLocalPathVersionRequirement EOF + // InternalSemver.g:175:68: (iv_ruleLocalPathVersionRequirement= ruleLocalPathVersionRequirement EOF ) + // InternalSemver.g:176:2: iv_ruleLocalPathVersionRequirement= ruleLocalPathVersionRequirement EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getLocalPathVersionRequirementRule()); @@ -477,7 +526,7 @@ public final EObject entryRuleLocalPathVersionRequirement() throws RecognitionEx // $ANTLR start "ruleLocalPathVersionRequirement" - // InternalSemver.g:168:1: ruleLocalPathVersionRequirement returns [EObject current=null] : ( ruleFILE_TAG ( (lv_localPath_1_0= rulePATH ) ) ) ; + // InternalSemver.g:182:1: ruleLocalPathVersionRequirement returns [EObject current=null] : ( ruleFILE_TAG ( (lv_localPath_1_0= rulePATH ) ) ) ; public final EObject ruleLocalPathVersionRequirement() throws RecognitionException { EObject current = null; @@ -488,11 +537,11 @@ public final EObject ruleLocalPathVersionRequirement() throws RecognitionExcepti enterRule(); try { - // InternalSemver.g:174:2: ( ( ruleFILE_TAG ( (lv_localPath_1_0= rulePATH ) ) ) ) - // InternalSemver.g:175:2: ( ruleFILE_TAG ( (lv_localPath_1_0= rulePATH ) ) ) + // InternalSemver.g:188:2: ( ( ruleFILE_TAG ( (lv_localPath_1_0= rulePATH ) ) ) ) + // InternalSemver.g:189:2: ( ruleFILE_TAG ( (lv_localPath_1_0= rulePATH ) ) ) { - // InternalSemver.g:175:2: ( ruleFILE_TAG ( (lv_localPath_1_0= rulePATH ) ) ) - // InternalSemver.g:176:3: ruleFILE_TAG ( (lv_localPath_1_0= rulePATH ) ) + // InternalSemver.g:189:2: ( ruleFILE_TAG ( (lv_localPath_1_0= rulePATH ) ) ) + // InternalSemver.g:190:3: ruleFILE_TAG ( (lv_localPath_1_0= rulePATH ) ) { if ( state.backtracking==0 ) { @@ -509,11 +558,11 @@ public final EObject ruleLocalPathVersionRequirement() throws RecognitionExcepti afterParserOrEnumRuleCall(); } - // InternalSemver.g:183:3: ( (lv_localPath_1_0= rulePATH ) ) - // InternalSemver.g:184:4: (lv_localPath_1_0= rulePATH ) + // InternalSemver.g:197:3: ( (lv_localPath_1_0= rulePATH ) ) + // InternalSemver.g:198:4: (lv_localPath_1_0= rulePATH ) { - // InternalSemver.g:184:4: (lv_localPath_1_0= rulePATH ) - // InternalSemver.g:185:5: lv_localPath_1_0= rulePATH + // InternalSemver.g:198:4: (lv_localPath_1_0= rulePATH ) + // InternalSemver.g:199:5: lv_localPath_1_0= rulePATH { if ( state.backtracking==0 ) { @@ -569,7 +618,7 @@ public final EObject ruleLocalPathVersionRequirement() throws RecognitionExcepti // $ANTLR start "entryRuleURLVersionRequirement" - // InternalSemver.g:206:1: entryRuleURLVersionRequirement returns [EObject current=null] : iv_ruleURLVersionRequirement= ruleURLVersionRequirement EOF ; + // InternalSemver.g:220:1: entryRuleURLVersionRequirement returns [EObject current=null] : iv_ruleURLVersionRequirement= ruleURLVersionRequirement EOF ; public final EObject entryRuleURLVersionRequirement() throws RecognitionException { EObject current = null; @@ -577,8 +626,8 @@ public final EObject entryRuleURLVersionRequirement() throws RecognitionExceptio try { - // InternalSemver.g:206:62: (iv_ruleURLVersionRequirement= ruleURLVersionRequirement EOF ) - // InternalSemver.g:207:2: iv_ruleURLVersionRequirement= ruleURLVersionRequirement EOF + // InternalSemver.g:220:62: (iv_ruleURLVersionRequirement= ruleURLVersionRequirement EOF ) + // InternalSemver.g:221:2: iv_ruleURLVersionRequirement= ruleURLVersionRequirement EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getURLVersionRequirementRule()); @@ -609,7 +658,7 @@ public final EObject entryRuleURLVersionRequirement() throws RecognitionExceptio // $ANTLR start "ruleURLVersionRequirement" - // InternalSemver.g:213:1: ruleURLVersionRequirement returns [EObject current=null] : ( ( (lv_protocol_0_0= ruleURL_PROTOCOL ) ) (otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' ) ( (lv_url_4_0= ruleURL ) ) (otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) )? ) ; + // InternalSemver.g:227:1: ruleURLVersionRequirement returns [EObject current=null] : ( ( (lv_protocol_0_0= ruleURL_PROTOCOL ) ) (otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' ) ( (lv_url_4_0= ruleURL ) ) (otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) )? ) ; public final EObject ruleURLVersionRequirement() throws RecognitionException { EObject current = null; @@ -628,17 +677,17 @@ public final EObject ruleURLVersionRequirement() throws RecognitionException { enterRule(); try { - // InternalSemver.g:219:2: ( ( ( (lv_protocol_0_0= ruleURL_PROTOCOL ) ) (otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' ) ( (lv_url_4_0= ruleURL ) ) (otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) )? ) ) - // InternalSemver.g:220:2: ( ( (lv_protocol_0_0= ruleURL_PROTOCOL ) ) (otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' ) ( (lv_url_4_0= ruleURL ) ) (otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) )? ) + // InternalSemver.g:233:2: ( ( ( (lv_protocol_0_0= ruleURL_PROTOCOL ) ) (otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' ) ( (lv_url_4_0= ruleURL ) ) (otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) )? ) ) + // InternalSemver.g:234:2: ( ( (lv_protocol_0_0= ruleURL_PROTOCOL ) ) (otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' ) ( (lv_url_4_0= ruleURL ) ) (otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) )? ) { - // InternalSemver.g:220:2: ( ( (lv_protocol_0_0= ruleURL_PROTOCOL ) ) (otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' ) ( (lv_url_4_0= ruleURL ) ) (otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) )? ) - // InternalSemver.g:221:3: ( (lv_protocol_0_0= ruleURL_PROTOCOL ) ) (otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' ) ( (lv_url_4_0= ruleURL ) ) (otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) )? + // InternalSemver.g:234:2: ( ( (lv_protocol_0_0= ruleURL_PROTOCOL ) ) (otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' ) ( (lv_url_4_0= ruleURL ) ) (otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) )? ) + // InternalSemver.g:235:3: ( (lv_protocol_0_0= ruleURL_PROTOCOL ) ) (otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' ) ( (lv_url_4_0= ruleURL ) ) (otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) )? { - // InternalSemver.g:221:3: ( (lv_protocol_0_0= ruleURL_PROTOCOL ) ) - // InternalSemver.g:222:4: (lv_protocol_0_0= ruleURL_PROTOCOL ) + // InternalSemver.g:235:3: ( (lv_protocol_0_0= ruleURL_PROTOCOL ) ) + // InternalSemver.g:236:4: (lv_protocol_0_0= ruleURL_PROTOCOL ) { - // InternalSemver.g:222:4: (lv_protocol_0_0= ruleURL_PROTOCOL ) - // InternalSemver.g:223:5: lv_protocol_0_0= ruleURL_PROTOCOL + // InternalSemver.g:236:4: (lv_protocol_0_0= ruleURL_PROTOCOL ) + // InternalSemver.g:237:5: lv_protocol_0_0= ruleURL_PROTOCOL { if ( state.backtracking==0 ) { @@ -669,22 +718,22 @@ public final EObject ruleURLVersionRequirement() throws RecognitionException { } - // InternalSemver.g:240:3: (otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' ) - // InternalSemver.g:241:4: otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' + // InternalSemver.g:254:3: (otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' ) + // InternalSemver.g:255:4: otherlv_1= ':' otherlv_2= '/' otherlv_3= '/' { - otherlv_1=(Token)match(input,35,FOLLOW_7); if (state.failed) return current; + otherlv_1=(Token)match(input,41,FOLLOW_7); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_1, grammarAccess.getURLVersionRequirementAccess().getColonKeyword_1_0()); } - otherlv_2=(Token)match(input,36,FOLLOW_7); if (state.failed) return current; + otherlv_2=(Token)match(input,42,FOLLOW_7); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_2, grammarAccess.getURLVersionRequirementAccess().getSolidusKeyword_1_1()); } - otherlv_3=(Token)match(input,36,FOLLOW_8); if (state.failed) return current; + otherlv_3=(Token)match(input,42,FOLLOW_8); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_3, grammarAccess.getURLVersionRequirementAccess().getSolidusKeyword_1_2()); @@ -693,11 +742,11 @@ public final EObject ruleURLVersionRequirement() throws RecognitionException { } - // InternalSemver.g:254:3: ( (lv_url_4_0= ruleURL ) ) - // InternalSemver.g:255:4: (lv_url_4_0= ruleURL ) + // InternalSemver.g:268:3: ( (lv_url_4_0= ruleURL ) ) + // InternalSemver.g:269:4: (lv_url_4_0= ruleURL ) { - // InternalSemver.g:255:4: (lv_url_4_0= ruleURL ) - // InternalSemver.g:256:5: lv_url_4_0= ruleURL + // InternalSemver.g:269:4: (lv_url_4_0= ruleURL ) + // InternalSemver.g:270:5: lv_url_4_0= ruleURL { if ( state.backtracking==0 ) { @@ -728,28 +777,28 @@ public final EObject ruleURLVersionRequirement() throws RecognitionException { } - // InternalSemver.g:273:3: (otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) )? - int alt6=2; - int LA6_0 = input.LA(1); + // InternalSemver.g:287:3: (otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) )? + int alt7=2; + int LA7_0 = input.LA(1); - if ( (LA6_0==37) ) { - alt6=1; + if ( (LA7_0==43) ) { + alt7=1; } - switch (alt6) { + switch (alt7) { case 1 : - // InternalSemver.g:274:4: otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) + // InternalSemver.g:288:4: otherlv_5= '#' ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) { - otherlv_5=(Token)match(input,37,FOLLOW_10); if (state.failed) return current; + otherlv_5=(Token)match(input,43,FOLLOW_10); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_5, grammarAccess.getURLVersionRequirementAccess().getNumberSignKeyword_3_0()); } - // InternalSemver.g:278:4: ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) - // InternalSemver.g:279:5: (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) + // InternalSemver.g:292:4: ( (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) ) + // InternalSemver.g:293:5: (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) { - // InternalSemver.g:279:5: (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) - // InternalSemver.g:280:6: lv_versionSpecifier_6_0= ruleURLVersionSpecifier + // InternalSemver.g:293:5: (lv_versionSpecifier_6_0= ruleURLVersionSpecifier ) + // InternalSemver.g:294:6: lv_versionSpecifier_6_0= ruleURLVersionSpecifier { if ( state.backtracking==0 ) { @@ -811,7 +860,7 @@ public final EObject ruleURLVersionRequirement() throws RecognitionException { // $ANTLR start "entryRuleURLVersionSpecifier" - // InternalSemver.g:302:1: entryRuleURLVersionSpecifier returns [EObject current=null] : iv_ruleURLVersionSpecifier= ruleURLVersionSpecifier EOF ; + // InternalSemver.g:316:1: entryRuleURLVersionSpecifier returns [EObject current=null] : iv_ruleURLVersionSpecifier= ruleURLVersionSpecifier EOF ; public final EObject entryRuleURLVersionSpecifier() throws RecognitionException { EObject current = null; @@ -819,8 +868,8 @@ public final EObject entryRuleURLVersionSpecifier() throws RecognitionException try { - // InternalSemver.g:302:60: (iv_ruleURLVersionSpecifier= ruleURLVersionSpecifier EOF ) - // InternalSemver.g:303:2: iv_ruleURLVersionSpecifier= ruleURLVersionSpecifier EOF + // InternalSemver.g:316:60: (iv_ruleURLVersionSpecifier= ruleURLVersionSpecifier EOF ) + // InternalSemver.g:317:2: iv_ruleURLVersionSpecifier= ruleURLVersionSpecifier EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getURLVersionSpecifierRule()); @@ -851,7 +900,7 @@ public final EObject entryRuleURLVersionSpecifier() throws RecognitionException // $ANTLR start "ruleURLVersionSpecifier" - // InternalSemver.g:309:1: ruleURLVersionSpecifier returns [EObject current=null] : ( ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) | ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) | ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) ) ; + // InternalSemver.g:323:1: ruleURLVersionSpecifier returns [EObject current=null] : ( ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) | ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) | ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) ) ; public final EObject ruleURLVersionSpecifier() throws RecognitionException { EObject current = null; @@ -866,18 +915,18 @@ public final EObject ruleURLVersionSpecifier() throws RecognitionException { enterRule(); try { - // InternalSemver.g:315:2: ( ( ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) | ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) | ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) ) ) - // InternalSemver.g:316:2: ( ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) | ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) | ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) ) + // InternalSemver.g:329:2: ( ( ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) | ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) | ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) ) ) + // InternalSemver.g:330:2: ( ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) | ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) | ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) ) { - // InternalSemver.g:316:2: ( ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) | ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) | ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) ) - int alt7=3; - alt7 = dfa7.predict(input); - switch (alt7) { + // InternalSemver.g:330:2: ( ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) | ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) | ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) ) + int alt8=3; + alt8 = dfa8.predict(input); + switch (alt8) { case 1 : - // InternalSemver.g:317:3: ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) + // InternalSemver.g:331:3: ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) { - // InternalSemver.g:317:3: ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) - // InternalSemver.g:318:4: ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver + // InternalSemver.g:331:3: ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) + // InternalSemver.g:332:4: ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver { if ( state.backtracking==0 ) { @@ -902,13 +951,13 @@ public final EObject ruleURLVersionSpecifier() throws RecognitionException { } break; case 2 : - // InternalSemver.g:330:3: ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) + // InternalSemver.g:344:3: ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) { - // InternalSemver.g:330:3: ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) - // InternalSemver.g:331:4: () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) + // InternalSemver.g:344:3: ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) + // InternalSemver.g:345:4: () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) { - // InternalSemver.g:331:4: () - // InternalSemver.g:332:5: + // InternalSemver.g:345:4: () + // InternalSemver.g:346:5: { if ( state.backtracking==0 ) { @@ -920,11 +969,11 @@ public final EObject ruleURLVersionSpecifier() throws RecognitionException { } - // InternalSemver.g:338:4: ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) - // InternalSemver.g:339:5: (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) + // InternalSemver.g:352:4: ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) + // InternalSemver.g:353:5: (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) { - // InternalSemver.g:339:5: (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) - // InternalSemver.g:340:6: lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS + // InternalSemver.g:353:5: (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) + // InternalSemver.g:354:6: lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS { if ( state.backtracking==0 ) { @@ -962,13 +1011,13 @@ public final EObject ruleURLVersionSpecifier() throws RecognitionException { } break; case 3 : - // InternalSemver.g:359:3: ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) + // InternalSemver.g:373:3: ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) { - // InternalSemver.g:359:3: ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) - // InternalSemver.g:360:4: () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:373:3: ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) + // InternalSemver.g:374:4: () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) { - // InternalSemver.g:360:4: () - // InternalSemver.g:361:5: + // InternalSemver.g:374:4: () + // InternalSemver.g:375:5: { if ( state.backtracking==0 ) { @@ -980,11 +1029,11 @@ public final EObject ruleURLVersionSpecifier() throws RecognitionException { } - // InternalSemver.g:367:4: ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) - // InternalSemver.g:368:5: (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:381:4: ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:382:5: (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) { - // InternalSemver.g:368:5: (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) - // InternalSemver.g:369:6: lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS + // InternalSemver.g:382:5: (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:383:6: lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS { if ( state.backtracking==0 ) { @@ -1046,7 +1095,7 @@ public final EObject ruleURLVersionSpecifier() throws RecognitionException { // $ANTLR start "entryRuleURLSemver" - // InternalSemver.g:391:1: entryRuleURLSemver returns [EObject current=null] : iv_ruleURLSemver= ruleURLSemver EOF ; + // InternalSemver.g:405:1: entryRuleURLSemver returns [EObject current=null] : iv_ruleURLSemver= ruleURLSemver EOF ; public final EObject entryRuleURLSemver() throws RecognitionException { EObject current = null; @@ -1054,8 +1103,8 @@ public final EObject entryRuleURLSemver() throws RecognitionException { try { - // InternalSemver.g:391:50: (iv_ruleURLSemver= ruleURLSemver EOF ) - // InternalSemver.g:392:2: iv_ruleURLSemver= ruleURLSemver EOF + // InternalSemver.g:405:50: (iv_ruleURLSemver= ruleURLSemver EOF ) + // InternalSemver.g:406:2: iv_ruleURLSemver= ruleURLSemver EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getURLSemverRule()); @@ -1086,7 +1135,7 @@ public final EObject entryRuleURLSemver() throws RecognitionException { // $ANTLR start "ruleURLSemver" - // InternalSemver.g:398:1: ruleURLSemver returns [EObject current=null] : ( () ( (lv_withSemverTag_1_0= ruleSEMVER_TAG ) )? ( (lv_simpleVersion_2_0= ruleSimpleVersion ) ) ) ; + // InternalSemver.g:412:1: ruleURLSemver returns [EObject current=null] : ( () ( (lv_withSemverTag_1_0= ruleSEMVER_TAG ) )? ( (lv_simpleVersion_2_0= ruleSimpleVersion ) ) ) ; public final EObject ruleURLSemver() throws RecognitionException { EObject current = null; @@ -1099,14 +1148,14 @@ public final EObject ruleURLSemver() throws RecognitionException { enterRule(); try { - // InternalSemver.g:404:2: ( ( () ( (lv_withSemverTag_1_0= ruleSEMVER_TAG ) )? ( (lv_simpleVersion_2_0= ruleSimpleVersion ) ) ) ) - // InternalSemver.g:405:2: ( () ( (lv_withSemverTag_1_0= ruleSEMVER_TAG ) )? ( (lv_simpleVersion_2_0= ruleSimpleVersion ) ) ) + // InternalSemver.g:418:2: ( ( () ( (lv_withSemverTag_1_0= ruleSEMVER_TAG ) )? ( (lv_simpleVersion_2_0= ruleSimpleVersion ) ) ) ) + // InternalSemver.g:419:2: ( () ( (lv_withSemverTag_1_0= ruleSEMVER_TAG ) )? ( (lv_simpleVersion_2_0= ruleSimpleVersion ) ) ) { - // InternalSemver.g:405:2: ( () ( (lv_withSemverTag_1_0= ruleSEMVER_TAG ) )? ( (lv_simpleVersion_2_0= ruleSimpleVersion ) ) ) - // InternalSemver.g:406:3: () ( (lv_withSemverTag_1_0= ruleSEMVER_TAG ) )? ( (lv_simpleVersion_2_0= ruleSimpleVersion ) ) + // InternalSemver.g:419:2: ( () ( (lv_withSemverTag_1_0= ruleSEMVER_TAG ) )? ( (lv_simpleVersion_2_0= ruleSimpleVersion ) ) ) + // InternalSemver.g:420:3: () ( (lv_withSemverTag_1_0= ruleSEMVER_TAG ) )? ( (lv_simpleVersion_2_0= ruleSimpleVersion ) ) { - // InternalSemver.g:406:3: () - // InternalSemver.g:407:4: + // InternalSemver.g:420:3: () + // InternalSemver.g:421:4: { if ( state.backtracking==0 ) { @@ -1118,19 +1167,19 @@ public final EObject ruleURLSemver() throws RecognitionException { } - // InternalSemver.g:413:3: ( (lv_withSemverTag_1_0= ruleSEMVER_TAG ) )? - int alt8=2; - int LA8_0 = input.LA(1); + // InternalSemver.g:427:3: ( (lv_withSemverTag_1_0= ruleSEMVER_TAG ) )? + int alt9=2; + int LA9_0 = input.LA(1); - if ( (LA8_0==RULE_LETTER_S) ) { - alt8=1; + if ( (LA9_0==RULE_LETTER_S) ) { + alt9=1; } - switch (alt8) { + switch (alt9) { case 1 : - // InternalSemver.g:414:4: (lv_withSemverTag_1_0= ruleSEMVER_TAG ) + // InternalSemver.g:428:4: (lv_withSemverTag_1_0= ruleSEMVER_TAG ) { - // InternalSemver.g:414:4: (lv_withSemverTag_1_0= ruleSEMVER_TAG ) - // InternalSemver.g:415:5: lv_withSemverTag_1_0= ruleSEMVER_TAG + // InternalSemver.g:428:4: (lv_withSemverTag_1_0= ruleSEMVER_TAG ) + // InternalSemver.g:429:5: lv_withSemverTag_1_0= ruleSEMVER_TAG { if ( state.backtracking==0 ) { @@ -1164,11 +1213,11 @@ public final EObject ruleURLSemver() throws RecognitionException { } - // InternalSemver.g:432:3: ( (lv_simpleVersion_2_0= ruleSimpleVersion ) ) - // InternalSemver.g:433:4: (lv_simpleVersion_2_0= ruleSimpleVersion ) + // InternalSemver.g:446:3: ( (lv_simpleVersion_2_0= ruleSimpleVersion ) ) + // InternalSemver.g:447:4: (lv_simpleVersion_2_0= ruleSimpleVersion ) { - // InternalSemver.g:433:4: (lv_simpleVersion_2_0= ruleSimpleVersion ) - // InternalSemver.g:434:5: lv_simpleVersion_2_0= ruleSimpleVersion + // InternalSemver.g:447:4: (lv_simpleVersion_2_0= ruleSimpleVersion ) + // InternalSemver.g:448:5: lv_simpleVersion_2_0= ruleSimpleVersion { if ( state.backtracking==0 ) { @@ -1223,28 +1272,28 @@ public final EObject ruleURLSemver() throws RecognitionException { // $ANTLR end "ruleURLSemver" - // $ANTLR start "entryRuleTagVersionRequirement" - // InternalSemver.g:455:1: entryRuleTagVersionRequirement returns [EObject current=null] : iv_ruleTagVersionRequirement= ruleTagVersionRequirement EOF ; - public final EObject entryRuleTagVersionRequirement() throws RecognitionException { + // $ANTLR start "entryRuleWorkspaceVersionRequirement" + // InternalSemver.g:469:1: entryRuleWorkspaceVersionRequirement returns [EObject current=null] : iv_ruleWorkspaceVersionRequirement= ruleWorkspaceVersionRequirement EOF ; + public final EObject entryRuleWorkspaceVersionRequirement() throws RecognitionException { EObject current = null; - EObject iv_ruleTagVersionRequirement = null; + EObject iv_ruleWorkspaceVersionRequirement = null; try { - // InternalSemver.g:455:62: (iv_ruleTagVersionRequirement= ruleTagVersionRequirement EOF ) - // InternalSemver.g:456:2: iv_ruleTagVersionRequirement= ruleTagVersionRequirement EOF + // InternalSemver.g:469:68: (iv_ruleWorkspaceVersionRequirement= ruleWorkspaceVersionRequirement EOF ) + // InternalSemver.g:470:2: iv_ruleWorkspaceVersionRequirement= ruleWorkspaceVersionRequirement EOF { if ( state.backtracking==0 ) { - newCompositeNode(grammarAccess.getTagVersionRequirementRule()); + newCompositeNode(grammarAccess.getWorkspaceVersionRequirementRule()); } pushFollow(FOLLOW_1); - iv_ruleTagVersionRequirement=ruleTagVersionRequirement(); + iv_ruleWorkspaceVersionRequirement=ruleWorkspaceVersionRequirement(); state._fsp--; if (state.failed) return current; if ( state.backtracking==0 ) { - current =iv_ruleTagVersionRequirement; + current =iv_ruleWorkspaceVersionRequirement; } match(input,EOF,FOLLOW_2); if (state.failed) return current; @@ -1260,53 +1309,130 @@ public final EObject entryRuleTagVersionRequirement() throws RecognitionExceptio } return current; } - // $ANTLR end "entryRuleTagVersionRequirement" + // $ANTLR end "entryRuleWorkspaceVersionRequirement" - // $ANTLR start "ruleTagVersionRequirement" - // InternalSemver.g:462:1: ruleTagVersionRequirement returns [EObject current=null] : ( (lv_tagName_0_0= ruleTAG ) ) ; - public final EObject ruleTagVersionRequirement() throws RecognitionException { + // $ANTLR start "ruleWorkspaceVersionRequirement" + // InternalSemver.g:476:1: ruleWorkspaceVersionRequirement returns [EObject current=null] : ( ruleWORKSPACE_TAG ( ( ( ( ruleSimpleVersion ) )=> (lv_version_1_0= ruleSimpleVersion ) ) | ( (lv_otherVersion_2_0= ruleWORKSPACE_VERSION ) ) ) ) ; + public final EObject ruleWorkspaceVersionRequirement() throws RecognitionException { EObject current = null; - AntlrDatatypeRuleToken lv_tagName_0_0 = null; + EObject lv_version_1_0 = null; + + AntlrDatatypeRuleToken lv_otherVersion_2_0 = null; enterRule(); try { - // InternalSemver.g:468:2: ( ( (lv_tagName_0_0= ruleTAG ) ) ) - // InternalSemver.g:469:2: ( (lv_tagName_0_0= ruleTAG ) ) - { - // InternalSemver.g:469:2: ( (lv_tagName_0_0= ruleTAG ) ) - // InternalSemver.g:470:3: (lv_tagName_0_0= ruleTAG ) + // InternalSemver.g:482:2: ( ( ruleWORKSPACE_TAG ( ( ( ( ruleSimpleVersion ) )=> (lv_version_1_0= ruleSimpleVersion ) ) | ( (lv_otherVersion_2_0= ruleWORKSPACE_VERSION ) ) ) ) ) + // InternalSemver.g:483:2: ( ruleWORKSPACE_TAG ( ( ( ( ruleSimpleVersion ) )=> (lv_version_1_0= ruleSimpleVersion ) ) | ( (lv_otherVersion_2_0= ruleWORKSPACE_VERSION ) ) ) ) { - // InternalSemver.g:470:3: (lv_tagName_0_0= ruleTAG ) - // InternalSemver.g:471:4: lv_tagName_0_0= ruleTAG + // InternalSemver.g:483:2: ( ruleWORKSPACE_TAG ( ( ( ( ruleSimpleVersion ) )=> (lv_version_1_0= ruleSimpleVersion ) ) | ( (lv_otherVersion_2_0= ruleWORKSPACE_VERSION ) ) ) ) + // InternalSemver.g:484:3: ruleWORKSPACE_TAG ( ( ( ( ruleSimpleVersion ) )=> (lv_version_1_0= ruleSimpleVersion ) ) | ( (lv_otherVersion_2_0= ruleWORKSPACE_VERSION ) ) ) { if ( state.backtracking==0 ) { - newCompositeNode(grammarAccess.getTagVersionRequirementAccess().getTagNameTAGParserRuleCall_0()); - + newCompositeNode(grammarAccess.getWorkspaceVersionRequirementAccess().getWORKSPACE_TAGParserRuleCall_0()); + } - pushFollow(FOLLOW_2); - lv_tagName_0_0=ruleTAG(); + pushFollow(FOLLOW_11); + ruleWORKSPACE_TAG(); state._fsp--; if (state.failed) return current; if ( state.backtracking==0 ) { - if (current==null) { - current = createModelElementForParent(grammarAccess.getTagVersionRequirementRule()); - } - set( - current, - "tagName", - lv_tagName_0_0, - "org.eclipse.n4js.semver.Semver.TAG"); - afterParserOrEnumRuleCall(); - + afterParserOrEnumRuleCall(); + } + // InternalSemver.g:491:3: ( ( ( ( ruleSimpleVersion ) )=> (lv_version_1_0= ruleSimpleVersion ) ) | ( (lv_otherVersion_2_0= ruleWORKSPACE_VERSION ) ) ) + int alt10=2; + alt10 = dfa10.predict(input); + switch (alt10) { + case 1 : + // InternalSemver.g:492:4: ( ( ( ruleSimpleVersion ) )=> (lv_version_1_0= ruleSimpleVersion ) ) + { + // InternalSemver.g:492:4: ( ( ( ruleSimpleVersion ) )=> (lv_version_1_0= ruleSimpleVersion ) ) + // InternalSemver.g:493:5: ( ( ruleSimpleVersion ) )=> (lv_version_1_0= ruleSimpleVersion ) + { + // InternalSemver.g:497:5: (lv_version_1_0= ruleSimpleVersion ) + // InternalSemver.g:498:6: lv_version_1_0= ruleSimpleVersion + { + if ( state.backtracking==0 ) { + + newCompositeNode(grammarAccess.getWorkspaceVersionRequirementAccess().getVersionSimpleVersionParserRuleCall_1_0_0()); + + } + pushFollow(FOLLOW_2); + lv_version_1_0=ruleSimpleVersion(); + + state._fsp--; + if (state.failed) return current; + if ( state.backtracking==0 ) { + + if (current==null) { + current = createModelElementForParent(grammarAccess.getWorkspaceVersionRequirementRule()); + } + set( + current, + "version", + lv_version_1_0, + "org.eclipse.n4js.semver.Semver.SimpleVersion"); + afterParserOrEnumRuleCall(); + + } + + } + + + } + + + } + break; + case 2 : + // InternalSemver.g:516:4: ( (lv_otherVersion_2_0= ruleWORKSPACE_VERSION ) ) + { + // InternalSemver.g:516:4: ( (lv_otherVersion_2_0= ruleWORKSPACE_VERSION ) ) + // InternalSemver.g:517:5: (lv_otherVersion_2_0= ruleWORKSPACE_VERSION ) + { + // InternalSemver.g:517:5: (lv_otherVersion_2_0= ruleWORKSPACE_VERSION ) + // InternalSemver.g:518:6: lv_otherVersion_2_0= ruleWORKSPACE_VERSION + { + if ( state.backtracking==0 ) { + + newCompositeNode(grammarAccess.getWorkspaceVersionRequirementAccess().getOtherVersionWORKSPACE_VERSIONParserRuleCall_1_1_0()); + + } + pushFollow(FOLLOW_2); + lv_otherVersion_2_0=ruleWORKSPACE_VERSION(); + + state._fsp--; + if (state.failed) return current; + if ( state.backtracking==0 ) { + + if (current==null) { + current = createModelElementForParent(grammarAccess.getWorkspaceVersionRequirementRule()); + } + set( + current, + "otherVersion", + lv_otherVersion_2_0, + "org.eclipse.n4js.semver.Semver.WORKSPACE_VERSION"); + afterParserOrEnumRuleCall(); + + } + + } + + + } + + + } + break; } @@ -1331,11 +1457,11 @@ public final EObject ruleTagVersionRequirement() throws RecognitionException { } return current; } - // $ANTLR end "ruleTagVersionRequirement" + // $ANTLR end "ruleWorkspaceVersionRequirement" // $ANTLR start "entryRuleGitHubVersionRequirement" - // InternalSemver.g:491:1: entryRuleGitHubVersionRequirement returns [EObject current=null] : iv_ruleGitHubVersionRequirement= ruleGitHubVersionRequirement EOF ; + // InternalSemver.g:540:1: entryRuleGitHubVersionRequirement returns [EObject current=null] : iv_ruleGitHubVersionRequirement= ruleGitHubVersionRequirement EOF ; public final EObject entryRuleGitHubVersionRequirement() throws RecognitionException { EObject current = null; @@ -1343,8 +1469,8 @@ public final EObject entryRuleGitHubVersionRequirement() throws RecognitionExcep try { - // InternalSemver.g:491:65: (iv_ruleGitHubVersionRequirement= ruleGitHubVersionRequirement EOF ) - // InternalSemver.g:492:2: iv_ruleGitHubVersionRequirement= ruleGitHubVersionRequirement EOF + // InternalSemver.g:540:65: (iv_ruleGitHubVersionRequirement= ruleGitHubVersionRequirement EOF ) + // InternalSemver.g:541:2: iv_ruleGitHubVersionRequirement= ruleGitHubVersionRequirement EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getGitHubVersionRequirementRule()); @@ -1375,7 +1501,7 @@ public final EObject entryRuleGitHubVersionRequirement() throws RecognitionExcep // $ANTLR start "ruleGitHubVersionRequirement" - // InternalSemver.g:498:1: ruleGitHubVersionRequirement returns [EObject current=null] : ( ( (lv_githubUrl_0_0= ruleURL_NO_VX ) ) (otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) )? ) ; + // InternalSemver.g:547:1: ruleGitHubVersionRequirement returns [EObject current=null] : ( ( (lv_githubUrl_0_0= ruleURL_NO_VX ) ) (otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) )? ) ; public final EObject ruleGitHubVersionRequirement() throws RecognitionException { EObject current = null; @@ -1389,17 +1515,17 @@ public final EObject ruleGitHubVersionRequirement() throws RecognitionException enterRule(); try { - // InternalSemver.g:504:2: ( ( ( (lv_githubUrl_0_0= ruleURL_NO_VX ) ) (otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) )? ) ) - // InternalSemver.g:505:2: ( ( (lv_githubUrl_0_0= ruleURL_NO_VX ) ) (otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) )? ) + // InternalSemver.g:553:2: ( ( ( (lv_githubUrl_0_0= ruleURL_NO_VX ) ) (otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) )? ) ) + // InternalSemver.g:554:2: ( ( (lv_githubUrl_0_0= ruleURL_NO_VX ) ) (otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) )? ) { - // InternalSemver.g:505:2: ( ( (lv_githubUrl_0_0= ruleURL_NO_VX ) ) (otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) )? ) - // InternalSemver.g:506:3: ( (lv_githubUrl_0_0= ruleURL_NO_VX ) ) (otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) )? + // InternalSemver.g:554:2: ( ( (lv_githubUrl_0_0= ruleURL_NO_VX ) ) (otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) )? ) + // InternalSemver.g:555:3: ( (lv_githubUrl_0_0= ruleURL_NO_VX ) ) (otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) )? { - // InternalSemver.g:506:3: ( (lv_githubUrl_0_0= ruleURL_NO_VX ) ) - // InternalSemver.g:507:4: (lv_githubUrl_0_0= ruleURL_NO_VX ) + // InternalSemver.g:555:3: ( (lv_githubUrl_0_0= ruleURL_NO_VX ) ) + // InternalSemver.g:556:4: (lv_githubUrl_0_0= ruleURL_NO_VX ) { - // InternalSemver.g:507:4: (lv_githubUrl_0_0= ruleURL_NO_VX ) - // InternalSemver.g:508:5: lv_githubUrl_0_0= ruleURL_NO_VX + // InternalSemver.g:556:4: (lv_githubUrl_0_0= ruleURL_NO_VX ) + // InternalSemver.g:557:5: lv_githubUrl_0_0= ruleURL_NO_VX { if ( state.backtracking==0 ) { @@ -1430,28 +1556,28 @@ public final EObject ruleGitHubVersionRequirement() throws RecognitionException } - // InternalSemver.g:525:3: (otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) )? - int alt9=2; - int LA9_0 = input.LA(1); + // InternalSemver.g:574:3: (otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) )? + int alt11=2; + int LA11_0 = input.LA(1); - if ( (LA9_0==37) ) { - alt9=1; + if ( (LA11_0==43) ) { + alt11=1; } - switch (alt9) { + switch (alt11) { case 1 : - // InternalSemver.g:526:4: otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:575:4: otherlv_1= '#' ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) { - otherlv_1=(Token)match(input,37,FOLLOW_10); if (state.failed) return current; + otherlv_1=(Token)match(input,43,FOLLOW_10); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_1, grammarAccess.getGitHubVersionRequirementAccess().getNumberSignKeyword_1_0()); } - // InternalSemver.g:530:4: ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) - // InternalSemver.g:531:5: (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:579:4: ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:580:5: (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) { - // InternalSemver.g:531:5: (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) - // InternalSemver.g:532:6: lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS + // InternalSemver.g:580:5: (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:581:6: lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS { if ( state.backtracking==0 ) { @@ -1512,8 +1638,119 @@ public final EObject ruleGitHubVersionRequirement() throws RecognitionException // $ANTLR end "ruleGitHubVersionRequirement" + // $ANTLR start "entryRuleTagVersionRequirement" + // InternalSemver.g:603:1: entryRuleTagVersionRequirement returns [EObject current=null] : iv_ruleTagVersionRequirement= ruleTagVersionRequirement EOF ; + public final EObject entryRuleTagVersionRequirement() throws RecognitionException { + EObject current = null; + + EObject iv_ruleTagVersionRequirement = null; + + + try { + // InternalSemver.g:603:62: (iv_ruleTagVersionRequirement= ruleTagVersionRequirement EOF ) + // InternalSemver.g:604:2: iv_ruleTagVersionRequirement= ruleTagVersionRequirement EOF + { + if ( state.backtracking==0 ) { + newCompositeNode(grammarAccess.getTagVersionRequirementRule()); + } + pushFollow(FOLLOW_1); + iv_ruleTagVersionRequirement=ruleTagVersionRequirement(); + + state._fsp--; + if (state.failed) return current; + if ( state.backtracking==0 ) { + current =iv_ruleTagVersionRequirement; + } + match(input,EOF,FOLLOW_2); if (state.failed) return current; + + } + + } + + catch (RecognitionException re) { + recover(input,re); + appendSkippedTokens(); + } + finally { + } + return current; + } + // $ANTLR end "entryRuleTagVersionRequirement" + + + // $ANTLR start "ruleTagVersionRequirement" + // InternalSemver.g:610:1: ruleTagVersionRequirement returns [EObject current=null] : ( (lv_tagName_0_0= ruleTAG ) ) ; + public final EObject ruleTagVersionRequirement() throws RecognitionException { + EObject current = null; + + AntlrDatatypeRuleToken lv_tagName_0_0 = null; + + + + enterRule(); + + try { + // InternalSemver.g:616:2: ( ( (lv_tagName_0_0= ruleTAG ) ) ) + // InternalSemver.g:617:2: ( (lv_tagName_0_0= ruleTAG ) ) + { + // InternalSemver.g:617:2: ( (lv_tagName_0_0= ruleTAG ) ) + // InternalSemver.g:618:3: (lv_tagName_0_0= ruleTAG ) + { + // InternalSemver.g:618:3: (lv_tagName_0_0= ruleTAG ) + // InternalSemver.g:619:4: lv_tagName_0_0= ruleTAG + { + if ( state.backtracking==0 ) { + + newCompositeNode(grammarAccess.getTagVersionRequirementAccess().getTagNameTAGParserRuleCall_0()); + + } + pushFollow(FOLLOW_2); + lv_tagName_0_0=ruleTAG(); + + state._fsp--; + if (state.failed) return current; + if ( state.backtracking==0 ) { + + if (current==null) { + current = createModelElementForParent(grammarAccess.getTagVersionRequirementRule()); + } + set( + current, + "tagName", + lv_tagName_0_0, + "org.eclipse.n4js.semver.Semver.TAG"); + afterParserOrEnumRuleCall(); + + } + + } + + + } + + + } + + if ( state.backtracking==0 ) { + + leaveRule(); + + } + } + + catch (RecognitionException re) { + recover(input,re); + appendSkippedTokens(); + } + finally { + } + return current; + } + // $ANTLR end "ruleTagVersionRequirement" + + // $ANTLR start "entryRuleVersionRangeSetRequirement" - // InternalSemver.g:554:1: entryRuleVersionRangeSetRequirement returns [EObject current=null] : iv_ruleVersionRangeSetRequirement= ruleVersionRangeSetRequirement EOF ; + // InternalSemver.g:639:1: entryRuleVersionRangeSetRequirement returns [EObject current=null] : iv_ruleVersionRangeSetRequirement= ruleVersionRangeSetRequirement EOF ; public final EObject entryRuleVersionRangeSetRequirement() throws RecognitionException { EObject current = null; @@ -1521,8 +1758,8 @@ public final EObject entryRuleVersionRangeSetRequirement() throws RecognitionExc try { - // InternalSemver.g:554:67: (iv_ruleVersionRangeSetRequirement= ruleVersionRangeSetRequirement EOF ) - // InternalSemver.g:555:2: iv_ruleVersionRangeSetRequirement= ruleVersionRangeSetRequirement EOF + // InternalSemver.g:639:67: (iv_ruleVersionRangeSetRequirement= ruleVersionRangeSetRequirement EOF ) + // InternalSemver.g:640:2: iv_ruleVersionRangeSetRequirement= ruleVersionRangeSetRequirement EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getVersionRangeSetRequirementRule()); @@ -1553,7 +1790,7 @@ public final EObject entryRuleVersionRangeSetRequirement() throws RecognitionExc // $ANTLR start "ruleVersionRangeSetRequirement" - // InternalSemver.g:561:1: ruleVersionRangeSetRequirement returns [EObject current=null] : ( () ( ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? )? ) ; + // InternalSemver.g:646:1: ruleVersionRangeSetRequirement returns [EObject current=null] : ( () ( ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? )? ) ; public final EObject ruleVersionRangeSetRequirement() throws RecognitionException { EObject current = null; @@ -1570,14 +1807,14 @@ public final EObject ruleVersionRangeSetRequirement() throws RecognitionExceptio enterRule(); try { - // InternalSemver.g:567:2: ( ( () ( ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? )? ) ) - // InternalSemver.g:568:2: ( () ( ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? )? ) + // InternalSemver.g:652:2: ( ( () ( ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? )? ) ) + // InternalSemver.g:653:2: ( () ( ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? )? ) { - // InternalSemver.g:568:2: ( () ( ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? )? ) - // InternalSemver.g:569:3: () ( ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? )? + // InternalSemver.g:653:2: ( () ( ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? )? ) + // InternalSemver.g:654:3: () ( ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? )? { - // InternalSemver.g:569:3: () - // InternalSemver.g:570:4: + // InternalSemver.g:654:3: () + // InternalSemver.g:655:4: { if ( state.backtracking==0 ) { @@ -1589,29 +1826,29 @@ public final EObject ruleVersionRangeSetRequirement() throws RecognitionExceptio } - // InternalSemver.g:576:3: ( ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? )? - int alt14=2; - int LA14_0 = input.LA(1); + // InternalSemver.g:661:3: ( ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? )? + int alt16=2; + int LA16_0 = input.LA(1); - if ( ((LA14_0>=RULE_LETTER_V && LA14_0<=RULE_DIGITS)||(LA14_0>=RULE_LETTER_X && LA14_0<=RULE_ASTERIX)||(LA14_0>=44 && LA14_0<=50)) ) { - alt14=1; + if ( ((LA16_0>=RULE_LETTER_V && LA16_0<=RULE_DIGITS)||(LA16_0>=RULE_ASTERIX && LA16_0<=RULE_LETTER_X)||(LA16_0>=50 && LA16_0<=56)) ) { + alt16=1; } - switch (alt14) { + switch (alt16) { case 1 : - // InternalSemver.g:577:4: ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? + // InternalSemver.g:662:4: ( (lv_ranges_1_0= ruleVersionRange ) ) ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* (this_WS_6= RULE_WS )? { - // InternalSemver.g:577:4: ( (lv_ranges_1_0= ruleVersionRange ) ) - // InternalSemver.g:578:5: (lv_ranges_1_0= ruleVersionRange ) + // InternalSemver.g:662:4: ( (lv_ranges_1_0= ruleVersionRange ) ) + // InternalSemver.g:663:5: (lv_ranges_1_0= ruleVersionRange ) { - // InternalSemver.g:578:5: (lv_ranges_1_0= ruleVersionRange ) - // InternalSemver.g:579:6: lv_ranges_1_0= ruleVersionRange + // InternalSemver.g:663:5: (lv_ranges_1_0= ruleVersionRange ) + // InternalSemver.g:664:6: lv_ranges_1_0= ruleVersionRange { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getVersionRangeSetRequirementAccess().getRangesVersionRangeParserRuleCall_1_0_0()); } - pushFollow(FOLLOW_11); + pushFollow(FOLLOW_12); lv_ranges_1_0=ruleVersionRange(); state._fsp--; @@ -1635,42 +1872,42 @@ public final EObject ruleVersionRangeSetRequirement() throws RecognitionExceptio } - // InternalSemver.g:596:4: ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* - loop12: + // InternalSemver.g:681:4: ( (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) )* + loop14: do { - int alt12=2; - int LA12_0 = input.LA(1); + int alt14=2; + int LA14_0 = input.LA(1); - if ( (LA12_0==RULE_WS) ) { - int LA12_1 = input.LA(2); + if ( (LA14_0==RULE_WS) ) { + int LA14_1 = input.LA(2); - if ( (LA12_1==38) ) { - alt12=1; + if ( (LA14_1==44) ) { + alt14=1; } } - else if ( (LA12_0==38) ) { - alt12=1; + else if ( (LA14_0==44) ) { + alt14=1; } - switch (alt12) { + switch (alt14) { case 1 : - // InternalSemver.g:597:5: (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) + // InternalSemver.g:682:5: (this_WS_2= RULE_WS )? otherlv_3= '||' (this_WS_4= RULE_WS )? ( (lv_ranges_5_0= ruleVersionRange ) ) { - // InternalSemver.g:597:5: (this_WS_2= RULE_WS )? - int alt10=2; - int LA10_0 = input.LA(1); + // InternalSemver.g:682:5: (this_WS_2= RULE_WS )? + int alt12=2; + int LA12_0 = input.LA(1); - if ( (LA10_0==RULE_WS) ) { - alt10=1; + if ( (LA12_0==RULE_WS) ) { + alt12=1; } - switch (alt10) { + switch (alt12) { case 1 : - // InternalSemver.g:598:6: this_WS_2= RULE_WS + // InternalSemver.g:683:6: this_WS_2= RULE_WS { - this_WS_2=(Token)match(input,RULE_WS,FOLLOW_12); if (state.failed) return current; + this_WS_2=(Token)match(input,RULE_WS,FOLLOW_13); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(this_WS_2, grammarAccess.getVersionRangeSetRequirementAccess().getWSTerminalRuleCall_1_1_0()); @@ -1682,22 +1919,22 @@ else if ( (LA12_0==38) ) { } - otherlv_3=(Token)match(input,38,FOLLOW_13); if (state.failed) return current; + otherlv_3=(Token)match(input,44,FOLLOW_14); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_3, grammarAccess.getVersionRangeSetRequirementAccess().getVerticalLineVerticalLineKeyword_1_1_1()); } - // InternalSemver.g:607:5: (this_WS_4= RULE_WS )? - int alt11=2; - int LA11_0 = input.LA(1); + // InternalSemver.g:692:5: (this_WS_4= RULE_WS )? + int alt13=2; + int LA13_0 = input.LA(1); - if ( (LA11_0==RULE_WS) ) { - alt11=1; + if ( (LA13_0==RULE_WS) ) { + alt13=1; } - switch (alt11) { + switch (alt13) { case 1 : - // InternalSemver.g:608:6: this_WS_4= RULE_WS + // InternalSemver.g:693:6: this_WS_4= RULE_WS { this_WS_4=(Token)match(input,RULE_WS,FOLLOW_3); if (state.failed) return current; if ( state.backtracking==0 ) { @@ -1711,18 +1948,18 @@ else if ( (LA12_0==38) ) { } - // InternalSemver.g:613:5: ( (lv_ranges_5_0= ruleVersionRange ) ) - // InternalSemver.g:614:6: (lv_ranges_5_0= ruleVersionRange ) + // InternalSemver.g:698:5: ( (lv_ranges_5_0= ruleVersionRange ) ) + // InternalSemver.g:699:6: (lv_ranges_5_0= ruleVersionRange ) { - // InternalSemver.g:614:6: (lv_ranges_5_0= ruleVersionRange ) - // InternalSemver.g:615:7: lv_ranges_5_0= ruleVersionRange + // InternalSemver.g:699:6: (lv_ranges_5_0= ruleVersionRange ) + // InternalSemver.g:700:7: lv_ranges_5_0= ruleVersionRange { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getVersionRangeSetRequirementAccess().getRangesVersionRangeParserRuleCall_1_1_3_0()); } - pushFollow(FOLLOW_11); + pushFollow(FOLLOW_12); lv_ranges_5_0=ruleVersionRange(); state._fsp--; @@ -1751,20 +1988,20 @@ else if ( (LA12_0==38) ) { break; default : - break loop12; + break loop14; } } while (true); - // InternalSemver.g:633:4: (this_WS_6= RULE_WS )? - int alt13=2; - int LA13_0 = input.LA(1); + // InternalSemver.g:718:4: (this_WS_6= RULE_WS )? + int alt15=2; + int LA15_0 = input.LA(1); - if ( (LA13_0==RULE_WS) ) { - alt13=1; + if ( (LA15_0==RULE_WS) ) { + alt15=1; } - switch (alt13) { + switch (alt15) { case 1 : - // InternalSemver.g:634:5: this_WS_6= RULE_WS + // InternalSemver.g:719:5: this_WS_6= RULE_WS { this_WS_6=(Token)match(input,RULE_WS,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { @@ -1809,7 +2046,7 @@ else if ( (LA12_0==38) ) { // $ANTLR start "entryRuleVersionRange" - // InternalSemver.g:644:1: entryRuleVersionRange returns [EObject current=null] : iv_ruleVersionRange= ruleVersionRange EOF ; + // InternalSemver.g:729:1: entryRuleVersionRange returns [EObject current=null] : iv_ruleVersionRange= ruleVersionRange EOF ; public final EObject entryRuleVersionRange() throws RecognitionException { EObject current = null; @@ -1817,8 +2054,8 @@ public final EObject entryRuleVersionRange() throws RecognitionException { try { - // InternalSemver.g:644:53: (iv_ruleVersionRange= ruleVersionRange EOF ) - // InternalSemver.g:645:2: iv_ruleVersionRange= ruleVersionRange EOF + // InternalSemver.g:729:53: (iv_ruleVersionRange= ruleVersionRange EOF ) + // InternalSemver.g:730:2: iv_ruleVersionRange= ruleVersionRange EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getVersionRangeRule()); @@ -1849,7 +2086,7 @@ public final EObject entryRuleVersionRange() throws RecognitionException { // $ANTLR start "ruleVersionRange" - // InternalSemver.g:651:1: ruleVersionRange returns [EObject current=null] : (this_VersionRangeContraint_0= ruleVersionRangeContraint | this_HyphenVersionRange_1= ruleHyphenVersionRange ) ; + // InternalSemver.g:736:1: ruleVersionRange returns [EObject current=null] : (this_VersionRangeContraint_0= ruleVersionRangeContraint | this_HyphenVersionRange_1= ruleHyphenVersionRange ) ; public final EObject ruleVersionRange() throws RecognitionException { EObject current = null; @@ -1862,15 +2099,15 @@ public final EObject ruleVersionRange() throws RecognitionException { enterRule(); try { - // InternalSemver.g:657:2: ( (this_VersionRangeContraint_0= ruleVersionRangeContraint | this_HyphenVersionRange_1= ruleHyphenVersionRange ) ) - // InternalSemver.g:658:2: (this_VersionRangeContraint_0= ruleVersionRangeContraint | this_HyphenVersionRange_1= ruleHyphenVersionRange ) + // InternalSemver.g:742:2: ( (this_VersionRangeContraint_0= ruleVersionRangeContraint | this_HyphenVersionRange_1= ruleHyphenVersionRange ) ) + // InternalSemver.g:743:2: (this_VersionRangeContraint_0= ruleVersionRangeContraint | this_HyphenVersionRange_1= ruleHyphenVersionRange ) { - // InternalSemver.g:658:2: (this_VersionRangeContraint_0= ruleVersionRangeContraint | this_HyphenVersionRange_1= ruleHyphenVersionRange ) - int alt15=2; - alt15 = dfa15.predict(input); - switch (alt15) { + // InternalSemver.g:743:2: (this_VersionRangeContraint_0= ruleVersionRangeContraint | this_HyphenVersionRange_1= ruleHyphenVersionRange ) + int alt17=2; + alt17 = dfa17.predict(input); + switch (alt17) { case 1 : - // InternalSemver.g:659:3: this_VersionRangeContraint_0= ruleVersionRangeContraint + // InternalSemver.g:744:3: this_VersionRangeContraint_0= ruleVersionRangeContraint { if ( state.backtracking==0 ) { @@ -1892,7 +2129,7 @@ public final EObject ruleVersionRange() throws RecognitionException { } break; case 2 : - // InternalSemver.g:668:3: this_HyphenVersionRange_1= ruleHyphenVersionRange + // InternalSemver.g:753:3: this_HyphenVersionRange_1= ruleHyphenVersionRange { if ( state.backtracking==0 ) { @@ -1938,7 +2175,7 @@ public final EObject ruleVersionRange() throws RecognitionException { // $ANTLR start "entryRuleHyphenVersionRange" - // InternalSemver.g:680:1: entryRuleHyphenVersionRange returns [EObject current=null] : iv_ruleHyphenVersionRange= ruleHyphenVersionRange EOF ; + // InternalSemver.g:765:1: entryRuleHyphenVersionRange returns [EObject current=null] : iv_ruleHyphenVersionRange= ruleHyphenVersionRange EOF ; public final EObject entryRuleHyphenVersionRange() throws RecognitionException { EObject current = null; @@ -1946,8 +2183,8 @@ public final EObject entryRuleHyphenVersionRange() throws RecognitionException { try { - // InternalSemver.g:680:59: (iv_ruleHyphenVersionRange= ruleHyphenVersionRange EOF ) - // InternalSemver.g:681:2: iv_ruleHyphenVersionRange= ruleHyphenVersionRange EOF + // InternalSemver.g:765:59: (iv_ruleHyphenVersionRange= ruleHyphenVersionRange EOF ) + // InternalSemver.g:766:2: iv_ruleHyphenVersionRange= ruleHyphenVersionRange EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getHyphenVersionRangeRule()); @@ -1978,7 +2215,7 @@ public final EObject entryRuleHyphenVersionRange() throws RecognitionException { // $ANTLR start "ruleHyphenVersionRange" - // InternalSemver.g:687:1: ruleHyphenVersionRange returns [EObject current=null] : ( () ( (lv_from_1_0= ruleVersionNumber ) ) this_WS_2= RULE_WS otherlv_3= '-' this_WS_4= RULE_WS ( (lv_to_5_0= ruleVersionNumber ) ) ) ; + // InternalSemver.g:772:1: ruleHyphenVersionRange returns [EObject current=null] : ( () ( (lv_from_1_0= ruleVersionNumber ) ) this_WS_2= RULE_WS otherlv_3= '-' this_WS_4= RULE_WS ( (lv_to_5_0= ruleVersionNumber ) ) ) ; public final EObject ruleHyphenVersionRange() throws RecognitionException { EObject current = null; @@ -1994,14 +2231,14 @@ public final EObject ruleHyphenVersionRange() throws RecognitionException { enterRule(); try { - // InternalSemver.g:693:2: ( ( () ( (lv_from_1_0= ruleVersionNumber ) ) this_WS_2= RULE_WS otherlv_3= '-' this_WS_4= RULE_WS ( (lv_to_5_0= ruleVersionNumber ) ) ) ) - // InternalSemver.g:694:2: ( () ( (lv_from_1_0= ruleVersionNumber ) ) this_WS_2= RULE_WS otherlv_3= '-' this_WS_4= RULE_WS ( (lv_to_5_0= ruleVersionNumber ) ) ) + // InternalSemver.g:778:2: ( ( () ( (lv_from_1_0= ruleVersionNumber ) ) this_WS_2= RULE_WS otherlv_3= '-' this_WS_4= RULE_WS ( (lv_to_5_0= ruleVersionNumber ) ) ) ) + // InternalSemver.g:779:2: ( () ( (lv_from_1_0= ruleVersionNumber ) ) this_WS_2= RULE_WS otherlv_3= '-' this_WS_4= RULE_WS ( (lv_to_5_0= ruleVersionNumber ) ) ) { - // InternalSemver.g:694:2: ( () ( (lv_from_1_0= ruleVersionNumber ) ) this_WS_2= RULE_WS otherlv_3= '-' this_WS_4= RULE_WS ( (lv_to_5_0= ruleVersionNumber ) ) ) - // InternalSemver.g:695:3: () ( (lv_from_1_0= ruleVersionNumber ) ) this_WS_2= RULE_WS otherlv_3= '-' this_WS_4= RULE_WS ( (lv_to_5_0= ruleVersionNumber ) ) + // InternalSemver.g:779:2: ( () ( (lv_from_1_0= ruleVersionNumber ) ) this_WS_2= RULE_WS otherlv_3= '-' this_WS_4= RULE_WS ( (lv_to_5_0= ruleVersionNumber ) ) ) + // InternalSemver.g:780:3: () ( (lv_from_1_0= ruleVersionNumber ) ) this_WS_2= RULE_WS otherlv_3= '-' this_WS_4= RULE_WS ( (lv_to_5_0= ruleVersionNumber ) ) { - // InternalSemver.g:695:3: () - // InternalSemver.g:696:4: + // InternalSemver.g:780:3: () + // InternalSemver.g:781:4: { if ( state.backtracking==0 ) { @@ -2013,18 +2250,18 @@ public final EObject ruleHyphenVersionRange() throws RecognitionException { } - // InternalSemver.g:702:3: ( (lv_from_1_0= ruleVersionNumber ) ) - // InternalSemver.g:703:4: (lv_from_1_0= ruleVersionNumber ) + // InternalSemver.g:787:3: ( (lv_from_1_0= ruleVersionNumber ) ) + // InternalSemver.g:788:4: (lv_from_1_0= ruleVersionNumber ) { - // InternalSemver.g:703:4: (lv_from_1_0= ruleVersionNumber ) - // InternalSemver.g:704:5: lv_from_1_0= ruleVersionNumber + // InternalSemver.g:788:4: (lv_from_1_0= ruleVersionNumber ) + // InternalSemver.g:789:5: lv_from_1_0= ruleVersionNumber { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getHyphenVersionRangeAccess().getFromVersionNumberParserRuleCall_1_0()); } - pushFollow(FOLLOW_14); + pushFollow(FOLLOW_15); lv_from_1_0=ruleVersionNumber(); state._fsp--; @@ -2048,13 +2285,13 @@ public final EObject ruleHyphenVersionRange() throws RecognitionException { } - this_WS_2=(Token)match(input,RULE_WS,FOLLOW_15); if (state.failed) return current; + this_WS_2=(Token)match(input,RULE_WS,FOLLOW_16); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(this_WS_2, grammarAccess.getHyphenVersionRangeAccess().getWSTerminalRuleCall_2()); } - otherlv_3=(Token)match(input,39,FOLLOW_14); if (state.failed) return current; + otherlv_3=(Token)match(input,45,FOLLOW_15); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_3, grammarAccess.getHyphenVersionRangeAccess().getHyphenMinusKeyword_3()); @@ -2066,11 +2303,11 @@ public final EObject ruleHyphenVersionRange() throws RecognitionException { newLeafNode(this_WS_4, grammarAccess.getHyphenVersionRangeAccess().getWSTerminalRuleCall_4()); } - // InternalSemver.g:733:3: ( (lv_to_5_0= ruleVersionNumber ) ) - // InternalSemver.g:734:4: (lv_to_5_0= ruleVersionNumber ) + // InternalSemver.g:818:3: ( (lv_to_5_0= ruleVersionNumber ) ) + // InternalSemver.g:819:4: (lv_to_5_0= ruleVersionNumber ) { - // InternalSemver.g:734:4: (lv_to_5_0= ruleVersionNumber ) - // InternalSemver.g:735:5: lv_to_5_0= ruleVersionNumber + // InternalSemver.g:819:4: (lv_to_5_0= ruleVersionNumber ) + // InternalSemver.g:820:5: lv_to_5_0= ruleVersionNumber { if ( state.backtracking==0 ) { @@ -2126,7 +2363,7 @@ public final EObject ruleHyphenVersionRange() throws RecognitionException { // $ANTLR start "entryRuleVersionRangeContraint" - // InternalSemver.g:756:1: entryRuleVersionRangeContraint returns [EObject current=null] : iv_ruleVersionRangeContraint= ruleVersionRangeContraint EOF ; + // InternalSemver.g:841:1: entryRuleVersionRangeContraint returns [EObject current=null] : iv_ruleVersionRangeContraint= ruleVersionRangeContraint EOF ; public final EObject entryRuleVersionRangeContraint() throws RecognitionException { EObject current = null; @@ -2134,8 +2371,8 @@ public final EObject entryRuleVersionRangeContraint() throws RecognitionExceptio try { - // InternalSemver.g:756:62: (iv_ruleVersionRangeContraint= ruleVersionRangeContraint EOF ) - // InternalSemver.g:757:2: iv_ruleVersionRangeContraint= ruleVersionRangeContraint EOF + // InternalSemver.g:841:62: (iv_ruleVersionRangeContraint= ruleVersionRangeContraint EOF ) + // InternalSemver.g:842:2: iv_ruleVersionRangeContraint= ruleVersionRangeContraint EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getVersionRangeContraintRule()); @@ -2166,7 +2403,7 @@ public final EObject entryRuleVersionRangeContraint() throws RecognitionExceptio // $ANTLR start "ruleVersionRangeContraint" - // InternalSemver.g:763:1: ruleVersionRangeContraint returns [EObject current=null] : ( () ( (lv_versionConstraints_1_0= ruleSimpleVersion ) ) (this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) )* ) ; + // InternalSemver.g:848:1: ruleVersionRangeContraint returns [EObject current=null] : ( () ( (lv_versionConstraints_1_0= ruleSimpleVersion ) ) (this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) )* ) ; public final EObject ruleVersionRangeContraint() throws RecognitionException { EObject current = null; @@ -2180,14 +2417,14 @@ public final EObject ruleVersionRangeContraint() throws RecognitionException { enterRule(); try { - // InternalSemver.g:769:2: ( ( () ( (lv_versionConstraints_1_0= ruleSimpleVersion ) ) (this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) )* ) ) - // InternalSemver.g:770:2: ( () ( (lv_versionConstraints_1_0= ruleSimpleVersion ) ) (this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) )* ) + // InternalSemver.g:854:2: ( ( () ( (lv_versionConstraints_1_0= ruleSimpleVersion ) ) (this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) )* ) ) + // InternalSemver.g:855:2: ( () ( (lv_versionConstraints_1_0= ruleSimpleVersion ) ) (this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) )* ) { - // InternalSemver.g:770:2: ( () ( (lv_versionConstraints_1_0= ruleSimpleVersion ) ) (this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) )* ) - // InternalSemver.g:771:3: () ( (lv_versionConstraints_1_0= ruleSimpleVersion ) ) (this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) )* + // InternalSemver.g:855:2: ( () ( (lv_versionConstraints_1_0= ruleSimpleVersion ) ) (this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) )* ) + // InternalSemver.g:856:3: () ( (lv_versionConstraints_1_0= ruleSimpleVersion ) ) (this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) )* { - // InternalSemver.g:771:3: () - // InternalSemver.g:772:4: + // InternalSemver.g:856:3: () + // InternalSemver.g:857:4: { if ( state.backtracking==0 ) { @@ -2199,11 +2436,11 @@ public final EObject ruleVersionRangeContraint() throws RecognitionException { } - // InternalSemver.g:778:3: ( (lv_versionConstraints_1_0= ruleSimpleVersion ) ) - // InternalSemver.g:779:4: (lv_versionConstraints_1_0= ruleSimpleVersion ) + // InternalSemver.g:863:3: ( (lv_versionConstraints_1_0= ruleSimpleVersion ) ) + // InternalSemver.g:864:4: (lv_versionConstraints_1_0= ruleSimpleVersion ) { - // InternalSemver.g:779:4: (lv_versionConstraints_1_0= ruleSimpleVersion ) - // InternalSemver.g:780:5: lv_versionConstraints_1_0= ruleSimpleVersion + // InternalSemver.g:864:4: (lv_versionConstraints_1_0= ruleSimpleVersion ) + // InternalSemver.g:865:5: lv_versionConstraints_1_0= ruleSimpleVersion { if ( state.backtracking==0 ) { @@ -2234,26 +2471,26 @@ public final EObject ruleVersionRangeContraint() throws RecognitionException { } - // InternalSemver.g:797:3: (this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) )* - loop16: + // InternalSemver.g:882:3: (this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) )* + loop18: do { - int alt16=2; - int LA16_0 = input.LA(1); + int alt18=2; + int LA18_0 = input.LA(1); - if ( (LA16_0==RULE_WS) ) { - int LA16_1 = input.LA(2); + if ( (LA18_0==RULE_WS) ) { + int LA18_1 = input.LA(2); - if ( ((LA16_1>=RULE_LETTER_V && LA16_1<=RULE_DIGITS)||(LA16_1>=RULE_LETTER_X && LA16_1<=RULE_ASTERIX)||(LA16_1>=44 && LA16_1<=50)) ) { - alt16=1; + if ( ((LA18_1>=RULE_LETTER_V && LA18_1<=RULE_DIGITS)||(LA18_1>=RULE_ASTERIX && LA18_1<=RULE_LETTER_X)||(LA18_1>=50 && LA18_1<=56)) ) { + alt18=1; } } - switch (alt16) { + switch (alt18) { case 1 : - // InternalSemver.g:798:4: this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) + // InternalSemver.g:883:4: this_WS_2= RULE_WS ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) { this_WS_2=(Token)match(input,RULE_WS,FOLLOW_3); if (state.failed) return current; if ( state.backtracking==0 ) { @@ -2261,11 +2498,11 @@ public final EObject ruleVersionRangeContraint() throws RecognitionException { newLeafNode(this_WS_2, grammarAccess.getVersionRangeContraintAccess().getWSTerminalRuleCall_2_0()); } - // InternalSemver.g:802:4: ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) - // InternalSemver.g:803:5: (lv_versionConstraints_3_0= ruleSimpleVersion ) + // InternalSemver.g:887:4: ( (lv_versionConstraints_3_0= ruleSimpleVersion ) ) + // InternalSemver.g:888:5: (lv_versionConstraints_3_0= ruleSimpleVersion ) { - // InternalSemver.g:803:5: (lv_versionConstraints_3_0= ruleSimpleVersion ) - // InternalSemver.g:804:6: lv_versionConstraints_3_0= ruleSimpleVersion + // InternalSemver.g:888:5: (lv_versionConstraints_3_0= ruleSimpleVersion ) + // InternalSemver.g:889:6: lv_versionConstraints_3_0= ruleSimpleVersion { if ( state.backtracking==0 ) { @@ -2301,7 +2538,7 @@ public final EObject ruleVersionRangeContraint() throws RecognitionException { break; default : - break loop16; + break loop18; } } while (true); @@ -2330,7 +2567,7 @@ public final EObject ruleVersionRangeContraint() throws RecognitionException { // $ANTLR start "entryRuleSimpleVersion" - // InternalSemver.g:826:1: entryRuleSimpleVersion returns [EObject current=null] : iv_ruleSimpleVersion= ruleSimpleVersion EOF ; + // InternalSemver.g:911:1: entryRuleSimpleVersion returns [EObject current=null] : iv_ruleSimpleVersion= ruleSimpleVersion EOF ; public final EObject entryRuleSimpleVersion() throws RecognitionException { EObject current = null; @@ -2338,8 +2575,8 @@ public final EObject entryRuleSimpleVersion() throws RecognitionException { try { - // InternalSemver.g:826:54: (iv_ruleSimpleVersion= ruleSimpleVersion EOF ) - // InternalSemver.g:827:2: iv_ruleSimpleVersion= ruleSimpleVersion EOF + // InternalSemver.g:911:54: (iv_ruleSimpleVersion= ruleSimpleVersion EOF ) + // InternalSemver.g:912:2: iv_ruleSimpleVersion= ruleSimpleVersion EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getSimpleVersionRule()); @@ -2370,7 +2607,7 @@ public final EObject entryRuleSimpleVersion() throws RecognitionException { // $ANTLR start "ruleSimpleVersion" - // InternalSemver.g:833:1: ruleSimpleVersion returns [EObject current=null] : ( ( ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? )* ( (lv_withLetterV_2_0= RULE_LETTER_V ) )? ( (lv_number_3_0= ruleVersionNumber ) ) ) ; + // InternalSemver.g:918:1: ruleSimpleVersion returns [EObject current=null] : ( ( ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? )* ( (lv_withLetterV_2_0= RULE_LETTER_V ) )? ( (lv_number_3_0= ruleVersionNumber ) ) ) ; public final EObject ruleSimpleVersion() throws RecognitionException { EObject current = null; @@ -2385,39 +2622,39 @@ public final EObject ruleSimpleVersion() throws RecognitionException { enterRule(); try { - // InternalSemver.g:839:2: ( ( ( ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? )* ( (lv_withLetterV_2_0= RULE_LETTER_V ) )? ( (lv_number_3_0= ruleVersionNumber ) ) ) ) - // InternalSemver.g:840:2: ( ( ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? )* ( (lv_withLetterV_2_0= RULE_LETTER_V ) )? ( (lv_number_3_0= ruleVersionNumber ) ) ) + // InternalSemver.g:924:2: ( ( ( ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? )* ( (lv_withLetterV_2_0= RULE_LETTER_V ) )? ( (lv_number_3_0= ruleVersionNumber ) ) ) ) + // InternalSemver.g:925:2: ( ( ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? )* ( (lv_withLetterV_2_0= RULE_LETTER_V ) )? ( (lv_number_3_0= ruleVersionNumber ) ) ) { - // InternalSemver.g:840:2: ( ( ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? )* ( (lv_withLetterV_2_0= RULE_LETTER_V ) )? ( (lv_number_3_0= ruleVersionNumber ) ) ) - // InternalSemver.g:841:3: ( ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? )* ( (lv_withLetterV_2_0= RULE_LETTER_V ) )? ( (lv_number_3_0= ruleVersionNumber ) ) + // InternalSemver.g:925:2: ( ( ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? )* ( (lv_withLetterV_2_0= RULE_LETTER_V ) )? ( (lv_number_3_0= ruleVersionNumber ) ) ) + // InternalSemver.g:926:3: ( ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? )* ( (lv_withLetterV_2_0= RULE_LETTER_V ) )? ( (lv_number_3_0= ruleVersionNumber ) ) { - // InternalSemver.g:841:3: ( ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? )* - loop18: + // InternalSemver.g:926:3: ( ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? )* + loop20: do { - int alt18=2; - int LA18_0 = input.LA(1); + int alt20=2; + int LA20_0 = input.LA(1); - if ( ((LA18_0>=44 && LA18_0<=50)) ) { - alt18=1; + if ( ((LA20_0>=50 && LA20_0<=56)) ) { + alt20=1; } - switch (alt18) { + switch (alt20) { case 1 : - // InternalSemver.g:842:4: ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? + // InternalSemver.g:927:4: ( (lv_comparators_0_0= ruleVersionComparator ) ) (this_WS_1= RULE_WS )? { - // InternalSemver.g:842:4: ( (lv_comparators_0_0= ruleVersionComparator ) ) - // InternalSemver.g:843:5: (lv_comparators_0_0= ruleVersionComparator ) + // InternalSemver.g:927:4: ( (lv_comparators_0_0= ruleVersionComparator ) ) + // InternalSemver.g:928:5: (lv_comparators_0_0= ruleVersionComparator ) { - // InternalSemver.g:843:5: (lv_comparators_0_0= ruleVersionComparator ) - // InternalSemver.g:844:6: lv_comparators_0_0= ruleVersionComparator + // InternalSemver.g:928:5: (lv_comparators_0_0= ruleVersionComparator ) + // InternalSemver.g:929:6: lv_comparators_0_0= ruleVersionComparator { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getSimpleVersionAccess().getComparatorsVersionComparatorEnumRuleCall_0_0_0()); } - pushFollow(FOLLOW_13); + pushFollow(FOLLOW_14); lv_comparators_0_0=ruleVersionComparator(); state._fsp--; @@ -2441,16 +2678,16 @@ public final EObject ruleSimpleVersion() throws RecognitionException { } - // InternalSemver.g:861:4: (this_WS_1= RULE_WS )? - int alt17=2; - int LA17_0 = input.LA(1); + // InternalSemver.g:946:4: (this_WS_1= RULE_WS )? + int alt19=2; + int LA19_0 = input.LA(1); - if ( (LA17_0==RULE_WS) ) { - alt17=1; + if ( (LA19_0==RULE_WS) ) { + alt19=1; } - switch (alt17) { + switch (alt19) { case 1 : - // InternalSemver.g:862:5: this_WS_1= RULE_WS + // InternalSemver.g:947:5: this_WS_1= RULE_WS { this_WS_1=(Token)match(input,RULE_WS,FOLLOW_3); if (state.failed) return current; if ( state.backtracking==0 ) { @@ -2469,23 +2706,23 @@ public final EObject ruleSimpleVersion() throws RecognitionException { break; default : - break loop18; + break loop20; } } while (true); - // InternalSemver.g:868:3: ( (lv_withLetterV_2_0= RULE_LETTER_V ) )? - int alt19=2; - int LA19_0 = input.LA(1); + // InternalSemver.g:953:3: ( (lv_withLetterV_2_0= RULE_LETTER_V ) )? + int alt21=2; + int LA21_0 = input.LA(1); - if ( (LA19_0==RULE_LETTER_V) ) { - alt19=1; + if ( (LA21_0==RULE_LETTER_V) ) { + alt21=1; } - switch (alt19) { + switch (alt21) { case 1 : - // InternalSemver.g:869:4: (lv_withLetterV_2_0= RULE_LETTER_V ) + // InternalSemver.g:954:4: (lv_withLetterV_2_0= RULE_LETTER_V ) { - // InternalSemver.g:869:4: (lv_withLetterV_2_0= RULE_LETTER_V ) - // InternalSemver.g:870:5: lv_withLetterV_2_0= RULE_LETTER_V + // InternalSemver.g:954:4: (lv_withLetterV_2_0= RULE_LETTER_V ) + // InternalSemver.g:955:5: lv_withLetterV_2_0= RULE_LETTER_V { lv_withLetterV_2_0=(Token)match(input,RULE_LETTER_V,FOLLOW_3); if (state.failed) return current; if ( state.backtracking==0 ) { @@ -2514,11 +2751,11 @@ public final EObject ruleSimpleVersion() throws RecognitionException { } - // InternalSemver.g:886:3: ( (lv_number_3_0= ruleVersionNumber ) ) - // InternalSemver.g:887:4: (lv_number_3_0= ruleVersionNumber ) + // InternalSemver.g:971:3: ( (lv_number_3_0= ruleVersionNumber ) ) + // InternalSemver.g:972:4: (lv_number_3_0= ruleVersionNumber ) { - // InternalSemver.g:887:4: (lv_number_3_0= ruleVersionNumber ) - // InternalSemver.g:888:5: lv_number_3_0= ruleVersionNumber + // InternalSemver.g:972:4: (lv_number_3_0= ruleVersionNumber ) + // InternalSemver.g:973:5: lv_number_3_0= ruleVersionNumber { if ( state.backtracking==0 ) { @@ -2574,7 +2811,7 @@ public final EObject ruleSimpleVersion() throws RecognitionException { // $ANTLR start "entryRuleVersionNumber" - // InternalSemver.g:909:1: entryRuleVersionNumber returns [EObject current=null] : iv_ruleVersionNumber= ruleVersionNumber EOF ; + // InternalSemver.g:994:1: entryRuleVersionNumber returns [EObject current=null] : iv_ruleVersionNumber= ruleVersionNumber EOF ; public final EObject entryRuleVersionNumber() throws RecognitionException { EObject current = null; @@ -2582,8 +2819,8 @@ public final EObject entryRuleVersionNumber() throws RecognitionException { try { - // InternalSemver.g:909:54: (iv_ruleVersionNumber= ruleVersionNumber EOF ) - // InternalSemver.g:910:2: iv_ruleVersionNumber= ruleVersionNumber EOF + // InternalSemver.g:994:54: (iv_ruleVersionNumber= ruleVersionNumber EOF ) + // InternalSemver.g:995:2: iv_ruleVersionNumber= ruleVersionNumber EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getVersionNumberRule()); @@ -2614,7 +2851,7 @@ public final EObject entryRuleVersionNumber() throws RecognitionException { // $ANTLR start "ruleVersionNumber" - // InternalSemver.g:916:1: ruleVersionNumber returns [EObject current=null] : ( ( (lv_major_0_0= ruleVersionPart ) ) (otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? )? ( (lv_qualifier_7_0= ruleQualifier ) )? ) ; + // InternalSemver.g:1001:1: ruleVersionNumber returns [EObject current=null] : ( ( (lv_major_0_0= ruleVersionPart ) ) (otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? )? ( (lv_qualifier_7_0= ruleQualifier ) )? ) ; public final EObject ruleVersionNumber() throws RecognitionException { EObject current = null; @@ -2636,24 +2873,24 @@ public final EObject ruleVersionNumber() throws RecognitionException { enterRule(); try { - // InternalSemver.g:922:2: ( ( ( (lv_major_0_0= ruleVersionPart ) ) (otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? )? ( (lv_qualifier_7_0= ruleQualifier ) )? ) ) - // InternalSemver.g:923:2: ( ( (lv_major_0_0= ruleVersionPart ) ) (otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? )? ( (lv_qualifier_7_0= ruleQualifier ) )? ) + // InternalSemver.g:1007:2: ( ( ( (lv_major_0_0= ruleVersionPart ) ) (otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? )? ( (lv_qualifier_7_0= ruleQualifier ) )? ) ) + // InternalSemver.g:1008:2: ( ( (lv_major_0_0= ruleVersionPart ) ) (otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? )? ( (lv_qualifier_7_0= ruleQualifier ) )? ) { - // InternalSemver.g:923:2: ( ( (lv_major_0_0= ruleVersionPart ) ) (otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? )? ( (lv_qualifier_7_0= ruleQualifier ) )? ) - // InternalSemver.g:924:3: ( (lv_major_0_0= ruleVersionPart ) ) (otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? )? ( (lv_qualifier_7_0= ruleQualifier ) )? + // InternalSemver.g:1008:2: ( ( (lv_major_0_0= ruleVersionPart ) ) (otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? )? ( (lv_qualifier_7_0= ruleQualifier ) )? ) + // InternalSemver.g:1009:3: ( (lv_major_0_0= ruleVersionPart ) ) (otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? )? ( (lv_qualifier_7_0= ruleQualifier ) )? { - // InternalSemver.g:924:3: ( (lv_major_0_0= ruleVersionPart ) ) - // InternalSemver.g:925:4: (lv_major_0_0= ruleVersionPart ) + // InternalSemver.g:1009:3: ( (lv_major_0_0= ruleVersionPart ) ) + // InternalSemver.g:1010:4: (lv_major_0_0= ruleVersionPart ) { - // InternalSemver.g:925:4: (lv_major_0_0= ruleVersionPart ) - // InternalSemver.g:926:5: lv_major_0_0= ruleVersionPart + // InternalSemver.g:1010:4: (lv_major_0_0= ruleVersionPart ) + // InternalSemver.g:1011:5: lv_major_0_0= ruleVersionPart { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getVersionNumberAccess().getMajorVersionPartParserRuleCall_0_0()); } - pushFollow(FOLLOW_16); + pushFollow(FOLLOW_17); lv_major_0_0=ruleVersionPart(); state._fsp--; @@ -2677,35 +2914,35 @@ public final EObject ruleVersionNumber() throws RecognitionException { } - // InternalSemver.g:943:3: (otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? )? - int alt22=2; - int LA22_0 = input.LA(1); + // InternalSemver.g:1028:3: (otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? )? + int alt24=2; + int LA24_0 = input.LA(1); - if ( (LA22_0==40) ) { - alt22=1; + if ( (LA24_0==46) ) { + alt24=1; } - switch (alt22) { + switch (alt24) { case 1 : - // InternalSemver.g:944:4: otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? + // InternalSemver.g:1029:4: otherlv_1= '.' ( (lv_minor_2_0= ruleVersionPart ) ) (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? { - otherlv_1=(Token)match(input,40,FOLLOW_3); if (state.failed) return current; + otherlv_1=(Token)match(input,46,FOLLOW_3); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_1, grammarAccess.getVersionNumberAccess().getFullStopKeyword_1_0()); } - // InternalSemver.g:948:4: ( (lv_minor_2_0= ruleVersionPart ) ) - // InternalSemver.g:949:5: (lv_minor_2_0= ruleVersionPart ) + // InternalSemver.g:1033:4: ( (lv_minor_2_0= ruleVersionPart ) ) + // InternalSemver.g:1034:5: (lv_minor_2_0= ruleVersionPart ) { - // InternalSemver.g:949:5: (lv_minor_2_0= ruleVersionPart ) - // InternalSemver.g:950:6: lv_minor_2_0= ruleVersionPart + // InternalSemver.g:1034:5: (lv_minor_2_0= ruleVersionPart ) + // InternalSemver.g:1035:6: lv_minor_2_0= ruleVersionPart { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getVersionNumberAccess().getMinorVersionPartParserRuleCall_1_1_0()); } - pushFollow(FOLLOW_16); + pushFollow(FOLLOW_17); lv_minor_2_0=ruleVersionPart(); state._fsp--; @@ -2729,35 +2966,35 @@ public final EObject ruleVersionNumber() throws RecognitionException { } - // InternalSemver.g:967:4: (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? - int alt21=2; - int LA21_0 = input.LA(1); + // InternalSemver.g:1052:4: (otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* )? + int alt23=2; + int LA23_0 = input.LA(1); - if ( (LA21_0==40) ) { - alt21=1; + if ( (LA23_0==46) ) { + alt23=1; } - switch (alt21) { + switch (alt23) { case 1 : - // InternalSemver.g:968:5: otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* + // InternalSemver.g:1053:5: otherlv_3= '.' ( (lv_patch_4_0= ruleVersionPart ) ) (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* { - otherlv_3=(Token)match(input,40,FOLLOW_3); if (state.failed) return current; + otherlv_3=(Token)match(input,46,FOLLOW_3); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_3, grammarAccess.getVersionNumberAccess().getFullStopKeyword_1_2_0()); } - // InternalSemver.g:972:5: ( (lv_patch_4_0= ruleVersionPart ) ) - // InternalSemver.g:973:6: (lv_patch_4_0= ruleVersionPart ) + // InternalSemver.g:1057:5: ( (lv_patch_4_0= ruleVersionPart ) ) + // InternalSemver.g:1058:6: (lv_patch_4_0= ruleVersionPart ) { - // InternalSemver.g:973:6: (lv_patch_4_0= ruleVersionPart ) - // InternalSemver.g:974:7: lv_patch_4_0= ruleVersionPart + // InternalSemver.g:1058:6: (lv_patch_4_0= ruleVersionPart ) + // InternalSemver.g:1059:7: lv_patch_4_0= ruleVersionPart { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getVersionNumberAccess().getPatchVersionPartParserRuleCall_1_2_1_0()); } - pushFollow(FOLLOW_16); + pushFollow(FOLLOW_17); lv_patch_4_0=ruleVersionPart(); state._fsp--; @@ -2781,39 +3018,39 @@ public final EObject ruleVersionNumber() throws RecognitionException { } - // InternalSemver.g:991:5: (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* - loop20: + // InternalSemver.g:1076:5: (otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) )* + loop22: do { - int alt20=2; - int LA20_0 = input.LA(1); + int alt22=2; + int LA22_0 = input.LA(1); - if ( (LA20_0==40) ) { - alt20=1; + if ( (LA22_0==46) ) { + alt22=1; } - switch (alt20) { + switch (alt22) { case 1 : - // InternalSemver.g:992:6: otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) + // InternalSemver.g:1077:6: otherlv_5= '.' ( (lv_extended_6_0= ruleVersionPart ) ) { - otherlv_5=(Token)match(input,40,FOLLOW_3); if (state.failed) return current; + otherlv_5=(Token)match(input,46,FOLLOW_3); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_5, grammarAccess.getVersionNumberAccess().getFullStopKeyword_1_2_2_0()); } - // InternalSemver.g:996:6: ( (lv_extended_6_0= ruleVersionPart ) ) - // InternalSemver.g:997:7: (lv_extended_6_0= ruleVersionPart ) + // InternalSemver.g:1081:6: ( (lv_extended_6_0= ruleVersionPart ) ) + // InternalSemver.g:1082:7: (lv_extended_6_0= ruleVersionPart ) { - // InternalSemver.g:997:7: (lv_extended_6_0= ruleVersionPart ) - // InternalSemver.g:998:8: lv_extended_6_0= ruleVersionPart + // InternalSemver.g:1082:7: (lv_extended_6_0= ruleVersionPart ) + // InternalSemver.g:1083:8: lv_extended_6_0= ruleVersionPart { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getVersionNumberAccess().getExtendedVersionPartParserRuleCall_1_2_2_1_0()); } - pushFollow(FOLLOW_16); + pushFollow(FOLLOW_17); lv_extended_6_0=ruleVersionPart(); state._fsp--; @@ -2842,7 +3079,7 @@ public final EObject ruleVersionNumber() throws RecognitionException { break; default : - break loop20; + break loop22; } } while (true); @@ -2858,19 +3095,19 @@ public final EObject ruleVersionNumber() throws RecognitionException { } - // InternalSemver.g:1018:3: ( (lv_qualifier_7_0= ruleQualifier ) )? - int alt23=2; - int LA23_0 = input.LA(1); + // InternalSemver.g:1103:3: ( (lv_qualifier_7_0= ruleQualifier ) )? + int alt25=2; + int LA25_0 = input.LA(1); - if ( (LA23_0==39||LA23_0==41) ) { - alt23=1; + if ( (LA25_0==45||LA25_0==47) ) { + alt25=1; } - switch (alt23) { + switch (alt25) { case 1 : - // InternalSemver.g:1019:4: (lv_qualifier_7_0= ruleQualifier ) + // InternalSemver.g:1104:4: (lv_qualifier_7_0= ruleQualifier ) { - // InternalSemver.g:1019:4: (lv_qualifier_7_0= ruleQualifier ) - // InternalSemver.g:1020:5: lv_qualifier_7_0= ruleQualifier + // InternalSemver.g:1104:4: (lv_qualifier_7_0= ruleQualifier ) + // InternalSemver.g:1105:5: lv_qualifier_7_0= ruleQualifier { if ( state.backtracking==0 ) { @@ -2929,7 +3166,7 @@ public final EObject ruleVersionNumber() throws RecognitionException { // $ANTLR start "entryRuleVersionPart" - // InternalSemver.g:1041:1: entryRuleVersionPart returns [EObject current=null] : iv_ruleVersionPart= ruleVersionPart EOF ; + // InternalSemver.g:1126:1: entryRuleVersionPart returns [EObject current=null] : iv_ruleVersionPart= ruleVersionPart EOF ; public final EObject entryRuleVersionPart() throws RecognitionException { EObject current = null; @@ -2937,8 +3174,8 @@ public final EObject entryRuleVersionPart() throws RecognitionException { try { - // InternalSemver.g:1041:52: (iv_ruleVersionPart= ruleVersionPart EOF ) - // InternalSemver.g:1042:2: iv_ruleVersionPart= ruleVersionPart EOF + // InternalSemver.g:1126:52: (iv_ruleVersionPart= ruleVersionPart EOF ) + // InternalSemver.g:1127:2: iv_ruleVersionPart= ruleVersionPart EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getVersionPartRule()); @@ -2969,7 +3206,7 @@ public final EObject entryRuleVersionPart() throws RecognitionException { // $ANTLR start "ruleVersionPart" - // InternalSemver.g:1048:1: ruleVersionPart returns [EObject current=null] : ( ( (lv_wildcard_0_0= ruleWILDCARD ) ) | ( (lv_numberRaw_1_0= RULE_DIGITS ) ) ) ; + // InternalSemver.g:1133:1: ruleVersionPart returns [EObject current=null] : ( ( (lv_wildcard_0_0= ruleWILDCARD ) ) | ( (lv_numberRaw_1_0= RULE_DIGITS ) ) ) ; public final EObject ruleVersionPart() throws RecognitionException { EObject current = null; @@ -2981,35 +3218,35 @@ public final EObject ruleVersionPart() throws RecognitionException { enterRule(); try { - // InternalSemver.g:1054:2: ( ( ( (lv_wildcard_0_0= ruleWILDCARD ) ) | ( (lv_numberRaw_1_0= RULE_DIGITS ) ) ) ) - // InternalSemver.g:1055:2: ( ( (lv_wildcard_0_0= ruleWILDCARD ) ) | ( (lv_numberRaw_1_0= RULE_DIGITS ) ) ) + // InternalSemver.g:1139:2: ( ( ( (lv_wildcard_0_0= ruleWILDCARD ) ) | ( (lv_numberRaw_1_0= RULE_DIGITS ) ) ) ) + // InternalSemver.g:1140:2: ( ( (lv_wildcard_0_0= ruleWILDCARD ) ) | ( (lv_numberRaw_1_0= RULE_DIGITS ) ) ) { - // InternalSemver.g:1055:2: ( ( (lv_wildcard_0_0= ruleWILDCARD ) ) | ( (lv_numberRaw_1_0= RULE_DIGITS ) ) ) - int alt24=2; - int LA24_0 = input.LA(1); + // InternalSemver.g:1140:2: ( ( (lv_wildcard_0_0= ruleWILDCARD ) ) | ( (lv_numberRaw_1_0= RULE_DIGITS ) ) ) + int alt26=2; + int LA26_0 = input.LA(1); - if ( ((LA24_0>=RULE_LETTER_X && LA24_0<=RULE_ASTERIX)) ) { - alt24=1; + if ( ((LA26_0>=RULE_ASTERIX && LA26_0<=RULE_LETTER_X)) ) { + alt26=1; } - else if ( (LA24_0==RULE_DIGITS) ) { - alt24=2; + else if ( (LA26_0==RULE_DIGITS) ) { + alt26=2; } else { if (state.backtracking>0) {state.failed=true; return current;} NoViableAltException nvae = - new NoViableAltException("", 24, 0, input); + new NoViableAltException("", 26, 0, input); throw nvae; } - switch (alt24) { + switch (alt26) { case 1 : - // InternalSemver.g:1056:3: ( (lv_wildcard_0_0= ruleWILDCARD ) ) + // InternalSemver.g:1141:3: ( (lv_wildcard_0_0= ruleWILDCARD ) ) { - // InternalSemver.g:1056:3: ( (lv_wildcard_0_0= ruleWILDCARD ) ) - // InternalSemver.g:1057:4: (lv_wildcard_0_0= ruleWILDCARD ) + // InternalSemver.g:1141:3: ( (lv_wildcard_0_0= ruleWILDCARD ) ) + // InternalSemver.g:1142:4: (lv_wildcard_0_0= ruleWILDCARD ) { - // InternalSemver.g:1057:4: (lv_wildcard_0_0= ruleWILDCARD ) - // InternalSemver.g:1058:5: lv_wildcard_0_0= ruleWILDCARD + // InternalSemver.g:1142:4: (lv_wildcard_0_0= ruleWILDCARD ) + // InternalSemver.g:1143:5: lv_wildcard_0_0= ruleWILDCARD { if ( state.backtracking==0 ) { @@ -3044,13 +3281,13 @@ else if ( (LA24_0==RULE_DIGITS) ) { } break; case 2 : - // InternalSemver.g:1076:3: ( (lv_numberRaw_1_0= RULE_DIGITS ) ) + // InternalSemver.g:1161:3: ( (lv_numberRaw_1_0= RULE_DIGITS ) ) { - // InternalSemver.g:1076:3: ( (lv_numberRaw_1_0= RULE_DIGITS ) ) - // InternalSemver.g:1077:4: (lv_numberRaw_1_0= RULE_DIGITS ) + // InternalSemver.g:1161:3: ( (lv_numberRaw_1_0= RULE_DIGITS ) ) + // InternalSemver.g:1162:4: (lv_numberRaw_1_0= RULE_DIGITS ) { - // InternalSemver.g:1077:4: (lv_numberRaw_1_0= RULE_DIGITS ) - // InternalSemver.g:1078:5: lv_numberRaw_1_0= RULE_DIGITS + // InternalSemver.g:1162:4: (lv_numberRaw_1_0= RULE_DIGITS ) + // InternalSemver.g:1163:5: lv_numberRaw_1_0= RULE_DIGITS { lv_numberRaw_1_0=(Token)match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { @@ -3104,7 +3341,7 @@ else if ( (LA24_0==RULE_DIGITS) ) { // $ANTLR start "entryRuleQualifier" - // InternalSemver.g:1098:1: entryRuleQualifier returns [EObject current=null] : iv_ruleQualifier= ruleQualifier EOF ; + // InternalSemver.g:1183:1: entryRuleQualifier returns [EObject current=null] : iv_ruleQualifier= ruleQualifier EOF ; public final EObject entryRuleQualifier() throws RecognitionException { EObject current = null; @@ -3112,8 +3349,8 @@ public final EObject entryRuleQualifier() throws RecognitionException { try { - // InternalSemver.g:1098:50: (iv_ruleQualifier= ruleQualifier EOF ) - // InternalSemver.g:1099:2: iv_ruleQualifier= ruleQualifier EOF + // InternalSemver.g:1183:50: (iv_ruleQualifier= ruleQualifier EOF ) + // InternalSemver.g:1184:2: iv_ruleQualifier= ruleQualifier EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getQualifierRule()); @@ -3144,7 +3381,7 @@ public final EObject entryRuleQualifier() throws RecognitionException { // $ANTLR start "ruleQualifier" - // InternalSemver.g:1105:1: ruleQualifier returns [EObject current=null] : ( (otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? ) | (otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) ) ) ; + // InternalSemver.g:1190:1: ruleQualifier returns [EObject current=null] : ( (otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? ) | (otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) ) ) ; public final EObject ruleQualifier() throws RecognitionException { EObject current = null; @@ -3162,51 +3399,51 @@ public final EObject ruleQualifier() throws RecognitionException { enterRule(); try { - // InternalSemver.g:1111:2: ( ( (otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? ) | (otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) ) ) ) - // InternalSemver.g:1112:2: ( (otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? ) | (otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) ) ) + // InternalSemver.g:1196:2: ( ( (otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? ) | (otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) ) ) ) + // InternalSemver.g:1197:2: ( (otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? ) | (otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) ) ) { - // InternalSemver.g:1112:2: ( (otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? ) | (otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) ) ) - int alt26=2; - int LA26_0 = input.LA(1); + // InternalSemver.g:1197:2: ( (otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? ) | (otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) ) ) + int alt28=2; + int LA28_0 = input.LA(1); - if ( (LA26_0==39) ) { - alt26=1; + if ( (LA28_0==45) ) { + alt28=1; } - else if ( (LA26_0==41) ) { - alt26=2; + else if ( (LA28_0==47) ) { + alt28=2; } else { if (state.backtracking>0) {state.failed=true; return current;} NoViableAltException nvae = - new NoViableAltException("", 26, 0, input); + new NoViableAltException("", 28, 0, input); throw nvae; } - switch (alt26) { + switch (alt28) { case 1 : - // InternalSemver.g:1113:3: (otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? ) + // InternalSemver.g:1198:3: (otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? ) { - // InternalSemver.g:1113:3: (otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? ) - // InternalSemver.g:1114:4: otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? + // InternalSemver.g:1198:3: (otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? ) + // InternalSemver.g:1199:4: otherlv_0= '-' ( (lv_preRelease_1_0= ruleQualifierTag ) ) (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? { - otherlv_0=(Token)match(input,39,FOLLOW_10); if (state.failed) return current; + otherlv_0=(Token)match(input,45,FOLLOW_10); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_0, grammarAccess.getQualifierAccess().getHyphenMinusKeyword_0_0()); } - // InternalSemver.g:1118:4: ( (lv_preRelease_1_0= ruleQualifierTag ) ) - // InternalSemver.g:1119:5: (lv_preRelease_1_0= ruleQualifierTag ) + // InternalSemver.g:1203:4: ( (lv_preRelease_1_0= ruleQualifierTag ) ) + // InternalSemver.g:1204:5: (lv_preRelease_1_0= ruleQualifierTag ) { - // InternalSemver.g:1119:5: (lv_preRelease_1_0= ruleQualifierTag ) - // InternalSemver.g:1120:6: lv_preRelease_1_0= ruleQualifierTag + // InternalSemver.g:1204:5: (lv_preRelease_1_0= ruleQualifierTag ) + // InternalSemver.g:1205:6: lv_preRelease_1_0= ruleQualifierTag { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getQualifierAccess().getPreReleaseQualifierTagParserRuleCall_0_1_0()); } - pushFollow(FOLLOW_17); + pushFollow(FOLLOW_18); lv_preRelease_1_0=ruleQualifierTag(); state._fsp--; @@ -3230,28 +3467,28 @@ else if ( (LA26_0==41) ) { } - // InternalSemver.g:1137:4: (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? - int alt25=2; - int LA25_0 = input.LA(1); + // InternalSemver.g:1222:4: (otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) )? + int alt27=2; + int LA27_0 = input.LA(1); - if ( (LA25_0==41) ) { - alt25=1; + if ( (LA27_0==47) ) { + alt27=1; } - switch (alt25) { + switch (alt27) { case 1 : - // InternalSemver.g:1138:5: otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) + // InternalSemver.g:1223:5: otherlv_2= '+' ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) { - otherlv_2=(Token)match(input,41,FOLLOW_10); if (state.failed) return current; + otherlv_2=(Token)match(input,47,FOLLOW_10); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_2, grammarAccess.getQualifierAccess().getPlusSignKeyword_0_2_0()); } - // InternalSemver.g:1142:5: ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) - // InternalSemver.g:1143:6: (lv_buildMetadata_3_0= ruleQualifierTag ) + // InternalSemver.g:1227:5: ( (lv_buildMetadata_3_0= ruleQualifierTag ) ) + // InternalSemver.g:1228:6: (lv_buildMetadata_3_0= ruleQualifierTag ) { - // InternalSemver.g:1143:6: (lv_buildMetadata_3_0= ruleQualifierTag ) - // InternalSemver.g:1144:7: lv_buildMetadata_3_0= ruleQualifierTag + // InternalSemver.g:1228:6: (lv_buildMetadata_3_0= ruleQualifierTag ) + // InternalSemver.g:1229:7: lv_buildMetadata_3_0= ruleQualifierTag { if ( state.backtracking==0 ) { @@ -3295,22 +3532,22 @@ else if ( (LA26_0==41) ) { } break; case 2 : - // InternalSemver.g:1164:3: (otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) ) + // InternalSemver.g:1249:3: (otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) ) { - // InternalSemver.g:1164:3: (otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) ) - // InternalSemver.g:1165:4: otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) + // InternalSemver.g:1249:3: (otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) ) + // InternalSemver.g:1250:4: otherlv_4= '+' ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) { - otherlv_4=(Token)match(input,41,FOLLOW_10); if (state.failed) return current; + otherlv_4=(Token)match(input,47,FOLLOW_10); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_4, grammarAccess.getQualifierAccess().getPlusSignKeyword_1_0()); } - // InternalSemver.g:1169:4: ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) - // InternalSemver.g:1170:5: (lv_buildMetadata_5_0= ruleQualifierTag ) + // InternalSemver.g:1254:4: ( (lv_buildMetadata_5_0= ruleQualifierTag ) ) + // InternalSemver.g:1255:5: (lv_buildMetadata_5_0= ruleQualifierTag ) { - // InternalSemver.g:1170:5: (lv_buildMetadata_5_0= ruleQualifierTag ) - // InternalSemver.g:1171:6: lv_buildMetadata_5_0= ruleQualifierTag + // InternalSemver.g:1255:5: (lv_buildMetadata_5_0= ruleQualifierTag ) + // InternalSemver.g:1256:6: lv_buildMetadata_5_0= ruleQualifierTag { if ( state.backtracking==0 ) { @@ -3372,7 +3609,7 @@ else if ( (LA26_0==41) ) { // $ANTLR start "entryRuleQualifierTag" - // InternalSemver.g:1193:1: entryRuleQualifierTag returns [EObject current=null] : iv_ruleQualifierTag= ruleQualifierTag EOF ; + // InternalSemver.g:1278:1: entryRuleQualifierTag returns [EObject current=null] : iv_ruleQualifierTag= ruleQualifierTag EOF ; public final EObject entryRuleQualifierTag() throws RecognitionException { EObject current = null; @@ -3380,8 +3617,8 @@ public final EObject entryRuleQualifierTag() throws RecognitionException { try { - // InternalSemver.g:1193:53: (iv_ruleQualifierTag= ruleQualifierTag EOF ) - // InternalSemver.g:1194:2: iv_ruleQualifierTag= ruleQualifierTag EOF + // InternalSemver.g:1278:53: (iv_ruleQualifierTag= ruleQualifierTag EOF ) + // InternalSemver.g:1279:2: iv_ruleQualifierTag= ruleQualifierTag EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getQualifierTagRule()); @@ -3412,7 +3649,7 @@ public final EObject entryRuleQualifierTag() throws RecognitionException { // $ANTLR start "ruleQualifierTag" - // InternalSemver.g:1200:1: ruleQualifierTag returns [EObject current=null] : ( ( (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) ) (otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) )* ) ; + // InternalSemver.g:1285:1: ruleQualifierTag returns [EObject current=null] : ( ( (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) ) (otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) )* ) ; public final EObject ruleQualifierTag() throws RecognitionException { EObject current = null; @@ -3426,24 +3663,24 @@ public final EObject ruleQualifierTag() throws RecognitionException { enterRule(); try { - // InternalSemver.g:1206:2: ( ( ( (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) ) (otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) )* ) ) - // InternalSemver.g:1207:2: ( ( (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) ) (otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) )* ) + // InternalSemver.g:1291:2: ( ( ( (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) ) (otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) )* ) ) + // InternalSemver.g:1292:2: ( ( (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) ) (otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) )* ) { - // InternalSemver.g:1207:2: ( ( (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) ) (otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) )* ) - // InternalSemver.g:1208:3: ( (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) ) (otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) )* + // InternalSemver.g:1292:2: ( ( (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) ) (otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) )* ) + // InternalSemver.g:1293:3: ( (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) ) (otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) )* { - // InternalSemver.g:1208:3: ( (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) ) - // InternalSemver.g:1209:4: (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:1293:3: ( (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:1294:4: (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) { - // InternalSemver.g:1209:4: (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) - // InternalSemver.g:1210:5: lv_parts_0_0= ruleALPHA_NUMERIC_CHARS + // InternalSemver.g:1294:4: (lv_parts_0_0= ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:1295:5: lv_parts_0_0= ruleALPHA_NUMERIC_CHARS { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getQualifierTagAccess().getPartsALPHA_NUMERIC_CHARSParserRuleCall_0_0()); } - pushFollow(FOLLOW_18); + pushFollow(FOLLOW_19); lv_parts_0_0=ruleALPHA_NUMERIC_CHARS(); state._fsp--; @@ -3467,39 +3704,39 @@ public final EObject ruleQualifierTag() throws RecognitionException { } - // InternalSemver.g:1227:3: (otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) )* - loop27: + // InternalSemver.g:1312:3: (otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) )* + loop29: do { - int alt27=2; - int LA27_0 = input.LA(1); + int alt29=2; + int LA29_0 = input.LA(1); - if ( (LA27_0==40) ) { - alt27=1; + if ( (LA29_0==46) ) { + alt29=1; } - switch (alt27) { + switch (alt29) { case 1 : - // InternalSemver.g:1228:4: otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:1313:4: otherlv_1= '.' ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) { - otherlv_1=(Token)match(input,40,FOLLOW_10); if (state.failed) return current; + otherlv_1=(Token)match(input,46,FOLLOW_10); if (state.failed) return current; if ( state.backtracking==0 ) { newLeafNode(otherlv_1, grammarAccess.getQualifierTagAccess().getFullStopKeyword_1_0()); } - // InternalSemver.g:1232:4: ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) - // InternalSemver.g:1233:5: (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:1317:4: ( (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:1318:5: (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) { - // InternalSemver.g:1233:5: (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) - // InternalSemver.g:1234:6: lv_parts_2_0= ruleALPHA_NUMERIC_CHARS + // InternalSemver.g:1318:5: (lv_parts_2_0= ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:1319:6: lv_parts_2_0= ruleALPHA_NUMERIC_CHARS { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getQualifierTagAccess().getPartsALPHA_NUMERIC_CHARSParserRuleCall_1_1_0()); } - pushFollow(FOLLOW_18); + pushFollow(FOLLOW_19); lv_parts_2_0=ruleALPHA_NUMERIC_CHARS(); state._fsp--; @@ -3528,7 +3765,7 @@ public final EObject ruleQualifierTag() throws RecognitionException { break; default : - break loop27; + break loop29; } } while (true); @@ -3557,7 +3794,7 @@ public final EObject ruleQualifierTag() throws RecognitionException { // $ANTLR start "entryRuleFILE_TAG" - // InternalSemver.g:1256:1: entryRuleFILE_TAG returns [String current=null] : iv_ruleFILE_TAG= ruleFILE_TAG EOF ; + // InternalSemver.g:1341:1: entryRuleFILE_TAG returns [String current=null] : iv_ruleFILE_TAG= ruleFILE_TAG EOF ; public final String entryRuleFILE_TAG() throws RecognitionException { String current = null; @@ -3565,8 +3802,8 @@ public final String entryRuleFILE_TAG() throws RecognitionException { try { - // InternalSemver.g:1256:48: (iv_ruleFILE_TAG= ruleFILE_TAG EOF ) - // InternalSemver.g:1257:2: iv_ruleFILE_TAG= ruleFILE_TAG EOF + // InternalSemver.g:1341:48: (iv_ruleFILE_TAG= ruleFILE_TAG EOF ) + // InternalSemver.g:1342:2: iv_ruleFILE_TAG= ruleFILE_TAG EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getFILE_TAGRule()); @@ -3597,7 +3834,7 @@ public final String entryRuleFILE_TAG() throws RecognitionException { // $ANTLR start "ruleFILE_TAG" - // InternalSemver.g:1263:1: ruleFILE_TAG returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_F_0= RULE_LETTER_F this_LETTER_I_1= RULE_LETTER_I this_LETTER_L_2= RULE_LETTER_L this_LETTER_E_3= RULE_LETTER_E kw= ':' ) ; + // InternalSemver.g:1348:1: ruleFILE_TAG returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_F_0= RULE_LETTER_F this_LETTER_I_1= RULE_LETTER_I this_LETTER_L_2= RULE_LETTER_L this_LETTER_E_3= RULE_LETTER_E kw= ':' ) ; public final AntlrDatatypeRuleToken ruleFILE_TAG() throws RecognitionException { AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); @@ -3611,13 +3848,13 @@ public final AntlrDatatypeRuleToken ruleFILE_TAG() throws RecognitionException { enterRule(); try { - // InternalSemver.g:1269:2: ( (this_LETTER_F_0= RULE_LETTER_F this_LETTER_I_1= RULE_LETTER_I this_LETTER_L_2= RULE_LETTER_L this_LETTER_E_3= RULE_LETTER_E kw= ':' ) ) - // InternalSemver.g:1270:2: (this_LETTER_F_0= RULE_LETTER_F this_LETTER_I_1= RULE_LETTER_I this_LETTER_L_2= RULE_LETTER_L this_LETTER_E_3= RULE_LETTER_E kw= ':' ) + // InternalSemver.g:1354:2: ( (this_LETTER_F_0= RULE_LETTER_F this_LETTER_I_1= RULE_LETTER_I this_LETTER_L_2= RULE_LETTER_L this_LETTER_E_3= RULE_LETTER_E kw= ':' ) ) + // InternalSemver.g:1355:2: (this_LETTER_F_0= RULE_LETTER_F this_LETTER_I_1= RULE_LETTER_I this_LETTER_L_2= RULE_LETTER_L this_LETTER_E_3= RULE_LETTER_E kw= ':' ) { - // InternalSemver.g:1270:2: (this_LETTER_F_0= RULE_LETTER_F this_LETTER_I_1= RULE_LETTER_I this_LETTER_L_2= RULE_LETTER_L this_LETTER_E_3= RULE_LETTER_E kw= ':' ) - // InternalSemver.g:1271:3: this_LETTER_F_0= RULE_LETTER_F this_LETTER_I_1= RULE_LETTER_I this_LETTER_L_2= RULE_LETTER_L this_LETTER_E_3= RULE_LETTER_E kw= ':' + // InternalSemver.g:1355:2: (this_LETTER_F_0= RULE_LETTER_F this_LETTER_I_1= RULE_LETTER_I this_LETTER_L_2= RULE_LETTER_L this_LETTER_E_3= RULE_LETTER_E kw= ':' ) + // InternalSemver.g:1356:3: this_LETTER_F_0= RULE_LETTER_F this_LETTER_I_1= RULE_LETTER_I this_LETTER_L_2= RULE_LETTER_L this_LETTER_E_3= RULE_LETTER_E kw= ':' { - this_LETTER_F_0=(Token)match(input,RULE_LETTER_F,FOLLOW_19); if (state.failed) return current; + this_LETTER_F_0=(Token)match(input,RULE_LETTER_F,FOLLOW_20); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(this_LETTER_F_0); @@ -3628,7 +3865,7 @@ public final AntlrDatatypeRuleToken ruleFILE_TAG() throws RecognitionException { newLeafNode(this_LETTER_F_0, grammarAccess.getFILE_TAGAccess().getLETTER_FTerminalRuleCall_0()); } - this_LETTER_I_1=(Token)match(input,RULE_LETTER_I,FOLLOW_20); if (state.failed) return current; + this_LETTER_I_1=(Token)match(input,RULE_LETTER_I,FOLLOW_21); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(this_LETTER_I_1); @@ -3639,7 +3876,7 @@ public final AntlrDatatypeRuleToken ruleFILE_TAG() throws RecognitionException { newLeafNode(this_LETTER_I_1, grammarAccess.getFILE_TAGAccess().getLETTER_ITerminalRuleCall_1()); } - this_LETTER_L_2=(Token)match(input,RULE_LETTER_L,FOLLOW_21); if (state.failed) return current; + this_LETTER_L_2=(Token)match(input,RULE_LETTER_L,FOLLOW_22); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(this_LETTER_L_2); @@ -3661,7 +3898,7 @@ public final AntlrDatatypeRuleToken ruleFILE_TAG() throws RecognitionException { newLeafNode(this_LETTER_E_3, grammarAccess.getFILE_TAGAccess().getLETTER_ETerminalRuleCall_3()); } - kw=(Token)match(input,35,FOLLOW_2); if (state.failed) return current; + kw=(Token)match(input,41,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -3693,7 +3930,7 @@ public final AntlrDatatypeRuleToken ruleFILE_TAG() throws RecognitionException { // $ANTLR start "entryRuleSEMVER_TAG" - // InternalSemver.g:1308:1: entryRuleSEMVER_TAG returns [String current=null] : iv_ruleSEMVER_TAG= ruleSEMVER_TAG EOF ; + // InternalSemver.g:1393:1: entryRuleSEMVER_TAG returns [String current=null] : iv_ruleSEMVER_TAG= ruleSEMVER_TAG EOF ; public final String entryRuleSEMVER_TAG() throws RecognitionException { String current = null; @@ -3701,8 +3938,8 @@ public final String entryRuleSEMVER_TAG() throws RecognitionException { try { - // InternalSemver.g:1308:50: (iv_ruleSEMVER_TAG= ruleSEMVER_TAG EOF ) - // InternalSemver.g:1309:2: iv_ruleSEMVER_TAG= ruleSEMVER_TAG EOF + // InternalSemver.g:1393:50: (iv_ruleSEMVER_TAG= ruleSEMVER_TAG EOF ) + // InternalSemver.g:1394:2: iv_ruleSEMVER_TAG= ruleSEMVER_TAG EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getSEMVER_TAGRule()); @@ -3733,7 +3970,7 @@ public final String entryRuleSEMVER_TAG() throws RecognitionException { // $ANTLR start "ruleSEMVER_TAG" - // InternalSemver.g:1315:1: ruleSEMVER_TAG returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_S_0= RULE_LETTER_S this_LETTER_E_1= RULE_LETTER_E this_LETTER_M_2= RULE_LETTER_M this_LETTER_V_3= RULE_LETTER_V this_LETTER_E_4= RULE_LETTER_E this_LETTER_R_5= RULE_LETTER_R kw= ':' ) ; + // InternalSemver.g:1400:1: ruleSEMVER_TAG returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_S_0= RULE_LETTER_S this_LETTER_E_1= RULE_LETTER_E this_LETTER_M_2= RULE_LETTER_M this_LETTER_V_3= RULE_LETTER_V this_LETTER_E_4= RULE_LETTER_E this_LETTER_R_5= RULE_LETTER_R kw= ':' ) ; public final AntlrDatatypeRuleToken ruleSEMVER_TAG() throws RecognitionException { AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); @@ -3749,13 +3986,13 @@ public final AntlrDatatypeRuleToken ruleSEMVER_TAG() throws RecognitionException enterRule(); try { - // InternalSemver.g:1321:2: ( (this_LETTER_S_0= RULE_LETTER_S this_LETTER_E_1= RULE_LETTER_E this_LETTER_M_2= RULE_LETTER_M this_LETTER_V_3= RULE_LETTER_V this_LETTER_E_4= RULE_LETTER_E this_LETTER_R_5= RULE_LETTER_R kw= ':' ) ) - // InternalSemver.g:1322:2: (this_LETTER_S_0= RULE_LETTER_S this_LETTER_E_1= RULE_LETTER_E this_LETTER_M_2= RULE_LETTER_M this_LETTER_V_3= RULE_LETTER_V this_LETTER_E_4= RULE_LETTER_E this_LETTER_R_5= RULE_LETTER_R kw= ':' ) + // InternalSemver.g:1406:2: ( (this_LETTER_S_0= RULE_LETTER_S this_LETTER_E_1= RULE_LETTER_E this_LETTER_M_2= RULE_LETTER_M this_LETTER_V_3= RULE_LETTER_V this_LETTER_E_4= RULE_LETTER_E this_LETTER_R_5= RULE_LETTER_R kw= ':' ) ) + // InternalSemver.g:1407:2: (this_LETTER_S_0= RULE_LETTER_S this_LETTER_E_1= RULE_LETTER_E this_LETTER_M_2= RULE_LETTER_M this_LETTER_V_3= RULE_LETTER_V this_LETTER_E_4= RULE_LETTER_E this_LETTER_R_5= RULE_LETTER_R kw= ':' ) { - // InternalSemver.g:1322:2: (this_LETTER_S_0= RULE_LETTER_S this_LETTER_E_1= RULE_LETTER_E this_LETTER_M_2= RULE_LETTER_M this_LETTER_V_3= RULE_LETTER_V this_LETTER_E_4= RULE_LETTER_E this_LETTER_R_5= RULE_LETTER_R kw= ':' ) - // InternalSemver.g:1323:3: this_LETTER_S_0= RULE_LETTER_S this_LETTER_E_1= RULE_LETTER_E this_LETTER_M_2= RULE_LETTER_M this_LETTER_V_3= RULE_LETTER_V this_LETTER_E_4= RULE_LETTER_E this_LETTER_R_5= RULE_LETTER_R kw= ':' + // InternalSemver.g:1407:2: (this_LETTER_S_0= RULE_LETTER_S this_LETTER_E_1= RULE_LETTER_E this_LETTER_M_2= RULE_LETTER_M this_LETTER_V_3= RULE_LETTER_V this_LETTER_E_4= RULE_LETTER_E this_LETTER_R_5= RULE_LETTER_R kw= ':' ) + // InternalSemver.g:1408:3: this_LETTER_S_0= RULE_LETTER_S this_LETTER_E_1= RULE_LETTER_E this_LETTER_M_2= RULE_LETTER_M this_LETTER_V_3= RULE_LETTER_V this_LETTER_E_4= RULE_LETTER_E this_LETTER_R_5= RULE_LETTER_R kw= ':' { - this_LETTER_S_0=(Token)match(input,RULE_LETTER_S,FOLLOW_21); if (state.failed) return current; + this_LETTER_S_0=(Token)match(input,RULE_LETTER_S,FOLLOW_22); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(this_LETTER_S_0); @@ -3766,7 +4003,7 @@ public final AntlrDatatypeRuleToken ruleSEMVER_TAG() throws RecognitionException newLeafNode(this_LETTER_S_0, grammarAccess.getSEMVER_TAGAccess().getLETTER_STerminalRuleCall_0()); } - this_LETTER_E_1=(Token)match(input,RULE_LETTER_E,FOLLOW_22); if (state.failed) return current; + this_LETTER_E_1=(Token)match(input,RULE_LETTER_E,FOLLOW_23); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(this_LETTER_E_1); @@ -3777,7 +4014,7 @@ public final AntlrDatatypeRuleToken ruleSEMVER_TAG() throws RecognitionException newLeafNode(this_LETTER_E_1, grammarAccess.getSEMVER_TAGAccess().getLETTER_ETerminalRuleCall_1()); } - this_LETTER_M_2=(Token)match(input,RULE_LETTER_M,FOLLOW_23); if (state.failed) return current; + this_LETTER_M_2=(Token)match(input,RULE_LETTER_M,FOLLOW_24); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(this_LETTER_M_2); @@ -3788,7 +4025,7 @@ public final AntlrDatatypeRuleToken ruleSEMVER_TAG() throws RecognitionException newLeafNode(this_LETTER_M_2, grammarAccess.getSEMVER_TAGAccess().getLETTER_MTerminalRuleCall_2()); } - this_LETTER_V_3=(Token)match(input,RULE_LETTER_V,FOLLOW_21); if (state.failed) return current; + this_LETTER_V_3=(Token)match(input,RULE_LETTER_V,FOLLOW_22); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(this_LETTER_V_3); @@ -3799,7 +4036,7 @@ public final AntlrDatatypeRuleToken ruleSEMVER_TAG() throws RecognitionException newLeafNode(this_LETTER_V_3, grammarAccess.getSEMVER_TAGAccess().getLETTER_VTerminalRuleCall_3()); } - this_LETTER_E_4=(Token)match(input,RULE_LETTER_E,FOLLOW_24); if (state.failed) return current; + this_LETTER_E_4=(Token)match(input,RULE_LETTER_E,FOLLOW_25); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(this_LETTER_E_4); @@ -3821,7 +4058,7 @@ public final AntlrDatatypeRuleToken ruleSEMVER_TAG() throws RecognitionException newLeafNode(this_LETTER_R_5, grammarAccess.getSEMVER_TAGAccess().getLETTER_RTerminalRuleCall_5()); } - kw=(Token)match(input,35,FOLLOW_2); if (state.failed) return current; + kw=(Token)match(input,41,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -3852,8 +4089,204 @@ public final AntlrDatatypeRuleToken ruleSEMVER_TAG() throws RecognitionException // $ANTLR end "ruleSEMVER_TAG" + // $ANTLR start "entryRuleWORKSPACE_TAG" + // InternalSemver.g:1459:1: entryRuleWORKSPACE_TAG returns [String current=null] : iv_ruleWORKSPACE_TAG= ruleWORKSPACE_TAG EOF ; + public final String entryRuleWORKSPACE_TAG() throws RecognitionException { + String current = null; + + AntlrDatatypeRuleToken iv_ruleWORKSPACE_TAG = null; + + + try { + // InternalSemver.g:1459:53: (iv_ruleWORKSPACE_TAG= ruleWORKSPACE_TAG EOF ) + // InternalSemver.g:1460:2: iv_ruleWORKSPACE_TAG= ruleWORKSPACE_TAG EOF + { + if ( state.backtracking==0 ) { + newCompositeNode(grammarAccess.getWORKSPACE_TAGRule()); + } + pushFollow(FOLLOW_1); + iv_ruleWORKSPACE_TAG=ruleWORKSPACE_TAG(); + + state._fsp--; + if (state.failed) return current; + if ( state.backtracking==0 ) { + current =iv_ruleWORKSPACE_TAG.getText(); + } + match(input,EOF,FOLLOW_2); if (state.failed) return current; + + } + + } + + catch (RecognitionException re) { + recover(input,re); + appendSkippedTokens(); + } + finally { + } + return current; + } + // $ANTLR end "entryRuleWORKSPACE_TAG" + + + // $ANTLR start "ruleWORKSPACE_TAG" + // InternalSemver.g:1466:1: ruleWORKSPACE_TAG returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_W_0= RULE_LETTER_W this_LETTER_O_1= RULE_LETTER_O this_LETTER_R_2= RULE_LETTER_R this_LETTER_K_3= RULE_LETTER_K this_LETTER_S_4= RULE_LETTER_S this_LETTER_P_5= RULE_LETTER_P this_LETTER_A_6= RULE_LETTER_A this_LETTER_C_7= RULE_LETTER_C this_LETTER_E_8= RULE_LETTER_E kw= ':' ) ; + public final AntlrDatatypeRuleToken ruleWORKSPACE_TAG() throws RecognitionException { + AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); + + Token this_LETTER_W_0=null; + Token this_LETTER_O_1=null; + Token this_LETTER_R_2=null; + Token this_LETTER_K_3=null; + Token this_LETTER_S_4=null; + Token this_LETTER_P_5=null; + Token this_LETTER_A_6=null; + Token this_LETTER_C_7=null; + Token this_LETTER_E_8=null; + Token kw=null; + + + enterRule(); + + try { + // InternalSemver.g:1472:2: ( (this_LETTER_W_0= RULE_LETTER_W this_LETTER_O_1= RULE_LETTER_O this_LETTER_R_2= RULE_LETTER_R this_LETTER_K_3= RULE_LETTER_K this_LETTER_S_4= RULE_LETTER_S this_LETTER_P_5= RULE_LETTER_P this_LETTER_A_6= RULE_LETTER_A this_LETTER_C_7= RULE_LETTER_C this_LETTER_E_8= RULE_LETTER_E kw= ':' ) ) + // InternalSemver.g:1473:2: (this_LETTER_W_0= RULE_LETTER_W this_LETTER_O_1= RULE_LETTER_O this_LETTER_R_2= RULE_LETTER_R this_LETTER_K_3= RULE_LETTER_K this_LETTER_S_4= RULE_LETTER_S this_LETTER_P_5= RULE_LETTER_P this_LETTER_A_6= RULE_LETTER_A this_LETTER_C_7= RULE_LETTER_C this_LETTER_E_8= RULE_LETTER_E kw= ':' ) + { + // InternalSemver.g:1473:2: (this_LETTER_W_0= RULE_LETTER_W this_LETTER_O_1= RULE_LETTER_O this_LETTER_R_2= RULE_LETTER_R this_LETTER_K_3= RULE_LETTER_K this_LETTER_S_4= RULE_LETTER_S this_LETTER_P_5= RULE_LETTER_P this_LETTER_A_6= RULE_LETTER_A this_LETTER_C_7= RULE_LETTER_C this_LETTER_E_8= RULE_LETTER_E kw= ':' ) + // InternalSemver.g:1474:3: this_LETTER_W_0= RULE_LETTER_W this_LETTER_O_1= RULE_LETTER_O this_LETTER_R_2= RULE_LETTER_R this_LETTER_K_3= RULE_LETTER_K this_LETTER_S_4= RULE_LETTER_S this_LETTER_P_5= RULE_LETTER_P this_LETTER_A_6= RULE_LETTER_A this_LETTER_C_7= RULE_LETTER_C this_LETTER_E_8= RULE_LETTER_E kw= ':' + { + this_LETTER_W_0=(Token)match(input,RULE_LETTER_W,FOLLOW_26); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_W_0); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_W_0, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_WTerminalRuleCall_0()); + + } + this_LETTER_O_1=(Token)match(input,RULE_LETTER_O,FOLLOW_25); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_O_1); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_O_1, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_OTerminalRuleCall_1()); + + } + this_LETTER_R_2=(Token)match(input,RULE_LETTER_R,FOLLOW_27); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_R_2); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_R_2, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_RTerminalRuleCall_2()); + + } + this_LETTER_K_3=(Token)match(input,RULE_LETTER_K,FOLLOW_28); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_K_3); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_K_3, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_KTerminalRuleCall_3()); + + } + this_LETTER_S_4=(Token)match(input,RULE_LETTER_S,FOLLOW_29); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_S_4); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_S_4, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_STerminalRuleCall_4()); + + } + this_LETTER_P_5=(Token)match(input,RULE_LETTER_P,FOLLOW_30); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_P_5); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_P_5, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_PTerminalRuleCall_5()); + + } + this_LETTER_A_6=(Token)match(input,RULE_LETTER_A,FOLLOW_31); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_A_6); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_A_6, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_ATerminalRuleCall_6()); + + } + this_LETTER_C_7=(Token)match(input,RULE_LETTER_C,FOLLOW_22); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_C_7); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_C_7, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_CTerminalRuleCall_7()); + + } + this_LETTER_E_8=(Token)match(input,RULE_LETTER_E,FOLLOW_6); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_E_8); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_E_8, grammarAccess.getWORKSPACE_TAGAccess().getLETTER_ETerminalRuleCall_8()); + + } + kw=(Token)match(input,41,FOLLOW_2); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_TAGAccess().getColonKeyword_9()); + + } + + } + + + } + + if ( state.backtracking==0 ) { + + leaveRule(); + + } + } + + catch (RecognitionException re) { + recover(input,re); + appendSkippedTokens(); + } + finally { + } + return current; + } + // $ANTLR end "ruleWORKSPACE_TAG" + + // $ANTLR start "entryRulePATH" - // InternalSemver.g:1374:1: entryRulePATH returns [String current=null] : iv_rulePATH= rulePATH EOF ; + // InternalSemver.g:1546:1: entryRulePATH returns [String current=null] : iv_rulePATH= rulePATH EOF ; public final String entryRulePATH() throws RecognitionException { String current = null; @@ -3861,8 +4294,8 @@ public final String entryRulePATH() throws RecognitionException { try { - // InternalSemver.g:1374:44: (iv_rulePATH= rulePATH EOF ) - // InternalSemver.g:1375:2: iv_rulePATH= rulePATH EOF + // InternalSemver.g:1546:44: (iv_rulePATH= rulePATH EOF ) + // InternalSemver.g:1547:2: iv_rulePATH= rulePATH EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getPATHRule()); @@ -3893,59 +4326,49 @@ public final String entryRulePATH() throws RecognitionException { // $ANTLR start "rulePATH" - // InternalSemver.g:1381:1: rulePATH returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (kw= '/' | kw= '.' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_5= RULE_DIGITS | this_LETTER_6= ruleLETTER )+ ; + // InternalSemver.g:1553:1: rulePATH returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (kw= '/' | kw= '.' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_4= ruleALPHA_NUMERIC_CHAR )+ ; public final AntlrDatatypeRuleToken rulePATH() throws RecognitionException { AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); Token kw=null; - Token this_DIGITS_5=null; - AntlrDatatypeRuleToken this_LETTER_6 = null; + AntlrDatatypeRuleToken this_ALPHA_NUMERIC_CHAR_4 = null; enterRule(); try { - // InternalSemver.g:1387:2: ( (kw= '/' | kw= '.' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_5= RULE_DIGITS | this_LETTER_6= ruleLETTER )+ ) - // InternalSemver.g:1388:2: (kw= '/' | kw= '.' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_5= RULE_DIGITS | this_LETTER_6= ruleLETTER )+ + // InternalSemver.g:1559:2: ( (kw= '/' | kw= '.' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_4= ruleALPHA_NUMERIC_CHAR )+ ) + // InternalSemver.g:1560:2: (kw= '/' | kw= '.' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_4= ruleALPHA_NUMERIC_CHAR )+ { - // InternalSemver.g:1388:2: (kw= '/' | kw= '.' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_5= RULE_DIGITS | this_LETTER_6= ruleLETTER )+ - int cnt28=0; - loop28: + // InternalSemver.g:1560:2: (kw= '/' | kw= '.' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_4= ruleALPHA_NUMERIC_CHAR )+ + int cnt30=0; + loop30: do { - int alt28=8; + int alt30=6; switch ( input.LA(1) ) { - case 36: - { - alt28=1; - } - break; - case 40: - { - alt28=2; - } - break; case 42: { - alt28=3; + alt30=1; } break; - case 39: + case 46: { - alt28=4; + alt30=2; } break; - case 43: + case 48: { - alt28=5; + alt30=3; } break; - case RULE_DIGITS: + case 49: { - alt28=6; + alt30=4; } break; case RULE_LETTER_V: + case RULE_DIGITS: case RULE_LETTER_F: case RULE_LETTER_I: case RULE_LETTER_L: @@ -3953,20 +4376,27 @@ public final AntlrDatatypeRuleToken rulePATH() throws RecognitionException { case RULE_LETTER_S: case RULE_LETTER_M: case RULE_LETTER_R: + case RULE_LETTER_W: + case RULE_LETTER_O: + case RULE_LETTER_K: + case RULE_LETTER_P: + case RULE_LETTER_A: + case RULE_LETTER_C: case RULE_LETTER_X: case RULE_LETTER_OTHER: + case 45: { - alt28=7; + alt30=5; } break; } - switch (alt28) { + switch (alt30) { case 1 : - // InternalSemver.g:1389:3: kw= '/' + // InternalSemver.g:1561:3: kw= '/' { - kw=(Token)match(input,36,FOLLOW_25); if (state.failed) return current; + kw=(Token)match(input,42,FOLLOW_32); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -3977,9 +4407,9 @@ public final AntlrDatatypeRuleToken rulePATH() throws RecognitionException { } break; case 2 : - // InternalSemver.g:1395:3: kw= '.' + // InternalSemver.g:1567:3: kw= '.' { - kw=(Token)match(input,40,FOLLOW_25); if (state.failed) return current; + kw=(Token)match(input,46,FOLLOW_32); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -3990,9 +4420,9 @@ public final AntlrDatatypeRuleToken rulePATH() throws RecognitionException { } break; case 3 : - // InternalSemver.g:1401:3: kw= '@' + // InternalSemver.g:1573:3: kw= '@' { - kw=(Token)match(input,42,FOLLOW_25); if (state.failed) return current; + kw=(Token)match(input,48,FOLLOW_32); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -4003,64 +4433,34 @@ public final AntlrDatatypeRuleToken rulePATH() throws RecognitionException { } break; case 4 : - // InternalSemver.g:1407:3: kw= '-' + // InternalSemver.g:1579:3: kw= '_' { - kw=(Token)match(input,39,FOLLOW_25); if (state.failed) return current; + kw=(Token)match(input,49,FOLLOW_32); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); - newLeafNode(kw, grammarAccess.getPATHAccess().getHyphenMinusKeyword_3()); + newLeafNode(kw, grammarAccess.getPATHAccess().get_Keyword_3()); } } break; case 5 : - // InternalSemver.g:1413:3: kw= '_' - { - kw=(Token)match(input,43,FOLLOW_25); if (state.failed) return current; - if ( state.backtracking==0 ) { - - current.merge(kw); - newLeafNode(kw, grammarAccess.getPATHAccess().get_Keyword_4()); - - } - - } - break; - case 6 : - // InternalSemver.g:1419:3: this_DIGITS_5= RULE_DIGITS - { - this_DIGITS_5=(Token)match(input,RULE_DIGITS,FOLLOW_25); if (state.failed) return current; - if ( state.backtracking==0 ) { - - current.merge(this_DIGITS_5); - - } - if ( state.backtracking==0 ) { - - newLeafNode(this_DIGITS_5, grammarAccess.getPATHAccess().getDIGITSTerminalRuleCall_5()); - - } - - } - break; - case 7 : - // InternalSemver.g:1427:3: this_LETTER_6= ruleLETTER + // InternalSemver.g:1585:3: this_ALPHA_NUMERIC_CHAR_4= ruleALPHA_NUMERIC_CHAR { if ( state.backtracking==0 ) { - newCompositeNode(grammarAccess.getPATHAccess().getLETTERParserRuleCall_6()); + newCompositeNode(grammarAccess.getPATHAccess().getALPHA_NUMERIC_CHARParserRuleCall_4()); } - pushFollow(FOLLOW_25); - this_LETTER_6=ruleLETTER(); + pushFollow(FOLLOW_32); + this_ALPHA_NUMERIC_CHAR_4=ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_LETTER_6); + current.merge(this_ALPHA_NUMERIC_CHAR_4); } if ( state.backtracking==0 ) { @@ -4073,13 +4473,13 @@ public final AntlrDatatypeRuleToken rulePATH() throws RecognitionException { break; default : - if ( cnt28 >= 1 ) break loop28; + if ( cnt30 >= 1 ) break loop30; if (state.backtracking>0) {state.failed=true; return current;} EarlyExitException eee = - new EarlyExitException(28, input); + new EarlyExitException(30, input); throw eee; } - cnt28++; + cnt30++; } while (true); @@ -4104,7 +4504,7 @@ public final AntlrDatatypeRuleToken rulePATH() throws RecognitionException { // $ANTLR start "entryRuleURL_PROTOCOL" - // InternalSemver.g:1441:1: entryRuleURL_PROTOCOL returns [String current=null] : iv_ruleURL_PROTOCOL= ruleURL_PROTOCOL EOF ; + // InternalSemver.g:1599:1: entryRuleURL_PROTOCOL returns [String current=null] : iv_ruleURL_PROTOCOL= ruleURL_PROTOCOL EOF ; public final String entryRuleURL_PROTOCOL() throws RecognitionException { String current = null; @@ -4112,8 +4512,8 @@ public final String entryRuleURL_PROTOCOL() throws RecognitionException { try { - // InternalSemver.g:1441:52: (iv_ruleURL_PROTOCOL= ruleURL_PROTOCOL EOF ) - // InternalSemver.g:1442:2: iv_ruleURL_PROTOCOL= ruleURL_PROTOCOL EOF + // InternalSemver.g:1599:52: (iv_ruleURL_PROTOCOL= ruleURL_PROTOCOL EOF ) + // InternalSemver.g:1600:2: iv_ruleURL_PROTOCOL= ruleURL_PROTOCOL EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getURL_PROTOCOLRule()); @@ -4144,7 +4544,7 @@ public final String entryRuleURL_PROTOCOL() throws RecognitionException { // $ANTLR start "ruleURL_PROTOCOL" - // InternalSemver.g:1448:1: ruleURL_PROTOCOL returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_NO_VX_0= ruleLETTER_NO_VX (this_LETTER_1= ruleLETTER | kw= '+' )+ ) ; + // InternalSemver.g:1606:1: ruleURL_PROTOCOL returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_NO_VX_0= ruleLETTER_NO_VX (this_LETTER_1= ruleLETTER | kw= '+' )+ ) ; public final AntlrDatatypeRuleToken ruleURL_PROTOCOL() throws RecognitionException { AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); @@ -4158,18 +4558,18 @@ public final AntlrDatatypeRuleToken ruleURL_PROTOCOL() throws RecognitionExcepti enterRule(); try { - // InternalSemver.g:1454:2: ( (this_LETTER_NO_VX_0= ruleLETTER_NO_VX (this_LETTER_1= ruleLETTER | kw= '+' )+ ) ) - // InternalSemver.g:1455:2: (this_LETTER_NO_VX_0= ruleLETTER_NO_VX (this_LETTER_1= ruleLETTER | kw= '+' )+ ) + // InternalSemver.g:1612:2: ( (this_LETTER_NO_VX_0= ruleLETTER_NO_VX (this_LETTER_1= ruleLETTER | kw= '+' )+ ) ) + // InternalSemver.g:1613:2: (this_LETTER_NO_VX_0= ruleLETTER_NO_VX (this_LETTER_1= ruleLETTER | kw= '+' )+ ) { - // InternalSemver.g:1455:2: (this_LETTER_NO_VX_0= ruleLETTER_NO_VX (this_LETTER_1= ruleLETTER | kw= '+' )+ ) - // InternalSemver.g:1456:3: this_LETTER_NO_VX_0= ruleLETTER_NO_VX (this_LETTER_1= ruleLETTER | kw= '+' )+ + // InternalSemver.g:1613:2: (this_LETTER_NO_VX_0= ruleLETTER_NO_VX (this_LETTER_1= ruleLETTER | kw= '+' )+ ) + // InternalSemver.g:1614:3: this_LETTER_NO_VX_0= ruleLETTER_NO_VX (this_LETTER_1= ruleLETTER | kw= '+' )+ { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getURL_PROTOCOLAccess().getLETTER_NO_VXParserRuleCall_0()); } - pushFollow(FOLLOW_26); + pushFollow(FOLLOW_33); this_LETTER_NO_VX_0=ruleLETTER_NO_VX(); state._fsp--; @@ -4184,31 +4584,31 @@ public final AntlrDatatypeRuleToken ruleURL_PROTOCOL() throws RecognitionExcepti afterParserOrEnumRuleCall(); } - // InternalSemver.g:1466:3: (this_LETTER_1= ruleLETTER | kw= '+' )+ - int cnt29=0; - loop29: + // InternalSemver.g:1624:3: (this_LETTER_1= ruleLETTER | kw= '+' )+ + int cnt31=0; + loop31: do { - int alt29=3; - int LA29_0 = input.LA(1); + int alt31=3; + int LA31_0 = input.LA(1); - if ( (LA29_0==RULE_LETTER_V||(LA29_0>=RULE_LETTER_F && LA29_0<=RULE_LETTER_X)||LA29_0==RULE_LETTER_OTHER) ) { - alt29=1; + if ( (LA31_0==RULE_LETTER_V||(LA31_0>=RULE_LETTER_F && LA31_0<=RULE_LETTER_C)||(LA31_0>=RULE_LETTER_X && LA31_0<=RULE_LETTER_OTHER)) ) { + alt31=1; } - else if ( (LA29_0==41) ) { - alt29=2; + else if ( (LA31_0==47) ) { + alt31=2; } - switch (alt29) { + switch (alt31) { case 1 : - // InternalSemver.g:1467:4: this_LETTER_1= ruleLETTER + // InternalSemver.g:1625:4: this_LETTER_1= ruleLETTER { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getURL_PROTOCOLAccess().getLETTERParserRuleCall_1_0()); } - pushFollow(FOLLOW_27); + pushFollow(FOLLOW_34); this_LETTER_1=ruleLETTER(); state._fsp--; @@ -4227,9 +4627,9 @@ else if ( (LA29_0==41) ) { } break; case 2 : - // InternalSemver.g:1478:4: kw= '+' + // InternalSemver.g:1636:4: kw= '+' { - kw=(Token)match(input,41,FOLLOW_27); if (state.failed) return current; + kw=(Token)match(input,47,FOLLOW_34); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -4241,13 +4641,13 @@ else if ( (LA29_0==41) ) { break; default : - if ( cnt29 >= 1 ) break loop29; + if ( cnt31 >= 1 ) break loop31; if (state.backtracking>0) {state.failed=true; return current;} EarlyExitException eee = - new EarlyExitException(29, input); + new EarlyExitException(31, input); throw eee; } - cnt29++; + cnt31++; } while (true); @@ -4275,7 +4675,7 @@ else if ( (LA29_0==41) ) { // $ANTLR start "entryRuleURL" - // InternalSemver.g:1488:1: entryRuleURL returns [String current=null] : iv_ruleURL= ruleURL EOF ; + // InternalSemver.g:1646:1: entryRuleURL returns [String current=null] : iv_ruleURL= ruleURL EOF ; public final String entryRuleURL() throws RecognitionException { String current = null; @@ -4283,8 +4683,8 @@ public final String entryRuleURL() throws RecognitionException { try { - // InternalSemver.g:1488:43: (iv_ruleURL= ruleURL EOF ) - // InternalSemver.g:1489:2: iv_ruleURL= ruleURL EOF + // InternalSemver.g:1646:43: (iv_ruleURL= ruleURL EOF ) + // InternalSemver.g:1647:2: iv_ruleURL= ruleURL EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getURLRule()); @@ -4315,177 +4715,122 @@ public final String entryRuleURL() throws RecognitionException { // $ANTLR start "ruleURL" - // InternalSemver.g:1495:1: ruleURL returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : ( (kw= '-' | kw= '_' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_14= RULE_DIGITS | this_LETTER_15= ruleLETTER )* ) ; + // InternalSemver.g:1653:1: ruleURL returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : ( (kw= '_' | this_ALPHA_NUMERIC_CHAR_1= ruleALPHA_NUMERIC_CHAR )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_11= ruleALPHA_NUMERIC_CHAR )* ) ; public final AntlrDatatypeRuleToken ruleURL() throws RecognitionException { AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); Token kw=null; - Token this_DIGITS_2=null; - Token this_DIGITS_14=null; - AntlrDatatypeRuleToken this_LETTER_3 = null; + AntlrDatatypeRuleToken this_ALPHA_NUMERIC_CHAR_1 = null; - AntlrDatatypeRuleToken this_LETTER_15 = null; + AntlrDatatypeRuleToken this_ALPHA_NUMERIC_CHAR_11 = null; enterRule(); try { - // InternalSemver.g:1501:2: ( ( (kw= '-' | kw= '_' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_14= RULE_DIGITS | this_LETTER_15= ruleLETTER )* ) ) - // InternalSemver.g:1502:2: ( (kw= '-' | kw= '_' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_14= RULE_DIGITS | this_LETTER_15= ruleLETTER )* ) + // InternalSemver.g:1659:2: ( ( (kw= '_' | this_ALPHA_NUMERIC_CHAR_1= ruleALPHA_NUMERIC_CHAR )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_11= ruleALPHA_NUMERIC_CHAR )* ) ) + // InternalSemver.g:1660:2: ( (kw= '_' | this_ALPHA_NUMERIC_CHAR_1= ruleALPHA_NUMERIC_CHAR )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_11= ruleALPHA_NUMERIC_CHAR )* ) { - // InternalSemver.g:1502:2: ( (kw= '-' | kw= '_' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_14= RULE_DIGITS | this_LETTER_15= ruleLETTER )* ) - // InternalSemver.g:1503:3: (kw= '-' | kw= '_' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_14= RULE_DIGITS | this_LETTER_15= ruleLETTER )* + // InternalSemver.g:1660:2: ( (kw= '_' | this_ALPHA_NUMERIC_CHAR_1= ruleALPHA_NUMERIC_CHAR )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_11= ruleALPHA_NUMERIC_CHAR )* ) + // InternalSemver.g:1661:3: (kw= '_' | this_ALPHA_NUMERIC_CHAR_1= ruleALPHA_NUMERIC_CHAR )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_11= ruleALPHA_NUMERIC_CHAR )* { - // InternalSemver.g:1503:3: (kw= '-' | kw= '_' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )* - loop30: + // InternalSemver.g:1661:3: (kw= '_' | this_ALPHA_NUMERIC_CHAR_1= ruleALPHA_NUMERIC_CHAR )* + loop32: do { - int alt30=5; - switch ( input.LA(1) ) { - case 39: - { - alt30=1; - } - break; - case 43: - { - alt30=2; - } - break; - case RULE_DIGITS: - { - alt30=3; - } - break; - case RULE_LETTER_V: - case RULE_LETTER_F: - case RULE_LETTER_I: - case RULE_LETTER_L: - case RULE_LETTER_E: - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: - case RULE_LETTER_X: - case RULE_LETTER_OTHER: - { - alt30=4; - } - break; + int alt32=3; + int LA32_0 = input.LA(1); + if ( (LA32_0==49) ) { + alt32=1; + } + else if ( ((LA32_0>=RULE_LETTER_V && LA32_0<=RULE_LETTER_C)||(LA32_0>=RULE_LETTER_X && LA32_0<=RULE_LETTER_OTHER)||LA32_0==45) ) { + alt32=2; } - switch (alt30) { + + switch (alt32) { case 1 : - // InternalSemver.g:1504:4: kw= '-' + // InternalSemver.g:1662:4: kw= '_' { - kw=(Token)match(input,39,FOLLOW_8); if (state.failed) return current; + kw=(Token)match(input,49,FOLLOW_8); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); - newLeafNode(kw, grammarAccess.getURLAccess().getHyphenMinusKeyword_0_0()); + newLeafNode(kw, grammarAccess.getURLAccess().get_Keyword_0_0()); } } break; case 2 : - // InternalSemver.g:1510:4: kw= '_' + // InternalSemver.g:1668:4: this_ALPHA_NUMERIC_CHAR_1= ruleALPHA_NUMERIC_CHAR { - kw=(Token)match(input,43,FOLLOW_8); if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(kw); - newLeafNode(kw, grammarAccess.getURLAccess().get_Keyword_0_1()); + newCompositeNode(grammarAccess.getURLAccess().getALPHA_NUMERIC_CHARParserRuleCall_0_1()); } + pushFollow(FOLLOW_8); + this_ALPHA_NUMERIC_CHAR_1=ruleALPHA_NUMERIC_CHAR(); - } - break; - case 3 : - // InternalSemver.g:1516:4: this_DIGITS_2= RULE_DIGITS - { - this_DIGITS_2=(Token)match(input,RULE_DIGITS,FOLLOW_8); if (state.failed) return current; + state._fsp--; + if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_DIGITS_2); + current.merge(this_ALPHA_NUMERIC_CHAR_1); } if ( state.backtracking==0 ) { - newLeafNode(this_DIGITS_2, grammarAccess.getURLAccess().getDIGITSTerminalRuleCall_0_2()); + afterParserOrEnumRuleCall(); } } break; - case 4 : - // InternalSemver.g:1524:4: this_LETTER_3= ruleLETTER - { - if ( state.backtracking==0 ) { - newCompositeNode(grammarAccess.getURLAccess().getLETTERParserRuleCall_0_3()); - - } - pushFollow(FOLLOW_8); - this_LETTER_3=ruleLETTER(); + default : + break loop32; + } + } while (true); - state._fsp--; - if (state.failed) return current; - if ( state.backtracking==0 ) { - - current.merge(this_LETTER_3); - - } - if ( state.backtracking==0 ) { - - afterParserOrEnumRuleCall(); - - } - - } - break; - - default : - break loop30; - } - } while (true); - - // InternalSemver.g:1535:3: (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) - int alt31=4; + // InternalSemver.g:1679:3: (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) + int alt33=4; switch ( input.LA(1) ) { - case 36: + case 42: { - alt31=1; + alt33=1; } break; - case 40: + case 46: { - alt31=2; + alt33=2; } break; - case 35: + case 41: { - alt31=3; + alt33=3; } break; - case 42: + case 48: { - alt31=4; + alt33=4; } break; default: if (state.backtracking>0) {state.failed=true; return current;} NoViableAltException nvae = - new NoViableAltException("", 31, 0, input); + new NoViableAltException("", 33, 0, input); throw nvae; } - switch (alt31) { + switch (alt33) { case 1 : - // InternalSemver.g:1536:4: kw= '/' + // InternalSemver.g:1680:4: kw= '/' { - kw=(Token)match(input,36,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,42,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -4496,9 +4841,9 @@ public final AntlrDatatypeRuleToken ruleURL() throws RecognitionException { } break; case 2 : - // InternalSemver.g:1542:4: kw= '.' + // InternalSemver.g:1686:4: kw= '.' { - kw=(Token)match(input,40,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,46,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -4509,9 +4854,9 @@ public final AntlrDatatypeRuleToken ruleURL() throws RecognitionException { } break; case 3 : - // InternalSemver.g:1548:4: kw= ':' + // InternalSemver.g:1692:4: kw= ':' { - kw=(Token)match(input,35,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,41,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -4522,9 +4867,9 @@ public final AntlrDatatypeRuleToken ruleURL() throws RecognitionException { } break; case 4 : - // InternalSemver.g:1554:4: kw= '@' + // InternalSemver.g:1698:4: kw= '@' { - kw=(Token)match(input,42,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,48,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -4537,47 +4882,38 @@ public final AntlrDatatypeRuleToken ruleURL() throws RecognitionException { } - // InternalSemver.g:1560:3: (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_14= RULE_DIGITS | this_LETTER_15= ruleLETTER )* - loop32: + // InternalSemver.g:1704:3: (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_11= ruleALPHA_NUMERIC_CHAR )* + loop34: do { - int alt32=9; + int alt34=7; switch ( input.LA(1) ) { - case 36: - { - alt32=1; - } - break; - case 40: - { - alt32=2; - } - break; - case 35: + case 42: { - alt32=3; + alt34=1; } break; - case 42: + case 46: { - alt32=4; + alt34=2; } break; - case 39: + case 41: { - alt32=5; + alt34=3; } break; - case 43: + case 48: { - alt32=6; + alt34=4; } break; - case RULE_DIGITS: + case 49: { - alt32=7; + alt34=5; } break; case RULE_LETTER_V: + case RULE_DIGITS: case RULE_LETTER_F: case RULE_LETTER_I: case RULE_LETTER_L: @@ -4585,20 +4921,27 @@ public final AntlrDatatypeRuleToken ruleURL() throws RecognitionException { case RULE_LETTER_S: case RULE_LETTER_M: case RULE_LETTER_R: + case RULE_LETTER_W: + case RULE_LETTER_O: + case RULE_LETTER_K: + case RULE_LETTER_P: + case RULE_LETTER_A: + case RULE_LETTER_C: case RULE_LETTER_X: case RULE_LETTER_OTHER: + case 45: { - alt32=8; + alt34=6; } break; } - switch (alt32) { + switch (alt34) { case 1 : - // InternalSemver.g:1561:4: kw= '/' + // InternalSemver.g:1705:4: kw= '/' { - kw=(Token)match(input,36,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,42,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -4609,9 +4952,9 @@ public final AntlrDatatypeRuleToken ruleURL() throws RecognitionException { } break; case 2 : - // InternalSemver.g:1567:4: kw= '.' + // InternalSemver.g:1711:4: kw= '.' { - kw=(Token)match(input,40,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,46,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -4622,9 +4965,9 @@ public final AntlrDatatypeRuleToken ruleURL() throws RecognitionException { } break; case 3 : - // InternalSemver.g:1573:4: kw= ':' + // InternalSemver.g:1717:4: kw= ':' { - kw=(Token)match(input,35,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,41,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -4635,9 +4978,9 @@ public final AntlrDatatypeRuleToken ruleURL() throws RecognitionException { } break; case 4 : - // InternalSemver.g:1579:4: kw= '@' + // InternalSemver.g:1723:4: kw= '@' { - kw=(Token)match(input,42,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,48,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -4648,64 +4991,34 @@ public final AntlrDatatypeRuleToken ruleURL() throws RecognitionException { } break; case 5 : - // InternalSemver.g:1585:4: kw= '-' + // InternalSemver.g:1729:4: kw= '_' { - kw=(Token)match(input,39,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,49,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); - newLeafNode(kw, grammarAccess.getURLAccess().getHyphenMinusKeyword_2_4()); + newLeafNode(kw, grammarAccess.getURLAccess().get_Keyword_2_4()); } } break; case 6 : - // InternalSemver.g:1591:4: kw= '_' - { - kw=(Token)match(input,43,FOLLOW_28); if (state.failed) return current; - if ( state.backtracking==0 ) { - - current.merge(kw); - newLeafNode(kw, grammarAccess.getURLAccess().get_Keyword_2_5()); - - } - - } - break; - case 7 : - // InternalSemver.g:1597:4: this_DIGITS_14= RULE_DIGITS - { - this_DIGITS_14=(Token)match(input,RULE_DIGITS,FOLLOW_28); if (state.failed) return current; - if ( state.backtracking==0 ) { - - current.merge(this_DIGITS_14); - - } - if ( state.backtracking==0 ) { - - newLeafNode(this_DIGITS_14, grammarAccess.getURLAccess().getDIGITSTerminalRuleCall_2_6()); - - } - - } - break; - case 8 : - // InternalSemver.g:1605:4: this_LETTER_15= ruleLETTER + // InternalSemver.g:1735:4: this_ALPHA_NUMERIC_CHAR_11= ruleALPHA_NUMERIC_CHAR { if ( state.backtracking==0 ) { - newCompositeNode(grammarAccess.getURLAccess().getLETTERParserRuleCall_2_7()); + newCompositeNode(grammarAccess.getURLAccess().getALPHA_NUMERIC_CHARParserRuleCall_2_5()); } - pushFollow(FOLLOW_28); - this_LETTER_15=ruleLETTER(); + pushFollow(FOLLOW_35); + this_ALPHA_NUMERIC_CHAR_11=ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_LETTER_15); + current.merge(this_ALPHA_NUMERIC_CHAR_11); } if ( state.backtracking==0 ) { @@ -4718,7 +5031,7 @@ public final AntlrDatatypeRuleToken ruleURL() throws RecognitionException { break; default : - break loop32; + break loop34; } } while (true); @@ -4747,7 +5060,7 @@ public final AntlrDatatypeRuleToken ruleURL() throws RecognitionException { // $ANTLR start "entryRuleURL_NO_VX" - // InternalSemver.g:1620:1: entryRuleURL_NO_VX returns [String current=null] : iv_ruleURL_NO_VX= ruleURL_NO_VX EOF ; + // InternalSemver.g:1750:1: entryRuleURL_NO_VX returns [String current=null] : iv_ruleURL_NO_VX= ruleURL_NO_VX EOF ; public final String entryRuleURL_NO_VX() throws RecognitionException { String current = null; @@ -4755,8 +5068,8 @@ public final String entryRuleURL_NO_VX() throws RecognitionException { try { - // InternalSemver.g:1620:49: (iv_ruleURL_NO_VX= ruleURL_NO_VX EOF ) - // InternalSemver.g:1621:2: iv_ruleURL_NO_VX= ruleURL_NO_VX EOF + // InternalSemver.g:1750:49: (iv_ruleURL_NO_VX= ruleURL_NO_VX EOF ) + // InternalSemver.g:1751:2: iv_ruleURL_NO_VX= ruleURL_NO_VX EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getURL_NO_VXRule()); @@ -4787,41 +5100,39 @@ public final String entryRuleURL_NO_VX() throws RecognitionException { // $ANTLR start "ruleURL_NO_VX" - // InternalSemver.g:1627:1: ruleURL_NO_VX returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : ( (kw= '-' | kw= '_' | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) (kw= '-' | kw= '_' | this_DIGITS_5= RULE_DIGITS | this_LETTER_6= ruleLETTER )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_17= RULE_DIGITS | this_LETTER_18= ruleLETTER )* ) ; + // InternalSemver.g:1757:1: ruleURL_NO_VX returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : ( (kw= '_' | kw= '-' | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) (kw= '_' | this_ALPHA_NUMERIC_CHAR_4= ruleALPHA_NUMERIC_CHAR )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_14= ruleALPHA_NUMERIC_CHAR )* ) ; public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException { AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); Token kw=null; - Token this_DIGITS_5=null; - Token this_DIGITS_17=null; AntlrDatatypeRuleToken this_LETTER_NO_VX_2 = null; - AntlrDatatypeRuleToken this_LETTER_6 = null; + AntlrDatatypeRuleToken this_ALPHA_NUMERIC_CHAR_4 = null; - AntlrDatatypeRuleToken this_LETTER_18 = null; + AntlrDatatypeRuleToken this_ALPHA_NUMERIC_CHAR_14 = null; enterRule(); try { - // InternalSemver.g:1633:2: ( ( (kw= '-' | kw= '_' | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) (kw= '-' | kw= '_' | this_DIGITS_5= RULE_DIGITS | this_LETTER_6= ruleLETTER )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_17= RULE_DIGITS | this_LETTER_18= ruleLETTER )* ) ) - // InternalSemver.g:1634:2: ( (kw= '-' | kw= '_' | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) (kw= '-' | kw= '_' | this_DIGITS_5= RULE_DIGITS | this_LETTER_6= ruleLETTER )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_17= RULE_DIGITS | this_LETTER_18= ruleLETTER )* ) + // InternalSemver.g:1763:2: ( ( (kw= '_' | kw= '-' | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) (kw= '_' | this_ALPHA_NUMERIC_CHAR_4= ruleALPHA_NUMERIC_CHAR )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_14= ruleALPHA_NUMERIC_CHAR )* ) ) + // InternalSemver.g:1764:2: ( (kw= '_' | kw= '-' | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) (kw= '_' | this_ALPHA_NUMERIC_CHAR_4= ruleALPHA_NUMERIC_CHAR )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_14= ruleALPHA_NUMERIC_CHAR )* ) { - // InternalSemver.g:1634:2: ( (kw= '-' | kw= '_' | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) (kw= '-' | kw= '_' | this_DIGITS_5= RULE_DIGITS | this_LETTER_6= ruleLETTER )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_17= RULE_DIGITS | this_LETTER_18= ruleLETTER )* ) - // InternalSemver.g:1635:3: (kw= '-' | kw= '_' | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) (kw= '-' | kw= '_' | this_DIGITS_5= RULE_DIGITS | this_LETTER_6= ruleLETTER )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_17= RULE_DIGITS | this_LETTER_18= ruleLETTER )* + // InternalSemver.g:1764:2: ( (kw= '_' | kw= '-' | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) (kw= '_' | this_ALPHA_NUMERIC_CHAR_4= ruleALPHA_NUMERIC_CHAR )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_14= ruleALPHA_NUMERIC_CHAR )* ) + // InternalSemver.g:1765:3: (kw= '_' | kw= '-' | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) (kw= '_' | this_ALPHA_NUMERIC_CHAR_4= ruleALPHA_NUMERIC_CHAR )* (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_14= ruleALPHA_NUMERIC_CHAR )* { - // InternalSemver.g:1635:3: (kw= '-' | kw= '_' | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) - int alt33=3; + // InternalSemver.g:1765:3: (kw= '_' | kw= '-' | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) + int alt35=3; switch ( input.LA(1) ) { - case 39: + case 49: { - alt33=1; + alt35=1; } break; - case 43: + case 45: { - alt33=2; + alt35=2; } break; case RULE_LETTER_F: @@ -4831,48 +5142,54 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException case RULE_LETTER_S: case RULE_LETTER_M: case RULE_LETTER_R: + case RULE_LETTER_W: + case RULE_LETTER_O: + case RULE_LETTER_K: + case RULE_LETTER_P: + case RULE_LETTER_A: + case RULE_LETTER_C: case RULE_LETTER_OTHER: { - alt33=3; + alt35=3; } break; default: if (state.backtracking>0) {state.failed=true; return current;} NoViableAltException nvae = - new NoViableAltException("", 33, 0, input); + new NoViableAltException("", 35, 0, input); throw nvae; } - switch (alt33) { + switch (alt35) { case 1 : - // InternalSemver.g:1636:4: kw= '-' + // InternalSemver.g:1766:4: kw= '_' { - kw=(Token)match(input,39,FOLLOW_8); if (state.failed) return current; + kw=(Token)match(input,49,FOLLOW_8); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); - newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_0_0()); + newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().get_Keyword_0_0()); } } break; case 2 : - // InternalSemver.g:1642:4: kw= '_' + // InternalSemver.g:1772:4: kw= '-' { - kw=(Token)match(input,43,FOLLOW_8); if (state.failed) return current; + kw=(Token)match(input,45,FOLLOW_8); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); - newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().get_Keyword_0_1()); + newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_0_1()); } } break; case 3 : - // InternalSemver.g:1648:4: this_LETTER_NO_VX_2= ruleLETTER_NO_VX + // InternalSemver.g:1778:4: this_LETTER_NO_VX_2= ruleLETTER_NO_VX { if ( state.backtracking==0 ) { @@ -4900,103 +5217,50 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException } - // InternalSemver.g:1659:3: (kw= '-' | kw= '_' | this_DIGITS_5= RULE_DIGITS | this_LETTER_6= ruleLETTER )* - loop34: + // InternalSemver.g:1789:3: (kw= '_' | this_ALPHA_NUMERIC_CHAR_4= ruleALPHA_NUMERIC_CHAR )* + loop36: do { - int alt34=5; - switch ( input.LA(1) ) { - case 39: - { - alt34=1; - } - break; - case 43: - { - alt34=2; - } - break; - case RULE_DIGITS: - { - alt34=3; - } - break; - case RULE_LETTER_V: - case RULE_LETTER_F: - case RULE_LETTER_I: - case RULE_LETTER_L: - case RULE_LETTER_E: - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: - case RULE_LETTER_X: - case RULE_LETTER_OTHER: - { - alt34=4; - } - break; + int alt36=3; + int LA36_0 = input.LA(1); + if ( (LA36_0==49) ) { + alt36=1; + } + else if ( ((LA36_0>=RULE_LETTER_V && LA36_0<=RULE_LETTER_C)||(LA36_0>=RULE_LETTER_X && LA36_0<=RULE_LETTER_OTHER)||LA36_0==45) ) { + alt36=2; } - switch (alt34) { + + switch (alt36) { case 1 : - // InternalSemver.g:1660:4: kw= '-' + // InternalSemver.g:1790:4: kw= '_' { - kw=(Token)match(input,39,FOLLOW_8); if (state.failed) return current; + kw=(Token)match(input,49,FOLLOW_8); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); - newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_1_0()); + newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().get_Keyword_1_0()); } } break; case 2 : - // InternalSemver.g:1666:4: kw= '_' - { - kw=(Token)match(input,43,FOLLOW_8); if (state.failed) return current; - if ( state.backtracking==0 ) { - - current.merge(kw); - newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().get_Keyword_1_1()); - - } - - } - break; - case 3 : - // InternalSemver.g:1672:4: this_DIGITS_5= RULE_DIGITS - { - this_DIGITS_5=(Token)match(input,RULE_DIGITS,FOLLOW_8); if (state.failed) return current; - if ( state.backtracking==0 ) { - - current.merge(this_DIGITS_5); - - } - if ( state.backtracking==0 ) { - - newLeafNode(this_DIGITS_5, grammarAccess.getURL_NO_VXAccess().getDIGITSTerminalRuleCall_1_2()); - - } - - } - break; - case 4 : - // InternalSemver.g:1680:4: this_LETTER_6= ruleLETTER + // InternalSemver.g:1796:4: this_ALPHA_NUMERIC_CHAR_4= ruleALPHA_NUMERIC_CHAR { if ( state.backtracking==0 ) { - newCompositeNode(grammarAccess.getURL_NO_VXAccess().getLETTERParserRuleCall_1_3()); + newCompositeNode(grammarAccess.getURL_NO_VXAccess().getALPHA_NUMERIC_CHARParserRuleCall_1_1()); } pushFollow(FOLLOW_8); - this_LETTER_6=ruleLETTER(); + this_ALPHA_NUMERIC_CHAR_4=ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_LETTER_6); + current.merge(this_ALPHA_NUMERIC_CHAR_4); } if ( state.backtracking==0 ) { @@ -5009,46 +5273,46 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException break; default : - break loop34; + break loop36; } } while (true); - // InternalSemver.g:1691:3: (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) - int alt35=4; + // InternalSemver.g:1807:3: (kw= '/' | kw= '.' | kw= ':' | kw= '@' ) + int alt37=4; switch ( input.LA(1) ) { - case 36: + case 42: { - alt35=1; + alt37=1; } break; - case 40: + case 46: { - alt35=2; + alt37=2; } break; - case 35: + case 41: { - alt35=3; + alt37=3; } break; - case 42: + case 48: { - alt35=4; + alt37=4; } break; default: if (state.backtracking>0) {state.failed=true; return current;} NoViableAltException nvae = - new NoViableAltException("", 35, 0, input); + new NoViableAltException("", 37, 0, input); throw nvae; } - switch (alt35) { + switch (alt37) { case 1 : - // InternalSemver.g:1692:4: kw= '/' + // InternalSemver.g:1808:4: kw= '/' { - kw=(Token)match(input,36,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,42,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -5059,9 +5323,9 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException } break; case 2 : - // InternalSemver.g:1698:4: kw= '.' + // InternalSemver.g:1814:4: kw= '.' { - kw=(Token)match(input,40,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,46,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -5072,9 +5336,9 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException } break; case 3 : - // InternalSemver.g:1704:4: kw= ':' + // InternalSemver.g:1820:4: kw= ':' { - kw=(Token)match(input,35,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,41,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -5085,9 +5349,9 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException } break; case 4 : - // InternalSemver.g:1710:4: kw= '@' + // InternalSemver.g:1826:4: kw= '@' { - kw=(Token)match(input,42,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,48,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -5100,47 +5364,38 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException } - // InternalSemver.g:1716:3: (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '-' | kw= '_' | this_DIGITS_17= RULE_DIGITS | this_LETTER_18= ruleLETTER )* - loop36: + // InternalSemver.g:1832:3: (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | this_ALPHA_NUMERIC_CHAR_14= ruleALPHA_NUMERIC_CHAR )* + loop38: do { - int alt36=9; + int alt38=7; switch ( input.LA(1) ) { - case 36: - { - alt36=1; - } - break; - case 40: - { - alt36=2; - } - break; - case 35: + case 42: { - alt36=3; + alt38=1; } break; - case 42: + case 46: { - alt36=4; + alt38=2; } break; - case 39: + case 41: { - alt36=5; + alt38=3; } break; - case 43: + case 48: { - alt36=6; + alt38=4; } break; - case RULE_DIGITS: + case 49: { - alt36=7; + alt38=5; } break; case RULE_LETTER_V: + case RULE_DIGITS: case RULE_LETTER_F: case RULE_LETTER_I: case RULE_LETTER_L: @@ -5148,20 +5403,27 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException case RULE_LETTER_S: case RULE_LETTER_M: case RULE_LETTER_R: + case RULE_LETTER_W: + case RULE_LETTER_O: + case RULE_LETTER_K: + case RULE_LETTER_P: + case RULE_LETTER_A: + case RULE_LETTER_C: case RULE_LETTER_X: case RULE_LETTER_OTHER: + case 45: { - alt36=8; + alt38=6; } break; } - switch (alt36) { + switch (alt38) { case 1 : - // InternalSemver.g:1717:4: kw= '/' + // InternalSemver.g:1833:4: kw= '/' { - kw=(Token)match(input,36,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,42,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -5172,9 +5434,9 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException } break; case 2 : - // InternalSemver.g:1723:4: kw= '.' + // InternalSemver.g:1839:4: kw= '.' { - kw=(Token)match(input,40,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,46,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -5185,9 +5447,9 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException } break; case 3 : - // InternalSemver.g:1729:4: kw= ':' + // InternalSemver.g:1845:4: kw= ':' { - kw=(Token)match(input,35,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,41,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -5198,9 +5460,9 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException } break; case 4 : - // InternalSemver.g:1735:4: kw= '@' + // InternalSemver.g:1851:4: kw= '@' { - kw=(Token)match(input,42,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,48,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); @@ -5211,64 +5473,34 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException } break; case 5 : - // InternalSemver.g:1741:4: kw= '-' + // InternalSemver.g:1857:4: kw= '_' { - kw=(Token)match(input,39,FOLLOW_28); if (state.failed) return current; + kw=(Token)match(input,49,FOLLOW_35); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); - newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().getHyphenMinusKeyword_3_4()); + newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().get_Keyword_3_4()); } } break; case 6 : - // InternalSemver.g:1747:4: kw= '_' - { - kw=(Token)match(input,43,FOLLOW_28); if (state.failed) return current; - if ( state.backtracking==0 ) { - - current.merge(kw); - newLeafNode(kw, grammarAccess.getURL_NO_VXAccess().get_Keyword_3_5()); - - } - - } - break; - case 7 : - // InternalSemver.g:1753:4: this_DIGITS_17= RULE_DIGITS - { - this_DIGITS_17=(Token)match(input,RULE_DIGITS,FOLLOW_28); if (state.failed) return current; - if ( state.backtracking==0 ) { - - current.merge(this_DIGITS_17); - - } - if ( state.backtracking==0 ) { - - newLeafNode(this_DIGITS_17, grammarAccess.getURL_NO_VXAccess().getDIGITSTerminalRuleCall_3_6()); - - } - - } - break; - case 8 : - // InternalSemver.g:1761:4: this_LETTER_18= ruleLETTER + // InternalSemver.g:1863:4: this_ALPHA_NUMERIC_CHAR_14= ruleALPHA_NUMERIC_CHAR { if ( state.backtracking==0 ) { - newCompositeNode(grammarAccess.getURL_NO_VXAccess().getLETTERParserRuleCall_3_7()); + newCompositeNode(grammarAccess.getURL_NO_VXAccess().getALPHA_NUMERIC_CHARParserRuleCall_3_5()); } - pushFollow(FOLLOW_28); - this_LETTER_18=ruleLETTER(); + pushFollow(FOLLOW_35); + this_ALPHA_NUMERIC_CHAR_14=ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_LETTER_18); + current.merge(this_ALPHA_NUMERIC_CHAR_14); } if ( state.backtracking==0 ) { @@ -5281,7 +5513,7 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException break; default : - break loop36; + break loop38; } } while (true); @@ -5310,7 +5542,7 @@ public final AntlrDatatypeRuleToken ruleURL_NO_VX() throws RecognitionException // $ANTLR start "entryRuleTAG" - // InternalSemver.g:1776:1: entryRuleTAG returns [String current=null] : iv_ruleTAG= ruleTAG EOF ; + // InternalSemver.g:1878:1: entryRuleTAG returns [String current=null] : iv_ruleTAG= ruleTAG EOF ; public final String entryRuleTAG() throws RecognitionException { String current = null; @@ -5318,8 +5550,8 @@ public final String entryRuleTAG() throws RecognitionException { try { - // InternalSemver.g:1776:43: (iv_ruleTAG= ruleTAG EOF ) - // InternalSemver.g:1777:2: iv_ruleTAG= ruleTAG EOF + // InternalSemver.g:1878:43: (iv_ruleTAG= ruleTAG EOF ) + // InternalSemver.g:1879:2: iv_ruleTAG= ruleTAG EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getTAGRule()); @@ -5350,33 +5582,31 @@ public final String entryRuleTAG() throws RecognitionException { // $ANTLR start "ruleTAG" - // InternalSemver.g:1783:1: ruleTAG returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_NO_VX_0= ruleLETTER_NO_VX (kw= '-' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )+ ) ; + // InternalSemver.g:1885:1: ruleTAG returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_NO_VX_0= ruleLETTER_NO_VX this_ALPHA_NUMERIC_CHARS_1= ruleALPHA_NUMERIC_CHARS ) ; public final AntlrDatatypeRuleToken ruleTAG() throws RecognitionException { AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); - Token kw=null; - Token this_DIGITS_2=null; AntlrDatatypeRuleToken this_LETTER_NO_VX_0 = null; - AntlrDatatypeRuleToken this_LETTER_3 = null; + AntlrDatatypeRuleToken this_ALPHA_NUMERIC_CHARS_1 = null; enterRule(); try { - // InternalSemver.g:1789:2: ( (this_LETTER_NO_VX_0= ruleLETTER_NO_VX (kw= '-' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )+ ) ) - // InternalSemver.g:1790:2: (this_LETTER_NO_VX_0= ruleLETTER_NO_VX (kw= '-' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )+ ) + // InternalSemver.g:1891:2: ( (this_LETTER_NO_VX_0= ruleLETTER_NO_VX this_ALPHA_NUMERIC_CHARS_1= ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:1892:2: (this_LETTER_NO_VX_0= ruleLETTER_NO_VX this_ALPHA_NUMERIC_CHARS_1= ruleALPHA_NUMERIC_CHARS ) { - // InternalSemver.g:1790:2: (this_LETTER_NO_VX_0= ruleLETTER_NO_VX (kw= '-' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )+ ) - // InternalSemver.g:1791:3: this_LETTER_NO_VX_0= ruleLETTER_NO_VX (kw= '-' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )+ + // InternalSemver.g:1892:2: (this_LETTER_NO_VX_0= ruleLETTER_NO_VX this_ALPHA_NUMERIC_CHARS_1= ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:1893:3: this_LETTER_NO_VX_0= ruleLETTER_NO_VX this_ALPHA_NUMERIC_CHARS_1= ruleALPHA_NUMERIC_CHARS { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getTAGAccess().getLETTER_NO_VXParserRuleCall_0()); } - pushFollow(FOLLOW_5); + pushFollow(FOLLOW_10); this_LETTER_NO_VX_0=ruleLETTER_NO_VX(); state._fsp--; @@ -5391,109 +5621,28 @@ public final AntlrDatatypeRuleToken ruleTAG() throws RecognitionException { afterParserOrEnumRuleCall(); } - // InternalSemver.g:1801:3: (kw= '-' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )+ - int cnt37=0; - loop37: - do { - int alt37=4; - switch ( input.LA(1) ) { - case 39: - { - alt37=1; - } - break; - case RULE_DIGITS: - { - alt37=2; - } - break; - case RULE_LETTER_V: - case RULE_LETTER_F: - case RULE_LETTER_I: - case RULE_LETTER_L: - case RULE_LETTER_E: - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: - case RULE_LETTER_X: - case RULE_LETTER_OTHER: - { - alt37=3; - } - break; + if ( state.backtracking==0 ) { - } + newCompositeNode(grammarAccess.getTAGAccess().getALPHA_NUMERIC_CHARSParserRuleCall_1()); + + } + pushFollow(FOLLOW_2); + this_ALPHA_NUMERIC_CHARS_1=ruleALPHA_NUMERIC_CHARS(); - switch (alt37) { - case 1 : - // InternalSemver.g:1802:4: kw= '-' - { - kw=(Token)match(input,39,FOLLOW_25); if (state.failed) return current; - if ( state.backtracking==0 ) { + state._fsp--; + if (state.failed) return current; + if ( state.backtracking==0 ) { - current.merge(kw); - newLeafNode(kw, grammarAccess.getTAGAccess().getHyphenMinusKeyword_1_0()); - - } + current.merge(this_ALPHA_NUMERIC_CHARS_1); + + } + if ( state.backtracking==0 ) { - } - break; - case 2 : - // InternalSemver.g:1808:4: this_DIGITS_2= RULE_DIGITS - { - this_DIGITS_2=(Token)match(input,RULE_DIGITS,FOLLOW_25); if (state.failed) return current; - if ( state.backtracking==0 ) { + afterParserOrEnumRuleCall(); + + } - current.merge(this_DIGITS_2); - - } - if ( state.backtracking==0 ) { - - newLeafNode(this_DIGITS_2, grammarAccess.getTAGAccess().getDIGITSTerminalRuleCall_1_1()); - - } - - } - break; - case 3 : - // InternalSemver.g:1816:4: this_LETTER_3= ruleLETTER - { - if ( state.backtracking==0 ) { - - newCompositeNode(grammarAccess.getTAGAccess().getLETTERParserRuleCall_1_2()); - - } - pushFollow(FOLLOW_25); - this_LETTER_3=ruleLETTER(); - - state._fsp--; - if (state.failed) return current; - if ( state.backtracking==0 ) { - - current.merge(this_LETTER_3); - - } - if ( state.backtracking==0 ) { - - afterParserOrEnumRuleCall(); - - } - - } - break; - - default : - if ( cnt37 >= 1 ) break loop37; - if (state.backtracking>0) {state.failed=true; return current;} - EarlyExitException eee = - new EarlyExitException(37, input); - throw eee; - } - cnt37++; - } while (true); - - - } + } } @@ -5516,28 +5665,28 @@ public final AntlrDatatypeRuleToken ruleTAG() throws RecognitionException { // $ANTLR end "ruleTAG" - // $ANTLR start "entryRuleALPHA_NUMERIC_CHARS" - // InternalSemver.g:1831:1: entryRuleALPHA_NUMERIC_CHARS returns [String current=null] : iv_ruleALPHA_NUMERIC_CHARS= ruleALPHA_NUMERIC_CHARS EOF ; - public final String entryRuleALPHA_NUMERIC_CHARS() throws RecognitionException { + // $ANTLR start "entryRuleWORKSPACE_VERSION" + // InternalSemver.g:1917:1: entryRuleWORKSPACE_VERSION returns [String current=null] : iv_ruleWORKSPACE_VERSION= ruleWORKSPACE_VERSION EOF ; + public final String entryRuleWORKSPACE_VERSION() throws RecognitionException { String current = null; - AntlrDatatypeRuleToken iv_ruleALPHA_NUMERIC_CHARS = null; + AntlrDatatypeRuleToken iv_ruleWORKSPACE_VERSION = null; try { - // InternalSemver.g:1831:59: (iv_ruleALPHA_NUMERIC_CHARS= ruleALPHA_NUMERIC_CHARS EOF ) - // InternalSemver.g:1832:2: iv_ruleALPHA_NUMERIC_CHARS= ruleALPHA_NUMERIC_CHARS EOF + // InternalSemver.g:1917:57: (iv_ruleWORKSPACE_VERSION= ruleWORKSPACE_VERSION EOF ) + // InternalSemver.g:1918:2: iv_ruleWORKSPACE_VERSION= ruleWORKSPACE_VERSION EOF { if ( state.backtracking==0 ) { - newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARSRule()); + newCompositeNode(grammarAccess.getWORKSPACE_VERSIONRule()); } pushFollow(FOLLOW_1); - iv_ruleALPHA_NUMERIC_CHARS=ruleALPHA_NUMERIC_CHARS(); + iv_ruleWORKSPACE_VERSION=ruleWORKSPACE_VERSION(); state._fsp--; if (state.failed) return current; if ( state.backtracking==0 ) { - current =iv_ruleALPHA_NUMERIC_CHARS.getText(); + current =iv_ruleWORKSPACE_VERSION.getText(); } match(input,EOF,FOLLOW_2); if (state.failed) return current; @@ -5553,43 +5702,99 @@ public final String entryRuleALPHA_NUMERIC_CHARS() throws RecognitionException { } return current; } - // $ANTLR end "entryRuleALPHA_NUMERIC_CHARS" + // $ANTLR end "entryRuleWORKSPACE_VERSION" - // $ANTLR start "ruleALPHA_NUMERIC_CHARS" - // InternalSemver.g:1838:1: ruleALPHA_NUMERIC_CHARS returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (kw= '-' | this_DIGITS_1= RULE_DIGITS | this_LETTER_2= ruleLETTER )+ ; - public final AntlrDatatypeRuleToken ruleALPHA_NUMERIC_CHARS() throws RecognitionException { + // $ANTLR start "ruleWORKSPACE_VERSION" + // InternalSemver.g:1924:1: ruleWORKSPACE_VERSION returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | kw= '=' | kw= '~' | kw= '^' | kw= '<' | kw= '>' | kw= '<=' | kw= '>=' | this_ASTERIX_12= RULE_ASTERIX | this_ALPHA_NUMERIC_CHAR_13= ruleALPHA_NUMERIC_CHAR )+ ; + public final AntlrDatatypeRuleToken ruleWORKSPACE_VERSION() throws RecognitionException { AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); Token kw=null; - Token this_DIGITS_1=null; - AntlrDatatypeRuleToken this_LETTER_2 = null; + Token this_ASTERIX_12=null; + AntlrDatatypeRuleToken this_ALPHA_NUMERIC_CHAR_13 = null; enterRule(); try { - // InternalSemver.g:1844:2: ( (kw= '-' | this_DIGITS_1= RULE_DIGITS | this_LETTER_2= ruleLETTER )+ ) - // InternalSemver.g:1845:2: (kw= '-' | this_DIGITS_1= RULE_DIGITS | this_LETTER_2= ruleLETTER )+ + // InternalSemver.g:1930:2: ( (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | kw= '=' | kw= '~' | kw= '^' | kw= '<' | kw= '>' | kw= '<=' | kw= '>=' | this_ASTERIX_12= RULE_ASTERIX | this_ALPHA_NUMERIC_CHAR_13= ruleALPHA_NUMERIC_CHAR )+ ) + // InternalSemver.g:1931:2: (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | kw= '=' | kw= '~' | kw= '^' | kw= '<' | kw= '>' | kw= '<=' | kw= '>=' | this_ASTERIX_12= RULE_ASTERIX | this_ALPHA_NUMERIC_CHAR_13= ruleALPHA_NUMERIC_CHAR )+ { - // InternalSemver.g:1845:2: (kw= '-' | this_DIGITS_1= RULE_DIGITS | this_LETTER_2= ruleLETTER )+ - int cnt38=0; - loop38: + // InternalSemver.g:1931:2: (kw= '/' | kw= '.' | kw= ':' | kw= '@' | kw= '_' | kw= '=' | kw= '~' | kw= '^' | kw= '<' | kw= '>' | kw= '<=' | kw= '>=' | this_ASTERIX_12= RULE_ASTERIX | this_ALPHA_NUMERIC_CHAR_13= ruleALPHA_NUMERIC_CHAR )+ + int cnt39=0; + loop39: do { - int alt38=4; + int alt39=15; switch ( input.LA(1) ) { - case 39: + case 42: { - alt38=1; + alt39=1; } break; - case RULE_DIGITS: + case 46: { - alt38=2; + alt39=2; + } + break; + case 41: + { + alt39=3; + } + break; + case 48: + { + alt39=4; + } + break; + case 49: + { + alt39=5; + } + break; + case 50: + { + alt39=6; + } + break; + case 51: + { + alt39=7; + } + break; + case 52: + { + alt39=8; + } + break; + case 53: + { + alt39=9; + } + break; + case 54: + { + alt39=10; + } + break; + case 55: + { + alt39=11; + } + break; + case 56: + { + alt39=12; + } + break; + case RULE_ASTERIX: + { + alt39=13; } break; case RULE_LETTER_V: + case RULE_DIGITS: case RULE_LETTER_F: case RULE_LETTER_I: case RULE_LETTER_L: @@ -5597,62 +5802,212 @@ public final AntlrDatatypeRuleToken ruleALPHA_NUMERIC_CHARS() throws Recognition case RULE_LETTER_S: case RULE_LETTER_M: case RULE_LETTER_R: + case RULE_LETTER_W: + case RULE_LETTER_O: + case RULE_LETTER_K: + case RULE_LETTER_P: + case RULE_LETTER_A: + case RULE_LETTER_C: case RULE_LETTER_X: case RULE_LETTER_OTHER: + case 45: { - alt38=3; + alt39=14; } break; } - switch (alt38) { + switch (alt39) { case 1 : - // InternalSemver.g:1846:3: kw= '-' + // InternalSemver.g:1932:3: kw= '/' { - kw=(Token)match(input,39,FOLLOW_25); if (state.failed) return current; + kw=(Token)match(input,42,FOLLOW_36); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(kw); - newLeafNode(kw, grammarAccess.getALPHA_NUMERIC_CHARSAccess().getHyphenMinusKeyword_0()); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getSolidusKeyword_0()); } } break; case 2 : - // InternalSemver.g:1852:3: this_DIGITS_1= RULE_DIGITS + // InternalSemver.g:1938:3: kw= '.' + { + kw=(Token)match(input,46,FOLLOW_36); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getFullStopKeyword_1()); + + } + + } + break; + case 3 : + // InternalSemver.g:1944:3: kw= ':' { - this_DIGITS_1=(Token)match(input,RULE_DIGITS,FOLLOW_25); if (state.failed) return current; + kw=(Token)match(input,41,FOLLOW_36); if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_DIGITS_1); + current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getColonKeyword_2()); } + + } + break; + case 4 : + // InternalSemver.g:1950:3: kw= '@' + { + kw=(Token)match(input,48,FOLLOW_36); if (state.failed) return current; if ( state.backtracking==0 ) { - newLeafNode(this_DIGITS_1, grammarAccess.getALPHA_NUMERIC_CHARSAccess().getDIGITSTerminalRuleCall_1()); + current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getCommercialAtKeyword_3()); } } break; - case 3 : - // InternalSemver.g:1860:3: this_LETTER_2= ruleLETTER + case 5 : + // InternalSemver.g:1956:3: kw= '_' + { + kw=(Token)match(input,49,FOLLOW_36); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().get_Keyword_4()); + + } + + } + break; + case 6 : + // InternalSemver.g:1962:3: kw= '=' + { + kw=(Token)match(input,50,FOLLOW_36); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getEqualsSignKeyword_5()); + + } + + } + break; + case 7 : + // InternalSemver.g:1968:3: kw= '~' + { + kw=(Token)match(input,51,FOLLOW_36); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getTildeKeyword_6()); + + } + + } + break; + case 8 : + // InternalSemver.g:1974:3: kw= '^' + { + kw=(Token)match(input,52,FOLLOW_36); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getCircumflexAccentKeyword_7()); + + } + + } + break; + case 9 : + // InternalSemver.g:1980:3: kw= '<' + { + kw=(Token)match(input,53,FOLLOW_36); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getLessThanSignKeyword_8()); + + } + + } + break; + case 10 : + // InternalSemver.g:1986:3: kw= '>' + { + kw=(Token)match(input,54,FOLLOW_36); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getGreaterThanSignKeyword_9()); + + } + + } + break; + case 11 : + // InternalSemver.g:1992:3: kw= '<=' + { + kw=(Token)match(input,55,FOLLOW_36); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getLessThanSignEqualsSignKeyword_10()); + + } + + } + break; + case 12 : + // InternalSemver.g:1998:3: kw= '>=' + { + kw=(Token)match(input,56,FOLLOW_36); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(kw); + newLeafNode(kw, grammarAccess.getWORKSPACE_VERSIONAccess().getGreaterThanSignEqualsSignKeyword_11()); + + } + + } + break; + case 13 : + // InternalSemver.g:2004:3: this_ASTERIX_12= RULE_ASTERIX + { + this_ASTERIX_12=(Token)match(input,RULE_ASTERIX,FOLLOW_36); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_ASTERIX_12); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_ASTERIX_12, grammarAccess.getWORKSPACE_VERSIONAccess().getASTERIXTerminalRuleCall_12()); + + } + + } + break; + case 14 : + // InternalSemver.g:2012:3: this_ALPHA_NUMERIC_CHAR_13= ruleALPHA_NUMERIC_CHAR { if ( state.backtracking==0 ) { - newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getLETTERParserRuleCall_2()); + newCompositeNode(grammarAccess.getWORKSPACE_VERSIONAccess().getALPHA_NUMERIC_CHARParserRuleCall_13()); } - pushFollow(FOLLOW_25); - this_LETTER_2=ruleLETTER(); + pushFollow(FOLLOW_36); + this_ALPHA_NUMERIC_CHAR_13=ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_LETTER_2); + current.merge(this_ALPHA_NUMERIC_CHAR_13); } if ( state.backtracking==0 ) { @@ -5665,13 +6020,13 @@ public final AntlrDatatypeRuleToken ruleALPHA_NUMERIC_CHARS() throws Recognition break; default : - if ( cnt38 >= 1 ) break loop38; + if ( cnt39 >= 1 ) break loop39; if (state.backtracking>0) {state.failed=true; return current;} EarlyExitException eee = - new EarlyExitException(38, input); + new EarlyExitException(39, input); throw eee; } - cnt38++; + cnt39++; } while (true); @@ -5692,11 +6047,11 @@ public final AntlrDatatypeRuleToken ruleALPHA_NUMERIC_CHARS() throws Recognition } return current; } - // $ANTLR end "ruleALPHA_NUMERIC_CHARS" + // $ANTLR end "ruleWORKSPACE_VERSION" // $ANTLR start "entryRuleALPHA_NUMERIC_CHARS_START_WITH_DIGITS" - // InternalSemver.g:1874:1: entryRuleALPHA_NUMERIC_CHARS_START_WITH_DIGITS returns [String current=null] : iv_ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS EOF ; + // InternalSemver.g:2026:1: entryRuleALPHA_NUMERIC_CHARS_START_WITH_DIGITS returns [String current=null] : iv_ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS EOF ; public final String entryRuleALPHA_NUMERIC_CHARS_START_WITH_DIGITS() throws RecognitionException { String current = null; @@ -5704,8 +6059,8 @@ public final String entryRuleALPHA_NUMERIC_CHARS_START_WITH_DIGITS() throws Reco try { - // InternalSemver.g:1874:77: (iv_ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS EOF ) - // InternalSemver.g:1875:2: iv_ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS EOF + // InternalSemver.g:2026:77: (iv_ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS EOF ) + // InternalSemver.g:2027:2: iv_ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSRule()); @@ -5736,27 +6091,25 @@ public final String entryRuleALPHA_NUMERIC_CHARS_START_WITH_DIGITS() throws Reco // $ANTLR start "ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS" - // InternalSemver.g:1881:1: ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_DIGITS_0= RULE_DIGITS (kw= '-' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )+ ) ; + // InternalSemver.g:2033:1: ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_DIGITS_0= RULE_DIGITS this_ALPHA_NUMERIC_CHARS_1= ruleALPHA_NUMERIC_CHARS ) ; public final AntlrDatatypeRuleToken ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS() throws RecognitionException { AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); Token this_DIGITS_0=null; - Token kw=null; - Token this_DIGITS_2=null; - AntlrDatatypeRuleToken this_LETTER_3 = null; + AntlrDatatypeRuleToken this_ALPHA_NUMERIC_CHARS_1 = null; enterRule(); try { - // InternalSemver.g:1887:2: ( (this_DIGITS_0= RULE_DIGITS (kw= '-' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )+ ) ) - // InternalSemver.g:1888:2: (this_DIGITS_0= RULE_DIGITS (kw= '-' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )+ ) + // InternalSemver.g:2039:2: ( (this_DIGITS_0= RULE_DIGITS this_ALPHA_NUMERIC_CHARS_1= ruleALPHA_NUMERIC_CHARS ) ) + // InternalSemver.g:2040:2: (this_DIGITS_0= RULE_DIGITS this_ALPHA_NUMERIC_CHARS_1= ruleALPHA_NUMERIC_CHARS ) { - // InternalSemver.g:1888:2: (this_DIGITS_0= RULE_DIGITS (kw= '-' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )+ ) - // InternalSemver.g:1889:3: this_DIGITS_0= RULE_DIGITS (kw= '-' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )+ + // InternalSemver.g:2040:2: (this_DIGITS_0= RULE_DIGITS this_ALPHA_NUMERIC_CHARS_1= ruleALPHA_NUMERIC_CHARS ) + // InternalSemver.g:2041:3: this_DIGITS_0= RULE_DIGITS this_ALPHA_NUMERIC_CHARS_1= ruleALPHA_NUMERIC_CHARS { - this_DIGITS_0=(Token)match(input,RULE_DIGITS,FOLLOW_5); if (state.failed) return current; + this_DIGITS_0=(Token)match(input,RULE_DIGITS,FOLLOW_10); if (state.failed) return current; if ( state.backtracking==0 ) { current.merge(this_DIGITS_0); @@ -5767,110 +6120,334 @@ public final AntlrDatatypeRuleToken ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS() newLeafNode(this_DIGITS_0, grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getDIGITSTerminalRuleCall_0()); } - // InternalSemver.g:1896:3: (kw= '-' | this_DIGITS_2= RULE_DIGITS | this_LETTER_3= ruleLETTER )+ - int cnt39=0; - loop39: - do { - int alt39=4; - switch ( input.LA(1) ) { - case 39: - { - alt39=1; - } - break; - case RULE_DIGITS: - { - alt39=2; - } - break; - case RULE_LETTER_V: - case RULE_LETTER_F: - case RULE_LETTER_I: - case RULE_LETTER_L: - case RULE_LETTER_E: - case RULE_LETTER_S: - case RULE_LETTER_M: - case RULE_LETTER_R: - case RULE_LETTER_X: - case RULE_LETTER_OTHER: - { - alt39=3; - } - break; + if ( state.backtracking==0 ) { - } + newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getALPHA_NUMERIC_CHARSParserRuleCall_1()); + + } + pushFollow(FOLLOW_2); + this_ALPHA_NUMERIC_CHARS_1=ruleALPHA_NUMERIC_CHARS(); - switch (alt39) { - case 1 : - // InternalSemver.g:1897:4: kw= '-' - { - kw=(Token)match(input,39,FOLLOW_25); if (state.failed) return current; - if ( state.backtracking==0 ) { + state._fsp--; + if (state.failed) return current; + if ( state.backtracking==0 ) { - current.merge(kw); - newLeafNode(kw, grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getHyphenMinusKeyword_1_0()); - - } + current.merge(this_ALPHA_NUMERIC_CHARS_1); + + } + if ( state.backtracking==0 ) { - } - break; - case 2 : - // InternalSemver.g:1903:4: this_DIGITS_2= RULE_DIGITS - { - this_DIGITS_2=(Token)match(input,RULE_DIGITS,FOLLOW_25); if (state.failed) return current; - if ( state.backtracking==0 ) { + afterParserOrEnumRuleCall(); + + } - current.merge(this_DIGITS_2); - - } - if ( state.backtracking==0 ) { + } - newLeafNode(this_DIGITS_2, grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getDIGITSTerminalRuleCall_1_1()); - - } - } - break; - case 3 : - // InternalSemver.g:1911:4: this_LETTER_3= ruleLETTER + } + + if ( state.backtracking==0 ) { + + leaveRule(); + + } + } + + catch (RecognitionException re) { + recover(input,re); + appendSkippedTokens(); + } + finally { + } + return current; + } + // $ANTLR end "ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS" + + + // $ANTLR start "entryRuleALPHA_NUMERIC_CHARS" + // InternalSemver.g:2062:1: entryRuleALPHA_NUMERIC_CHARS returns [String current=null] : iv_ruleALPHA_NUMERIC_CHARS= ruleALPHA_NUMERIC_CHARS EOF ; + public final String entryRuleALPHA_NUMERIC_CHARS() throws RecognitionException { + String current = null; + + AntlrDatatypeRuleToken iv_ruleALPHA_NUMERIC_CHARS = null; + + + try { + // InternalSemver.g:2062:59: (iv_ruleALPHA_NUMERIC_CHARS= ruleALPHA_NUMERIC_CHARS EOF ) + // InternalSemver.g:2063:2: iv_ruleALPHA_NUMERIC_CHARS= ruleALPHA_NUMERIC_CHARS EOF + { + if ( state.backtracking==0 ) { + newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARSRule()); + } + pushFollow(FOLLOW_1); + iv_ruleALPHA_NUMERIC_CHARS=ruleALPHA_NUMERIC_CHARS(); + + state._fsp--; + if (state.failed) return current; + if ( state.backtracking==0 ) { + current =iv_ruleALPHA_NUMERIC_CHARS.getText(); + } + match(input,EOF,FOLLOW_2); if (state.failed) return current; + + } + + } + + catch (RecognitionException re) { + recover(input,re); + appendSkippedTokens(); + } + finally { + } + return current; + } + // $ANTLR end "entryRuleALPHA_NUMERIC_CHARS" + + + // $ANTLR start "ruleALPHA_NUMERIC_CHARS" + // InternalSemver.g:2069:1: ruleALPHA_NUMERIC_CHARS returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_ALPHA_NUMERIC_CHAR_0= ruleALPHA_NUMERIC_CHAR )+ ; + public final AntlrDatatypeRuleToken ruleALPHA_NUMERIC_CHARS() throws RecognitionException { + AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); + + AntlrDatatypeRuleToken this_ALPHA_NUMERIC_CHAR_0 = null; + + + + enterRule(); + + try { + // InternalSemver.g:2075:2: ( (this_ALPHA_NUMERIC_CHAR_0= ruleALPHA_NUMERIC_CHAR )+ ) + // InternalSemver.g:2076:2: (this_ALPHA_NUMERIC_CHAR_0= ruleALPHA_NUMERIC_CHAR )+ + { + // InternalSemver.g:2076:2: (this_ALPHA_NUMERIC_CHAR_0= ruleALPHA_NUMERIC_CHAR )+ + int cnt40=0; + loop40: + do { + int alt40=2; + int LA40_0 = input.LA(1); + + if ( ((LA40_0>=RULE_LETTER_V && LA40_0<=RULE_LETTER_C)||(LA40_0>=RULE_LETTER_X && LA40_0<=RULE_LETTER_OTHER)||LA40_0==45) ) { + alt40=1; + } + + + switch (alt40) { + case 1 : + // InternalSemver.g:2077:3: this_ALPHA_NUMERIC_CHAR_0= ruleALPHA_NUMERIC_CHAR { if ( state.backtracking==0 ) { - newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getLETTERParserRuleCall_1_2()); - + newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARSAccess().getALPHA_NUMERIC_CHARParserRuleCall()); + } - pushFollow(FOLLOW_25); - this_LETTER_3=ruleLETTER(); + pushFollow(FOLLOW_32); + this_ALPHA_NUMERIC_CHAR_0=ruleALPHA_NUMERIC_CHAR(); state._fsp--; if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_LETTER_3); - + current.merge(this_ALPHA_NUMERIC_CHAR_0); + } if ( state.backtracking==0 ) { - afterParserOrEnumRuleCall(); - + afterParserOrEnumRuleCall(); + } } break; default : - if ( cnt39 >= 1 ) break loop39; + if ( cnt40 >= 1 ) break loop40; if (state.backtracking>0) {state.failed=true; return current;} EarlyExitException eee = - new EarlyExitException(39, input); + new EarlyExitException(40, input); throw eee; } - cnt39++; + cnt40++; } while (true); } + if ( state.backtracking==0 ) { + + leaveRule(); + + } + } + + catch (RecognitionException re) { + recover(input,re); + appendSkippedTokens(); + } + finally { + } + return current; + } + // $ANTLR end "ruleALPHA_NUMERIC_CHARS" + + + // $ANTLR start "entryRuleALPHA_NUMERIC_CHAR" + // InternalSemver.g:2091:1: entryRuleALPHA_NUMERIC_CHAR returns [String current=null] : iv_ruleALPHA_NUMERIC_CHAR= ruleALPHA_NUMERIC_CHAR EOF ; + public final String entryRuleALPHA_NUMERIC_CHAR() throws RecognitionException { + String current = null; + + AntlrDatatypeRuleToken iv_ruleALPHA_NUMERIC_CHAR = null; + + + try { + // InternalSemver.g:2091:58: (iv_ruleALPHA_NUMERIC_CHAR= ruleALPHA_NUMERIC_CHAR EOF ) + // InternalSemver.g:2092:2: iv_ruleALPHA_NUMERIC_CHAR= ruleALPHA_NUMERIC_CHAR EOF + { + if ( state.backtracking==0 ) { + newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARRule()); + } + pushFollow(FOLLOW_1); + iv_ruleALPHA_NUMERIC_CHAR=ruleALPHA_NUMERIC_CHAR(); + + state._fsp--; + if (state.failed) return current; + if ( state.backtracking==0 ) { + current =iv_ruleALPHA_NUMERIC_CHAR.getText(); + } + match(input,EOF,FOLLOW_2); if (state.failed) return current; + + } + + } + + catch (RecognitionException re) { + recover(input,re); + appendSkippedTokens(); + } + finally { + } + return current; + } + // $ANTLR end "entryRuleALPHA_NUMERIC_CHAR" + + + // $ANTLR start "ruleALPHA_NUMERIC_CHAR" + // InternalSemver.g:2098:1: ruleALPHA_NUMERIC_CHAR returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (kw= '-' | this_DIGITS_1= RULE_DIGITS | this_LETTER_2= ruleLETTER ) ; + public final AntlrDatatypeRuleToken ruleALPHA_NUMERIC_CHAR() throws RecognitionException { + AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); + + Token kw=null; + Token this_DIGITS_1=null; + AntlrDatatypeRuleToken this_LETTER_2 = null; + + + + enterRule(); + + try { + // InternalSemver.g:2104:2: ( (kw= '-' | this_DIGITS_1= RULE_DIGITS | this_LETTER_2= ruleLETTER ) ) + // InternalSemver.g:2105:2: (kw= '-' | this_DIGITS_1= RULE_DIGITS | this_LETTER_2= ruleLETTER ) + { + // InternalSemver.g:2105:2: (kw= '-' | this_DIGITS_1= RULE_DIGITS | this_LETTER_2= ruleLETTER ) + int alt41=3; + switch ( input.LA(1) ) { + case 45: + { + alt41=1; + } + break; + case RULE_DIGITS: + { + alt41=2; + } + break; + case RULE_LETTER_V: + case RULE_LETTER_F: + case RULE_LETTER_I: + case RULE_LETTER_L: + case RULE_LETTER_E: + case RULE_LETTER_S: + case RULE_LETTER_M: + case RULE_LETTER_R: + case RULE_LETTER_W: + case RULE_LETTER_O: + case RULE_LETTER_K: + case RULE_LETTER_P: + case RULE_LETTER_A: + case RULE_LETTER_C: + case RULE_LETTER_X: + case RULE_LETTER_OTHER: + { + alt41=3; + } + break; + default: + if (state.backtracking>0) {state.failed=true; return current;} + NoViableAltException nvae = + new NoViableAltException("", 41, 0, input); + + throw nvae; + } + + switch (alt41) { + case 1 : + // InternalSemver.g:2106:3: kw= '-' + { + kw=(Token)match(input,45,FOLLOW_2); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(kw); + newLeafNode(kw, grammarAccess.getALPHA_NUMERIC_CHARAccess().getHyphenMinusKeyword_0()); + + } + + } + break; + case 2 : + // InternalSemver.g:2112:3: this_DIGITS_1= RULE_DIGITS + { + this_DIGITS_1=(Token)match(input,RULE_DIGITS,FOLLOW_2); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_DIGITS_1); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_DIGITS_1, grammarAccess.getALPHA_NUMERIC_CHARAccess().getDIGITSTerminalRuleCall_1()); + + } + + } + break; + case 3 : + // InternalSemver.g:2120:3: this_LETTER_2= ruleLETTER + { + if ( state.backtracking==0 ) { + + newCompositeNode(grammarAccess.getALPHA_NUMERIC_CHARAccess().getLETTERParserRuleCall_2()); + + } + pushFollow(FOLLOW_2); + this_LETTER_2=ruleLETTER(); + + state._fsp--; + if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_2); + + } + if ( state.backtracking==0 ) { + + afterParserOrEnumRuleCall(); + + } + + } + break; + + } + } @@ -5889,11 +6466,11 @@ public final AntlrDatatypeRuleToken ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS() } return current; } - // $ANTLR end "ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS" + // $ANTLR end "ruleALPHA_NUMERIC_CHAR" // $ANTLR start "entryRuleWILDCARD" - // InternalSemver.g:1926:1: entryRuleWILDCARD returns [String current=null] : iv_ruleWILDCARD= ruleWILDCARD EOF ; + // InternalSemver.g:2134:1: entryRuleWILDCARD returns [String current=null] : iv_ruleWILDCARD= ruleWILDCARD EOF ; public final String entryRuleWILDCARD() throws RecognitionException { String current = null; @@ -5901,8 +6478,8 @@ public final String entryRuleWILDCARD() throws RecognitionException { try { - // InternalSemver.g:1926:48: (iv_ruleWILDCARD= ruleWILDCARD EOF ) - // InternalSemver.g:1927:2: iv_ruleWILDCARD= ruleWILDCARD EOF + // InternalSemver.g:2134:48: (iv_ruleWILDCARD= ruleWILDCARD EOF ) + // InternalSemver.g:2135:2: iv_ruleWILDCARD= ruleWILDCARD EOF { if ( state.backtracking==0 ) { newCompositeNode(grammarAccess.getWILDCARDRule()); @@ -5933,7 +6510,7 @@ public final String entryRuleWILDCARD() throws RecognitionException { // $ANTLR start "ruleWILDCARD" - // InternalSemver.g:1933:1: ruleWILDCARD returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_X_0= RULE_LETTER_X | this_ASTERIX_1= RULE_ASTERIX ) ; + // InternalSemver.g:2141:1: ruleWILDCARD returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_X_0= RULE_LETTER_X | this_ASTERIX_1= RULE_ASTERIX ) ; public final AntlrDatatypeRuleToken ruleWILDCARD() throws RecognitionException { AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); @@ -5944,29 +6521,29 @@ public final AntlrDatatypeRuleToken ruleWILDCARD() throws RecognitionException { enterRule(); try { - // InternalSemver.g:1939:2: ( (this_LETTER_X_0= RULE_LETTER_X | this_ASTERIX_1= RULE_ASTERIX ) ) - // InternalSemver.g:1940:2: (this_LETTER_X_0= RULE_LETTER_X | this_ASTERIX_1= RULE_ASTERIX ) + // InternalSemver.g:2147:2: ( (this_LETTER_X_0= RULE_LETTER_X | this_ASTERIX_1= RULE_ASTERIX ) ) + // InternalSemver.g:2148:2: (this_LETTER_X_0= RULE_LETTER_X | this_ASTERIX_1= RULE_ASTERIX ) { - // InternalSemver.g:1940:2: (this_LETTER_X_0= RULE_LETTER_X | this_ASTERIX_1= RULE_ASTERIX ) - int alt40=2; - int LA40_0 = input.LA(1); + // InternalSemver.g:2148:2: (this_LETTER_X_0= RULE_LETTER_X | this_ASTERIX_1= RULE_ASTERIX ) + int alt42=2; + int LA42_0 = input.LA(1); - if ( (LA40_0==RULE_LETTER_X) ) { - alt40=1; + if ( (LA42_0==RULE_LETTER_X) ) { + alt42=1; } - else if ( (LA40_0==RULE_ASTERIX) ) { - alt40=2; + else if ( (LA42_0==RULE_ASTERIX) ) { + alt42=2; } else { if (state.backtracking>0) {state.failed=true; return current;} NoViableAltException nvae = - new NoViableAltException("", 40, 0, input); + new NoViableAltException("", 42, 0, input); throw nvae; } - switch (alt40) { + switch (alt42) { case 1 : - // InternalSemver.g:1941:3: this_LETTER_X_0= RULE_LETTER_X + // InternalSemver.g:2149:3: this_LETTER_X_0= RULE_LETTER_X { this_LETTER_X_0=(Token)match(input,RULE_LETTER_X,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { @@ -5983,7 +6560,7 @@ else if ( (LA40_0==RULE_ASTERIX) ) { } break; case 2 : - // InternalSemver.g:1949:3: this_ASTERIX_1= RULE_ASTERIX + // InternalSemver.g:2157:3: this_ASTERIX_1= RULE_ASTERIX { this_ASTERIX_1=(Token)match(input,RULE_ASTERIX,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { @@ -6024,7 +6601,7 @@ else if ( (LA40_0==RULE_ASTERIX) ) { // $ANTLR start "ruleLETTER" - // InternalSemver.g:1961:1: ruleLETTER returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_V_0= RULE_LETTER_V | this_LETTER_X_1= RULE_LETTER_X | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) ; + // InternalSemver.g:2169:1: ruleLETTER returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_V_0= RULE_LETTER_V | this_LETTER_X_1= RULE_LETTER_X | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) ; public final AntlrDatatypeRuleToken ruleLETTER() throws RecognitionException { AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); @@ -6037,20 +6614,20 @@ public final AntlrDatatypeRuleToken ruleLETTER() throws RecognitionException { enterRule(); try { - // InternalSemver.g:1967:2: ( (this_LETTER_V_0= RULE_LETTER_V | this_LETTER_X_1= RULE_LETTER_X | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) ) - // InternalSemver.g:1968:2: (this_LETTER_V_0= RULE_LETTER_V | this_LETTER_X_1= RULE_LETTER_X | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) + // InternalSemver.g:2175:2: ( (this_LETTER_V_0= RULE_LETTER_V | this_LETTER_X_1= RULE_LETTER_X | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) ) + // InternalSemver.g:2176:2: (this_LETTER_V_0= RULE_LETTER_V | this_LETTER_X_1= RULE_LETTER_X | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) { - // InternalSemver.g:1968:2: (this_LETTER_V_0= RULE_LETTER_V | this_LETTER_X_1= RULE_LETTER_X | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) - int alt41=3; + // InternalSemver.g:2176:2: (this_LETTER_V_0= RULE_LETTER_V | this_LETTER_X_1= RULE_LETTER_X | this_LETTER_NO_VX_2= ruleLETTER_NO_VX ) + int alt43=3; switch ( input.LA(1) ) { case RULE_LETTER_V: { - alt41=1; + alt43=1; } break; case RULE_LETTER_X: { - alt41=2; + alt43=2; } break; case RULE_LETTER_F: @@ -6060,22 +6637,28 @@ public final AntlrDatatypeRuleToken ruleLETTER() throws RecognitionException { case RULE_LETTER_S: case RULE_LETTER_M: case RULE_LETTER_R: + case RULE_LETTER_W: + case RULE_LETTER_O: + case RULE_LETTER_K: + case RULE_LETTER_P: + case RULE_LETTER_A: + case RULE_LETTER_C: case RULE_LETTER_OTHER: { - alt41=3; + alt43=3; } break; default: if (state.backtracking>0) {state.failed=true; return current;} NoViableAltException nvae = - new NoViableAltException("", 41, 0, input); + new NoViableAltException("", 43, 0, input); throw nvae; } - switch (alt41) { + switch (alt43) { case 1 : - // InternalSemver.g:1969:3: this_LETTER_V_0= RULE_LETTER_V + // InternalSemver.g:2177:3: this_LETTER_V_0= RULE_LETTER_V { this_LETTER_V_0=(Token)match(input,RULE_LETTER_V,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { @@ -6092,7 +6675,7 @@ public final AntlrDatatypeRuleToken ruleLETTER() throws RecognitionException { } break; case 2 : - // InternalSemver.g:1977:3: this_LETTER_X_1= RULE_LETTER_X + // InternalSemver.g:2185:3: this_LETTER_X_1= RULE_LETTER_X { this_LETTER_X_1=(Token)match(input,RULE_LETTER_X,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { @@ -6109,7 +6692,7 @@ public final AntlrDatatypeRuleToken ruleLETTER() throws RecognitionException { } break; case 3 : - // InternalSemver.g:1985:3: this_LETTER_NO_VX_2= ruleLETTER_NO_VX + // InternalSemver.g:2193:3: this_LETTER_NO_VX_2= ruleLETTER_NO_VX { if ( state.backtracking==0 ) { @@ -6159,131 +6742,167 @@ public final AntlrDatatypeRuleToken ruleLETTER() throws RecognitionException { // $ANTLR start "ruleLETTER_NO_VX" - // InternalSemver.g:2000:1: ruleLETTER_NO_VX returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_S_0= RULE_LETTER_S | this_LETTER_M_1= RULE_LETTER_M | this_LETTER_R_2= RULE_LETTER_R | this_LETTER_F_3= RULE_LETTER_F | this_LETTER_I_4= RULE_LETTER_I | this_LETTER_L_5= RULE_LETTER_L | this_LETTER_E_6= RULE_LETTER_E | this_LETTER_OTHER_7= RULE_LETTER_OTHER ) ; + // InternalSemver.g:2208:1: ruleLETTER_NO_VX returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_LETTER_A_0= RULE_LETTER_A | this_LETTER_C_1= RULE_LETTER_C | this_LETTER_E_2= RULE_LETTER_E | this_LETTER_F_3= RULE_LETTER_F | this_LETTER_I_4= RULE_LETTER_I | this_LETTER_K_5= RULE_LETTER_K | this_LETTER_L_6= RULE_LETTER_L | this_LETTER_M_7= RULE_LETTER_M | this_LETTER_O_8= RULE_LETTER_O | this_LETTER_P_9= RULE_LETTER_P | this_LETTER_R_10= RULE_LETTER_R | this_LETTER_S_11= RULE_LETTER_S | this_LETTER_W_12= RULE_LETTER_W | this_LETTER_OTHER_13= RULE_LETTER_OTHER ) ; public final AntlrDatatypeRuleToken ruleLETTER_NO_VX() throws RecognitionException { AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken(); - Token this_LETTER_S_0=null; - Token this_LETTER_M_1=null; - Token this_LETTER_R_2=null; + Token this_LETTER_A_0=null; + Token this_LETTER_C_1=null; + Token this_LETTER_E_2=null; Token this_LETTER_F_3=null; Token this_LETTER_I_4=null; - Token this_LETTER_L_5=null; - Token this_LETTER_E_6=null; - Token this_LETTER_OTHER_7=null; + Token this_LETTER_K_5=null; + Token this_LETTER_L_6=null; + Token this_LETTER_M_7=null; + Token this_LETTER_O_8=null; + Token this_LETTER_P_9=null; + Token this_LETTER_R_10=null; + Token this_LETTER_S_11=null; + Token this_LETTER_W_12=null; + Token this_LETTER_OTHER_13=null; enterRule(); try { - // InternalSemver.g:2006:2: ( (this_LETTER_S_0= RULE_LETTER_S | this_LETTER_M_1= RULE_LETTER_M | this_LETTER_R_2= RULE_LETTER_R | this_LETTER_F_3= RULE_LETTER_F | this_LETTER_I_4= RULE_LETTER_I | this_LETTER_L_5= RULE_LETTER_L | this_LETTER_E_6= RULE_LETTER_E | this_LETTER_OTHER_7= RULE_LETTER_OTHER ) ) - // InternalSemver.g:2007:2: (this_LETTER_S_0= RULE_LETTER_S | this_LETTER_M_1= RULE_LETTER_M | this_LETTER_R_2= RULE_LETTER_R | this_LETTER_F_3= RULE_LETTER_F | this_LETTER_I_4= RULE_LETTER_I | this_LETTER_L_5= RULE_LETTER_L | this_LETTER_E_6= RULE_LETTER_E | this_LETTER_OTHER_7= RULE_LETTER_OTHER ) + // InternalSemver.g:2214:2: ( (this_LETTER_A_0= RULE_LETTER_A | this_LETTER_C_1= RULE_LETTER_C | this_LETTER_E_2= RULE_LETTER_E | this_LETTER_F_3= RULE_LETTER_F | this_LETTER_I_4= RULE_LETTER_I | this_LETTER_K_5= RULE_LETTER_K | this_LETTER_L_6= RULE_LETTER_L | this_LETTER_M_7= RULE_LETTER_M | this_LETTER_O_8= RULE_LETTER_O | this_LETTER_P_9= RULE_LETTER_P | this_LETTER_R_10= RULE_LETTER_R | this_LETTER_S_11= RULE_LETTER_S | this_LETTER_W_12= RULE_LETTER_W | this_LETTER_OTHER_13= RULE_LETTER_OTHER ) ) + // InternalSemver.g:2215:2: (this_LETTER_A_0= RULE_LETTER_A | this_LETTER_C_1= RULE_LETTER_C | this_LETTER_E_2= RULE_LETTER_E | this_LETTER_F_3= RULE_LETTER_F | this_LETTER_I_4= RULE_LETTER_I | this_LETTER_K_5= RULE_LETTER_K | this_LETTER_L_6= RULE_LETTER_L | this_LETTER_M_7= RULE_LETTER_M | this_LETTER_O_8= RULE_LETTER_O | this_LETTER_P_9= RULE_LETTER_P | this_LETTER_R_10= RULE_LETTER_R | this_LETTER_S_11= RULE_LETTER_S | this_LETTER_W_12= RULE_LETTER_W | this_LETTER_OTHER_13= RULE_LETTER_OTHER ) { - // InternalSemver.g:2007:2: (this_LETTER_S_0= RULE_LETTER_S | this_LETTER_M_1= RULE_LETTER_M | this_LETTER_R_2= RULE_LETTER_R | this_LETTER_F_3= RULE_LETTER_F | this_LETTER_I_4= RULE_LETTER_I | this_LETTER_L_5= RULE_LETTER_L | this_LETTER_E_6= RULE_LETTER_E | this_LETTER_OTHER_7= RULE_LETTER_OTHER ) - int alt42=8; + // InternalSemver.g:2215:2: (this_LETTER_A_0= RULE_LETTER_A | this_LETTER_C_1= RULE_LETTER_C | this_LETTER_E_2= RULE_LETTER_E | this_LETTER_F_3= RULE_LETTER_F | this_LETTER_I_4= RULE_LETTER_I | this_LETTER_K_5= RULE_LETTER_K | this_LETTER_L_6= RULE_LETTER_L | this_LETTER_M_7= RULE_LETTER_M | this_LETTER_O_8= RULE_LETTER_O | this_LETTER_P_9= RULE_LETTER_P | this_LETTER_R_10= RULE_LETTER_R | this_LETTER_S_11= RULE_LETTER_S | this_LETTER_W_12= RULE_LETTER_W | this_LETTER_OTHER_13= RULE_LETTER_OTHER ) + int alt44=14; switch ( input.LA(1) ) { - case RULE_LETTER_S: + case RULE_LETTER_A: { - alt42=1; + alt44=1; } break; - case RULE_LETTER_M: + case RULE_LETTER_C: { - alt42=2; + alt44=2; } break; - case RULE_LETTER_R: + case RULE_LETTER_E: { - alt42=3; + alt44=3; } break; case RULE_LETTER_F: { - alt42=4; + alt44=4; } break; case RULE_LETTER_I: { - alt42=5; + alt44=5; + } + break; + case RULE_LETTER_K: + { + alt44=6; } break; case RULE_LETTER_L: { - alt42=6; + alt44=7; } break; - case RULE_LETTER_E: + case RULE_LETTER_M: + { + alt44=8; + } + break; + case RULE_LETTER_O: + { + alt44=9; + } + break; + case RULE_LETTER_P: + { + alt44=10; + } + break; + case RULE_LETTER_R: { - alt42=7; + alt44=11; + } + break; + case RULE_LETTER_S: + { + alt44=12; + } + break; + case RULE_LETTER_W: + { + alt44=13; } break; case RULE_LETTER_OTHER: { - alt42=8; + alt44=14; } break; default: if (state.backtracking>0) {state.failed=true; return current;} NoViableAltException nvae = - new NoViableAltException("", 42, 0, input); + new NoViableAltException("", 44, 0, input); throw nvae; } - switch (alt42) { + switch (alt44) { case 1 : - // InternalSemver.g:2008:3: this_LETTER_S_0= RULE_LETTER_S + // InternalSemver.g:2216:3: this_LETTER_A_0= RULE_LETTER_A { - this_LETTER_S_0=(Token)match(input,RULE_LETTER_S,FOLLOW_2); if (state.failed) return current; + this_LETTER_A_0=(Token)match(input,RULE_LETTER_A,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_LETTER_S_0); + current.merge(this_LETTER_A_0); } if ( state.backtracking==0 ) { - newLeafNode(this_LETTER_S_0, grammarAccess.getLETTER_NO_VXAccess().getLETTER_STerminalRuleCall_0()); + newLeafNode(this_LETTER_A_0, grammarAccess.getLETTER_NO_VXAccess().getLETTER_ATerminalRuleCall_0()); } } break; case 2 : - // InternalSemver.g:2016:3: this_LETTER_M_1= RULE_LETTER_M + // InternalSemver.g:2224:3: this_LETTER_C_1= RULE_LETTER_C { - this_LETTER_M_1=(Token)match(input,RULE_LETTER_M,FOLLOW_2); if (state.failed) return current; + this_LETTER_C_1=(Token)match(input,RULE_LETTER_C,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_LETTER_M_1); + current.merge(this_LETTER_C_1); } if ( state.backtracking==0 ) { - newLeafNode(this_LETTER_M_1, grammarAccess.getLETTER_NO_VXAccess().getLETTER_MTerminalRuleCall_1()); + newLeafNode(this_LETTER_C_1, grammarAccess.getLETTER_NO_VXAccess().getLETTER_CTerminalRuleCall_1()); } } break; case 3 : - // InternalSemver.g:2024:3: this_LETTER_R_2= RULE_LETTER_R + // InternalSemver.g:2232:3: this_LETTER_E_2= RULE_LETTER_E { - this_LETTER_R_2=(Token)match(input,RULE_LETTER_R,FOLLOW_2); if (state.failed) return current; + this_LETTER_E_2=(Token)match(input,RULE_LETTER_E,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_LETTER_R_2); + current.merge(this_LETTER_E_2); } if ( state.backtracking==0 ) { - newLeafNode(this_LETTER_R_2, grammarAccess.getLETTER_NO_VXAccess().getLETTER_RTerminalRuleCall_2()); + newLeafNode(this_LETTER_E_2, grammarAccess.getLETTER_NO_VXAccess().getLETTER_ETerminalRuleCall_2()); } } break; case 4 : - // InternalSemver.g:2032:3: this_LETTER_F_3= RULE_LETTER_F + // InternalSemver.g:2240:3: this_LETTER_F_3= RULE_LETTER_F { this_LETTER_F_3=(Token)match(input,RULE_LETTER_F,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { @@ -6300,7 +6919,7 @@ public final AntlrDatatypeRuleToken ruleLETTER_NO_VX() throws RecognitionExcepti } break; case 5 : - // InternalSemver.g:2040:3: this_LETTER_I_4= RULE_LETTER_I + // InternalSemver.g:2248:3: this_LETTER_I_4= RULE_LETTER_I { this_LETTER_I_4=(Token)match(input,RULE_LETTER_I,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { @@ -6317,51 +6936,153 @@ public final AntlrDatatypeRuleToken ruleLETTER_NO_VX() throws RecognitionExcepti } break; case 6 : - // InternalSemver.g:2048:3: this_LETTER_L_5= RULE_LETTER_L + // InternalSemver.g:2256:3: this_LETTER_K_5= RULE_LETTER_K { - this_LETTER_L_5=(Token)match(input,RULE_LETTER_L,FOLLOW_2); if (state.failed) return current; + this_LETTER_K_5=(Token)match(input,RULE_LETTER_K,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_LETTER_L_5); + current.merge(this_LETTER_K_5); } if ( state.backtracking==0 ) { - newLeafNode(this_LETTER_L_5, grammarAccess.getLETTER_NO_VXAccess().getLETTER_LTerminalRuleCall_5()); + newLeafNode(this_LETTER_K_5, grammarAccess.getLETTER_NO_VXAccess().getLETTER_KTerminalRuleCall_5()); } } break; case 7 : - // InternalSemver.g:2056:3: this_LETTER_E_6= RULE_LETTER_E + // InternalSemver.g:2264:3: this_LETTER_L_6= RULE_LETTER_L { - this_LETTER_E_6=(Token)match(input,RULE_LETTER_E,FOLLOW_2); if (state.failed) return current; + this_LETTER_L_6=(Token)match(input,RULE_LETTER_L,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_LETTER_E_6); + current.merge(this_LETTER_L_6); } if ( state.backtracking==0 ) { - newLeafNode(this_LETTER_E_6, grammarAccess.getLETTER_NO_VXAccess().getLETTER_ETerminalRuleCall_6()); + newLeafNode(this_LETTER_L_6, grammarAccess.getLETTER_NO_VXAccess().getLETTER_LTerminalRuleCall_6()); } } break; case 8 : - // InternalSemver.g:2064:3: this_LETTER_OTHER_7= RULE_LETTER_OTHER + // InternalSemver.g:2272:3: this_LETTER_M_7= RULE_LETTER_M + { + this_LETTER_M_7=(Token)match(input,RULE_LETTER_M,FOLLOW_2); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_M_7); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_M_7, grammarAccess.getLETTER_NO_VXAccess().getLETTER_MTerminalRuleCall_7()); + + } + + } + break; + case 9 : + // InternalSemver.g:2280:3: this_LETTER_O_8= RULE_LETTER_O + { + this_LETTER_O_8=(Token)match(input,RULE_LETTER_O,FOLLOW_2); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_O_8); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_O_8, grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTerminalRuleCall_8()); + + } + + } + break; + case 10 : + // InternalSemver.g:2288:3: this_LETTER_P_9= RULE_LETTER_P + { + this_LETTER_P_9=(Token)match(input,RULE_LETTER_P,FOLLOW_2); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_P_9); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_P_9, grammarAccess.getLETTER_NO_VXAccess().getLETTER_PTerminalRuleCall_9()); + + } + + } + break; + case 11 : + // InternalSemver.g:2296:3: this_LETTER_R_10= RULE_LETTER_R + { + this_LETTER_R_10=(Token)match(input,RULE_LETTER_R,FOLLOW_2); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_R_10); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_R_10, grammarAccess.getLETTER_NO_VXAccess().getLETTER_RTerminalRuleCall_10()); + + } + + } + break; + case 12 : + // InternalSemver.g:2304:3: this_LETTER_S_11= RULE_LETTER_S + { + this_LETTER_S_11=(Token)match(input,RULE_LETTER_S,FOLLOW_2); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_S_11); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_S_11, grammarAccess.getLETTER_NO_VXAccess().getLETTER_STerminalRuleCall_11()); + + } + + } + break; + case 13 : + // InternalSemver.g:2312:3: this_LETTER_W_12= RULE_LETTER_W + { + this_LETTER_W_12=(Token)match(input,RULE_LETTER_W,FOLLOW_2); if (state.failed) return current; + if ( state.backtracking==0 ) { + + current.merge(this_LETTER_W_12); + + } + if ( state.backtracking==0 ) { + + newLeafNode(this_LETTER_W_12, grammarAccess.getLETTER_NO_VXAccess().getLETTER_WTerminalRuleCall_12()); + + } + + } + break; + case 14 : + // InternalSemver.g:2320:3: this_LETTER_OTHER_13= RULE_LETTER_OTHER { - this_LETTER_OTHER_7=(Token)match(input,RULE_LETTER_OTHER,FOLLOW_2); if (state.failed) return current; + this_LETTER_OTHER_13=(Token)match(input,RULE_LETTER_OTHER,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { - current.merge(this_LETTER_OTHER_7); + current.merge(this_LETTER_OTHER_13); } if ( state.backtracking==0 ) { - newLeafNode(this_LETTER_OTHER_7, grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTHERTerminalRuleCall_7()); + newLeafNode(this_LETTER_OTHER_13, grammarAccess.getLETTER_NO_VXAccess().getLETTER_OTHERTerminalRuleCall_13()); } @@ -6392,7 +7113,7 @@ public final AntlrDatatypeRuleToken ruleLETTER_NO_VX() throws RecognitionExcepti // $ANTLR start "ruleVersionComparator" - // InternalSemver.g:2075:1: ruleVersionComparator returns [Enumerator current=null] : ( (enumLiteral_0= '=' ) | (enumLiteral_1= '<' ) | (enumLiteral_2= '~' ) | (enumLiteral_3= '^' ) | (enumLiteral_4= '<=' ) | (enumLiteral_5= '>' ) | (enumLiteral_6= '>=' ) ) ; + // InternalSemver.g:2331:1: ruleVersionComparator returns [Enumerator current=null] : ( (enumLiteral_0= '=' ) | (enumLiteral_1= '~' ) | (enumLiteral_2= '^' ) | (enumLiteral_3= '<' ) | (enumLiteral_4= '>' ) | (enumLiteral_5= '<=' ) | (enumLiteral_6= '>=' ) ) ; public final Enumerator ruleVersionComparator() throws RecognitionException { Enumerator current = null; @@ -6408,63 +7129,63 @@ public final Enumerator ruleVersionComparator() throws RecognitionException { enterRule(); try { - // InternalSemver.g:2081:2: ( ( (enumLiteral_0= '=' ) | (enumLiteral_1= '<' ) | (enumLiteral_2= '~' ) | (enumLiteral_3= '^' ) | (enumLiteral_4= '<=' ) | (enumLiteral_5= '>' ) | (enumLiteral_6= '>=' ) ) ) - // InternalSemver.g:2082:2: ( (enumLiteral_0= '=' ) | (enumLiteral_1= '<' ) | (enumLiteral_2= '~' ) | (enumLiteral_3= '^' ) | (enumLiteral_4= '<=' ) | (enumLiteral_5= '>' ) | (enumLiteral_6= '>=' ) ) + // InternalSemver.g:2337:2: ( ( (enumLiteral_0= '=' ) | (enumLiteral_1= '~' ) | (enumLiteral_2= '^' ) | (enumLiteral_3= '<' ) | (enumLiteral_4= '>' ) | (enumLiteral_5= '<=' ) | (enumLiteral_6= '>=' ) ) ) + // InternalSemver.g:2338:2: ( (enumLiteral_0= '=' ) | (enumLiteral_1= '~' ) | (enumLiteral_2= '^' ) | (enumLiteral_3= '<' ) | (enumLiteral_4= '>' ) | (enumLiteral_5= '<=' ) | (enumLiteral_6= '>=' ) ) { - // InternalSemver.g:2082:2: ( (enumLiteral_0= '=' ) | (enumLiteral_1= '<' ) | (enumLiteral_2= '~' ) | (enumLiteral_3= '^' ) | (enumLiteral_4= '<=' ) | (enumLiteral_5= '>' ) | (enumLiteral_6= '>=' ) ) - int alt43=7; + // InternalSemver.g:2338:2: ( (enumLiteral_0= '=' ) | (enumLiteral_1= '~' ) | (enumLiteral_2= '^' ) | (enumLiteral_3= '<' ) | (enumLiteral_4= '>' ) | (enumLiteral_5= '<=' ) | (enumLiteral_6= '>=' ) ) + int alt45=7; switch ( input.LA(1) ) { - case 44: + case 50: { - alt43=1; + alt45=1; } break; - case 45: + case 51: { - alt43=2; + alt45=2; } break; - case 46: + case 52: { - alt43=3; + alt45=3; } break; - case 47: + case 53: { - alt43=4; + alt45=4; } break; - case 48: + case 54: { - alt43=5; + alt45=5; } break; - case 49: + case 55: { - alt43=6; + alt45=6; } break; - case 50: + case 56: { - alt43=7; + alt45=7; } break; default: if (state.backtracking>0) {state.failed=true; return current;} NoViableAltException nvae = - new NoViableAltException("", 43, 0, input); + new NoViableAltException("", 45, 0, input); throw nvae; } - switch (alt43) { + switch (alt45) { case 1 : - // InternalSemver.g:2083:3: (enumLiteral_0= '=' ) + // InternalSemver.g:2339:3: (enumLiteral_0= '=' ) { - // InternalSemver.g:2083:3: (enumLiteral_0= '=' ) - // InternalSemver.g:2084:4: enumLiteral_0= '=' + // InternalSemver.g:2339:3: (enumLiteral_0= '=' ) + // InternalSemver.g:2340:4: enumLiteral_0= '=' { - enumLiteral_0=(Token)match(input,44,FOLLOW_2); if (state.failed) return current; + enumLiteral_0=(Token)match(input,50,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { current = grammarAccess.getVersionComparatorAccess().getEqualsEnumLiteralDeclaration_0().getEnumLiteral().getInstance(); @@ -6478,16 +7199,16 @@ public final Enumerator ruleVersionComparator() throws RecognitionException { } break; case 2 : - // InternalSemver.g:2091:3: (enumLiteral_1= '<' ) + // InternalSemver.g:2347:3: (enumLiteral_1= '~' ) { - // InternalSemver.g:2091:3: (enumLiteral_1= '<' ) - // InternalSemver.g:2092:4: enumLiteral_1= '<' + // InternalSemver.g:2347:3: (enumLiteral_1= '~' ) + // InternalSemver.g:2348:4: enumLiteral_1= '~' { - enumLiteral_1=(Token)match(input,45,FOLLOW_2); if (state.failed) return current; + enumLiteral_1=(Token)match(input,51,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { - current = grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_1().getEnumLiteral().getInstance(); - newLeafNode(enumLiteral_1, grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_1()); + current = grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_1().getEnumLiteral().getInstance(); + newLeafNode(enumLiteral_1, grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_1()); } @@ -6497,16 +7218,16 @@ public final Enumerator ruleVersionComparator() throws RecognitionException { } break; case 3 : - // InternalSemver.g:2099:3: (enumLiteral_2= '~' ) + // InternalSemver.g:2355:3: (enumLiteral_2= '^' ) { - // InternalSemver.g:2099:3: (enumLiteral_2= '~' ) - // InternalSemver.g:2100:4: enumLiteral_2= '~' + // InternalSemver.g:2355:3: (enumLiteral_2= '^' ) + // InternalSemver.g:2356:4: enumLiteral_2= '^' { - enumLiteral_2=(Token)match(input,46,FOLLOW_2); if (state.failed) return current; + enumLiteral_2=(Token)match(input,52,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { - current = grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_2().getEnumLiteral().getInstance(); - newLeafNode(enumLiteral_2, grammarAccess.getVersionComparatorAccess().getTildeEnumLiteralDeclaration_2()); + current = grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_2().getEnumLiteral().getInstance(); + newLeafNode(enumLiteral_2, grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_2()); } @@ -6516,16 +7237,16 @@ public final Enumerator ruleVersionComparator() throws RecognitionException { } break; case 4 : - // InternalSemver.g:2107:3: (enumLiteral_3= '^' ) + // InternalSemver.g:2363:3: (enumLiteral_3= '<' ) { - // InternalSemver.g:2107:3: (enumLiteral_3= '^' ) - // InternalSemver.g:2108:4: enumLiteral_3= '^' + // InternalSemver.g:2363:3: (enumLiteral_3= '<' ) + // InternalSemver.g:2364:4: enumLiteral_3= '<' { - enumLiteral_3=(Token)match(input,47,FOLLOW_2); if (state.failed) return current; + enumLiteral_3=(Token)match(input,53,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { - current = grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_3().getEnumLiteral().getInstance(); - newLeafNode(enumLiteral_3, grammarAccess.getVersionComparatorAccess().getCaretEnumLiteralDeclaration_3()); + current = grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_3().getEnumLiteral().getInstance(); + newLeafNode(enumLiteral_3, grammarAccess.getVersionComparatorAccess().getSmallerEnumLiteralDeclaration_3()); } @@ -6535,16 +7256,16 @@ public final Enumerator ruleVersionComparator() throws RecognitionException { } break; case 5 : - // InternalSemver.g:2115:3: (enumLiteral_4= '<=' ) + // InternalSemver.g:2371:3: (enumLiteral_4= '>' ) { - // InternalSemver.g:2115:3: (enumLiteral_4= '<=' ) - // InternalSemver.g:2116:4: enumLiteral_4= '<=' + // InternalSemver.g:2371:3: (enumLiteral_4= '>' ) + // InternalSemver.g:2372:4: enumLiteral_4= '>' { - enumLiteral_4=(Token)match(input,48,FOLLOW_2); if (state.failed) return current; + enumLiteral_4=(Token)match(input,54,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { - current = grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_4().getEnumLiteral().getInstance(); - newLeafNode(enumLiteral_4, grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_4()); + current = grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_4().getEnumLiteral().getInstance(); + newLeafNode(enumLiteral_4, grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_4()); } @@ -6554,16 +7275,16 @@ public final Enumerator ruleVersionComparator() throws RecognitionException { } break; case 6 : - // InternalSemver.g:2123:3: (enumLiteral_5= '>' ) + // InternalSemver.g:2379:3: (enumLiteral_5= '<=' ) { - // InternalSemver.g:2123:3: (enumLiteral_5= '>' ) - // InternalSemver.g:2124:4: enumLiteral_5= '>' + // InternalSemver.g:2379:3: (enumLiteral_5= '<=' ) + // InternalSemver.g:2380:4: enumLiteral_5= '<=' { - enumLiteral_5=(Token)match(input,49,FOLLOW_2); if (state.failed) return current; + enumLiteral_5=(Token)match(input,55,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { - current = grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_5().getEnumLiteral().getInstance(); - newLeafNode(enumLiteral_5, grammarAccess.getVersionComparatorAccess().getGreaterEnumLiteralDeclaration_5()); + current = grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_5().getEnumLiteral().getInstance(); + newLeafNode(enumLiteral_5, grammarAccess.getVersionComparatorAccess().getSmallerEqualsEnumLiteralDeclaration_5()); } @@ -6573,12 +7294,12 @@ public final Enumerator ruleVersionComparator() throws RecognitionException { } break; case 7 : - // InternalSemver.g:2131:3: (enumLiteral_6= '>=' ) + // InternalSemver.g:2387:3: (enumLiteral_6= '>=' ) { - // InternalSemver.g:2131:3: (enumLiteral_6= '>=' ) - // InternalSemver.g:2132:4: enumLiteral_6= '>=' + // InternalSemver.g:2387:3: (enumLiteral_6= '>=' ) + // InternalSemver.g:2388:4: enumLiteral_6= '>=' { - enumLiteral_6=(Token)match(input,50,FOLLOW_2); if (state.failed) return current; + enumLiteral_6=(Token)match(input,56,FOLLOW_2); if (state.failed) return current; if ( state.backtracking==0 ) { current = grammarAccess.getVersionComparatorAccess().getGreaterEqualsEnumLiteralDeclaration_6().getEnumLiteral().getInstance(); @@ -6646,11 +7367,11 @@ public final void synpred2_InternalSemver_fragment() throws RecognitionException // $ANTLR start synpred3_InternalSemver public final void synpred3_InternalSemver_fragment() throws RecognitionException { - // InternalSemver.g:318:4: ( ruleURLSemver ) - // InternalSemver.g:318:5: ruleURLSemver + // InternalSemver.g:133:8: ( ruleWorkspaceVersionRequirement ) + // InternalSemver.g:133:9: ruleWorkspaceVersionRequirement { pushFollow(FOLLOW_2); - ruleURLSemver(); + ruleWorkspaceVersionRequirement(); state._fsp--; if (state.failed) return ; @@ -6659,6 +7380,42 @@ public final void synpred3_InternalSemver_fragment() throws RecognitionException } // $ANTLR end synpred3_InternalSemver + // $ANTLR start synpred4_InternalSemver + public final void synpred4_InternalSemver_fragment() throws RecognitionException { + // InternalSemver.g:332:4: ( ruleURLSemver ) + // InternalSemver.g:332:5: ruleURLSemver + { + pushFollow(FOLLOW_2); + ruleURLSemver(); + + state._fsp--; + if (state.failed) return ; + + } + } + // $ANTLR end synpred4_InternalSemver + + // $ANTLR start synpred5_InternalSemver + public final void synpred5_InternalSemver_fragment() throws RecognitionException { + // InternalSemver.g:493:5: ( ( ruleSimpleVersion ) ) + // InternalSemver.g:493:6: ( ruleSimpleVersion ) + { + // InternalSemver.g:493:6: ( ruleSimpleVersion ) + // InternalSemver.g:494:6: ruleSimpleVersion + { + pushFollow(FOLLOW_2); + ruleSimpleVersion(); + + state._fsp--; + if (state.failed) return ; + + } + + + } + } + // $ANTLR end synpred5_InternalSemver + // Delegated rules public final boolean synpred1_InternalSemver() { @@ -6703,26 +7460,62 @@ public final boolean synpred3_InternalSemver() { state.failed=false; return success; } + public final boolean synpred4_InternalSemver() { + state.backtracking++; + int start = input.mark(); + try { + synpred4_InternalSemver_fragment(); // can never throw exception + } catch (RecognitionException re) { + System.err.println("impossible: "+re); + } + boolean success = !state.failed; + input.rewind(start); + state.backtracking--; + state.failed=false; + return success; + } + public final boolean synpred5_InternalSemver() { + state.backtracking++; + int start = input.mark(); + try { + synpred5_InternalSemver_fragment(); // can never throw exception + } catch (RecognitionException re) { + System.err.println("impossible: "+re); + } + boolean success = !state.failed; + input.rewind(start); + state.backtracking--; + state.failed=false; + return success; + } + protected DFA4 dfa4 = new DFA4(this); protected DFA3 dfa3 = new DFA3(this); protected DFA2 dfa2 = new DFA2(this); - protected DFA7 dfa7 = new DFA7(this); - protected DFA15 dfa15 = new DFA15(this); - static final String dfa_1s = "\30\uffff"; - static final String dfa_2s = "\3\uffff\4\2\21\uffff"; - static final String dfa_3s = "\1\7\1\5\1\uffff\4\4\20\0\1\uffff"; - static final String dfa_4s = "\2\53\1\uffff\4\53\20\0\1\uffff"; - static final String dfa_5s = "\2\uffff\1\2\24\uffff\1\1"; - static final String dfa_6s = "\7\uffff\1\16\1\7\1\1\1\12\1\2\1\14\1\3\1\5\1\13\1\15\1\17\1\0\1\4\1\6\1\10\1\11\1\uffff}>"; + protected DFA8 dfa8 = new DFA8(this); + protected DFA10 dfa10 = new DFA10(this); + protected DFA17 dfa17 = new DFA17(this); + static final String dfa_1s = "\36\uffff"; + static final String dfa_2s = "\3\uffff\4\2\27\uffff"; + static final String dfa_3s = "\1\7\1\5\1\uffff\4\4\26\0\1\uffff"; + static final String dfa_4s = "\2\61\1\uffff\4\61\26\0\1\uffff"; + static final String dfa_5s = "\2\uffff\1\2\32\uffff\1\1"; + static final String dfa_6s = "\7\uffff\1\2\1\22\1\4\1\13\1\10\1\24\1\17\1\5\1\7\1\23\1\12\1\0\1\15\1\3\1\20\1\6\1\21\1\11\1\25\1\14\1\1\1\16\1\uffff}>"; static final String[] dfa_7s = { - "\1\1\6\2\2\uffff\1\2\26\uffff\1\2\3\uffff\1\2", - "\3\2\1\3\6\2\1\uffff\1\2\22\uffff\2\2\2\uffff\5\2", + "\1\1\14\2\2\uffff\1\2\26\uffff\1\2\3\uffff\1\2", + "\3\2\1\3\13\2\1\uffff\2\2\22\uffff\2\2\2\uffff\5\2", "", - "\5\2\1\4\5\2\1\uffff\1\2\22\uffff\2\2\2\uffff\5\2", - "\6\2\1\5\4\2\1\uffff\1\2\22\uffff\2\2\2\uffff\5\2", - "\13\2\1\uffff\1\2\22\uffff\1\6\1\2\2\uffff\5\2", - "\1\2\1\15\1\14\1\22\1\23\1\24\1\25\1\17\1\20\1\21\1\16\1\uffff\1\26\22\uffff\1\2\1\7\1\2\1\uffff\1\12\1\10\1\uffff\1\11\1\13", + "\5\2\1\4\12\2\1\uffff\2\2\22\uffff\2\2\2\uffff\5\2", + "\6\2\1\5\11\2\1\uffff\2\2\22\uffff\2\2\2\uffff\5\2", + "\20\2\1\uffff\2\2\22\uffff\1\6\1\2\2\uffff\5\2", + "\1\2\1\15\1\14\1\22\1\23\1\25\1\21\1\32\1\26\1\31\1\33\1\27\1\24\1\30\1\17\1\20\1\uffff\1\16\1\34\22\uffff\1\2\1\7\1\2\1\uffff\1\13\1\10\1\uffff\1\11\1\12", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", "\1\uffff", "\1\uffff", "\1\uffff", @@ -6750,11 +7543,11 @@ public final boolean synpred3_InternalSemver() { static final short[] dfa_6 = DFA.unpackEncodedString(dfa_6s); static final short[][] dfa_7 = unpackEncodedStringArray(dfa_7s); - class DFA3 extends DFA { + class DFA4 extends DFA { - public DFA3(BaseRecognizer recognizer) { + public DFA4(BaseRecognizer recognizer) { this.recognizer = recognizer; - this.decisionNumber = 3; + this.decisionNumber = 4; this.eot = dfa_1; this.eof = dfa_2; this.min = dfa_3; @@ -6764,1170 +7557,3188 @@ public DFA3(BaseRecognizer recognizer) { this.transition = dfa_7; } public String getDescription() { - return "105:4: ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | this_GitHubVersionRequirement_4= ruleGitHubVersionRequirement | this_TagVersionRequirement_5= ruleTagVersionRequirement ) )"; + return "105:4: ( ( ( ruleLocalPathVersionRequirement )=>this_LocalPathVersionRequirement_2= ruleLocalPathVersionRequirement ) | ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) ) )"; } public int specialStateTransition(int s, IntStream _input) throws NoViableAltException { TokenStream input = (TokenStream)_input; int _s = s; switch ( s ) { case 0 : - int LA3_18 = input.LA(1); + int LA4_18 = input.LA(1); - int index3_18 = input.index(); + int index4_18 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_18); + input.seek(index4_18); if ( s>=0 ) return s; break; case 1 : - int LA3_9 = input.LA(1); + int LA4_27 = input.LA(1); - int index3_9 = input.index(); + int index4_27 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_9); + input.seek(index4_27); if ( s>=0 ) return s; break; case 2 : - int LA3_11 = input.LA(1); + int LA4_7 = input.LA(1); - int index3_11 = input.index(); + int index4_7 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_11); + input.seek(index4_7); if ( s>=0 ) return s; break; case 3 : - int LA3_13 = input.LA(1); + int LA4_20 = input.LA(1); - int index3_13 = input.index(); + int index4_20 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_13); + input.seek(index4_20); if ( s>=0 ) return s; break; case 4 : - int LA3_19 = input.LA(1); + int LA4_9 = input.LA(1); - int index3_19 = input.index(); + int index4_9 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_19); + input.seek(index4_9); if ( s>=0 ) return s; break; case 5 : - int LA3_14 = input.LA(1); + int LA4_14 = input.LA(1); - int index3_14 = input.index(); + int index4_14 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_14); + input.seek(index4_14); if ( s>=0 ) return s; break; case 6 : - int LA3_20 = input.LA(1); + int LA4_22 = input.LA(1); - int index3_20 = input.index(); + int index4_22 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_20); + input.seek(index4_22); if ( s>=0 ) return s; break; case 7 : - int LA3_8 = input.LA(1); + int LA4_15 = input.LA(1); - int index3_8 = input.index(); + int index4_15 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_8); + input.seek(index4_15); if ( s>=0 ) return s; break; case 8 : - int LA3_21 = input.LA(1); + int LA4_11 = input.LA(1); - int index3_21 = input.index(); + int index4_11 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_21); + input.seek(index4_11); if ( s>=0 ) return s; break; case 9 : - int LA3_22 = input.LA(1); + int LA4_24 = input.LA(1); - int index3_22 = input.index(); + int index4_24 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_22); + input.seek(index4_24); if ( s>=0 ) return s; break; case 10 : - int LA3_10 = input.LA(1); + int LA4_17 = input.LA(1); - int index3_10 = input.index(); + int index4_17 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_10); + input.seek(index4_17); if ( s>=0 ) return s; break; case 11 : - int LA3_15 = input.LA(1); + int LA4_10 = input.LA(1); - int index3_15 = input.index(); + int index4_10 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_15); + input.seek(index4_10); if ( s>=0 ) return s; break; case 12 : - int LA3_12 = input.LA(1); + int LA4_26 = input.LA(1); - int index3_12 = input.index(); + int index4_26 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_12); + input.seek(index4_26); if ( s>=0 ) return s; break; case 13 : - int LA3_16 = input.LA(1); + int LA4_19 = input.LA(1); - int index3_16 = input.index(); + int index4_19 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_16); + input.seek(index4_19); if ( s>=0 ) return s; break; case 14 : - int LA3_7 = input.LA(1); + int LA4_28 = input.LA(1); - int index3_7 = input.index(); + int index4_28 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_7); + input.seek(index4_28); if ( s>=0 ) return s; break; case 15 : - int LA3_17 = input.LA(1); + int LA4_13 = input.LA(1); - int index3_17 = input.index(); + int index4_13 = input.index(); input.rewind(); s = -1; - if ( (synpred1_InternalSemver()) ) {s = 23;} + if ( (synpred1_InternalSemver()) ) {s = 29;} else if ( (true) ) {s = 2;} - input.seek(index3_17); + input.seek(index4_13); if ( s>=0 ) return s; break; - } - if (state.backtracking>0) {state.failed=true; return -1;} - NoViableAltException nvae = - new NoViableAltException(getDescription(), 3, _s, input); - error(nvae); - throw nvae; - } - } - static final String dfa_8s = "\66\uffff"; - static final String dfa_9s = "\12\uffff\12\30\1\uffff\2\30\1\11\1\uffff\12\30\2\11\4\uffff\15\11"; - static final String dfa_10s = "\1\7\10\5\1\uffff\12\4\1\uffff\3\4\1\uffff\14\4\4\0\15\4"; - static final String dfa_11s = "\11\53\1\uffff\12\53\1\uffff\3\53\1\uffff\14\53\4\0\15\53"; - static final String dfa_12s = "\11\uffff\1\2\12\uffff\1\1\3\uffff\1\3\35\uffff"; - static final String dfa_13s = "\1\uffff\1\12\1\20\1\4\1\15\1\1\1\13\1\24\1\7\1\uffff\1\22\1\10\1\21\1\5\1\16\1\2\1\14\1\25\1\11\1\17\21\uffff\1\23\1\0\1\3\1\6\15\uffff}>"; - static final String[] dfa_14s = { - "\1\4\1\5\1\6\1\7\1\1\1\2\1\3\2\uffff\1\10\26\uffff\1\11\3\uffff\1\11", - "\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\2\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\2\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\2\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\2\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\2\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\2\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\2\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\2\11\2\uffff\1\25\1\11\1\24\2\11", - "", - "\1\30\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\1\27\1\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\30\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\1\27\1\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\30\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\1\27\1\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\30\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\1\27\1\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\30\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\1\27\1\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\30\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\1\27\1\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\30\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\1\27\1\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\30\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\1\27\1\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\30\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\1\27\1\11\2\uffff\1\25\1\11\1\24\2\11", - "\1\30\1\12\1\26\1\17\1\20\1\21\1\22\1\14\1\15\1\16\1\13\1\uffff\1\23\22\uffff\1\27\1\11\2\uffff\1\25\1\11\1\24\2\11", - "", - "\1\30\1\31\1\26\1\36\1\37\1\40\1\41\1\33\1\34\1\35\1\32\1\uffff\1\42\22\uffff\2\11\2\uffff\1\25\1\11\1\uffff\2\11", - "\1\30\1\31\1\26\1\36\1\37\1\40\1\41\1\33\1\34\1\35\1\32\1\uffff\1\42\22\uffff\2\11\2\uffff\1\25\1\11\1\uffff\2\11", - "\13\11\1\uffff\1\11\22\uffff\1\11\1\43\1\11\1\uffff\2\11\1\uffff\2\11", - "", - "\1\30\1\31\1\26\1\36\1\37\1\40\1\41\1\33\1\34\1\35\1\32\1\uffff\1\42\22\uffff\2\11\2\uffff\1\25\1\11\1\uffff\2\11", - "\1\30\1\31\1\26\1\36\1\37\1\40\1\41\1\33\1\34\1\35\1\32\1\uffff\1\42\22\uffff\2\11\2\uffff\1\25\1\11\1\uffff\2\11", - "\1\30\1\31\1\26\1\36\1\37\1\40\1\41\1\33\1\34\1\35\1\32\1\uffff\1\42\22\uffff\2\11\2\uffff\1\25\1\11\1\uffff\2\11", - "\1\30\1\31\1\26\1\36\1\37\1\40\1\41\1\33\1\34\1\35\1\32\1\uffff\1\42\22\uffff\2\11\2\uffff\1\25\1\11\1\uffff\2\11", - "\1\30\1\31\1\26\1\36\1\37\1\40\1\41\1\33\1\34\1\35\1\32\1\uffff\1\42\22\uffff\2\11\2\uffff\1\25\1\11\1\uffff\2\11", - "\1\30\1\31\1\26\1\36\1\37\1\40\1\41\1\33\1\34\1\35\1\32\1\uffff\1\42\22\uffff\2\11\2\uffff\1\25\1\11\1\uffff\2\11", - "\1\30\1\31\1\26\1\36\1\37\1\40\1\41\1\33\1\34\1\35\1\32\1\uffff\1\42\22\uffff\2\11\2\uffff\1\25\1\11\1\uffff\2\11", - "\1\30\1\31\1\26\1\36\1\37\1\40\1\41\1\33\1\34\1\35\1\32\1\uffff\1\42\22\uffff\2\11\2\uffff\1\25\1\11\1\uffff\2\11", - "\1\30\1\31\1\26\1\36\1\37\1\40\1\41\1\33\1\34\1\35\1\32\1\uffff\1\42\22\uffff\2\11\2\uffff\1\25\1\11\1\uffff\2\11", - "\1\30\1\31\1\26\1\36\1\37\1\40\1\41\1\33\1\34\1\35\1\32\1\uffff\1\42\22\uffff\2\11\2\uffff\1\25\1\11\1\uffff\2\11", - "\13\11\1\uffff\1\11\22\uffff\1\11\1\44\1\11\1\uffff\2\11\1\uffff\2\11", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52", - "\1\uffff", - "\1\uffff", - "\1\uffff", - "\1\uffff", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52", - "\1\11\1\54\1\53\1\61\1\62\1\63\1\64\1\56\1\57\1\60\1\55\1\uffff\1\65\22\uffff\1\47\1\45\1\11\1\uffff\1\51\1\46\1\uffff\1\50\1\52" - }; + case 16 : + int LA4_21 = input.LA(1); - static final short[] dfa_8 = DFA.unpackEncodedString(dfa_8s); - static final short[] dfa_9 = DFA.unpackEncodedString(dfa_9s); - static final char[] dfa_10 = DFA.unpackEncodedStringToUnsignedChars(dfa_10s); - static final char[] dfa_11 = DFA.unpackEncodedStringToUnsignedChars(dfa_11s); - static final short[] dfa_12 = DFA.unpackEncodedString(dfa_12s); - static final short[] dfa_13 = DFA.unpackEncodedString(dfa_13s); - static final short[][] dfa_14 = unpackEncodedStringArray(dfa_14s); + + int index4_21 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1_InternalSemver()) ) {s = 29;} - class DFA2 extends DFA { + else if ( (true) ) {s = 2;} - public DFA2(BaseRecognizer recognizer) { - this.recognizer = recognizer; - this.decisionNumber = 2; - this.eot = dfa_8; - this.eof = dfa_9; - this.min = dfa_10; - this.max = dfa_11; - this.accept = dfa_12; - this.special = dfa_13; - this.transition = dfa_14; - } - public String getDescription() { - return "118:5: ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | this_GitHubVersionRequirement_4= ruleGitHubVersionRequirement | this_TagVersionRequirement_5= ruleTagVersionRequirement )"; - } - public int specialStateTransition(int s, IntStream _input) throws NoViableAltException { - TokenStream input = (TokenStream)_input; - int _s = s; + + input.seek(index4_21); + if ( s>=0 ) return s; + break; + case 17 : + int LA4_23 = input.LA(1); + + + int index4_23 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index4_23); + if ( s>=0 ) return s; + break; + case 18 : + int LA4_8 = input.LA(1); + + + int index4_8 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index4_8); + if ( s>=0 ) return s; + break; + case 19 : + int LA4_16 = input.LA(1); + + + int index4_16 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index4_16); + if ( s>=0 ) return s; + break; + case 20 : + int LA4_12 = input.LA(1); + + + int index4_12 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index4_12); + if ( s>=0 ) return s; + break; + case 21 : + int LA4_25 = input.LA(1); + + + int index4_25 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1_InternalSemver()) ) {s = 29;} + + else if ( (true) ) {s = 2;} + + + input.seek(index4_25); + if ( s>=0 ) return s; + break; + } + if (state.backtracking>0) {state.failed=true; return -1;} + NoViableAltException nvae = + new NoViableAltException(getDescription(), 4, _s, input); + error(nvae); + throw nvae; + } + } + static final String dfa_8s = "\135\uffff"; + static final String dfa_9s = "\20\uffff\20\17\1\uffff\7\17\4\uffff\32\17\4\uffff\23\17"; + static final String dfa_10s = "\1\7\16\5\1\uffff\20\4\1\uffff\7\4\4\0\32\4\4\0\23\4"; + static final String dfa_11s = "\17\61\1\uffff\20\61\1\uffff\7\61\4\0\27\61\3\70\4\0\23\70"; + static final String dfa_12s = "\17\uffff\1\2\20\uffff\1\1\74\uffff"; + static final String dfa_13s = "\1\uffff\1\50\1\12\1\45\1\6\1\26\1\54\1\22\1\51\1\10\1\34\1\4\1\31\1\42\1\15\1\uffff\1\7\1\27\1\17\1\46\1\11\1\37\1\0\1\23\1\53\1\20\1\44\1\5\1\33\1\1\1\21\1\47\1\uffff\1\35\1\uffff\1\40\1\uffff\1\36\1\uffff\1\16\1\14\1\24\1\32\1\43\23\uffff\1\41\1\55\1\30\1\2\3\uffff\1\52\1\3\1\13\1\25\23\uffff}>"; + static final String[] dfa_14s = { + "\1\4\1\5\1\7\1\3\1\14\1\10\1\13\1\15\1\11\1\6\1\12\1\1\1\2\2\uffff\1\16\26\uffff\1\17\3\uffff\1\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\41\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\2\17\2\uffff\2\17\1\40\2\17", + "", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\43\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\20\17\1\uffff\2\17\22\uffff\1\17\1\44\1\17\1\uffff\2\17\1\uffff\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\45\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\20\17\1\uffff\2\17\22\uffff\1\17\1\46\1\17\1\uffff\2\17\1\uffff\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\47\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\77\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\57\1\56\1\64\1\65\1\67\1\63\1\74\1\70\1\73\1\75\1\71\1\66\1\72\1\61\1\62\1\uffff\1\60\1\76\22\uffff\1\52\1\50\1\17\1\uffff\1\55\1\51\1\uffff\1\53\1\54", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\100\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\101\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\102\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\42\1\17\2\uffff\2\17\1\40\2\17", + "\1\17\1\20\1\17\1\25\1\26\1\30\1\24\1\35\1\31\1\34\1\36\1\32\1\27\1\33\1\22\1\23\1\uffff\1\21\1\37\22\uffff\1\103\1\17\2\uffff\2\17\1\40\2\17", + "\23\17\22\uffff\1\17\1\104\1\17\1\uffff\2\17\1\uffff\11\17", + "\23\17\22\uffff\1\17\1\105\1\17\1\uffff\2\17\1\uffff\11\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17", + "\1\17\1\115\1\114\1\122\1\123\1\125\1\121\1\132\1\126\1\131\1\133\1\127\1\124\1\130\1\117\1\120\1\17\1\116\1\134\22\uffff\1\110\1\106\1\17\1\uffff\1\113\1\107\1\uffff\1\111\1\112\7\17" + }; + + static final short[] dfa_8 = DFA.unpackEncodedString(dfa_8s); + static final short[] dfa_9 = DFA.unpackEncodedString(dfa_9s); + static final char[] dfa_10 = DFA.unpackEncodedStringToUnsignedChars(dfa_10s); + static final char[] dfa_11 = DFA.unpackEncodedStringToUnsignedChars(dfa_11s); + static final short[] dfa_12 = DFA.unpackEncodedString(dfa_12s); + static final short[] dfa_13 = DFA.unpackEncodedString(dfa_13s); + static final short[][] dfa_14 = unpackEncodedStringArray(dfa_14s); + + class DFA3 extends DFA { + + public DFA3(BaseRecognizer recognizer) { + this.recognizer = recognizer; + this.decisionNumber = 3; + this.eot = dfa_8; + this.eof = dfa_9; + this.min = dfa_10; + this.max = dfa_11; + this.accept = dfa_12; + this.special = dfa_13; + this.transition = dfa_14; + } + public String getDescription() { + return "118:5: ( ( ( ruleURLVersionRequirement )=>this_URLVersionRequirement_3= ruleURLVersionRequirement ) | ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement ) )"; + } + public int specialStateTransition(int s, IntStream _input) throws NoViableAltException { + TokenStream input = (TokenStream)_input; + int _s = s; switch ( s ) { case 0 : - int LA2_38 = input.LA(1); + int LA3_22 = input.LA(1); + + + int index3_22 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_22==EOF||LA3_22==RULE_WS||LA3_22==RULE_DIGITS||LA3_22==42||(LA3_22>=45 && LA3_22<=46)||(LA3_22>=48 && LA3_22<=49)) ) {s = 15;} + + else if ( (LA3_22==41) ) {s = 34;} + + else if ( (LA3_22==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_22==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_22==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_22==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_22==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_22==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_22==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_22==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_22==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_22==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_22==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_22==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_22==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_22==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_22==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_22==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_22==47) && (synpred2_InternalSemver())) {s = 32;} - int index2_38 = input.index(); + input.seek(index3_22); + if ( s>=0 ) return s; + break; + case 1 : + int LA3_29 = input.LA(1); + + + int index3_29 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_29==EOF||LA3_29==RULE_WS||LA3_29==RULE_DIGITS||LA3_29==42||(LA3_29>=45 && LA3_29<=46)||(LA3_29>=48 && LA3_29<=49)) ) {s = 15;} + + else if ( (LA3_29==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_29==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_29==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_29==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_29==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_29==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_29==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_29==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_29==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_29==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_29==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_29==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_29==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_29==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_29==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_29==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_29==41) ) {s = 34;} + + else if ( (LA3_29==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_29); + if ( s>=0 ) return s; + break; + case 2 : + int LA3_66 = input.LA(1); + + + int index3_66 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_66==41) ) {s = 67;} + + else if ( (LA3_66==EOF||LA3_66==RULE_WS||LA3_66==RULE_DIGITS||LA3_66==42||(LA3_66>=45 && LA3_66<=46)||(LA3_66>=48 && LA3_66<=49)) ) {s = 15;} + + else if ( (LA3_66==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_66==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_66==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_66==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_66==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_66==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_66==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_66==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_66==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_66==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_66==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_66==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_66==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_66==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_66==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_66==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_66==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_66); + if ( s>=0 ) return s; + break; + case 3 : + int LA3_71 = input.LA(1); + + + int index3_71 = input.index(); + input.rewind(); + s = -1; + if ( (synpred2_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index3_71); + if ( s>=0 ) return s; + break; + case 4 : + int LA3_11 = input.LA(1); + + + int index3_11 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_11==RULE_DIGITS||(LA3_11>=41 && LA3_11<=42)||(LA3_11>=45 && LA3_11<=46)||(LA3_11>=48 && LA3_11<=49)) ) {s = 15;} + + else if ( (LA3_11==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_11==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_11==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_11==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_11==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_11==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_11==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_11==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_11==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_11==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_11==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_11==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_11==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_11==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_11==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_11==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_11==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_11); + if ( s>=0 ) return s; + break; + case 5 : + int LA3_27 = input.LA(1); + + + int index3_27 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_27==EOF||LA3_27==RULE_WS||LA3_27==RULE_DIGITS||LA3_27==42||(LA3_27>=45 && LA3_27<=46)||(LA3_27>=48 && LA3_27<=49)) ) {s = 15;} + + else if ( (LA3_27==41) ) {s = 34;} + + else if ( (LA3_27==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_27==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_27==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_27==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_27==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_27==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_27==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_27==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_27==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_27==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_27==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_27==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_27==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_27==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_27==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_27==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_27==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_27); + if ( s>=0 ) return s; + break; + case 6 : + int LA3_4 = input.LA(1); + + + int index3_4 = input.index(); input.rewind(); s = -1; - if ( (synpred2_InternalSemver()) ) {s = 20;} + if ( (LA3_4==RULE_DIGITS||(LA3_4>=41 && LA3_4<=42)||(LA3_4>=45 && LA3_4<=46)||(LA3_4>=48 && LA3_4<=49)) ) {s = 15;} + + else if ( (LA3_4==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_4==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_4==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_4==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_4==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_4==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_4==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_4==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_4==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_4==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_4==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_4==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_4==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_4==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_4==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_4==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_4==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_4); + if ( s>=0 ) return s; + break; + case 7 : + int LA3_16 = input.LA(1); + + + int index3_16 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_16==EOF||LA3_16==RULE_WS||LA3_16==RULE_DIGITS||LA3_16==42||(LA3_16>=45 && LA3_16<=46)||(LA3_16>=48 && LA3_16<=49)) ) {s = 15;} + + else if ( (LA3_16==41) ) {s = 34;} + + else if ( (LA3_16==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_16==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_16==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_16==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_16==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_16==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_16==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_16==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_16==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_16==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_16==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_16==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_16==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_16==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_16==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_16==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_16==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_16); + if ( s>=0 ) return s; + break; + case 8 : + int LA3_9 = input.LA(1); + + + int index3_9 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_9==RULE_DIGITS||(LA3_9>=41 && LA3_9<=42)||(LA3_9>=45 && LA3_9<=46)||(LA3_9>=48 && LA3_9<=49)) ) {s = 15;} + + else if ( (LA3_9==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_9==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_9==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_9==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_9==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_9==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_9==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_9==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_9==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_9==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_9==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_9==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_9==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_9==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_9==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_9==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_9==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_9); + if ( s>=0 ) return s; + break; + case 9 : + int LA3_20 = input.LA(1); + + + int index3_20 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_20==EOF||LA3_20==RULE_WS||LA3_20==RULE_DIGITS||LA3_20==42||(LA3_20>=45 && LA3_20<=46)||(LA3_20>=48 && LA3_20<=49)) ) {s = 15;} + + else if ( (LA3_20==41) ) {s = 34;} + + else if ( (LA3_20==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_20==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_20==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_20==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_20==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_20==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_20==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_20==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_20==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_20==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_20==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_20==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_20==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_20==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_20==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_20==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_20==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_20); + if ( s>=0 ) return s; + break; + case 10 : + int LA3_2 = input.LA(1); + + + int index3_2 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_2==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_2==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_2==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_2==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_2==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_2==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_2==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_2==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_2==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_2==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_2==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_2==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_2==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_2==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_2==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_2==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_2==47) && (synpred2_InternalSemver())) {s = 32;} + + else if ( (LA3_2==RULE_DIGITS||(LA3_2>=41 && LA3_2<=42)||(LA3_2>=45 && LA3_2<=46)||(LA3_2>=48 && LA3_2<=49)) ) {s = 15;} + + + input.seek(index3_2); + if ( s>=0 ) return s; + break; + case 11 : + int LA3_72 = input.LA(1); + + + int index3_72 = input.index(); + input.rewind(); + s = -1; + if ( (synpred2_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index3_72); + if ( s>=0 ) return s; + break; + case 12 : + int LA3_40 = input.LA(1); + + + int index3_40 = input.index(); + input.rewind(); + s = -1; + if ( (synpred2_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index3_40); + if ( s>=0 ) return s; + break; + case 13 : + int LA3_14 = input.LA(1); + + + int index3_14 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_14==RULE_DIGITS||(LA3_14>=41 && LA3_14<=42)||(LA3_14>=45 && LA3_14<=46)||(LA3_14>=48 && LA3_14<=49)) ) {s = 15;} + + else if ( (LA3_14==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_14==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_14==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_14==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_14==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_14==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_14==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_14==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_14==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_14==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_14==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_14==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_14==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_14==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_14==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_14==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_14==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_14); + if ( s>=0 ) return s; + break; + case 14 : + int LA3_39 = input.LA(1); + + + int index3_39 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_39==EOF||LA3_39==RULE_WS||LA3_39==RULE_DIGITS||LA3_39==42||(LA3_39>=45 && LA3_39<=46)||(LA3_39>=48 && LA3_39<=49)) ) {s = 15;} + + else if ( (LA3_39==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_39==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_39==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_39==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_39==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_39==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_39==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_39==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_39==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_39==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_39==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_39==RULE_LETTER_P) ) {s = 63;} + + else if ( (LA3_39==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_39==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_39==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_39==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_39==41) ) {s = 34;} + + else if ( (LA3_39==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_39); + if ( s>=0 ) return s; + break; + case 15 : + int LA3_18 = input.LA(1); + + + int index3_18 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_18==41) ) {s = 34;} + + else if ( (LA3_18==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_18==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_18==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_18==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_18==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_18==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_18==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_18==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_18==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_18==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_18==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_18==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_18==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_18==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_18==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_18==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_18==47) && (synpred2_InternalSemver())) {s = 32;} + + else if ( (LA3_18==EOF||LA3_18==RULE_WS||LA3_18==RULE_DIGITS||LA3_18==42||(LA3_18>=45 && LA3_18<=46)||(LA3_18>=48 && LA3_18<=49)) ) {s = 15;} + + + input.seek(index3_18); + if ( s>=0 ) return s; + break; + case 16 : + int LA3_25 = input.LA(1); + + + int index3_25 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_25==EOF||LA3_25==RULE_WS||LA3_25==RULE_DIGITS||LA3_25==42||(LA3_25>=45 && LA3_25<=46)||(LA3_25>=48 && LA3_25<=49)) ) {s = 15;} + + else if ( (LA3_25==41) ) {s = 34;} + + else if ( (LA3_25==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_25==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_25==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_25==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_25==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_25==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_25==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_25==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_25==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_25==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_25==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_25==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_25==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_25==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_25==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_25==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_25==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_25); + if ( s>=0 ) return s; + break; + case 17 : + int LA3_30 = input.LA(1); + + + int index3_30 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_30==EOF||LA3_30==RULE_WS||LA3_30==RULE_DIGITS||LA3_30==42||(LA3_30>=45 && LA3_30<=46)||(LA3_30>=48 && LA3_30<=49)) ) {s = 15;} + + else if ( (LA3_30==41) ) {s = 34;} + + else if ( (LA3_30==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_30==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_30==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_30==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_30==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_30==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_30==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_30==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_30==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_30==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_30==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_30==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_30==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_30==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_30==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_30==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_30==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_30); + if ( s>=0 ) return s; + break; + case 18 : + int LA3_7 = input.LA(1); + + + int index3_7 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_7==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_7==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_7==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_7==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_7==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_7==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_7==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_7==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_7==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_7==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_7==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_7==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_7==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_7==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_7==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_7==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_7==47) && (synpred2_InternalSemver())) {s = 32;} + + else if ( (LA3_7==RULE_DIGITS||(LA3_7>=41 && LA3_7<=42)||(LA3_7>=45 && LA3_7<=46)||(LA3_7>=48 && LA3_7<=49)) ) {s = 15;} + + + input.seek(index3_7); + if ( s>=0 ) return s; + break; + case 19 : + int LA3_23 = input.LA(1); + + + int index3_23 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_23==EOF||LA3_23==RULE_WS||LA3_23==RULE_DIGITS||LA3_23==42||(LA3_23>=45 && LA3_23<=46)||(LA3_23>=48 && LA3_23<=49)) ) {s = 15;} + + else if ( (LA3_23==41) ) {s = 34;} + + else if ( (LA3_23==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_23==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_23==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_23==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_23==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_23==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_23==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_23==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_23==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_23==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_23==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_23==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_23==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_23==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_23==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_23==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_23==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_23); + if ( s>=0 ) return s; + break; + case 20 : + int LA3_41 = input.LA(1); + + + int index3_41 = input.index(); + input.rewind(); + s = -1; + if ( (synpred2_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index3_41); + if ( s>=0 ) return s; + break; + case 21 : + int LA3_73 = input.LA(1); + + + int index3_73 = input.index(); + input.rewind(); + s = -1; + if ( (synpred2_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index3_73); + if ( s>=0 ) return s; + break; + case 22 : + int LA3_5 = input.LA(1); + + + int index3_5 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_5==RULE_DIGITS||(LA3_5>=41 && LA3_5<=42)||(LA3_5>=45 && LA3_5<=46)||(LA3_5>=48 && LA3_5<=49)) ) {s = 15;} + + else if ( (LA3_5==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_5==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_5==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_5==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_5==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_5==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_5==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_5==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_5==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_5==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_5==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_5==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_5==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_5==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_5==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_5==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_5==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_5); + if ( s>=0 ) return s; + break; + case 23 : + int LA3_17 = input.LA(1); + + + int index3_17 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_17==41) ) {s = 34;} + + else if ( (LA3_17==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_17==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_17==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_17==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_17==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_17==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_17==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_17==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_17==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_17==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_17==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_17==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_17==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_17==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_17==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_17==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_17==47) && (synpred2_InternalSemver())) {s = 32;} + + else if ( (LA3_17==EOF||LA3_17==RULE_WS||LA3_17==RULE_DIGITS||LA3_17==42||(LA3_17>=45 && LA3_17<=46)||(LA3_17>=48 && LA3_17<=49)) ) {s = 15;} + + + input.seek(index3_17); + if ( s>=0 ) return s; + break; + case 24 : + int LA3_65 = input.LA(1); + + + int index3_65 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_65==EOF||LA3_65==RULE_WS||LA3_65==RULE_DIGITS||LA3_65==42||(LA3_65>=45 && LA3_65<=46)||(LA3_65>=48 && LA3_65<=49)) ) {s = 15;} + + else if ( (LA3_65==41) ) {s = 34;} + + else if ( (LA3_65==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_65==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_65==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_65==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_65==RULE_LETTER_E) ) {s = 66;} + + else if ( (LA3_65==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_65==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_65==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_65==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_65==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_65==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_65==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_65==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_65==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_65==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_65==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_65==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_65); + if ( s>=0 ) return s; + break; + case 25 : + int LA3_12 = input.LA(1); + + + int index3_12 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_12==RULE_DIGITS||(LA3_12>=41 && LA3_12<=42)||(LA3_12>=45 && LA3_12<=46)||(LA3_12>=48 && LA3_12<=49)) ) {s = 15;} + + else if ( (LA3_12==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_12==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_12==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_12==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_12==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_12==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_12==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_12==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_12==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_12==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_12==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_12==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_12==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_12==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_12==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_12==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_12==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_12); + if ( s>=0 ) return s; + break; + case 26 : + int LA3_42 = input.LA(1); + + + int index3_42 = input.index(); + input.rewind(); + s = -1; + if ( (synpred2_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index3_42); + if ( s>=0 ) return s; + break; + case 27 : + int LA3_28 = input.LA(1); + + + int index3_28 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_28==EOF||LA3_28==RULE_WS||LA3_28==RULE_DIGITS||LA3_28==42||(LA3_28>=45 && LA3_28<=46)||(LA3_28>=48 && LA3_28<=49)) ) {s = 15;} + + else if ( (LA3_28==41) ) {s = 34;} + + else if ( (LA3_28==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_28==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_28==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_28==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_28==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_28==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_28==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_28==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_28==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_28==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_28==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_28==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_28==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_28==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_28==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_28==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_28==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_28); + if ( s>=0 ) return s; + break; + case 28 : + int LA3_10 = input.LA(1); + + + int index3_10 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_10==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_10==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_10==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_10==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_10==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_10==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_10==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_10==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_10==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_10==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_10==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_10==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_10==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_10==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_10==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_10==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_10==47) && (synpred2_InternalSemver())) {s = 32;} + + else if ( (LA3_10==RULE_DIGITS||(LA3_10>=41 && LA3_10<=42)||(LA3_10>=45 && LA3_10<=46)||(LA3_10>=48 && LA3_10<=49)) ) {s = 15;} + + + input.seek(index3_10); + if ( s>=0 ) return s; + break; + case 29 : + int LA3_33 = input.LA(1); + + + int index3_33 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_33==41) ) {s = 34;} + + else if ( (LA3_33==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_33==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_33==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_33==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_33==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_33==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_33==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_33==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_33==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_33==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_33==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_33==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_33==RULE_LETTER_R) ) {s = 35;} + + else if ( (LA3_33==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_33==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_33==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_33==47) && (synpred2_InternalSemver())) {s = 32;} + + else if ( (LA3_33==EOF||LA3_33==RULE_WS||LA3_33==RULE_DIGITS||LA3_33==42||(LA3_33>=45 && LA3_33<=46)||(LA3_33>=48 && LA3_33<=49)) ) {s = 15;} + + + input.seek(index3_33); + if ( s>=0 ) return s; + break; + case 30 : + int LA3_37 = input.LA(1); + + + int index3_37 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_37==RULE_LETTER_S) ) {s = 39;} + + else if ( (LA3_37==EOF||LA3_37==RULE_WS||LA3_37==RULE_DIGITS||LA3_37==42||(LA3_37>=45 && LA3_37<=46)||(LA3_37>=48 && LA3_37<=49)) ) {s = 15;} + + else if ( (LA3_37==41) ) {s = 34;} + + else if ( (LA3_37==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_37==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_37==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_37==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_37==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_37==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_37==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_37==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_37==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_37==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_37==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_37==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_37==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_37==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_37==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_37==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_37); + if ( s>=0 ) return s; + break; + case 31 : + int LA3_21 = input.LA(1); + + + int index3_21 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_21==EOF||LA3_21==RULE_WS||LA3_21==RULE_DIGITS||LA3_21==42||(LA3_21>=45 && LA3_21<=46)||(LA3_21>=48 && LA3_21<=49)) ) {s = 15;} + + else if ( (LA3_21==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_21==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_21==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_21==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_21==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_21==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_21==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_21==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_21==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_21==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_21==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_21==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_21==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_21==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_21==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_21==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_21==41) ) {s = 34;} + + else if ( (LA3_21==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_21); + if ( s>=0 ) return s; + break; + case 32 : + int LA3_35 = input.LA(1); + + + int index3_35 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_35==EOF||LA3_35==RULE_WS||LA3_35==RULE_DIGITS||LA3_35==42||(LA3_35>=45 && LA3_35<=46)||(LA3_35>=48 && LA3_35<=49)) ) {s = 15;} + + else if ( (LA3_35==41) ) {s = 34;} + + else if ( (LA3_35==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_35==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_35==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_35==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_35==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_35==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_35==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_35==RULE_LETTER_K) ) {s = 37;} + + else if ( (LA3_35==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_35==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_35==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_35==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_35==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_35==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_35==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_35==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_35==47) && (synpred2_InternalSemver())) {s = 32;} + + + input.seek(index3_35); + if ( s>=0 ) return s; + break; + case 33 : + int LA3_63 = input.LA(1); + + + int index3_63 = input.index(); + input.rewind(); + s = -1; + if ( (LA3_63==RULE_LETTER_A) ) {s = 64;} + + else if ( (LA3_63==EOF||LA3_63==RULE_WS||LA3_63==RULE_DIGITS||LA3_63==42||(LA3_63>=45 && LA3_63<=46)||(LA3_63>=48 && LA3_63<=49)) ) {s = 15;} + + else if ( (LA3_63==41) ) {s = 34;} + + else if ( (LA3_63==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_63==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_63==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_63==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_63==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_63==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_63==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_63==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_63==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_63==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_63==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_63==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_63==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_63==RULE_LETTER_W) ) {s = 30;} - else if ( (true) ) {s = 9;} + else if ( (LA3_63==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_63==47) && (synpred2_InternalSemver())) {s = 32;} - input.seek(index2_38); + input.seek(index3_63); if ( s>=0 ) return s; break; - case 1 : - int LA2_5 = input.LA(1); + case 34 : + int LA3_13 = input.LA(1); - int index2_5 = input.index(); + int index3_13 = input.index(); input.rewind(); s = -1; - if ( (LA2_5==39) ) {s = 21;} + if ( (LA3_13==RULE_DIGITS||(LA3_13>=41 && LA3_13<=42)||(LA3_13>=45 && LA3_13<=46)||(LA3_13>=48 && LA3_13<=49)) ) {s = 15;} + + else if ( (LA3_13==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_13==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_13==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_13==RULE_LETTER_C) ) {s = 19;} - else if ( ((LA2_5>=35 && LA2_5<=36)||LA2_5==40||(LA2_5>=42 && LA2_5<=43)) ) {s = 9;} + else if ( (LA3_13==RULE_LETTER_E) ) {s = 20;} - else if ( (LA2_5==RULE_DIGITS) ) {s = 22;} + else if ( (LA3_13==RULE_LETTER_F) ) {s = 21;} - else if ( (LA2_5==RULE_LETTER_V) ) {s = 10;} + else if ( (LA3_13==RULE_LETTER_I) ) {s = 22;} - else if ( (LA2_5==RULE_LETTER_X) ) {s = 11;} + else if ( (LA3_13==RULE_LETTER_K) ) {s = 23;} - else if ( (LA2_5==RULE_LETTER_S) ) {s = 12;} + else if ( (LA3_13==RULE_LETTER_L) ) {s = 24;} - else if ( (LA2_5==RULE_LETTER_M) ) {s = 13;} + else if ( (LA3_13==RULE_LETTER_M) ) {s = 25;} - else if ( (LA2_5==RULE_LETTER_R) ) {s = 14;} + else if ( (LA3_13==RULE_LETTER_O) ) {s = 33;} - else if ( (LA2_5==RULE_LETTER_F) ) {s = 15;} + else if ( (LA3_13==RULE_LETTER_P) ) {s = 27;} - else if ( (LA2_5==RULE_LETTER_I) ) {s = 16;} + else if ( (LA3_13==RULE_LETTER_R) ) {s = 28;} - else if ( (LA2_5==RULE_LETTER_L) ) {s = 17;} + else if ( (LA3_13==RULE_LETTER_S) ) {s = 29;} - else if ( (LA2_5==RULE_LETTER_E) ) {s = 18;} + else if ( (LA3_13==RULE_LETTER_W) ) {s = 30;} - else if ( (LA2_5==RULE_LETTER_OTHER) ) {s = 19;} + else if ( (LA3_13==RULE_LETTER_OTHER) ) {s = 31;} - else if ( (LA2_5==41) && (synpred2_InternalSemver())) {s = 20;} + else if ( (LA3_13==47) && (synpred2_InternalSemver())) {s = 32;} - input.seek(index2_5); + input.seek(index3_13); if ( s>=0 ) return s; break; - case 2 : - int LA2_15 = input.LA(1); + case 35 : + int LA3_43 = input.LA(1); + + + int index3_43 = input.index(); + input.rewind(); + s = -1; + if ( (synpred2_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index3_43); + if ( s>=0 ) return s; + break; + case 36 : + int LA3_26 = input.LA(1); - int index2_15 = input.index(); + int index3_26 = input.index(); input.rewind(); s = -1; - if ( (LA2_15==36||LA2_15==40||(LA2_15>=42 && LA2_15<=43)) ) {s = 9;} + if ( (LA3_26==41) ) {s = 34;} + + else if ( (LA3_26==RULE_LETTER_V) ) {s = 16;} - else if ( (LA2_15==35) ) {s = 23;} + else if ( (LA3_26==RULE_LETTER_X) ) {s = 17;} - else if ( (LA2_15==39) ) {s = 21;} + else if ( (LA3_26==RULE_LETTER_A) ) {s = 18;} - else if ( (LA2_15==RULE_DIGITS) ) {s = 22;} + else if ( (LA3_26==RULE_LETTER_C) ) {s = 19;} - else if ( (LA2_15==RULE_LETTER_V) ) {s = 10;} + else if ( (LA3_26==RULE_LETTER_E) ) {s = 20;} - else if ( (LA2_15==RULE_LETTER_X) ) {s = 11;} + else if ( (LA3_26==RULE_LETTER_F) ) {s = 21;} - else if ( (LA2_15==RULE_LETTER_S) ) {s = 12;} + else if ( (LA3_26==RULE_LETTER_I) ) {s = 22;} - else if ( (LA2_15==RULE_LETTER_M) ) {s = 13;} + else if ( (LA3_26==RULE_LETTER_K) ) {s = 23;} - else if ( (LA2_15==RULE_LETTER_R) ) {s = 14;} + else if ( (LA3_26==RULE_LETTER_L) ) {s = 24;} - else if ( (LA2_15==RULE_LETTER_F) ) {s = 15;} + else if ( (LA3_26==RULE_LETTER_M) ) {s = 25;} - else if ( (LA2_15==RULE_LETTER_I) ) {s = 16;} + else if ( (LA3_26==RULE_LETTER_O) ) {s = 26;} - else if ( (LA2_15==RULE_LETTER_L) ) {s = 17;} + else if ( (LA3_26==RULE_LETTER_P) ) {s = 27;} - else if ( (LA2_15==RULE_LETTER_E) ) {s = 18;} + else if ( (LA3_26==RULE_LETTER_R) ) {s = 28;} - else if ( (LA2_15==RULE_LETTER_OTHER) ) {s = 19;} + else if ( (LA3_26==RULE_LETTER_S) ) {s = 29;} - else if ( (LA2_15==41) && (synpred2_InternalSemver())) {s = 20;} + else if ( (LA3_26==RULE_LETTER_W) ) {s = 30;} - else if ( (LA2_15==EOF||LA2_15==RULE_WS) ) {s = 24;} + else if ( (LA3_26==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_26==47) && (synpred2_InternalSemver())) {s = 32;} + + else if ( (LA3_26==EOF||LA3_26==RULE_WS||LA3_26==RULE_DIGITS||LA3_26==42||(LA3_26>=45 && LA3_26<=46)||(LA3_26>=48 && LA3_26<=49)) ) {s = 15;} - input.seek(index2_15); + input.seek(index3_26); if ( s>=0 ) return s; break; - case 3 : - int LA2_39 = input.LA(1); + case 37 : + int LA3_3 = input.LA(1); - int index2_39 = input.index(); + int index3_3 = input.index(); input.rewind(); s = -1; - if ( (synpred2_InternalSemver()) ) {s = 20;} + if ( (LA3_3==RULE_DIGITS||(LA3_3>=41 && LA3_3<=42)||(LA3_3>=45 && LA3_3<=46)||(LA3_3>=48 && LA3_3<=49)) ) {s = 15;} + + else if ( (LA3_3==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_3==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_3==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_3==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_3==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_3==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_3==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_3==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_3==RULE_LETTER_L) ) {s = 24;} - else if ( (true) ) {s = 9;} + else if ( (LA3_3==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_3==RULE_LETTER_O) ) {s = 26;} + + else if ( (LA3_3==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_3==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_3==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_3==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_3==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_3==47) && (synpred2_InternalSemver())) {s = 32;} - input.seek(index2_39); + input.seek(index3_3); if ( s>=0 ) return s; break; - case 4 : - int LA2_3 = input.LA(1); + case 38 : + int LA3_19 = input.LA(1); - int index2_3 = input.index(); + int index3_19 = input.index(); input.rewind(); s = -1; - if ( (LA2_3==RULE_LETTER_V) ) {s = 10;} + if ( (LA3_19==EOF||LA3_19==RULE_WS||LA3_19==RULE_DIGITS||LA3_19==42||(LA3_19>=45 && LA3_19<=46)||(LA3_19>=48 && LA3_19<=49)) ) {s = 15;} + + else if ( (LA3_19==41) ) {s = 34;} + + else if ( (LA3_19==RULE_LETTER_V) ) {s = 16;} - else if ( (LA2_3==RULE_LETTER_X) ) {s = 11;} + else if ( (LA3_19==RULE_LETTER_X) ) {s = 17;} - else if ( (LA2_3==RULE_LETTER_S) ) {s = 12;} + else if ( (LA3_19==RULE_LETTER_A) ) {s = 18;} - else if ( (LA2_3==RULE_LETTER_M) ) {s = 13;} + else if ( (LA3_19==RULE_LETTER_C) ) {s = 19;} - else if ( (LA2_3==RULE_LETTER_R) ) {s = 14;} + else if ( (LA3_19==RULE_LETTER_E) ) {s = 20;} - else if ( (LA2_3==RULE_LETTER_F) ) {s = 15;} + else if ( (LA3_19==RULE_LETTER_F) ) {s = 21;} - else if ( (LA2_3==RULE_LETTER_I) ) {s = 16;} + else if ( (LA3_19==RULE_LETTER_I) ) {s = 22;} - else if ( (LA2_3==RULE_LETTER_L) ) {s = 17;} + else if ( (LA3_19==RULE_LETTER_K) ) {s = 23;} - else if ( (LA2_3==RULE_LETTER_E) ) {s = 18;} + else if ( (LA3_19==RULE_LETTER_L) ) {s = 24;} - else if ( (LA2_3==RULE_LETTER_OTHER) ) {s = 19;} + else if ( (LA3_19==RULE_LETTER_M) ) {s = 25;} - else if ( (LA2_3==41) && (synpred2_InternalSemver())) {s = 20;} + else if ( (LA3_19==RULE_LETTER_O) ) {s = 26;} - else if ( (LA2_3==39) ) {s = 21;} + else if ( (LA3_19==RULE_LETTER_P) ) {s = 27;} - else if ( ((LA2_3>=35 && LA2_3<=36)||LA2_3==40||(LA2_3>=42 && LA2_3<=43)) ) {s = 9;} + else if ( (LA3_19==RULE_LETTER_R) ) {s = 28;} - else if ( (LA2_3==RULE_DIGITS) ) {s = 22;} + else if ( (LA3_19==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_19==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_19==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_19==47) && (synpred2_InternalSemver())) {s = 32;} - input.seek(index2_3); + input.seek(index3_19); if ( s>=0 ) return s; break; - case 5 : - int LA2_13 = input.LA(1); + case 39 : + int LA3_31 = input.LA(1); - int index2_13 = input.index(); + int index3_31 = input.index(); input.rewind(); s = -1; - if ( (LA2_13==EOF||LA2_13==RULE_WS) ) {s = 24;} + if ( (LA3_31==EOF||LA3_31==RULE_WS||LA3_31==RULE_DIGITS||LA3_31==42||(LA3_31>=45 && LA3_31<=46)||(LA3_31>=48 && LA3_31<=49)) ) {s = 15;} + + else if ( (LA3_31==41) ) {s = 34;} + + else if ( (LA3_31==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_31==RULE_LETTER_X) ) {s = 17;} - else if ( (LA2_13==39) ) {s = 21;} + else if ( (LA3_31==RULE_LETTER_A) ) {s = 18;} - else if ( (LA2_13==RULE_DIGITS) ) {s = 22;} + else if ( (LA3_31==RULE_LETTER_C) ) {s = 19;} - else if ( (LA2_13==RULE_LETTER_V) ) {s = 10;} + else if ( (LA3_31==RULE_LETTER_E) ) {s = 20;} - else if ( (LA2_13==RULE_LETTER_X) ) {s = 11;} + else if ( (LA3_31==RULE_LETTER_F) ) {s = 21;} - else if ( (LA2_13==RULE_LETTER_S) ) {s = 12;} + else if ( (LA3_31==RULE_LETTER_I) ) {s = 22;} - else if ( (LA2_13==RULE_LETTER_M) ) {s = 13;} + else if ( (LA3_31==RULE_LETTER_K) ) {s = 23;} - else if ( (LA2_13==RULE_LETTER_R) ) {s = 14;} + else if ( (LA3_31==RULE_LETTER_L) ) {s = 24;} - else if ( (LA2_13==RULE_LETTER_F) ) {s = 15;} + else if ( (LA3_31==RULE_LETTER_M) ) {s = 25;} - else if ( (LA2_13==RULE_LETTER_I) ) {s = 16;} + else if ( (LA3_31==RULE_LETTER_O) ) {s = 26;} - else if ( (LA2_13==RULE_LETTER_L) ) {s = 17;} + else if ( (LA3_31==RULE_LETTER_P) ) {s = 27;} - else if ( (LA2_13==RULE_LETTER_E) ) {s = 18;} + else if ( (LA3_31==RULE_LETTER_R) ) {s = 28;} - else if ( (LA2_13==RULE_LETTER_OTHER) ) {s = 19;} + else if ( (LA3_31==RULE_LETTER_S) ) {s = 29;} - else if ( (LA2_13==36||LA2_13==40||(LA2_13>=42 && LA2_13<=43)) ) {s = 9;} + else if ( (LA3_31==RULE_LETTER_W) ) {s = 30;} - else if ( (LA2_13==35) ) {s = 23;} + else if ( (LA3_31==RULE_LETTER_OTHER) ) {s = 31;} - else if ( (LA2_13==41) && (synpred2_InternalSemver())) {s = 20;} + else if ( (LA3_31==47) && (synpred2_InternalSemver())) {s = 32;} - input.seek(index2_13); + input.seek(index3_31); if ( s>=0 ) return s; break; - case 6 : - int LA2_40 = input.LA(1); + case 40 : + int LA3_1 = input.LA(1); - int index2_40 = input.index(); + int index3_1 = input.index(); input.rewind(); s = -1; - if ( (synpred2_InternalSemver()) ) {s = 20;} + if ( (LA3_1==RULE_DIGITS||(LA3_1>=41 && LA3_1<=42)||(LA3_1>=45 && LA3_1<=46)||(LA3_1>=48 && LA3_1<=49)) ) {s = 15;} + + else if ( (LA3_1==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_1==RULE_LETTER_X) ) {s = 17;} + + else if ( (LA3_1==RULE_LETTER_A) ) {s = 18;} + + else if ( (LA3_1==RULE_LETTER_C) ) {s = 19;} + + else if ( (LA3_1==RULE_LETTER_E) ) {s = 20;} + + else if ( (LA3_1==RULE_LETTER_F) ) {s = 21;} + + else if ( (LA3_1==RULE_LETTER_I) ) {s = 22;} + + else if ( (LA3_1==RULE_LETTER_K) ) {s = 23;} + + else if ( (LA3_1==RULE_LETTER_L) ) {s = 24;} + + else if ( (LA3_1==RULE_LETTER_M) ) {s = 25;} + + else if ( (LA3_1==RULE_LETTER_O) ) {s = 26;} - else if ( (true) ) {s = 9;} + else if ( (LA3_1==RULE_LETTER_P) ) {s = 27;} + + else if ( (LA3_1==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_1==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_1==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_1==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_1==47) && (synpred2_InternalSemver())) {s = 32;} - input.seek(index2_40); + input.seek(index3_1); if ( s>=0 ) return s; break; - case 7 : - int LA2_8 = input.LA(1); + case 41 : + int LA3_8 = input.LA(1); - int index2_8 = input.index(); + int index3_8 = input.index(); input.rewind(); s = -1; - if ( (LA2_8==39) ) {s = 21;} + if ( (LA3_8==RULE_DIGITS||(LA3_8>=41 && LA3_8<=42)||(LA3_8>=45 && LA3_8<=46)||(LA3_8>=48 && LA3_8<=49)) ) {s = 15;} - else if ( ((LA2_8>=35 && LA2_8<=36)||LA2_8==40||(LA2_8>=42 && LA2_8<=43)) ) {s = 9;} + else if ( (LA3_8==RULE_LETTER_V) ) {s = 16;} - else if ( (LA2_8==RULE_DIGITS) ) {s = 22;} + else if ( (LA3_8==RULE_LETTER_X) ) {s = 17;} - else if ( (LA2_8==RULE_LETTER_V) ) {s = 10;} + else if ( (LA3_8==RULE_LETTER_A) ) {s = 18;} - else if ( (LA2_8==RULE_LETTER_X) ) {s = 11;} + else if ( (LA3_8==RULE_LETTER_C) ) {s = 19;} - else if ( (LA2_8==RULE_LETTER_S) ) {s = 12;} + else if ( (LA3_8==RULE_LETTER_E) ) {s = 20;} - else if ( (LA2_8==RULE_LETTER_M) ) {s = 13;} + else if ( (LA3_8==RULE_LETTER_F) ) {s = 21;} - else if ( (LA2_8==RULE_LETTER_R) ) {s = 14;} + else if ( (LA3_8==RULE_LETTER_I) ) {s = 22;} - else if ( (LA2_8==RULE_LETTER_F) ) {s = 15;} + else if ( (LA3_8==RULE_LETTER_K) ) {s = 23;} - else if ( (LA2_8==RULE_LETTER_I) ) {s = 16;} + else if ( (LA3_8==RULE_LETTER_L) ) {s = 24;} - else if ( (LA2_8==RULE_LETTER_L) ) {s = 17;} + else if ( (LA3_8==RULE_LETTER_M) ) {s = 25;} - else if ( (LA2_8==RULE_LETTER_E) ) {s = 18;} + else if ( (LA3_8==RULE_LETTER_O) ) {s = 26;} - else if ( (LA2_8==RULE_LETTER_OTHER) ) {s = 19;} + else if ( (LA3_8==RULE_LETTER_P) ) {s = 27;} - else if ( (LA2_8==41) && (synpred2_InternalSemver())) {s = 20;} + else if ( (LA3_8==RULE_LETTER_R) ) {s = 28;} + + else if ( (LA3_8==RULE_LETTER_S) ) {s = 29;} + + else if ( (LA3_8==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_8==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_8==47) && (synpred2_InternalSemver())) {s = 32;} - input.seek(index2_8); + input.seek(index3_8); if ( s>=0 ) return s; break; - case 8 : - int LA2_11 = input.LA(1); + case 42 : + int LA3_70 = input.LA(1); + + + int index3_70 = input.index(); + input.rewind(); + s = -1; + if ( (synpred2_InternalSemver()) ) {s = 32;} + + else if ( (true) ) {s = 15;} + + + input.seek(index3_70); + if ( s>=0 ) return s; + break; + case 43 : + int LA3_24 = input.LA(1); - int index2_11 = input.index(); + int index3_24 = input.index(); input.rewind(); s = -1; - if ( (LA2_11==36||LA2_11==40||(LA2_11>=42 && LA2_11<=43)) ) {s = 9;} + if ( (LA3_24==EOF||LA3_24==RULE_WS||LA3_24==RULE_DIGITS||LA3_24==42||(LA3_24>=45 && LA3_24<=46)||(LA3_24>=48 && LA3_24<=49)) ) {s = 15;} + + else if ( (LA3_24==41) ) {s = 34;} - else if ( (LA2_11==35) ) {s = 23;} + else if ( (LA3_24==RULE_LETTER_V) ) {s = 16;} - else if ( (LA2_11==39) ) {s = 21;} + else if ( (LA3_24==RULE_LETTER_X) ) {s = 17;} - else if ( (LA2_11==RULE_DIGITS) ) {s = 22;} + else if ( (LA3_24==RULE_LETTER_A) ) {s = 18;} - else if ( (LA2_11==RULE_LETTER_V) ) {s = 10;} + else if ( (LA3_24==RULE_LETTER_C) ) {s = 19;} - else if ( (LA2_11==RULE_LETTER_X) ) {s = 11;} + else if ( (LA3_24==RULE_LETTER_E) ) {s = 20;} - else if ( (LA2_11==RULE_LETTER_S) ) {s = 12;} + else if ( (LA3_24==RULE_LETTER_F) ) {s = 21;} - else if ( (LA2_11==RULE_LETTER_M) ) {s = 13;} + else if ( (LA3_24==RULE_LETTER_I) ) {s = 22;} - else if ( (LA2_11==RULE_LETTER_R) ) {s = 14;} + else if ( (LA3_24==RULE_LETTER_K) ) {s = 23;} - else if ( (LA2_11==RULE_LETTER_F) ) {s = 15;} + else if ( (LA3_24==RULE_LETTER_L) ) {s = 24;} - else if ( (LA2_11==RULE_LETTER_I) ) {s = 16;} + else if ( (LA3_24==RULE_LETTER_M) ) {s = 25;} - else if ( (LA2_11==RULE_LETTER_L) ) {s = 17;} + else if ( (LA3_24==RULE_LETTER_O) ) {s = 26;} - else if ( (LA2_11==RULE_LETTER_E) ) {s = 18;} + else if ( (LA3_24==RULE_LETTER_P) ) {s = 27;} - else if ( (LA2_11==RULE_LETTER_OTHER) ) {s = 19;} + else if ( (LA3_24==RULE_LETTER_R) ) {s = 28;} - else if ( (LA2_11==41) && (synpred2_InternalSemver())) {s = 20;} + else if ( (LA3_24==RULE_LETTER_S) ) {s = 29;} - else if ( (LA2_11==EOF||LA2_11==RULE_WS) ) {s = 24;} + else if ( (LA3_24==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_24==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_24==47) && (synpred2_InternalSemver())) {s = 32;} - input.seek(index2_11); + input.seek(index3_24); if ( s>=0 ) return s; break; - case 9 : - int LA2_18 = input.LA(1); + case 44 : + int LA3_6 = input.LA(1); - int index2_18 = input.index(); + int index3_6 = input.index(); input.rewind(); s = -1; - if ( (LA2_18==EOF||LA2_18==RULE_WS) ) {s = 24;} + if ( (LA3_6==RULE_DIGITS||(LA3_6>=41 && LA3_6<=42)||(LA3_6>=45 && LA3_6<=46)||(LA3_6>=48 && LA3_6<=49)) ) {s = 15;} + + else if ( (LA3_6==RULE_LETTER_V) ) {s = 16;} - else if ( (LA2_18==39) ) {s = 21;} + else if ( (LA3_6==RULE_LETTER_X) ) {s = 17;} - else if ( (LA2_18==RULE_DIGITS) ) {s = 22;} + else if ( (LA3_6==RULE_LETTER_A) ) {s = 18;} - else if ( (LA2_18==RULE_LETTER_V) ) {s = 10;} + else if ( (LA3_6==RULE_LETTER_C) ) {s = 19;} - else if ( (LA2_18==RULE_LETTER_X) ) {s = 11;} + else if ( (LA3_6==RULE_LETTER_E) ) {s = 20;} - else if ( (LA2_18==RULE_LETTER_S) ) {s = 12;} + else if ( (LA3_6==RULE_LETTER_F) ) {s = 21;} - else if ( (LA2_18==RULE_LETTER_M) ) {s = 13;} + else if ( (LA3_6==RULE_LETTER_I) ) {s = 22;} - else if ( (LA2_18==RULE_LETTER_R) ) {s = 14;} + else if ( (LA3_6==RULE_LETTER_K) ) {s = 23;} - else if ( (LA2_18==RULE_LETTER_F) ) {s = 15;} + else if ( (LA3_6==RULE_LETTER_L) ) {s = 24;} - else if ( (LA2_18==RULE_LETTER_I) ) {s = 16;} + else if ( (LA3_6==RULE_LETTER_M) ) {s = 25;} - else if ( (LA2_18==RULE_LETTER_L) ) {s = 17;} + else if ( (LA3_6==RULE_LETTER_O) ) {s = 26;} - else if ( (LA2_18==RULE_LETTER_E) ) {s = 18;} + else if ( (LA3_6==RULE_LETTER_P) ) {s = 27;} - else if ( (LA2_18==RULE_LETTER_OTHER) ) {s = 19;} + else if ( (LA3_6==RULE_LETTER_R) ) {s = 28;} - else if ( (LA2_18==36||LA2_18==40||(LA2_18>=42 && LA2_18<=43)) ) {s = 9;} + else if ( (LA3_6==RULE_LETTER_S) ) {s = 29;} - else if ( (LA2_18==35) ) {s = 23;} + else if ( (LA3_6==RULE_LETTER_W) ) {s = 30;} - else if ( (LA2_18==41) && (synpred2_InternalSemver())) {s = 20;} + else if ( (LA3_6==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_6==47) && (synpred2_InternalSemver())) {s = 32;} - input.seek(index2_18); + input.seek(index3_6); if ( s>=0 ) return s; break; - case 10 : - int LA2_1 = input.LA(1); + case 45 : + int LA3_64 = input.LA(1); - int index2_1 = input.index(); + int index3_64 = input.index(); input.rewind(); s = -1; - if ( (LA2_1==RULE_LETTER_V) ) {s = 10;} + if ( (LA3_64==41) ) {s = 34;} + + else if ( (LA3_64==RULE_LETTER_V) ) {s = 16;} + + else if ( (LA3_64==RULE_LETTER_X) ) {s = 17;} - else if ( (LA2_1==RULE_LETTER_X) ) {s = 11;} + else if ( (LA3_64==RULE_LETTER_A) ) {s = 18;} - else if ( (LA2_1==RULE_LETTER_S) ) {s = 12;} + else if ( (LA3_64==RULE_LETTER_C) ) {s = 65;} - else if ( (LA2_1==RULE_LETTER_M) ) {s = 13;} + else if ( (LA3_64==RULE_LETTER_E) ) {s = 20;} - else if ( (LA2_1==RULE_LETTER_R) ) {s = 14;} + else if ( (LA3_64==RULE_LETTER_F) ) {s = 21;} - else if ( (LA2_1==RULE_LETTER_F) ) {s = 15;} + else if ( (LA3_64==RULE_LETTER_I) ) {s = 22;} - else if ( (LA2_1==RULE_LETTER_I) ) {s = 16;} + else if ( (LA3_64==RULE_LETTER_K) ) {s = 23;} - else if ( (LA2_1==RULE_LETTER_L) ) {s = 17;} + else if ( (LA3_64==RULE_LETTER_L) ) {s = 24;} - else if ( (LA2_1==RULE_LETTER_E) ) {s = 18;} + else if ( (LA3_64==RULE_LETTER_M) ) {s = 25;} - else if ( (LA2_1==RULE_LETTER_OTHER) ) {s = 19;} + else if ( (LA3_64==RULE_LETTER_O) ) {s = 26;} - else if ( (LA2_1==41) && (synpred2_InternalSemver())) {s = 20;} + else if ( (LA3_64==RULE_LETTER_P) ) {s = 27;} - else if ( (LA2_1==39) ) {s = 21;} + else if ( (LA3_64==RULE_LETTER_R) ) {s = 28;} - else if ( ((LA2_1>=35 && LA2_1<=36)||LA2_1==40||(LA2_1>=42 && LA2_1<=43)) ) {s = 9;} + else if ( (LA3_64==RULE_LETTER_S) ) {s = 29;} - else if ( (LA2_1==RULE_DIGITS) ) {s = 22;} + else if ( (LA3_64==RULE_LETTER_W) ) {s = 30;} + + else if ( (LA3_64==RULE_LETTER_OTHER) ) {s = 31;} + + else if ( (LA3_64==47) && (synpred2_InternalSemver())) {s = 32;} + + else if ( (LA3_64==EOF||LA3_64==RULE_WS||LA3_64==RULE_DIGITS||LA3_64==42||(LA3_64>=45 && LA3_64<=46)||(LA3_64>=48 && LA3_64<=49)) ) {s = 15;} - input.seek(index2_1); + input.seek(index3_64); if ( s>=0 ) return s; break; - case 11 : - int LA2_6 = input.LA(1); + } + if (state.backtracking>0) {state.failed=true; return -1;} + NoViableAltException nvae = + new NoViableAltException(getDescription(), 3, _s, input); + error(nvae); + throw nvae; + } + } + static final String dfa_15s = "\113\uffff"; + static final String dfa_16s = "\20\uffff\23\43\1\uffff\7\43\1\2\37\uffff"; + static final String dfa_17s = "\1\7\1\5\1\uffff\15\5\23\4\1\uffff\10\4\27\0\10\uffff"; + static final String dfa_18s = "\2\61\1\uffff\40\61\1\uffff\7\61\1\70\27\0\10\uffff"; + static final String dfa_19s = "\2\uffff\1\2\40\uffff\1\3\37\uffff\10\1"; + static final String dfa_20s = "\53\uffff\1\26\1\24\1\0\1\3\1\7\1\12\1\4\1\23\1\11\1\20\1\1\1\13\1\16\1\27\1\5\1\15\1\21\1\2\1\10\1\17\1\25\1\6\1\14\1\22\10\uffff}>"; + static final String[] dfa_21s = { + "\1\6\1\7\1\11\1\5\1\16\1\12\1\15\1\1\1\13\1\10\1\14\1\3\1\4\2\uffff\1\17\26\uffff\1\2\3\uffff\1\2", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\34\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\44\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\45\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\46\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\47\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\50\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\51\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\52\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\2\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\43\1\22\1\21\1\27\1\30\1\32\1\26\1\37\1\33\1\36\1\40\1\42\1\31\1\35\1\24\1\25\1\uffff\1\23\1\41\22\uffff\1\53\1\2\2\uffff\1\20\1\2\1\uffff\2\2", + "\1\2\1\63\1\62\1\70\1\71\1\73\1\67\1\100\1\74\1\77\1\101\1\75\1\72\1\76\1\65\1\66\1\112\1\64\1\102\22\uffff\1\56\1\54\1\2\1\uffff\1\61\1\55\1\uffff\1\57\1\60\1\103\1\104\1\105\1\106\1\107\1\110\1\111", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "", + "", + "", + "", + "", + "", + "", + "" + }; + + static final short[] dfa_15 = DFA.unpackEncodedString(dfa_15s); + static final short[] dfa_16 = DFA.unpackEncodedString(dfa_16s); + static final char[] dfa_17 = DFA.unpackEncodedStringToUnsignedChars(dfa_17s); + static final char[] dfa_18 = DFA.unpackEncodedStringToUnsignedChars(dfa_18s); + static final short[] dfa_19 = DFA.unpackEncodedString(dfa_19s); + static final short[] dfa_20 = DFA.unpackEncodedString(dfa_20s); + static final short[][] dfa_21 = unpackEncodedStringArray(dfa_21s); + + class DFA2 extends DFA { + + public DFA2(BaseRecognizer recognizer) { + this.recognizer = recognizer; + this.decisionNumber = 2; + this.eot = dfa_15; + this.eof = dfa_16; + this.min = dfa_17; + this.max = dfa_18; + this.accept = dfa_19; + this.special = dfa_20; + this.transition = dfa_21; + } + public String getDescription() { + return "131:6: ( ( ( ruleWorkspaceVersionRequirement )=>this_WorkspaceVersionRequirement_4= ruleWorkspaceVersionRequirement ) | this_GitHubVersionRequirement_5= ruleGitHubVersionRequirement | this_TagVersionRequirement_6= ruleTagVersionRequirement )"; + } + public int specialStateTransition(int s, IntStream _input) throws NoViableAltException { + TokenStream input = (TokenStream)_input; + int _s = s; + switch ( s ) { + case 0 : + int LA2_45 = input.LA(1); + + + int index2_45 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} + + else if ( (true) ) {s = 2;} + + + input.seek(index2_45); + if ( s>=0 ) return s; + break; + case 1 : + int LA2_53 = input.LA(1); - int index2_6 = input.index(); + int index2_53 = input.index(); input.rewind(); s = -1; - if ( (LA2_6==RULE_LETTER_V) ) {s = 10;} + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_6==RULE_LETTER_X) ) {s = 11;} + else if ( (true) ) {s = 2;} - else if ( (LA2_6==RULE_LETTER_S) ) {s = 12;} + + input.seek(index2_53); + if ( s>=0 ) return s; + break; + case 2 : + int LA2_60 = input.LA(1); - else if ( (LA2_6==RULE_LETTER_M) ) {s = 13;} + + int index2_60 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_6==RULE_LETTER_R) ) {s = 14;} + else if ( (true) ) {s = 2;} - else if ( (LA2_6==RULE_LETTER_F) ) {s = 15;} + + input.seek(index2_60); + if ( s>=0 ) return s; + break; + case 3 : + int LA2_46 = input.LA(1); - else if ( (LA2_6==RULE_LETTER_I) ) {s = 16;} + + int index2_46 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_6==RULE_LETTER_L) ) {s = 17;} + else if ( (true) ) {s = 2;} - else if ( (LA2_6==RULE_LETTER_E) ) {s = 18;} + + input.seek(index2_46); + if ( s>=0 ) return s; + break; + case 4 : + int LA2_49 = input.LA(1); - else if ( (LA2_6==RULE_LETTER_OTHER) ) {s = 19;} + + int index2_49 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_6==41) && (synpred2_InternalSemver())) {s = 20;} + else if ( (true) ) {s = 2;} - else if ( (LA2_6==39) ) {s = 21;} + + input.seek(index2_49); + if ( s>=0 ) return s; + break; + case 5 : + int LA2_57 = input.LA(1); - else if ( ((LA2_6>=35 && LA2_6<=36)||LA2_6==40||(LA2_6>=42 && LA2_6<=43)) ) {s = 9;} + + int index2_57 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_6==RULE_DIGITS) ) {s = 22;} + else if ( (true) ) {s = 2;} - input.seek(index2_6); + input.seek(index2_57); if ( s>=0 ) return s; break; - case 12 : - int LA2_16 = input.LA(1); + case 6 : + int LA2_64 = input.LA(1); - int index2_16 = input.index(); + int index2_64 = input.index(); input.rewind(); s = -1; - if ( (LA2_16==35) ) {s = 23;} + if ( (synpred3_InternalSemver()) ) {s = 74;} + + else if ( (true) ) {s = 2;} - else if ( (LA2_16==RULE_LETTER_V) ) {s = 10;} + + input.seek(index2_64); + if ( s>=0 ) return s; + break; + case 7 : + int LA2_47 = input.LA(1); - else if ( (LA2_16==RULE_LETTER_X) ) {s = 11;} + + int index2_47 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_16==RULE_LETTER_S) ) {s = 12;} + else if ( (true) ) {s = 2;} - else if ( (LA2_16==RULE_LETTER_M) ) {s = 13;} + + input.seek(index2_47); + if ( s>=0 ) return s; + break; + case 8 : + int LA2_61 = input.LA(1); - else if ( (LA2_16==RULE_LETTER_R) ) {s = 14;} + + int index2_61 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_16==RULE_LETTER_F) ) {s = 15;} + else if ( (true) ) {s = 2;} - else if ( (LA2_16==RULE_LETTER_I) ) {s = 16;} + + input.seek(index2_61); + if ( s>=0 ) return s; + break; + case 9 : + int LA2_51 = input.LA(1); - else if ( (LA2_16==RULE_LETTER_L) ) {s = 17;} + + int index2_51 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_16==RULE_LETTER_E) ) {s = 18;} + else if ( (true) ) {s = 2;} - else if ( (LA2_16==RULE_LETTER_OTHER) ) {s = 19;} + + input.seek(index2_51); + if ( s>=0 ) return s; + break; + case 10 : + int LA2_48 = input.LA(1); - else if ( (LA2_16==41) && (synpred2_InternalSemver())) {s = 20;} + + int index2_48 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_16==EOF||LA2_16==RULE_WS) ) {s = 24;} + else if ( (true) ) {s = 2;} - else if ( (LA2_16==39) ) {s = 21;} + + input.seek(index2_48); + if ( s>=0 ) return s; + break; + case 11 : + int LA2_54 = input.LA(1); - else if ( (LA2_16==RULE_DIGITS) ) {s = 22;} + + int index2_54 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_16==36||LA2_16==40||(LA2_16>=42 && LA2_16<=43)) ) {s = 9;} + else if ( (true) ) {s = 2;} - input.seek(index2_16); + input.seek(index2_54); if ( s>=0 ) return s; break; - case 13 : - int LA2_4 = input.LA(1); + case 12 : + int LA2_65 = input.LA(1); - int index2_4 = input.index(); + int index2_65 = input.index(); input.rewind(); s = -1; - if ( (LA2_4==39) ) {s = 21;} - - else if ( (LA2_4==RULE_DIGITS) ) {s = 22;} - - else if ( (LA2_4==RULE_LETTER_V) ) {s = 10;} + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_4==RULE_LETTER_X) ) {s = 11;} - - else if ( (LA2_4==RULE_LETTER_S) ) {s = 12;} - - else if ( (LA2_4==RULE_LETTER_M) ) {s = 13;} - - else if ( (LA2_4==RULE_LETTER_R) ) {s = 14;} - - else if ( (LA2_4==RULE_LETTER_F) ) {s = 15;} - - else if ( (LA2_4==RULE_LETTER_I) ) {s = 16;} - - else if ( (LA2_4==RULE_LETTER_L) ) {s = 17;} - - else if ( (LA2_4==RULE_LETTER_E) ) {s = 18;} + else if ( (true) ) {s = 2;} - else if ( (LA2_4==RULE_LETTER_OTHER) ) {s = 19;} + + input.seek(index2_65); + if ( s>=0 ) return s; + break; + case 13 : + int LA2_58 = input.LA(1); - else if ( (LA2_4==41) && (synpred2_InternalSemver())) {s = 20;} + + int index2_58 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( ((LA2_4>=35 && LA2_4<=36)||LA2_4==40||(LA2_4>=42 && LA2_4<=43)) ) {s = 9;} + else if ( (true) ) {s = 2;} - input.seek(index2_4); + input.seek(index2_58); if ( s>=0 ) return s; break; case 14 : - int LA2_14 = input.LA(1); + int LA2_55 = input.LA(1); - int index2_14 = input.index(); + int index2_55 = input.index(); input.rewind(); s = -1; - if ( (LA2_14==35) ) {s = 23;} - - else if ( (LA2_14==RULE_LETTER_V) ) {s = 10;} - - else if ( (LA2_14==RULE_LETTER_X) ) {s = 11;} - - else if ( (LA2_14==RULE_LETTER_S) ) {s = 12;} - - else if ( (LA2_14==RULE_LETTER_M) ) {s = 13;} - - else if ( (LA2_14==RULE_LETTER_R) ) {s = 14;} - - else if ( (LA2_14==RULE_LETTER_F) ) {s = 15;} - - else if ( (LA2_14==RULE_LETTER_I) ) {s = 16;} - - else if ( (LA2_14==RULE_LETTER_L) ) {s = 17;} + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_14==RULE_LETTER_E) ) {s = 18;} + else if ( (true) ) {s = 2;} - else if ( (LA2_14==RULE_LETTER_OTHER) ) {s = 19;} + + input.seek(index2_55); + if ( s>=0 ) return s; + break; + case 15 : + int LA2_62 = input.LA(1); - else if ( (LA2_14==41) && (synpred2_InternalSemver())) {s = 20;} + + int index2_62 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_14==EOF||LA2_14==RULE_WS) ) {s = 24;} + else if ( (true) ) {s = 2;} - else if ( (LA2_14==39) ) {s = 21;} + + input.seek(index2_62); + if ( s>=0 ) return s; + break; + case 16 : + int LA2_52 = input.LA(1); - else if ( (LA2_14==RULE_DIGITS) ) {s = 22;} + + int index2_52 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_14==36||LA2_14==40||(LA2_14>=42 && LA2_14<=43)) ) {s = 9;} + else if ( (true) ) {s = 2;} - input.seek(index2_14); + input.seek(index2_52); if ( s>=0 ) return s; break; - case 15 : - int LA2_19 = input.LA(1); + case 17 : + int LA2_59 = input.LA(1); - int index2_19 = input.index(); + int index2_59 = input.index(); input.rewind(); s = -1; - if ( (LA2_19==35) ) {s = 23;} - - else if ( (LA2_19==RULE_LETTER_V) ) {s = 10;} + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_19==RULE_LETTER_X) ) {s = 11;} - - else if ( (LA2_19==RULE_LETTER_S) ) {s = 12;} + else if ( (true) ) {s = 2;} - else if ( (LA2_19==RULE_LETTER_M) ) {s = 13;} + + input.seek(index2_59); + if ( s>=0 ) return s; + break; + case 18 : + int LA2_66 = input.LA(1); - else if ( (LA2_19==RULE_LETTER_R) ) {s = 14;} + + int index2_66 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_19==RULE_LETTER_F) ) {s = 15;} + else if ( (true) ) {s = 2;} - else if ( (LA2_19==RULE_LETTER_I) ) {s = 16;} + + input.seek(index2_66); + if ( s>=0 ) return s; + break; + case 19 : + int LA2_50 = input.LA(1); - else if ( (LA2_19==RULE_LETTER_L) ) {s = 17;} + + int index2_50 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_19==RULE_LETTER_E) ) {s = 18;} + else if ( (true) ) {s = 2;} - else if ( (LA2_19==RULE_LETTER_OTHER) ) {s = 19;} + + input.seek(index2_50); + if ( s>=0 ) return s; + break; + case 20 : + int LA2_44 = input.LA(1); - else if ( (LA2_19==41) && (synpred2_InternalSemver())) {s = 20;} + + int index2_44 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_19==EOF||LA2_19==RULE_WS) ) {s = 24;} + else if ( (true) ) {s = 2;} - else if ( (LA2_19==39) ) {s = 21;} + + input.seek(index2_44); + if ( s>=0 ) return s; + break; + case 21 : + int LA2_63 = input.LA(1); - else if ( (LA2_19==RULE_DIGITS) ) {s = 22;} + + int index2_63 = input.index(); + input.rewind(); + s = -1; + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_19==36||LA2_19==40||(LA2_19>=42 && LA2_19<=43)) ) {s = 9;} + else if ( (true) ) {s = 2;} - input.seek(index2_19); + input.seek(index2_63); if ( s>=0 ) return s; break; - case 16 : - int LA2_2 = input.LA(1); + case 22 : + int LA2_43 = input.LA(1); - int index2_2 = input.index(); + int index2_43 = input.index(); input.rewind(); s = -1; - if ( (LA2_2==39) ) {s = 21;} + if ( (LA2_43==42) ) {s = 44;} - else if ( ((LA2_2>=35 && LA2_2<=36)||LA2_2==40||(LA2_2>=42 && LA2_2<=43)) ) {s = 9;} + else if ( (LA2_43==46) ) {s = 45;} - else if ( (LA2_2==RULE_DIGITS) ) {s = 22;} + else if ( (LA2_43==41) ) {s = 46;} - else if ( (LA2_2==RULE_LETTER_V) ) {s = 10;} + else if ( (LA2_43==48) ) {s = 47;} - else if ( (LA2_2==RULE_LETTER_X) ) {s = 11;} + else if ( (LA2_43==49) ) {s = 48;} - else if ( (LA2_2==RULE_LETTER_S) ) {s = 12;} + else if ( (LA2_43==45) ) {s = 49;} - else if ( (LA2_2==RULE_LETTER_M) ) {s = 13;} + else if ( (LA2_43==RULE_DIGITS) ) {s = 50;} - else if ( (LA2_2==RULE_LETTER_R) ) {s = 14;} + else if ( (LA2_43==RULE_LETTER_V) ) {s = 51;} - else if ( (LA2_2==RULE_LETTER_F) ) {s = 15;} + else if ( (LA2_43==RULE_LETTER_X) ) {s = 52;} - else if ( (LA2_2==RULE_LETTER_I) ) {s = 16;} + else if ( (LA2_43==RULE_LETTER_A) ) {s = 53;} - else if ( (LA2_2==RULE_LETTER_L) ) {s = 17;} + else if ( (LA2_43==RULE_LETTER_C) ) {s = 54;} - else if ( (LA2_2==RULE_LETTER_E) ) {s = 18;} + else if ( (LA2_43==RULE_LETTER_E) ) {s = 55;} - else if ( (LA2_2==RULE_LETTER_OTHER) ) {s = 19;} + else if ( (LA2_43==RULE_LETTER_F) ) {s = 56;} - else if ( (LA2_2==41) && (synpred2_InternalSemver())) {s = 20;} + else if ( (LA2_43==RULE_LETTER_I) ) {s = 57;} - - input.seek(index2_2); - if ( s>=0 ) return s; - break; - case 17 : - int LA2_12 = input.LA(1); + else if ( (LA2_43==RULE_LETTER_K) ) {s = 58;} - - int index2_12 = input.index(); - input.rewind(); - s = -1; - if ( (LA2_12==36||LA2_12==40||(LA2_12>=42 && LA2_12<=43)) ) {s = 9;} + else if ( (LA2_43==RULE_LETTER_L) ) {s = 59;} - else if ( (LA2_12==35) ) {s = 23;} + else if ( (LA2_43==RULE_LETTER_M) ) {s = 60;} - else if ( (LA2_12==39) ) {s = 21;} + else if ( (LA2_43==RULE_LETTER_O) ) {s = 61;} - else if ( (LA2_12==RULE_DIGITS) ) {s = 22;} + else if ( (LA2_43==RULE_LETTER_P) ) {s = 62;} - else if ( (LA2_12==RULE_LETTER_V) ) {s = 10;} + else if ( (LA2_43==RULE_LETTER_R) ) {s = 63;} - else if ( (LA2_12==RULE_LETTER_X) ) {s = 11;} + else if ( (LA2_43==RULE_LETTER_S) ) {s = 64;} - else if ( (LA2_12==RULE_LETTER_S) ) {s = 12;} + else if ( (LA2_43==RULE_LETTER_W) ) {s = 65;} - else if ( (LA2_12==RULE_LETTER_M) ) {s = 13;} + else if ( (LA2_43==RULE_LETTER_OTHER) ) {s = 66;} - else if ( (LA2_12==RULE_LETTER_R) ) {s = 14;} + else if ( (LA2_43==EOF||LA2_43==RULE_WS||LA2_43==43) ) {s = 2;} - else if ( (LA2_12==RULE_LETTER_F) ) {s = 15;} + else if ( (LA2_43==50) && (synpred3_InternalSemver())) {s = 67;} - else if ( (LA2_12==RULE_LETTER_I) ) {s = 16;} + else if ( (LA2_43==51) && (synpred3_InternalSemver())) {s = 68;} - else if ( (LA2_12==RULE_LETTER_L) ) {s = 17;} + else if ( (LA2_43==52) && (synpred3_InternalSemver())) {s = 69;} - else if ( (LA2_12==RULE_LETTER_E) ) {s = 18;} + else if ( (LA2_43==53) && (synpred3_InternalSemver())) {s = 70;} - else if ( (LA2_12==RULE_LETTER_OTHER) ) {s = 19;} + else if ( (LA2_43==54) && (synpred3_InternalSemver())) {s = 71;} - else if ( (LA2_12==41) && (synpred2_InternalSemver())) {s = 20;} + else if ( (LA2_43==55) && (synpred3_InternalSemver())) {s = 72;} - else if ( (LA2_12==EOF||LA2_12==RULE_WS) ) {s = 24;} + else if ( (LA2_43==56) && (synpred3_InternalSemver())) {s = 73;} + + else if ( (LA2_43==RULE_ASTERIX) && (synpred3_InternalSemver())) {s = 74;} - input.seek(index2_12); + input.seek(index2_43); if ( s>=0 ) return s; break; - case 18 : - int LA2_10 = input.LA(1); + case 23 : + int LA2_56 = input.LA(1); - int index2_10 = input.index(); + int index2_56 = input.index(); input.rewind(); s = -1; - if ( (LA2_10==35) ) {s = 23;} + if ( (synpred3_InternalSemver()) ) {s = 74;} - else if ( (LA2_10==RULE_LETTER_V) ) {s = 10;} - - else if ( (LA2_10==RULE_LETTER_X) ) {s = 11;} - - else if ( (LA2_10==RULE_LETTER_S) ) {s = 12;} - - else if ( (LA2_10==RULE_LETTER_M) ) {s = 13;} - - else if ( (LA2_10==RULE_LETTER_R) ) {s = 14;} - - else if ( (LA2_10==RULE_LETTER_F) ) {s = 15;} - - else if ( (LA2_10==RULE_LETTER_I) ) {s = 16;} + else if ( (true) ) {s = 2;} - else if ( (LA2_10==RULE_LETTER_L) ) {s = 17;} + + input.seek(index2_56); + if ( s>=0 ) return s; + break; + } + if (state.backtracking>0) {state.failed=true; return -1;} + NoViableAltException nvae = + new NoViableAltException(getDescription(), 2, _s, input); + error(nvae); + throw nvae; + } + } + static final String dfa_22s = "\26\uffff"; + static final String dfa_23s = "\1\uffff\1\15\7\uffff\1\15\4\uffff\1\15\2\uffff\4\15\1\uffff"; + static final String dfa_24s = "\1\5\1\4\7\uffff\1\4\1\0\1\uffff\1\5\1\uffff\1\4\1\0\1\uffff\4\4\1\uffff"; + static final String dfa_25s = "\1\70\1\55\7\uffff\1\55\1\0\1\uffff\1\55\1\uffff\1\55\1\0\1\uffff\4\55\1\uffff"; + static final String dfa_26s = "\2\uffff\7\1\2\uffff\1\1\1\uffff\1\3\2\uffff\1\2\4\uffff\1\1"; + static final String dfa_27s = "\1\5\10\uffff\1\0\1\4\1\uffff\1\3\2\uffff\1\1\4\uffff\1\2\1\uffff}>"; + static final String[] dfa_28s = { + "\1\11\1\14\4\15\1\1\10\15\1\13\1\12\1\15\26\uffff\1\15\4\uffff\1\2\1\3\1\4\1\5\1\6\1\7\1\10", + "\6\15\1\16\11\15\1\uffff\2\15\26\uffff\1\15", + "", + "", + "", + "", + "", + "", + "", + "\2\15\1\17\15\15\1\13\1\12\1\15\26\uffff\1\15", + "\1\uffff", + "", + "\17\20\1\uffff\2\20\26\uffff\1\20", + "", + "\10\15\1\21\7\15\1\uffff\2\15\26\uffff\1\15", + "\1\uffff", + "", + "\1\15\1\22\16\15\1\uffff\2\15\26\uffff\1\15", + "\6\15\1\23\11\15\1\uffff\2\15\26\uffff\1\15", + "\11\15\1\24\6\15\1\uffff\2\15\26\uffff\1\15", + "\20\15\1\uffff\2\15\22\uffff\1\25\3\uffff\1\15", + "" + }; - else if ( (LA2_10==RULE_LETTER_E) ) {s = 18;} + static final short[] dfa_22 = DFA.unpackEncodedString(dfa_22s); + static final short[] dfa_23 = DFA.unpackEncodedString(dfa_23s); + static final char[] dfa_24 = DFA.unpackEncodedStringToUnsignedChars(dfa_24s); + static final char[] dfa_25 = DFA.unpackEncodedStringToUnsignedChars(dfa_25s); + static final short[] dfa_26 = DFA.unpackEncodedString(dfa_26s); + static final short[] dfa_27 = DFA.unpackEncodedString(dfa_27s); + static final short[][] dfa_28 = unpackEncodedStringArray(dfa_28s); - else if ( (LA2_10==RULE_LETTER_OTHER) ) {s = 19;} + class DFA8 extends DFA { - else if ( (LA2_10==41) && (synpred2_InternalSemver())) {s = 20;} + public DFA8(BaseRecognizer recognizer) { + this.recognizer = recognizer; + this.decisionNumber = 8; + this.eot = dfa_22; + this.eof = dfa_23; + this.min = dfa_24; + this.max = dfa_25; + this.accept = dfa_26; + this.special = dfa_27; + this.transition = dfa_28; + } + public String getDescription() { + return "330:2: ( ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) | ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) | ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) )"; + } + public int specialStateTransition(int s, IntStream _input) throws NoViableAltException { + TokenStream input = (TokenStream)_input; + int _s = s; + switch ( s ) { + case 0 : + int LA8_9 = input.LA(1); - else if ( (LA2_10==EOF||LA2_10==RULE_WS) ) {s = 24;} + + int index8_9 = input.index(); + input.rewind(); + s = -1; + if ( (LA8_9==EOF||(LA8_9>=RULE_WS && LA8_9<=RULE_LETTER_V)||(LA8_9>=RULE_LETTER_F && LA8_9<=RULE_LETTER_C)||LA8_9==RULE_LETTER_OTHER||LA8_9==45) ) {s = 13;} - else if ( (LA2_10==39) ) {s = 21;} + else if ( (LA8_9==RULE_DIGITS) ) {s = 15;} - else if ( (LA2_10==RULE_DIGITS) ) {s = 22;} + else if ( (LA8_9==RULE_LETTER_X) ) {s = 10;} - else if ( (LA2_10==36||LA2_10==40||(LA2_10>=42 && LA2_10<=43)) ) {s = 9;} + else if ( (LA8_9==RULE_ASTERIX) && (synpred4_InternalSemver())) {s = 11;} - input.seek(index2_10); + input.seek(index8_9); if ( s>=0 ) return s; break; - case 19 : - int LA2_37 = input.LA(1); + case 1 : + int LA8_15 = input.LA(1); - int index2_37 = input.index(); + int index8_15 = input.index(); input.rewind(); s = -1; - if ( (synpred2_InternalSemver()) ) {s = 20;} + if ( (synpred4_InternalSemver()) ) {s = 11;} - else if ( (true) ) {s = 9;} + else if ( (true) ) {s = 13;} - input.seek(index2_37); + input.seek(index8_15); if ( s>=0 ) return s; break; - case 20 : - int LA2_7 = input.LA(1); + case 2 : + int LA8_20 = input.LA(1); - int index2_7 = input.index(); + int index8_20 = input.index(); input.rewind(); s = -1; - if ( (LA2_7==39) ) {s = 21;} + if ( (LA8_20==41) && (synpred4_InternalSemver())) {s = 21;} - else if ( (LA2_7==RULE_DIGITS) ) {s = 22;} + else if ( (LA8_20==EOF||(LA8_20>=RULE_WS && LA8_20<=RULE_LETTER_C)||(LA8_20>=RULE_LETTER_X && LA8_20<=RULE_LETTER_OTHER)||LA8_20==45) ) {s = 13;} - else if ( (LA2_7==RULE_LETTER_V) ) {s = 10;} - - else if ( (LA2_7==RULE_LETTER_X) ) {s = 11;} - - else if ( (LA2_7==RULE_LETTER_S) ) {s = 12;} - - else if ( (LA2_7==RULE_LETTER_M) ) {s = 13;} - - else if ( (LA2_7==RULE_LETTER_R) ) {s = 14;} - - else if ( (LA2_7==RULE_LETTER_F) ) {s = 15;} - - else if ( (LA2_7==RULE_LETTER_I) ) {s = 16;} - - else if ( (LA2_7==RULE_LETTER_L) ) {s = 17;} - - else if ( (LA2_7==RULE_LETTER_E) ) {s = 18;} + + input.seek(index8_20); + if ( s>=0 ) return s; + break; + case 3 : + int LA8_12 = input.LA(1); - else if ( (LA2_7==RULE_LETTER_OTHER) ) {s = 19;} + + int index8_12 = input.index(); + input.rewind(); + s = -1; + if ( ((LA8_12>=RULE_LETTER_V && LA8_12<=RULE_LETTER_C)||(LA8_12>=RULE_LETTER_X && LA8_12<=RULE_LETTER_OTHER)||LA8_12==45) ) {s = 16;} - else if ( (LA2_7==41) && (synpred2_InternalSemver())) {s = 20;} + else if ( (synpred4_InternalSemver()) ) {s = 11;} - else if ( ((LA2_7>=35 && LA2_7<=36)||LA2_7==40||(LA2_7>=42 && LA2_7<=43)) ) {s = 9;} + else if ( (true) ) {s = 13;} - input.seek(index2_7); + input.seek(index8_12); if ( s>=0 ) return s; break; - case 21 : - int LA2_17 = input.LA(1); + case 4 : + int LA8_10 = input.LA(1); - int index2_17 = input.index(); + int index8_10 = input.index(); input.rewind(); s = -1; - if ( (LA2_17==35) ) {s = 23;} + if ( (synpred4_InternalSemver()) ) {s = 11;} - else if ( (LA2_17==RULE_LETTER_V) ) {s = 10;} + else if ( (true) ) {s = 13;} - else if ( (LA2_17==RULE_LETTER_X) ) {s = 11;} + + input.seek(index8_10); + if ( s>=0 ) return s; + break; + case 5 : + int LA8_0 = input.LA(1); - else if ( (LA2_17==RULE_LETTER_S) ) {s = 12;} + + int index8_0 = input.index(); + input.rewind(); + s = -1; + if ( (LA8_0==RULE_LETTER_S) ) {s = 1;} - else if ( (LA2_17==RULE_LETTER_M) ) {s = 13;} + else if ( (LA8_0==50) && (synpred4_InternalSemver())) {s = 2;} - else if ( (LA2_17==RULE_LETTER_R) ) {s = 14;} + else if ( (LA8_0==51) && (synpred4_InternalSemver())) {s = 3;} - else if ( (LA2_17==RULE_LETTER_F) ) {s = 15;} + else if ( (LA8_0==52) && (synpred4_InternalSemver())) {s = 4;} - else if ( (LA2_17==RULE_LETTER_I) ) {s = 16;} + else if ( (LA8_0==53) && (synpred4_InternalSemver())) {s = 5;} - else if ( (LA2_17==RULE_LETTER_L) ) {s = 17;} + else if ( (LA8_0==54) && (synpred4_InternalSemver())) {s = 6;} - else if ( (LA2_17==RULE_LETTER_E) ) {s = 18;} + else if ( (LA8_0==55) && (synpred4_InternalSemver())) {s = 7;} - else if ( (LA2_17==RULE_LETTER_OTHER) ) {s = 19;} + else if ( (LA8_0==56) && (synpred4_InternalSemver())) {s = 8;} - else if ( (LA2_17==41) && (synpred2_InternalSemver())) {s = 20;} + else if ( (LA8_0==RULE_LETTER_V) ) {s = 9;} - else if ( (LA2_17==EOF||LA2_17==RULE_WS) ) {s = 24;} + else if ( (LA8_0==RULE_LETTER_X) ) {s = 10;} - else if ( (LA2_17==39) ) {s = 21;} + else if ( (LA8_0==RULE_ASTERIX) && (synpred4_InternalSemver())) {s = 11;} - else if ( (LA2_17==RULE_DIGITS) ) {s = 22;} + else if ( (LA8_0==RULE_DIGITS) ) {s = 12;} - else if ( (LA2_17==36||LA2_17==40||(LA2_17>=42 && LA2_17<=43)) ) {s = 9;} + else if ( ((LA8_0>=RULE_LETTER_F && LA8_0<=RULE_LETTER_E)||(LA8_0>=RULE_LETTER_M && LA8_0<=RULE_LETTER_C)||LA8_0==RULE_LETTER_OTHER||LA8_0==45) ) {s = 13;} - input.seek(index2_17); + input.seek(index8_0); if ( s>=0 ) return s; break; } if (state.backtracking>0) {state.failed=true; return -1;} NoViableAltException nvae = - new NoViableAltException(getDescription(), 2, _s, input); + new NoViableAltException(getDescription(), 8, _s, input); error(nvae); throw nvae; } } - static final String dfa_15s = "\26\uffff"; - static final String dfa_16s = "\1\uffff\1\15\7\uffff\1\15\4\uffff\1\15\2\uffff\4\15\1\uffff"; - static final String dfa_17s = "\1\5\1\4\7\uffff\1\4\1\0\1\uffff\1\5\1\uffff\1\4\1\0\1\uffff\4\4\1\uffff"; - static final String dfa_18s = "\1\62\1\47\7\uffff\1\47\1\0\1\uffff\1\47\1\uffff\1\47\1\0\1\uffff\4\47\1\uffff"; - static final String dfa_19s = "\2\uffff\7\1\2\uffff\1\1\1\uffff\1\3\2\uffff\1\2\4\uffff\1\1"; - static final String dfa_20s = "\1\4\10\uffff\1\1\1\0\1\uffff\1\2\2\uffff\1\3\4\uffff\1\5\1\uffff}>"; - static final String[] dfa_21s = { - "\1\11\1\14\4\15\1\1\2\15\1\12\1\13\1\15\26\uffff\1\15\4\uffff\1\2\1\3\1\4\1\5\1\6\1\7\1\10", - "\6\15\1\16\4\15\1\uffff\1\15\26\uffff\1\15", + static final String dfa_29s = "\31\uffff"; + static final String dfa_30s = "\1\uffff\10\14\4\uffff\1\14\13\uffff"; + static final String dfa_31s = "\1\5\10\4\3\0\1\uffff\1\5\13\uffff"; + static final String dfa_32s = "\11\70\3\0\1\uffff\1\70\13\uffff"; + static final String dfa_33s = "\14\uffff\1\2\1\uffff\13\1"; + static final String dfa_34s = "\11\uffff\1\0\1\2\1\3\1\uffff\1\1\13\uffff}>"; + static final String[] dfa_35s = { + "\1\10\1\13\15\14\1\12\1\11\1\14\22\uffff\2\14\2\uffff\2\14\1\uffff\2\14\1\1\1\2\1\3\1\4\1\5\1\6\1\7", + "\1\15\1\10\1\13\15\14\1\12\1\11\1\14\22\uffff\2\14\2\uffff\2\14\1\uffff\2\14\1\1\1\2\1\3\1\4\1\5\1\6\1\7", + "\1\15\1\10\1\13\15\14\1\12\1\11\1\14\22\uffff\2\14\2\uffff\2\14\1\uffff\2\14\1\1\1\2\1\3\1\4\1\5\1\6\1\7", + "\1\15\1\10\1\13\15\14\1\12\1\11\1\14\22\uffff\2\14\2\uffff\2\14\1\uffff\2\14\1\1\1\2\1\3\1\4\1\5\1\6\1\7", + "\1\15\1\10\1\13\15\14\1\12\1\11\1\14\22\uffff\2\14\2\uffff\2\14\1\uffff\2\14\1\1\1\2\1\3\1\4\1\5\1\6\1\7", + "\1\15\1\10\1\13\15\14\1\12\1\11\1\14\22\uffff\2\14\2\uffff\2\14\1\uffff\2\14\1\1\1\2\1\3\1\4\1\5\1\6\1\7", + "\1\15\1\10\1\13\15\14\1\12\1\11\1\14\22\uffff\2\14\2\uffff\2\14\1\uffff\2\14\1\1\1\2\1\3\1\4\1\5\1\6\1\7", + "\1\15\1\10\1\13\15\14\1\12\1\11\1\14\22\uffff\2\14\2\uffff\2\14\1\uffff\2\14\1\1\1\2\1\3\1\4\1\5\1\6\1\7", + "\2\14\1\13\15\14\1\12\1\11\1\14\22\uffff\2\14\2\uffff\2\14\1\uffff\11\14", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "", + "\1\17\1\21\15\uffff\1\20\1\16\34\uffff\1\22\1\23\1\24\1\25\1\26\1\27\1\30", "", "", "", @@ -7935,335 +10746,332 @@ public int specialStateTransition(int s, IntStream _input) throws NoViableAltExc "", "", "", - "\2\15\1\17\7\15\1\12\1\13\1\15\26\uffff\1\15", - "\1\uffff", "", - "\12\20\1\uffff\1\20\26\uffff\1\20", "", - "\10\15\1\21\2\15\1\uffff\1\15\26\uffff\1\15", - "\1\uffff", "", - "\1\15\1\22\11\15\1\uffff\1\15\26\uffff\1\15", - "\6\15\1\23\4\15\1\uffff\1\15\26\uffff\1\15", - "\11\15\1\24\1\15\1\uffff\1\15\26\uffff\1\15", - "\13\15\1\uffff\1\15\22\uffff\1\25\3\uffff\1\15", "" }; - static final short[] dfa_15 = DFA.unpackEncodedString(dfa_15s); - static final short[] dfa_16 = DFA.unpackEncodedString(dfa_16s); - static final char[] dfa_17 = DFA.unpackEncodedStringToUnsignedChars(dfa_17s); - static final char[] dfa_18 = DFA.unpackEncodedStringToUnsignedChars(dfa_18s); - static final short[] dfa_19 = DFA.unpackEncodedString(dfa_19s); - static final short[] dfa_20 = DFA.unpackEncodedString(dfa_20s); - static final short[][] dfa_21 = unpackEncodedStringArray(dfa_21s); + static final short[] dfa_29 = DFA.unpackEncodedString(dfa_29s); + static final short[] dfa_30 = DFA.unpackEncodedString(dfa_30s); + static final char[] dfa_31 = DFA.unpackEncodedStringToUnsignedChars(dfa_31s); + static final char[] dfa_32 = DFA.unpackEncodedStringToUnsignedChars(dfa_32s); + static final short[] dfa_33 = DFA.unpackEncodedString(dfa_33s); + static final short[] dfa_34 = DFA.unpackEncodedString(dfa_34s); + static final short[][] dfa_35 = unpackEncodedStringArray(dfa_35s); - class DFA7 extends DFA { + class DFA10 extends DFA { - public DFA7(BaseRecognizer recognizer) { + public DFA10(BaseRecognizer recognizer) { this.recognizer = recognizer; - this.decisionNumber = 7; - this.eot = dfa_15; - this.eof = dfa_16; - this.min = dfa_17; - this.max = dfa_18; - this.accept = dfa_19; - this.special = dfa_20; - this.transition = dfa_21; + this.decisionNumber = 10; + this.eot = dfa_29; + this.eof = dfa_30; + this.min = dfa_31; + this.max = dfa_32; + this.accept = dfa_33; + this.special = dfa_34; + this.transition = dfa_35; } public String getDescription() { - return "316:2: ( ( ( ruleURLSemver )=>this_URLSemver_0= ruleURLSemver ) | ( () ( (lv_commitISH_2_0= ruleALPHA_NUMERIC_CHARS_START_WITH_DIGITS ) ) ) | ( () ( (lv_commitISH_4_0= ruleALPHA_NUMERIC_CHARS ) ) ) )"; + return "491:3: ( ( ( ( ruleSimpleVersion ) )=> (lv_version_1_0= ruleSimpleVersion ) ) | ( (lv_otherVersion_2_0= ruleWORKSPACE_VERSION ) ) )"; } public int specialStateTransition(int s, IntStream _input) throws NoViableAltException { TokenStream input = (TokenStream)_input; int _s = s; switch ( s ) { case 0 : - int LA7_10 = input.LA(1); + int LA10_9 = input.LA(1); - int index7_10 = input.index(); + int index10_9 = input.index(); input.rewind(); s = -1; - if ( (synpred3_InternalSemver()) ) {s = 11;} + if ( (synpred5_InternalSemver()) ) {s = 14;} - else if ( (true) ) {s = 13;} + else if ( (true) ) {s = 12;} - input.seek(index7_10); + input.seek(index10_9); if ( s>=0 ) return s; break; case 1 : - int LA7_9 = input.LA(1); + int LA10_13 = input.LA(1); - int index7_9 = input.index(); + int index10_13 = input.index(); input.rewind(); s = -1; - if ( (LA7_9==RULE_LETTER_X) ) {s = 10;} + if ( (LA10_13==EOF) ) {s = 12;} - else if ( (LA7_9==RULE_ASTERIX) && (synpred3_InternalSemver())) {s = 11;} + else if ( (LA10_13==RULE_LETTER_V) && (synpred5_InternalSemver())) {s = 15;} - else if ( (LA7_9==RULE_DIGITS) ) {s = 15;} + else if ( (LA10_13==RULE_LETTER_X) && (synpred5_InternalSemver())) {s = 14;} - else if ( (LA7_9==EOF||(LA7_9>=RULE_WS && LA7_9<=RULE_LETTER_V)||(LA7_9>=RULE_LETTER_F && LA7_9<=RULE_LETTER_R)||LA7_9==RULE_LETTER_OTHER||LA7_9==39) ) {s = 13;} + else if ( (LA10_13==RULE_ASTERIX) && (synpred5_InternalSemver())) {s = 16;} - - input.seek(index7_9); - if ( s>=0 ) return s; - break; - case 2 : - int LA7_12 = input.LA(1); + else if ( (LA10_13==RULE_DIGITS) && (synpred5_InternalSemver())) {s = 17;} - - int index7_12 = input.index(); - input.rewind(); - s = -1; - if ( ((LA7_12>=RULE_LETTER_V && LA7_12<=RULE_LETTER_X)||LA7_12==RULE_LETTER_OTHER||LA7_12==39) ) {s = 16;} + else if ( (LA10_13==50) && (synpred5_InternalSemver())) {s = 18;} - else if ( (synpred3_InternalSemver()) ) {s = 11;} + else if ( (LA10_13==51) && (synpred5_InternalSemver())) {s = 19;} - else if ( (true) ) {s = 13;} + else if ( (LA10_13==52) && (synpred5_InternalSemver())) {s = 20;} - - input.seek(index7_12); - if ( s>=0 ) return s; - break; - case 3 : - int LA7_15 = input.LA(1); + else if ( (LA10_13==53) && (synpred5_InternalSemver())) {s = 21;} - - int index7_15 = input.index(); - input.rewind(); - s = -1; - if ( (synpred3_InternalSemver()) ) {s = 11;} + else if ( (LA10_13==54) && (synpred5_InternalSemver())) {s = 22;} - else if ( (true) ) {s = 13;} + else if ( (LA10_13==55) && (synpred5_InternalSemver())) {s = 23;} + + else if ( (LA10_13==56) && (synpred5_InternalSemver())) {s = 24;} - input.seek(index7_15); + input.seek(index10_13); if ( s>=0 ) return s; break; - case 4 : - int LA7_0 = input.LA(1); + case 2 : + int LA10_10 = input.LA(1); - int index7_0 = input.index(); + int index10_10 = input.index(); input.rewind(); s = -1; - if ( (LA7_0==RULE_LETTER_S) ) {s = 1;} - - else if ( (LA7_0==44) && (synpred3_InternalSemver())) {s = 2;} - - else if ( (LA7_0==45) && (synpred3_InternalSemver())) {s = 3;} - - else if ( (LA7_0==46) && (synpred3_InternalSemver())) {s = 4;} - - else if ( (LA7_0==47) && (synpred3_InternalSemver())) {s = 5;} + if ( (synpred5_InternalSemver()) ) {s = 14;} - else if ( (LA7_0==48) && (synpred3_InternalSemver())) {s = 6;} - - else if ( (LA7_0==49) && (synpred3_InternalSemver())) {s = 7;} - - else if ( (LA7_0==50) && (synpred3_InternalSemver())) {s = 8;} - - else if ( (LA7_0==RULE_LETTER_V) ) {s = 9;} - - else if ( (LA7_0==RULE_LETTER_X) ) {s = 10;} - - else if ( (LA7_0==RULE_ASTERIX) && (synpred3_InternalSemver())) {s = 11;} - - else if ( (LA7_0==RULE_DIGITS) ) {s = 12;} - - else if ( ((LA7_0>=RULE_LETTER_F && LA7_0<=RULE_LETTER_E)||(LA7_0>=RULE_LETTER_M && LA7_0<=RULE_LETTER_R)||LA7_0==RULE_LETTER_OTHER||LA7_0==39) ) {s = 13;} + else if ( (true) ) {s = 12;} - input.seek(index7_0); + input.seek(index10_10); if ( s>=0 ) return s; break; - case 5 : - int LA7_20 = input.LA(1); + case 3 : + int LA10_11 = input.LA(1); - int index7_20 = input.index(); + int index10_11 = input.index(); input.rewind(); s = -1; - if ( (LA7_20==EOF||(LA7_20>=RULE_WS && LA7_20<=RULE_LETTER_X)||LA7_20==RULE_LETTER_OTHER||LA7_20==39) ) {s = 13;} + if ( (synpred5_InternalSemver()) ) {s = 14;} - else if ( (LA7_20==35) && (synpred3_InternalSemver())) {s = 21;} + else if ( (true) ) {s = 12;} - input.seek(index7_20); + input.seek(index10_11); if ( s>=0 ) return s; break; } if (state.backtracking>0) {state.failed=true; return -1;} NoViableAltException nvae = - new NoViableAltException(getDescription(), 7, _s, input); + new NoViableAltException(getDescription(), 10, _s, input); error(nvae); throw nvae; } } - static final String dfa_22s = "\141\uffff"; - static final String dfa_23s = "\2\uffff\3\1\3\uffff\34\1\5\uffff\47\1\2\uffff\17\1"; - static final String dfa_24s = "\1\5\1\uffff\3\4\1\6\3\5\33\4\1\uffff\1\6\3\5\47\4\1\6\1\5\17\4"; - static final String dfa_25s = "\1\62\1\uffff\3\51\1\17\2\47\1\62\17\51\14\50\1\uffff\1\17\3\47\17\51\30\50\1\17\1\47\3\51\14\50"; - static final String dfa_26s = "\1\uffff\1\1\42\uffff\1\2\74\uffff"; - static final String dfa_27s = "\141\uffff}>"; - static final String[] dfa_28s = { - "\1\1\1\4\7\uffff\1\2\1\3\34\uffff\7\1", + static final String dfa_36s = "\u0085\uffff"; + static final String dfa_37s = "\2\uffff\3\1\3\uffff\50\1\5\uffff\71\1\2\uffff\25\1"; + static final String dfa_38s = "\1\5\1\uffff\3\4\1\6\3\5\47\4\1\uffff\1\6\3\5\71\4\1\6\1\5\25\4"; + static final String dfa_39s = "\1\70\1\uffff\3\57\1\25\2\55\1\70\25\57\22\56\1\uffff\1\25\3\55\25\57\44\56\1\25\1\55\3\57\22\56"; + static final String dfa_40s = "\1\uffff\1\1\56\uffff\1\2\124\uffff"; + static final String dfa_41s = "\u0085\uffff}>"; + static final String[] dfa_42s = { + "\1\1\1\4\15\uffff\1\3\1\2\34\uffff\7\1", "", - "\1\10\41\uffff\1\1\1\6\1\5\1\7", - "\1\10\41\uffff\1\1\1\6\1\5\1\7", - "\1\10\41\uffff\1\1\1\6\1\5\1\7", - "\1\13\7\uffff\1\11\1\12", - "\1\16\1\15\1\23\1\24\1\25\1\26\1\20\1\21\1\22\1\17\1\uffff\1\27\26\uffff\1\14", - "\1\32\1\31\1\37\1\40\1\41\1\42\1\34\1\35\1\36\1\33\1\uffff\1\43\26\uffff\1\30", - "\2\1\7\uffff\2\1\26\uffff\1\1\1\44\4\uffff\7\1", - "\1\10\41\uffff\1\1\1\6\1\45\1\7", - "\1\10\41\uffff\1\1\1\6\1\45\1\7", - "\1\10\41\uffff\1\1\1\6\1\45\1\7", - "\1\10\1\16\1\15\1\23\1\24\1\25\1\26\1\20\1\21\1\22\1\17\1\uffff\1\27\25\uffff\1\1\1\14\1\46\1\47", - "\1\10\1\16\1\15\1\23\1\24\1\25\1\26\1\20\1\21\1\22\1\17\1\uffff\1\27\25\uffff\1\1\1\14\1\46\1\47", - "\1\10\1\16\1\15\1\23\1\24\1\25\1\26\1\20\1\21\1\22\1\17\1\uffff\1\27\25\uffff\1\1\1\14\1\46\1\47", - "\1\10\1\16\1\15\1\23\1\24\1\25\1\26\1\20\1\21\1\22\1\17\1\uffff\1\27\25\uffff\1\1\1\14\1\46\1\47", - "\1\10\1\16\1\15\1\23\1\24\1\25\1\26\1\20\1\21\1\22\1\17\1\uffff\1\27\25\uffff\1\1\1\14\1\46\1\47", - "\1\10\1\16\1\15\1\23\1\24\1\25\1\26\1\20\1\21\1\22\1\17\1\uffff\1\27\25\uffff\1\1\1\14\1\46\1\47", - "\1\10\1\16\1\15\1\23\1\24\1\25\1\26\1\20\1\21\1\22\1\17\1\uffff\1\27\25\uffff\1\1\1\14\1\46\1\47", - "\1\10\1\16\1\15\1\23\1\24\1\25\1\26\1\20\1\21\1\22\1\17\1\uffff\1\27\25\uffff\1\1\1\14\1\46\1\47", - "\1\10\1\16\1\15\1\23\1\24\1\25\1\26\1\20\1\21\1\22\1\17\1\uffff\1\27\25\uffff\1\1\1\14\1\46\1\47", - "\1\10\1\16\1\15\1\23\1\24\1\25\1\26\1\20\1\21\1\22\1\17\1\uffff\1\27\25\uffff\1\1\1\14\1\46\1\47", - "\1\10\1\16\1\15\1\23\1\24\1\25\1\26\1\20\1\21\1\22\1\17\1\uffff\1\27\25\uffff\1\1\1\14\1\46\1\47", - "\1\10\1\16\1\15\1\23\1\24\1\25\1\26\1\20\1\21\1\22\1\17\1\uffff\1\27\25\uffff\1\1\1\14\1\46\1\47", - "\1\10\1\32\1\31\1\37\1\40\1\41\1\42\1\34\1\35\1\36\1\33\1\uffff\1\43\25\uffff\1\1\1\30\1\50", - "\1\10\1\32\1\31\1\37\1\40\1\41\1\42\1\34\1\35\1\36\1\33\1\uffff\1\43\25\uffff\1\1\1\30\1\50", - "\1\10\1\32\1\31\1\37\1\40\1\41\1\42\1\34\1\35\1\36\1\33\1\uffff\1\43\25\uffff\1\1\1\30\1\50", - "\1\10\1\32\1\31\1\37\1\40\1\41\1\42\1\34\1\35\1\36\1\33\1\uffff\1\43\25\uffff\1\1\1\30\1\50", - "\1\10\1\32\1\31\1\37\1\40\1\41\1\42\1\34\1\35\1\36\1\33\1\uffff\1\43\25\uffff\1\1\1\30\1\50", - "\1\10\1\32\1\31\1\37\1\40\1\41\1\42\1\34\1\35\1\36\1\33\1\uffff\1\43\25\uffff\1\1\1\30\1\50", - "\1\10\1\32\1\31\1\37\1\40\1\41\1\42\1\34\1\35\1\36\1\33\1\uffff\1\43\25\uffff\1\1\1\30\1\50", - "\1\10\1\32\1\31\1\37\1\40\1\41\1\42\1\34\1\35\1\36\1\33\1\uffff\1\43\25\uffff\1\1\1\30\1\50", - "\1\10\1\32\1\31\1\37\1\40\1\41\1\42\1\34\1\35\1\36\1\33\1\uffff\1\43\25\uffff\1\1\1\30\1\50", - "\1\10\1\32\1\31\1\37\1\40\1\41\1\42\1\34\1\35\1\36\1\33\1\uffff\1\43\25\uffff\1\1\1\30\1\50", - "\1\10\1\32\1\31\1\37\1\40\1\41\1\42\1\34\1\35\1\36\1\33\1\uffff\1\43\25\uffff\1\1\1\30\1\50", - "\1\10\1\32\1\31\1\37\1\40\1\41\1\42\1\34\1\35\1\36\1\33\1\uffff\1\43\25\uffff\1\1\1\30\1\50", + "\1\10\47\uffff\1\1\1\6\1\5\1\7", + "\1\10\47\uffff\1\1\1\6\1\5\1\7", + "\1\10\47\uffff\1\1\1\6\1\5\1\7", + "\1\13\15\uffff\1\12\1\11", + "\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\26\uffff\1\14", + "\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\26\uffff\1\36", + "\2\1\15\uffff\2\1\26\uffff\1\1\1\60\4\uffff\7\1", + "\1\10\47\uffff\1\1\1\6\1\61\1\7", + "\1\10\47\uffff\1\1\1\6\1\61\1\7", + "\1\10\47\uffff\1\1\1\6\1\61\1\7", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\16\1\15\1\23\1\24\1\26\1\22\1\33\1\27\1\32\1\34\1\30\1\25\1\31\1\20\1\21\1\uffff\1\17\1\35\25\uffff\1\1\1\14\1\62\1\63", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", + "\1\10\1\40\1\37\1\45\1\46\1\50\1\44\1\55\1\51\1\54\1\56\1\52\1\47\1\53\1\42\1\43\1\uffff\1\41\1\57\25\uffff\1\1\1\36\1\64", "", - "\1\53\7\uffff\1\51\1\52", - "\1\56\1\55\1\63\1\64\1\65\1\66\1\60\1\61\1\62\1\57\1\uffff\1\67\26\uffff\1\54", - "\1\72\1\71\1\77\1\100\1\101\1\102\1\74\1\75\1\76\1\73\1\uffff\1\103\26\uffff\1\70", - "\1\106\1\105\1\113\1\114\1\115\1\116\1\110\1\111\1\112\1\107\1\uffff\1\117\26\uffff\1\104", - "\1\10\41\uffff\1\1\1\6\1\120\1\7", - "\1\10\41\uffff\1\1\1\6\1\120\1\7", - "\1\10\41\uffff\1\1\1\6\1\120\1\7", - "\1\10\1\56\1\55\1\63\1\64\1\65\1\66\1\60\1\61\1\62\1\57\1\uffff\1\67\25\uffff\1\1\1\54\1\46\1\47", - "\1\10\1\56\1\55\1\63\1\64\1\65\1\66\1\60\1\61\1\62\1\57\1\uffff\1\67\25\uffff\1\1\1\54\1\46\1\47", - "\1\10\1\56\1\55\1\63\1\64\1\65\1\66\1\60\1\61\1\62\1\57\1\uffff\1\67\25\uffff\1\1\1\54\1\46\1\47", - "\1\10\1\56\1\55\1\63\1\64\1\65\1\66\1\60\1\61\1\62\1\57\1\uffff\1\67\25\uffff\1\1\1\54\1\46\1\47", - "\1\10\1\56\1\55\1\63\1\64\1\65\1\66\1\60\1\61\1\62\1\57\1\uffff\1\67\25\uffff\1\1\1\54\1\46\1\47", - "\1\10\1\56\1\55\1\63\1\64\1\65\1\66\1\60\1\61\1\62\1\57\1\uffff\1\67\25\uffff\1\1\1\54\1\46\1\47", - "\1\10\1\56\1\55\1\63\1\64\1\65\1\66\1\60\1\61\1\62\1\57\1\uffff\1\67\25\uffff\1\1\1\54\1\46\1\47", - "\1\10\1\56\1\55\1\63\1\64\1\65\1\66\1\60\1\61\1\62\1\57\1\uffff\1\67\25\uffff\1\1\1\54\1\46\1\47", - "\1\10\1\56\1\55\1\63\1\64\1\65\1\66\1\60\1\61\1\62\1\57\1\uffff\1\67\25\uffff\1\1\1\54\1\46\1\47", - "\1\10\1\56\1\55\1\63\1\64\1\65\1\66\1\60\1\61\1\62\1\57\1\uffff\1\67\25\uffff\1\1\1\54\1\46\1\47", - "\1\10\1\56\1\55\1\63\1\64\1\65\1\66\1\60\1\61\1\62\1\57\1\uffff\1\67\25\uffff\1\1\1\54\1\46\1\47", - "\1\10\1\56\1\55\1\63\1\64\1\65\1\66\1\60\1\61\1\62\1\57\1\uffff\1\67\25\uffff\1\1\1\54\1\46\1\47", - "\1\10\1\72\1\71\1\77\1\100\1\101\1\102\1\74\1\75\1\76\1\73\1\uffff\1\103\25\uffff\1\1\1\70\1\121", - "\1\10\1\72\1\71\1\77\1\100\1\101\1\102\1\74\1\75\1\76\1\73\1\uffff\1\103\25\uffff\1\1\1\70\1\121", - "\1\10\1\72\1\71\1\77\1\100\1\101\1\102\1\74\1\75\1\76\1\73\1\uffff\1\103\25\uffff\1\1\1\70\1\121", - "\1\10\1\72\1\71\1\77\1\100\1\101\1\102\1\74\1\75\1\76\1\73\1\uffff\1\103\25\uffff\1\1\1\70\1\121", - "\1\10\1\72\1\71\1\77\1\100\1\101\1\102\1\74\1\75\1\76\1\73\1\uffff\1\103\25\uffff\1\1\1\70\1\121", - "\1\10\1\72\1\71\1\77\1\100\1\101\1\102\1\74\1\75\1\76\1\73\1\uffff\1\103\25\uffff\1\1\1\70\1\121", - "\1\10\1\72\1\71\1\77\1\100\1\101\1\102\1\74\1\75\1\76\1\73\1\uffff\1\103\25\uffff\1\1\1\70\1\121", - "\1\10\1\72\1\71\1\77\1\100\1\101\1\102\1\74\1\75\1\76\1\73\1\uffff\1\103\25\uffff\1\1\1\70\1\121", - "\1\10\1\72\1\71\1\77\1\100\1\101\1\102\1\74\1\75\1\76\1\73\1\uffff\1\103\25\uffff\1\1\1\70\1\121", - "\1\10\1\72\1\71\1\77\1\100\1\101\1\102\1\74\1\75\1\76\1\73\1\uffff\1\103\25\uffff\1\1\1\70\1\121", - "\1\10\1\72\1\71\1\77\1\100\1\101\1\102\1\74\1\75\1\76\1\73\1\uffff\1\103\25\uffff\1\1\1\70\1\121", - "\1\10\1\72\1\71\1\77\1\100\1\101\1\102\1\74\1\75\1\76\1\73\1\uffff\1\103\25\uffff\1\1\1\70\1\121", - "\1\10\1\106\1\105\1\113\1\114\1\115\1\116\1\110\1\111\1\112\1\107\1\uffff\1\117\25\uffff\1\1\1\104\1\50", - "\1\10\1\106\1\105\1\113\1\114\1\115\1\116\1\110\1\111\1\112\1\107\1\uffff\1\117\25\uffff\1\1\1\104\1\50", - "\1\10\1\106\1\105\1\113\1\114\1\115\1\116\1\110\1\111\1\112\1\107\1\uffff\1\117\25\uffff\1\1\1\104\1\50", - "\1\10\1\106\1\105\1\113\1\114\1\115\1\116\1\110\1\111\1\112\1\107\1\uffff\1\117\25\uffff\1\1\1\104\1\50", - "\1\10\1\106\1\105\1\113\1\114\1\115\1\116\1\110\1\111\1\112\1\107\1\uffff\1\117\25\uffff\1\1\1\104\1\50", - "\1\10\1\106\1\105\1\113\1\114\1\115\1\116\1\110\1\111\1\112\1\107\1\uffff\1\117\25\uffff\1\1\1\104\1\50", - "\1\10\1\106\1\105\1\113\1\114\1\115\1\116\1\110\1\111\1\112\1\107\1\uffff\1\117\25\uffff\1\1\1\104\1\50", - "\1\10\1\106\1\105\1\113\1\114\1\115\1\116\1\110\1\111\1\112\1\107\1\uffff\1\117\25\uffff\1\1\1\104\1\50", - "\1\10\1\106\1\105\1\113\1\114\1\115\1\116\1\110\1\111\1\112\1\107\1\uffff\1\117\25\uffff\1\1\1\104\1\50", - "\1\10\1\106\1\105\1\113\1\114\1\115\1\116\1\110\1\111\1\112\1\107\1\uffff\1\117\25\uffff\1\1\1\104\1\50", - "\1\10\1\106\1\105\1\113\1\114\1\115\1\116\1\110\1\111\1\112\1\107\1\uffff\1\117\25\uffff\1\1\1\104\1\50", - "\1\10\1\106\1\105\1\113\1\114\1\115\1\116\1\110\1\111\1\112\1\107\1\uffff\1\117\25\uffff\1\1\1\104\1\50", - "\1\124\7\uffff\1\122\1\123", - "\1\127\1\126\1\134\1\135\1\136\1\137\1\131\1\132\1\133\1\130\1\uffff\1\140\26\uffff\1\125", - "\1\10\41\uffff\1\1\1\6\1\120\1\7", - "\1\10\41\uffff\1\1\1\6\1\120\1\7", - "\1\10\41\uffff\1\1\1\6\1\120\1\7", - "\1\10\1\127\1\126\1\134\1\135\1\136\1\137\1\131\1\132\1\133\1\130\1\uffff\1\140\25\uffff\1\1\1\125\1\121", - "\1\10\1\127\1\126\1\134\1\135\1\136\1\137\1\131\1\132\1\133\1\130\1\uffff\1\140\25\uffff\1\1\1\125\1\121", - "\1\10\1\127\1\126\1\134\1\135\1\136\1\137\1\131\1\132\1\133\1\130\1\uffff\1\140\25\uffff\1\1\1\125\1\121", - "\1\10\1\127\1\126\1\134\1\135\1\136\1\137\1\131\1\132\1\133\1\130\1\uffff\1\140\25\uffff\1\1\1\125\1\121", - "\1\10\1\127\1\126\1\134\1\135\1\136\1\137\1\131\1\132\1\133\1\130\1\uffff\1\140\25\uffff\1\1\1\125\1\121", - "\1\10\1\127\1\126\1\134\1\135\1\136\1\137\1\131\1\132\1\133\1\130\1\uffff\1\140\25\uffff\1\1\1\125\1\121", - "\1\10\1\127\1\126\1\134\1\135\1\136\1\137\1\131\1\132\1\133\1\130\1\uffff\1\140\25\uffff\1\1\1\125\1\121", - "\1\10\1\127\1\126\1\134\1\135\1\136\1\137\1\131\1\132\1\133\1\130\1\uffff\1\140\25\uffff\1\1\1\125\1\121", - "\1\10\1\127\1\126\1\134\1\135\1\136\1\137\1\131\1\132\1\133\1\130\1\uffff\1\140\25\uffff\1\1\1\125\1\121", - "\1\10\1\127\1\126\1\134\1\135\1\136\1\137\1\131\1\132\1\133\1\130\1\uffff\1\140\25\uffff\1\1\1\125\1\121", - "\1\10\1\127\1\126\1\134\1\135\1\136\1\137\1\131\1\132\1\133\1\130\1\uffff\1\140\25\uffff\1\1\1\125\1\121", - "\1\10\1\127\1\126\1\134\1\135\1\136\1\137\1\131\1\132\1\133\1\130\1\uffff\1\140\25\uffff\1\1\1\125\1\121" + "\1\67\15\uffff\1\66\1\65", + "\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\26\uffff\1\70", + "\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\26\uffff\1\112", + "\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\26\uffff\1\134", + "\1\10\47\uffff\1\1\1\6\1\156\1\7", + "\1\10\47\uffff\1\1\1\6\1\156\1\7", + "\1\10\47\uffff\1\1\1\6\1\156\1\7", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\72\1\71\1\77\1\100\1\102\1\76\1\107\1\103\1\106\1\110\1\104\1\101\1\105\1\74\1\75\1\uffff\1\73\1\111\25\uffff\1\1\1\70\1\62\1\63", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\114\1\113\1\121\1\122\1\124\1\120\1\131\1\125\1\130\1\132\1\126\1\123\1\127\1\116\1\117\1\uffff\1\115\1\133\25\uffff\1\1\1\112\1\157", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\10\1\136\1\135\1\143\1\144\1\146\1\142\1\153\1\147\1\152\1\154\1\150\1\145\1\151\1\140\1\141\1\uffff\1\137\1\155\25\uffff\1\1\1\134\1\64", + "\1\162\15\uffff\1\161\1\160", + "\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\26\uffff\1\163", + "\1\10\47\uffff\1\1\1\6\1\156\1\7", + "\1\10\47\uffff\1\1\1\6\1\156\1\7", + "\1\10\47\uffff\1\1\1\6\1\156\1\7", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157", + "\1\10\1\165\1\164\1\172\1\173\1\175\1\171\1\u0082\1\176\1\u0081\1\u0083\1\177\1\174\1\u0080\1\167\1\170\1\uffff\1\166\1\u0084\25\uffff\1\1\1\163\1\157" }; - static final short[] dfa_22 = DFA.unpackEncodedString(dfa_22s); - static final short[] dfa_23 = DFA.unpackEncodedString(dfa_23s); - static final char[] dfa_24 = DFA.unpackEncodedStringToUnsignedChars(dfa_24s); - static final char[] dfa_25 = DFA.unpackEncodedStringToUnsignedChars(dfa_25s); - static final short[] dfa_26 = DFA.unpackEncodedString(dfa_26s); - static final short[] dfa_27 = DFA.unpackEncodedString(dfa_27s); - static final short[][] dfa_28 = unpackEncodedStringArray(dfa_28s); + static final short[] dfa_36 = DFA.unpackEncodedString(dfa_36s); + static final short[] dfa_37 = DFA.unpackEncodedString(dfa_37s); + static final char[] dfa_38 = DFA.unpackEncodedStringToUnsignedChars(dfa_38s); + static final char[] dfa_39 = DFA.unpackEncodedStringToUnsignedChars(dfa_39s); + static final short[] dfa_40 = DFA.unpackEncodedString(dfa_40s); + static final short[] dfa_41 = DFA.unpackEncodedString(dfa_41s); + static final short[][] dfa_42 = unpackEncodedStringArray(dfa_42s); - class DFA15 extends DFA { + class DFA17 extends DFA { - public DFA15(BaseRecognizer recognizer) { + public DFA17(BaseRecognizer recognizer) { this.recognizer = recognizer; - this.decisionNumber = 15; - this.eot = dfa_22; - this.eof = dfa_23; - this.min = dfa_24; - this.max = dfa_25; - this.accept = dfa_26; - this.special = dfa_27; - this.transition = dfa_28; + this.decisionNumber = 17; + this.eot = dfa_36; + this.eof = dfa_37; + this.min = dfa_38; + this.max = dfa_39; + this.accept = dfa_40; + this.special = dfa_41; + this.transition = dfa_42; } public String getDescription() { - return "658:2: (this_VersionRangeContraint_0= ruleVersionRangeContraint | this_HyphenVersionRange_1= ruleHyphenVersionRange )"; + return "743:2: (this_VersionRangeContraint_0= ruleVersionRangeContraint | this_HyphenVersionRange_1= ruleHyphenVersionRange )"; } } public static final BitSet FOLLOW_1 = new BitSet(new long[]{0x0000000000000000L}); public static final BitSet FOLLOW_2 = new BitSet(new long[]{0x0000000000000002L}); - public static final BitSet FOLLOW_3 = new BitSet(new long[]{0x0007F0000000C060L}); + public static final BitSet FOLLOW_3 = new BitSet(new long[]{0x01FC000000300060L}); public static final BitSet FOLLOW_4 = new BitSet(new long[]{0x0000000000000012L}); - public static final BitSet FOLLOW_5 = new BitSet(new long[]{0x00000D9000017FE0L}); - public static final BitSet FOLLOW_6 = new BitSet(new long[]{0x0000000800000000L}); - public static final BitSet FOLLOW_7 = new BitSet(new long[]{0x0000001000000000L}); - public static final BitSet FOLLOW_8 = new BitSet(new long[]{0x00000D9800017FE0L}); - public static final BitSet FOLLOW_9 = new BitSet(new long[]{0x0000002000000002L}); - public static final BitSet FOLLOW_10 = new BitSet(new long[]{0x0007FD900001FFE0L}); - public static final BitSet FOLLOW_11 = new BitSet(new long[]{0x0000004000000012L}); - public static final BitSet FOLLOW_12 = new BitSet(new long[]{0x0000004000000000L}); - public static final BitSet FOLLOW_13 = new BitSet(new long[]{0x0007F0000000C070L}); - public static final BitSet FOLLOW_14 = new BitSet(new long[]{0x0000000000000010L}); - public static final BitSet FOLLOW_15 = new BitSet(new long[]{0x0000008000000000L}); - public static final BitSet FOLLOW_16 = new BitSet(new long[]{0x0000038000000002L}); - public static final BitSet FOLLOW_17 = new BitSet(new long[]{0x0000020000000002L}); - public static final BitSet FOLLOW_18 = new BitSet(new long[]{0x0000010000000002L}); - public static final BitSet FOLLOW_19 = new BitSet(new long[]{0x0000000000000100L}); - public static final BitSet FOLLOW_20 = new BitSet(new long[]{0x0000000000000200L}); - public static final BitSet FOLLOW_21 = new BitSet(new long[]{0x0000000000000400L}); - public static final BitSet FOLLOW_22 = new BitSet(new long[]{0x0000000000001000L}); - public static final BitSet FOLLOW_23 = new BitSet(new long[]{0x0000000000000020L}); - public static final BitSet FOLLOW_24 = new BitSet(new long[]{0x0000000000002000L}); - public static final BitSet FOLLOW_25 = new BitSet(new long[]{0x00000D9000017FE2L}); - public static final BitSet FOLLOW_26 = new BitSet(new long[]{0x00000F9000017FE0L}); - public static final BitSet FOLLOW_27 = new BitSet(new long[]{0x00000F9000017FE2L}); - public static final BitSet FOLLOW_28 = new BitSet(new long[]{0x00000D9800017FE2L}); + public static final BitSet FOLLOW_5 = new BitSet(new long[]{0x00036400006FFFE0L}); + public static final BitSet FOLLOW_6 = new BitSet(new long[]{0x0000020000000000L}); + public static final BitSet FOLLOW_7 = new BitSet(new long[]{0x0000040000000000L}); + public static final BitSet FOLLOW_8 = new BitSet(new long[]{0x00036600006FFFE0L}); + public static final BitSet FOLLOW_9 = new BitSet(new long[]{0x0000080000000002L}); + public static final BitSet FOLLOW_10 = new BitSet(new long[]{0x01FF6400007FFFE0L}); + public static final BitSet FOLLOW_11 = new BitSet(new long[]{0x01FF6600007FFFE0L}); + public static final BitSet FOLLOW_12 = new BitSet(new long[]{0x0000100000000012L}); + public static final BitSet FOLLOW_13 = new BitSet(new long[]{0x0000100000000000L}); + public static final BitSet FOLLOW_14 = new BitSet(new long[]{0x01FC000000300070L}); + public static final BitSet FOLLOW_15 = new BitSet(new long[]{0x0000000000000010L}); + public static final BitSet FOLLOW_16 = new BitSet(new long[]{0x0000200000000000L}); + public static final BitSet FOLLOW_17 = new BitSet(new long[]{0x0000E00000000002L}); + public static final BitSet FOLLOW_18 = new BitSet(new long[]{0x0000800000000002L}); + public static final BitSet FOLLOW_19 = new BitSet(new long[]{0x0000400000000002L}); + public static final BitSet FOLLOW_20 = new BitSet(new long[]{0x0000000000000100L}); + public static final BitSet FOLLOW_21 = new BitSet(new long[]{0x0000000000000200L}); + public static final BitSet FOLLOW_22 = new BitSet(new long[]{0x0000000000000400L}); + public static final BitSet FOLLOW_23 = new BitSet(new long[]{0x0000000000001000L}); + public static final BitSet FOLLOW_24 = new BitSet(new long[]{0x0000000000000020L}); + public static final BitSet FOLLOW_25 = new BitSet(new long[]{0x0000000000002000L}); + public static final BitSet FOLLOW_26 = new BitSet(new long[]{0x0000000000008000L}); + public static final BitSet FOLLOW_27 = new BitSet(new long[]{0x0000000000010000L}); + public static final BitSet FOLLOW_28 = new BitSet(new long[]{0x0000000000000800L}); + public static final BitSet FOLLOW_29 = new BitSet(new long[]{0x0000000000020000L}); + public static final BitSet FOLLOW_30 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_31 = new BitSet(new long[]{0x0000000000080000L}); + public static final BitSet FOLLOW_32 = new BitSet(new long[]{0x00036400006FFFE2L}); + public static final BitSet FOLLOW_33 = new BitSet(new long[]{0x0003E400006FFFE0L}); + public static final BitSet FOLLOW_34 = new BitSet(new long[]{0x0003E400006FFFE2L}); + public static final BitSet FOLLOW_35 = new BitSet(new long[]{0x00036600006FFFE2L}); + public static final BitSet FOLLOW_36 = new BitSet(new long[]{0x01FF6600007FFFE2L}); } \ No newline at end of file diff --git a/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/serializer/SemverSemanticSequencer.java b/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/serializer/SemverSemanticSequencer.java index b7d41cebed..882eb5af7e 100644 --- a/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/serializer/SemverSemanticSequencer.java +++ b/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/serializer/SemverSemanticSequencer.java @@ -29,6 +29,7 @@ import org.eclipse.n4js.semver.Semver.VersionPart; import org.eclipse.n4js.semver.Semver.VersionRangeConstraint; import org.eclipse.n4js.semver.Semver.VersionRangeSetRequirement; +import org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement; import org.eclipse.n4js.semver.services.SemverGrammarAccess; import org.eclipse.xtext.Action; import org.eclipse.xtext.Parameter; @@ -94,18 +95,23 @@ public void sequence(ISerializationContext context, EObject semanticObject) { case SemverPackage.VERSION_RANGE_SET_REQUIREMENT: sequence_VersionRangeSetRequirement(context, (VersionRangeSetRequirement) semanticObject); return; + case SemverPackage.WORKSPACE_VERSION_REQUIREMENT: + sequence_WorkspaceVersionRequirement(context, (WorkspaceVersionRequirement) semanticObject); + return; } if (errorAcceptor != null) errorAcceptor.accept(diagnosticProvider.createInvalidContextOrTypeDiagnostic(semanticObject, context)); } /** + *
 	 * Contexts:
 	 *     NPMVersionRequirement returns GitHubVersionRequirement
 	 *     GitHubVersionRequirement returns GitHubVersionRequirement
 	 *
 	 * Constraint:
 	 *     (githubUrl=URL_NO_VX commitISH=ALPHA_NUMERIC_CHARS?)
+	 * 
*/ protected void sequence_GitHubVersionRequirement(ISerializationContext context, GitHubVersionRequirement semanticObject) { genericSequencer.createSequence(context, semanticObject); @@ -113,12 +119,14 @@ protected void sequence_GitHubVersionRequirement(ISerializationContext context, /** + *
 	 * Contexts:
 	 *     VersionRange returns HyphenVersionRange
 	 *     HyphenVersionRange returns HyphenVersionRange
 	 *
 	 * Constraint:
 	 *     (from=VersionNumber to=VersionNumber)
+	 * 
*/ protected void sequence_HyphenVersionRange(ISerializationContext context, HyphenVersionRange semanticObject) { if (errorAcceptor != null) { @@ -135,12 +143,14 @@ protected void sequence_HyphenVersionRange(ISerializationContext context, Hyphen /** + *
 	 * Contexts:
 	 *     NPMVersionRequirement returns LocalPathVersionRequirement
 	 *     LocalPathVersionRequirement returns LocalPathVersionRequirement
 	 *
 	 * Constraint:
 	 *     localPath=PATH
+	 * 
*/ protected void sequence_LocalPathVersionRequirement(ISerializationContext context, LocalPathVersionRequirement semanticObject) { if (errorAcceptor != null) { @@ -154,11 +164,13 @@ protected void sequence_LocalPathVersionRequirement(ISerializationContext contex /** + *
 	 * Contexts:
 	 *     QualifierTag returns QualifierTag
 	 *
 	 * Constraint:
 	 *     (parts+=ALPHA_NUMERIC_CHARS parts+=ALPHA_NUMERIC_CHARS*)
+	 * 
*/ protected void sequence_QualifierTag(ISerializationContext context, QualifierTag semanticObject) { genericSequencer.createSequence(context, semanticObject); @@ -166,11 +178,13 @@ protected void sequence_QualifierTag(ISerializationContext context, QualifierTag /** + *
 	 * Contexts:
 	 *     Qualifier returns Qualifier
 	 *
 	 * Constraint:
 	 *     ((preRelease=QualifierTag buildMetadata=QualifierTag?) | buildMetadata=QualifierTag)
+	 * 
*/ protected void sequence_Qualifier(ISerializationContext context, Qualifier semanticObject) { genericSequencer.createSequence(context, semanticObject); @@ -178,11 +192,13 @@ protected void sequence_Qualifier(ISerializationContext context, Qualifier seman /** + *
 	 * Contexts:
 	 *     SimpleVersion returns SimpleVersion
 	 *
 	 * Constraint:
 	 *     (comparators+=VersionComparator* withLetterV?=LETTER_V? number=VersionNumber)
+	 * 
*/ protected void sequence_SimpleVersion(ISerializationContext context, SimpleVersion semanticObject) { genericSequencer.createSequence(context, semanticObject); @@ -190,12 +206,14 @@ protected void sequence_SimpleVersion(ISerializationContext context, SimpleVersi /** + *
 	 * Contexts:
 	 *     NPMVersionRequirement returns TagVersionRequirement
 	 *     TagVersionRequirement returns TagVersionRequirement
 	 *
 	 * Constraint:
 	 *     tagName=TAG
+	 * 
*/ protected void sequence_TagVersionRequirement(ISerializationContext context, TagVersionRequirement semanticObject) { if (errorAcceptor != null) { @@ -209,12 +227,14 @@ protected void sequence_TagVersionRequirement(ISerializationContext context, Tag /** + *
 	 * Contexts:
 	 *     URLVersionSpecifier returns URLSemver
 	 *     URLSemver returns URLSemver
 	 *
 	 * Constraint:
 	 *     (withSemverTag?=SEMVER_TAG? simpleVersion=SimpleVersion)
+	 * 
*/ protected void sequence_URLSemver(ISerializationContext context, URLSemver semanticObject) { genericSequencer.createSequence(context, semanticObject); @@ -222,12 +242,14 @@ protected void sequence_URLSemver(ISerializationContext context, URLSemver seman /** + *
 	 * Contexts:
 	 *     NPMVersionRequirement returns URLVersionRequirement
 	 *     URLVersionRequirement returns URLVersionRequirement
 	 *
 	 * Constraint:
 	 *     (protocol=URL_PROTOCOL url=URL versionSpecifier=URLVersionSpecifier?)
+	 * 
*/ protected void sequence_URLVersionRequirement(ISerializationContext context, URLVersionRequirement semanticObject) { genericSequencer.createSequence(context, semanticObject); @@ -235,11 +257,13 @@ protected void sequence_URLVersionRequirement(ISerializationContext context, URL /** + *
 	 * Contexts:
 	 *     URLVersionSpecifier returns URLCommitISH
 	 *
 	 * Constraint:
 	 *     (commitISH=ALPHA_NUMERIC_CHARS_START_WITH_DIGITS | commitISH=ALPHA_NUMERIC_CHARS)
+	 * 
*/ protected void sequence_URLVersionSpecifier(ISerializationContext context, URLCommitISH semanticObject) { genericSequencer.createSequence(context, semanticObject); @@ -247,11 +271,13 @@ protected void sequence_URLVersionSpecifier(ISerializationContext context, URLCo /** + *
 	 * Contexts:
 	 *     VersionNumber returns VersionNumber
 	 *
 	 * Constraint:
 	 *     (major=VersionPart (minor=VersionPart (patch=VersionPart extended+=VersionPart*)?)? qualifier=Qualifier?)
+	 * 
*/ protected void sequence_VersionNumber(ISerializationContext context, VersionNumber semanticObject) { genericSequencer.createSequence(context, semanticObject); @@ -259,11 +285,13 @@ protected void sequence_VersionNumber(ISerializationContext context, VersionNumb /** + *
 	 * Contexts:
 	 *     VersionPart returns VersionPart
 	 *
 	 * Constraint:
 	 *     (wildcard?=WILDCARD | numberRaw=DIGITS)
+	 * 
*/ protected void sequence_VersionPart(ISerializationContext context, VersionPart semanticObject) { genericSequencer.createSequence(context, semanticObject); @@ -271,12 +299,14 @@ protected void sequence_VersionPart(ISerializationContext context, VersionPart s /** + *
 	 * Contexts:
 	 *     VersionRange returns VersionRangeConstraint
 	 *     VersionRangeContraint returns VersionRangeConstraint
 	 *
 	 * Constraint:
 	 *     (versionConstraints+=SimpleVersion versionConstraints+=SimpleVersion*)
+	 * 
*/ protected void sequence_VersionRangeContraint(ISerializationContext context, VersionRangeConstraint semanticObject) { genericSequencer.createSequence(context, semanticObject); @@ -284,16 +314,33 @@ protected void sequence_VersionRangeContraint(ISerializationContext context, Ver /** + *
 	 * Contexts:
 	 *     NPMVersionRequirement returns VersionRangeSetRequirement
 	 *     VersionRangeSetRequirement returns VersionRangeSetRequirement
 	 *
 	 * Constraint:
 	 *     (ranges+=VersionRange ranges+=VersionRange*)?
+	 * 
*/ protected void sequence_VersionRangeSetRequirement(ISerializationContext context, VersionRangeSetRequirement semanticObject) { genericSequencer.createSequence(context, semanticObject); } + /** + *
+	 * Contexts:
+	 *     NPMVersionRequirement returns WorkspaceVersionRequirement
+	 *     WorkspaceVersionRequirement returns WorkspaceVersionRequirement
+	 *
+	 * Constraint:
+	 *     (version=SimpleVersion | otherVersion=WORKSPACE_VERSION)
+	 * 
+ */ + protected void sequence_WorkspaceVersionRequirement(ISerializationContext context, WorkspaceVersionRequirement semanticObject) { + genericSequencer.createSequence(context, semanticObject); + } + + } diff --git a/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/serializer/SemverSyntacticSequencer.java b/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/serializer/SemverSyntacticSequencer.java index 921c1755e3..1bd9efb0e6 100644 --- a/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/serializer/SemverSyntacticSequencer.java +++ b/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/serializer/SemverSyntacticSequencer.java @@ -55,6 +55,8 @@ else if (ruleCall.getRule() == grammarAccess.getSEMVER_TAGRule()) return getSEMVER_TAGToken(semanticObject, ruleCall, node); else if (ruleCall.getRule() == grammarAccess.getWILDCARDRule()) return getWILDCARDToken(semanticObject, ruleCall, node); + else if (ruleCall.getRule() == grammarAccess.getWORKSPACE_TAGRule()) + return getWORKSPACE_TAGToken(semanticObject, ruleCall, node); else if (ruleCall.getRule() == grammarAccess.getWSRule()) return getWSToken(semanticObject, ruleCall, node); return ""; @@ -104,6 +106,17 @@ protected String getWILDCARDToken(EObject semanticObject, RuleCall ruleCall, INo return "x"; } + /** + * WORKSPACE_TAG: + * LETTER_W LETTER_O LETTER_R LETTER_K LETTER_S LETTER_P LETTER_A LETTER_C LETTER_E ':' + * ; + */ + protected String getWORKSPACE_TAGToken(EObject semanticObject, RuleCall ruleCall, INode node) { + if (node != null) + return getTokenText(node); + return "w o r k s p a c e :"; + } + /** * terminal WS: * WHITESPACE_FRAGMENT+; @@ -137,18 +150,22 @@ else if (match_VersionRangeSetRequirement_WSTerminalRuleCall_1_2_q.equals(syntax } /** + *
 	 * Ambiguous syntax:
 	 *     WS?
 	 *
 	 * This ambiguous syntax occurs at:
 	 *     (rule start) (ambiguity) (rule start)
 	 *     (rule start) (ambiguity) ranges+=VersionRange
+	 
+	 * 
*/ protected void emit_NPMVersionRequirement_WSTerminalRuleCall_0_0_q(EObject semanticObject, ISynNavigable transition, List nodes) { acceptNodes(transition, nodes); } /** + *
 	 * Ambiguous syntax:
 	 *     WS?
 	 *
@@ -156,15 +173,20 @@ protected void emit_NPMVersionRequirement_WSTerminalRuleCall_0_0_q(EObject seman
 	 *     commitISH=ALPHA_NUMERIC_CHARS (ambiguity) (rule end)
 	 *     githubUrl=URL_NO_VX (ambiguity) (rule end)
 	 *     localPath=PATH (ambiguity) (rule end)
+	 *     otherVersion=WORKSPACE_VERSION (ambiguity) (rule end)
 	 *     tagName=TAG (ambiguity) (rule end)
 	 *     url=URL (ambiguity) (rule end)
+	 *     version=SimpleVersion (ambiguity) (rule end)
 	 *     versionSpecifier=URLVersionSpecifier (ambiguity) (rule end)
+	 
+	 * 
*/ protected void emit_NPMVersionRequirement_WSTerminalRuleCall_1_1_q(EObject semanticObject, ISynNavigable transition, List nodes) { acceptNodes(transition, nodes); } /** + *
 	 * Ambiguous syntax:
 	 *     WS?
 	 *
@@ -172,39 +194,50 @@ protected void emit_NPMVersionRequirement_WSTerminalRuleCall_1_1_q(EObject seman
 	 *     comparators+=VersionComparator (ambiguity) comparators+=VersionComparator
 	 *     comparators+=VersionComparator (ambiguity) number=VersionNumber
 	 *     comparators+=VersionComparator (ambiguity) withLetterV?=LETTER_V
+	 
+	 * 
*/ protected void emit_SimpleVersion_WSTerminalRuleCall_0_1_q(EObject semanticObject, ISynNavigable transition, List nodes) { acceptNodes(transition, nodes); } /** + *
 	 * Ambiguous syntax:
 	 *     WS?
 	 *
 	 * This ambiguous syntax occurs at:
 	 *     ranges+=VersionRange (ambiguity) '||' WS? ranges+=VersionRange
+	 
+	 * 
*/ protected void emit_VersionRangeSetRequirement_WSTerminalRuleCall_1_1_0_q(EObject semanticObject, ISynNavigable transition, List nodes) { acceptNodes(transition, nodes); } /** + *
 	 * Ambiguous syntax:
 	 *     WS?
 	 *
 	 * This ambiguous syntax occurs at:
 	 *     ranges+=VersionRange WS? '||' (ambiguity) ranges+=VersionRange
+	 
+	 * 
*/ protected void emit_VersionRangeSetRequirement_WSTerminalRuleCall_1_1_2_q(EObject semanticObject, ISynNavigable transition, List nodes) { acceptNodes(transition, nodes); } /** + *
 	 * Ambiguous syntax:
 	 *     WS?
 	 *
 	 * This ambiguous syntax occurs at:
 	 *     ranges+=VersionRange (ambiguity) (rule end)
+	 
+	 * 
*/ protected void emit_VersionRangeSetRequirement_WSTerminalRuleCall_1_2_q(EObject semanticObject, ISynNavigable transition, List nodes) { acceptNodes(transition, nodes); diff --git a/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/services/SemverGrammarAccess.java b/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/services/SemverGrammarAccess.java index 0267c57d3c..1c220750cd 100644 --- a/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/services/SemverGrammarAccess.java +++ b/plugins/org.eclipse.n4js.semver/src-gen/org/eclipse/n4js/semver/services/SemverGrammarAccess.java @@ -43,8 +43,10 @@ public class NPMVersionRequirementElements extends AbstractParserRuleElementFind private final RuleCall cLocalPathVersionRequirementParserRuleCall_1_0_0 = (RuleCall)cAlternatives_1_0.eContents().get(0); private final Alternatives cAlternatives_1_0_1 = (Alternatives)cAlternatives_1_0.eContents().get(1); private final RuleCall cURLVersionRequirementParserRuleCall_1_0_1_0 = (RuleCall)cAlternatives_1_0_1.eContents().get(0); - private final RuleCall cGitHubVersionRequirementParserRuleCall_1_0_1_1 = (RuleCall)cAlternatives_1_0_1.eContents().get(1); - private final RuleCall cTagVersionRequirementParserRuleCall_1_0_1_2 = (RuleCall)cAlternatives_1_0_1.eContents().get(2); + private final Alternatives cAlternatives_1_0_1_1 = (Alternatives)cAlternatives_1_0_1.eContents().get(1); + private final RuleCall cWorkspaceVersionRequirementParserRuleCall_1_0_1_1_0 = (RuleCall)cAlternatives_1_0_1_1.eContents().get(0); + private final RuleCall cGitHubVersionRequirementParserRuleCall_1_0_1_1_1 = (RuleCall)cAlternatives_1_0_1_1.eContents().get(1); + private final RuleCall cTagVersionRequirementParserRuleCall_1_0_1_1_2 = (RuleCall)cAlternatives_1_0_1_1.eContents().get(2); private final RuleCall cWSTerminalRuleCall_1_1 = (RuleCall)cGroup_1.eContents().get(1); //// This grammar of SemVer 2.0.0 is an adapted version of the BNF found at: @@ -55,8 +57,10 @@ public class NPMVersionRequirementElements extends AbstractParserRuleElementFind // ( // =>LocalPathVersionRequirement // | ( =>URLVersionRequirement - // | GitHubVersionRequirement - // | TagVersionRequirement + // | ( =>WorkspaceVersionRequirement + // | GitHubVersionRequirement + // | TagVersionRequirement // this can be any string + // ) // ) // ) WS? //; @@ -67,8 +71,10 @@ public class NPMVersionRequirementElements extends AbstractParserRuleElementFind // ( // =>LocalPathVersionRequirement // | ( =>URLVersionRequirement - // | GitHubVersionRequirement - // | TagVersionRequirement + // | ( =>WorkspaceVersionRequirement + // | GitHubVersionRequirement + // | TagVersionRequirement // this can be any string + // ) // ) // ) WS? public Alternatives getAlternatives() { return cAlternatives; } @@ -85,8 +91,10 @@ public class NPMVersionRequirementElements extends AbstractParserRuleElementFind //( // =>LocalPathVersionRequirement // | ( =>URLVersionRequirement - // | GitHubVersionRequirement - // | TagVersionRequirement + // | ( =>WorkspaceVersionRequirement + // | GitHubVersionRequirement + // | TagVersionRequirement // this can be any string + // ) // ) //) WS? public Group getGroup_1() { return cGroup_1; } @@ -94,8 +102,10 @@ public class NPMVersionRequirementElements extends AbstractParserRuleElementFind //( // =>LocalPathVersionRequirement // | ( =>URLVersionRequirement - // | GitHubVersionRequirement - // | TagVersionRequirement + // | ( =>WorkspaceVersionRequirement + // | GitHubVersionRequirement + // | TagVersionRequirement // this can be any string + // ) // ) //) public Alternatives getAlternatives_1_0() { return cAlternatives_1_0; } @@ -104,19 +114,30 @@ public class NPMVersionRequirementElements extends AbstractParserRuleElementFind public RuleCall getLocalPathVersionRequirementParserRuleCall_1_0_0() { return cLocalPathVersionRequirementParserRuleCall_1_0_0; } //( =>URLVersionRequirement - // | GitHubVersionRequirement - // | TagVersionRequirement + // | ( =>WorkspaceVersionRequirement + // | GitHubVersionRequirement + // | TagVersionRequirement // this can be any string + // ) // ) public Alternatives getAlternatives_1_0_1() { return cAlternatives_1_0_1; } //=>URLVersionRequirement public RuleCall getURLVersionRequirementParserRuleCall_1_0_1_0() { return cURLVersionRequirementParserRuleCall_1_0_1_0; } + //( =>WorkspaceVersionRequirement + // | GitHubVersionRequirement + // | TagVersionRequirement // this can be any string + // ) + public Alternatives getAlternatives_1_0_1_1() { return cAlternatives_1_0_1_1; } + + //=>WorkspaceVersionRequirement + public RuleCall getWorkspaceVersionRequirementParserRuleCall_1_0_1_1_0() { return cWorkspaceVersionRequirementParserRuleCall_1_0_1_1_0; } + //GitHubVersionRequirement - public RuleCall getGitHubVersionRequirementParserRuleCall_1_0_1_1() { return cGitHubVersionRequirementParserRuleCall_1_0_1_1; } + public RuleCall getGitHubVersionRequirementParserRuleCall_1_0_1_1_1() { return cGitHubVersionRequirementParserRuleCall_1_0_1_1_1; } //TagVersionRequirement - public RuleCall getTagVersionRequirementParserRuleCall_1_0_1_2() { return cTagVersionRequirementParserRuleCall_1_0_1_2; } + public RuleCall getTagVersionRequirementParserRuleCall_1_0_1_1_2() { return cTagVersionRequirementParserRuleCall_1_0_1_1_2; } //WS? public RuleCall getWSTerminalRuleCall_1_1() { return cWSTerminalRuleCall_1_1; } @@ -299,24 +320,49 @@ public class URLSemverElements extends AbstractParserRuleElementFinder { //SimpleVersion public RuleCall getSimpleVersionSimpleVersionParserRuleCall_2_0() { return cSimpleVersionSimpleVersionParserRuleCall_2_0; } } - public class TagVersionRequirementElements extends AbstractParserRuleElementFinder { - private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.TagVersionRequirement"); - private final Assignment cTagNameAssignment = (Assignment)rule.eContents().get(1); - private final RuleCall cTagNameTAGParserRuleCall_0 = (RuleCall)cTagNameAssignment.eContents().get(0); - - ////URLCommitISH: - //// commitISH=ALPHA_NUMERIC_CHARS - ////; - //TagVersionRequirement: - // tagName=TAG + public class WorkspaceVersionRequirementElements extends AbstractParserRuleElementFinder { + private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement"); + private final Group cGroup = (Group)rule.eContents().get(1); + private final RuleCall cWORKSPACE_TAGParserRuleCall_0 = (RuleCall)cGroup.eContents().get(0); + private final Alternatives cAlternatives_1 = (Alternatives)cGroup.eContents().get(1); + private final Assignment cVersionAssignment_1_0 = (Assignment)cAlternatives_1.eContents().get(0); + private final RuleCall cVersionSimpleVersionParserRuleCall_1_0_0 = (RuleCall)cVersionAssignment_1_0.eContents().get(0); + private final Assignment cOtherVersionAssignment_1_1 = (Assignment)cAlternatives_1.eContents().get(1); + private final RuleCall cOtherVersionWORKSPACE_VERSIONParserRuleCall_1_1_0 = (RuleCall)cOtherVersionAssignment_1_1.eContents().get(0); + + //WorkspaceVersionRequirement: + // (WORKSPACE_TAG) + // ( =>version=SimpleVersion + // | otherVersion=WORKSPACE_VERSION // fallback for various other version kinds + // ) //; @Override public ParserRule getRule() { return rule; } - //tagName=TAG - public Assignment getTagNameAssignment() { return cTagNameAssignment; } + //(WORKSPACE_TAG) + //( =>version=SimpleVersion + //| otherVersion=WORKSPACE_VERSION // fallback for various other version kinds + //) + public Group getGroup() { return cGroup; } - //TAG - public RuleCall getTagNameTAGParserRuleCall_0() { return cTagNameTAGParserRuleCall_0; } + //(WORKSPACE_TAG) + public RuleCall getWORKSPACE_TAGParserRuleCall_0() { return cWORKSPACE_TAGParserRuleCall_0; } + + //( =>version=SimpleVersion + //| otherVersion=WORKSPACE_VERSION // fallback for various other version kinds + //) + public Alternatives getAlternatives_1() { return cAlternatives_1; } + + //=>version=SimpleVersion + public Assignment getVersionAssignment_1_0() { return cVersionAssignment_1_0; } + + //SimpleVersion + public RuleCall getVersionSimpleVersionParserRuleCall_1_0_0() { return cVersionSimpleVersionParserRuleCall_1_0_0; } + + //otherVersion=WORKSPACE_VERSION + public Assignment getOtherVersionAssignment_1_1() { return cOtherVersionAssignment_1_1; } + + //WORKSPACE_VERSION + public RuleCall getOtherVersionWORKSPACE_VERSIONParserRuleCall_1_1_0() { return cOtherVersionWORKSPACE_VERSIONParserRuleCall_1_1_0; } } public class GitHubVersionRequirementElements extends AbstractParserRuleElementFinder { private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.GitHubVersionRequirement"); @@ -354,6 +400,25 @@ public class GitHubVersionRequirementElements extends AbstractParserRuleElementF //ALPHA_NUMERIC_CHARS public RuleCall getCommitISHALPHA_NUMERIC_CHARSParserRuleCall_1_1_0() { return cCommitISHALPHA_NUMERIC_CHARSParserRuleCall_1_1_0; } } + public class TagVersionRequirementElements extends AbstractParserRuleElementFinder { + private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.TagVersionRequirement"); + private final Assignment cTagNameAssignment = (Assignment)rule.eContents().get(1); + private final RuleCall cTagNameTAGParserRuleCall_0 = (RuleCall)cTagNameAssignment.eContents().get(0); + + ////URLCommitISH: + //// commitISH=ALPHA_NUMERIC_CHARS + ////; + //TagVersionRequirement: + // tagName=TAG + //; + @Override public ParserRule getRule() { return rule; } + + //tagName=TAG + public Assignment getTagNameAssignment() { return cTagNameAssignment; } + + //TAG + public RuleCall getTagNameTAGParserRuleCall_0() { return cTagNameTAGParserRuleCall_0; } + } public class VersionRangeSetRequirementElements extends AbstractParserRuleElementFinder { private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.VersionRangeSetRequirement"); private final Group cGroup = (Group)rule.eContents().get(1); @@ -852,23 +917,73 @@ public class SEMVER_TAGElements extends AbstractParserRuleElementFinder { //':' public Keyword getColonKeyword_6() { return cColonKeyword_6; } } + public class WORKSPACE_TAGElements extends AbstractParserRuleElementFinder { + private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.WORKSPACE_TAG"); + private final Group cGroup = (Group)rule.eContents().get(1); + private final RuleCall cLETTER_WTerminalRuleCall_0 = (RuleCall)cGroup.eContents().get(0); + private final RuleCall cLETTER_OTerminalRuleCall_1 = (RuleCall)cGroup.eContents().get(1); + private final RuleCall cLETTER_RTerminalRuleCall_2 = (RuleCall)cGroup.eContents().get(2); + private final RuleCall cLETTER_KTerminalRuleCall_3 = (RuleCall)cGroup.eContents().get(3); + private final RuleCall cLETTER_STerminalRuleCall_4 = (RuleCall)cGroup.eContents().get(4); + private final RuleCall cLETTER_PTerminalRuleCall_5 = (RuleCall)cGroup.eContents().get(5); + private final RuleCall cLETTER_ATerminalRuleCall_6 = (RuleCall)cGroup.eContents().get(6); + private final RuleCall cLETTER_CTerminalRuleCall_7 = (RuleCall)cGroup.eContents().get(7); + private final RuleCall cLETTER_ETerminalRuleCall_8 = (RuleCall)cGroup.eContents().get(8); + private final Keyword cColonKeyword_9 = (Keyword)cGroup.eContents().get(9); + + //WORKSPACE_TAG: + // LETTER_W LETTER_O LETTER_R LETTER_K LETTER_S LETTER_P LETTER_A LETTER_C LETTER_E ':' + //; + @Override public ParserRule getRule() { return rule; } + + //LETTER_W LETTER_O LETTER_R LETTER_K LETTER_S LETTER_P LETTER_A LETTER_C LETTER_E ':' + public Group getGroup() { return cGroup; } + + //LETTER_W + public RuleCall getLETTER_WTerminalRuleCall_0() { return cLETTER_WTerminalRuleCall_0; } + + //LETTER_O + public RuleCall getLETTER_OTerminalRuleCall_1() { return cLETTER_OTerminalRuleCall_1; } + + //LETTER_R + public RuleCall getLETTER_RTerminalRuleCall_2() { return cLETTER_RTerminalRuleCall_2; } + + //LETTER_K + public RuleCall getLETTER_KTerminalRuleCall_3() { return cLETTER_KTerminalRuleCall_3; } + + //LETTER_S + public RuleCall getLETTER_STerminalRuleCall_4() { return cLETTER_STerminalRuleCall_4; } + + //LETTER_P + public RuleCall getLETTER_PTerminalRuleCall_5() { return cLETTER_PTerminalRuleCall_5; } + + //LETTER_A + public RuleCall getLETTER_ATerminalRuleCall_6() { return cLETTER_ATerminalRuleCall_6; } + + //LETTER_C + public RuleCall getLETTER_CTerminalRuleCall_7() { return cLETTER_CTerminalRuleCall_7; } + + //LETTER_E + public RuleCall getLETTER_ETerminalRuleCall_8() { return cLETTER_ETerminalRuleCall_8; } + + //':' + public Keyword getColonKeyword_9() { return cColonKeyword_9; } + } public class PATHElements extends AbstractParserRuleElementFinder { private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.PATH"); private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1); private final Keyword cSolidusKeyword_0 = (Keyword)cAlternatives.eContents().get(0); private final Keyword cFullStopKeyword_1 = (Keyword)cAlternatives.eContents().get(1); private final Keyword cCommercialAtKeyword_2 = (Keyword)cAlternatives.eContents().get(2); - private final Keyword cHyphenMinusKeyword_3 = (Keyword)cAlternatives.eContents().get(3); - private final Keyword c_Keyword_4 = (Keyword)cAlternatives.eContents().get(4); - private final RuleCall cDIGITSTerminalRuleCall_5 = (RuleCall)cAlternatives.eContents().get(5); - private final RuleCall cLETTERParserRuleCall_6 = (RuleCall)cAlternatives.eContents().get(6); + private final Keyword c_Keyword_3 = (Keyword)cAlternatives.eContents().get(3); + private final RuleCall cALPHA_NUMERIC_CHARParserRuleCall_4 = (RuleCall)cAlternatives.eContents().get(4); //PATH: - // ('/' | '.' | '@' | '-' | '_' | DIGITS | LETTER)+ + // ('/' | '.' | '@' | '_' | ALPHA_NUMERIC_CHAR)+ //; @Override public ParserRule getRule() { return rule; } - //('/' | '.' | '@' | '-' | '_' | DIGITS | LETTER)+ + //('/' | '.' | '@' | '_' | ALPHA_NUMERIC_CHAR)+ public Alternatives getAlternatives() { return cAlternatives; } //'/' @@ -880,17 +995,11 @@ public class PATHElements extends AbstractParserRuleElementFinder { //'@' public Keyword getCommercialAtKeyword_2() { return cCommercialAtKeyword_2; } - //'-' - public Keyword getHyphenMinusKeyword_3() { return cHyphenMinusKeyword_3; } - //'_' - public Keyword get_Keyword_4() { return c_Keyword_4; } - - //DIGITS - public RuleCall getDIGITSTerminalRuleCall_5() { return cDIGITSTerminalRuleCall_5; } + public Keyword get_Keyword_3() { return c_Keyword_3; } - //LETTER - public RuleCall getLETTERParserRuleCall_6() { return cLETTERParserRuleCall_6; } + //ALPHA_NUMERIC_CHAR + public RuleCall getALPHA_NUMERIC_CHARParserRuleCall_4() { return cALPHA_NUMERIC_CHARParserRuleCall_4; } } public class URL_PROTOCOLElements extends AbstractParserRuleElementFinder { private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.URL_PROTOCOL"); @@ -924,10 +1033,8 @@ public class URLElements extends AbstractParserRuleElementFinder { private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.URL"); private final Group cGroup = (Group)rule.eContents().get(1); private final Alternatives cAlternatives_0 = (Alternatives)cGroup.eContents().get(0); - private final Keyword cHyphenMinusKeyword_0_0 = (Keyword)cAlternatives_0.eContents().get(0); - private final Keyword c_Keyword_0_1 = (Keyword)cAlternatives_0.eContents().get(1); - private final RuleCall cDIGITSTerminalRuleCall_0_2 = (RuleCall)cAlternatives_0.eContents().get(2); - private final RuleCall cLETTERParserRuleCall_0_3 = (RuleCall)cAlternatives_0.eContents().get(3); + private final Keyword c_Keyword_0_0 = (Keyword)cAlternatives_0.eContents().get(0); + private final RuleCall cALPHA_NUMERIC_CHARParserRuleCall_0_1 = (RuleCall)cAlternatives_0.eContents().get(1); private final Alternatives cAlternatives_1 = (Alternatives)cGroup.eContents().get(1); private final Keyword cSolidusKeyword_1_0 = (Keyword)cAlternatives_1.eContents().get(0); private final Keyword cFullStopKeyword_1_1 = (Keyword)cAlternatives_1.eContents().get(1); @@ -938,37 +1045,29 @@ public class URLElements extends AbstractParserRuleElementFinder { private final Keyword cFullStopKeyword_2_1 = (Keyword)cAlternatives_2.eContents().get(1); private final Keyword cColonKeyword_2_2 = (Keyword)cAlternatives_2.eContents().get(2); private final Keyword cCommercialAtKeyword_2_3 = (Keyword)cAlternatives_2.eContents().get(3); - private final Keyword cHyphenMinusKeyword_2_4 = (Keyword)cAlternatives_2.eContents().get(4); - private final Keyword c_Keyword_2_5 = (Keyword)cAlternatives_2.eContents().get(5); - private final RuleCall cDIGITSTerminalRuleCall_2_6 = (RuleCall)cAlternatives_2.eContents().get(6); - private final RuleCall cLETTERParserRuleCall_2_7 = (RuleCall)cAlternatives_2.eContents().get(7); + private final Keyword c_Keyword_2_4 = (Keyword)cAlternatives_2.eContents().get(4); + private final RuleCall cALPHA_NUMERIC_CHARParserRuleCall_2_5 = (RuleCall)cAlternatives_2.eContents().get(5); //URL: - // ('-' | '_' | DIGITS | LETTER)* + // ('_' | ALPHA_NUMERIC_CHAR)* // ('/' | '.' | ':' | '@') - // ('/' | '.' | ':' | '@' | '-' | '_' | DIGITS | LETTER)* + // ('/' | '.' | ':' | '@' | '_' | ALPHA_NUMERIC_CHAR)* //; @Override public ParserRule getRule() { return rule; } - //('-' | '_' | DIGITS | LETTER)* + //('_' | ALPHA_NUMERIC_CHAR)* //('/' | '.' | ':' | '@') - //('/' | '.' | ':' | '@' | '-' | '_' | DIGITS | LETTER)* + //('/' | '.' | ':' | '@' | '_' | ALPHA_NUMERIC_CHAR)* public Group getGroup() { return cGroup; } - //('-' | '_' | DIGITS | LETTER)* + //('_' | ALPHA_NUMERIC_CHAR)* public Alternatives getAlternatives_0() { return cAlternatives_0; } - //'-' - public Keyword getHyphenMinusKeyword_0_0() { return cHyphenMinusKeyword_0_0; } - //'_' - public Keyword get_Keyword_0_1() { return c_Keyword_0_1; } + public Keyword get_Keyword_0_0() { return c_Keyword_0_0; } - //DIGITS - public RuleCall getDIGITSTerminalRuleCall_0_2() { return cDIGITSTerminalRuleCall_0_2; } - - //LETTER - public RuleCall getLETTERParserRuleCall_0_3() { return cLETTERParserRuleCall_0_3; } + //ALPHA_NUMERIC_CHAR + public RuleCall getALPHA_NUMERIC_CHARParserRuleCall_0_1() { return cALPHA_NUMERIC_CHARParserRuleCall_0_1; } //('/' | '.' | ':' | '@') public Alternatives getAlternatives_1() { return cAlternatives_1; } @@ -985,7 +1084,7 @@ public class URLElements extends AbstractParserRuleElementFinder { //'@' public Keyword getCommercialAtKeyword_1_3() { return cCommercialAtKeyword_1_3; } - //('/' | '.' | ':' | '@' | '-' | '_' | DIGITS | LETTER)* + //('/' | '.' | ':' | '@' | '_' | ALPHA_NUMERIC_CHAR)* public Alternatives getAlternatives_2() { return cAlternatives_2; } //'/' @@ -1000,30 +1099,22 @@ public class URLElements extends AbstractParserRuleElementFinder { //'@' public Keyword getCommercialAtKeyword_2_3() { return cCommercialAtKeyword_2_3; } - //'-' - public Keyword getHyphenMinusKeyword_2_4() { return cHyphenMinusKeyword_2_4; } - //'_' - public Keyword get_Keyword_2_5() { return c_Keyword_2_5; } - - //DIGITS - public RuleCall getDIGITSTerminalRuleCall_2_6() { return cDIGITSTerminalRuleCall_2_6; } + public Keyword get_Keyword_2_4() { return c_Keyword_2_4; } - //LETTER - public RuleCall getLETTERParserRuleCall_2_7() { return cLETTERParserRuleCall_2_7; } + //ALPHA_NUMERIC_CHAR + public RuleCall getALPHA_NUMERIC_CHARParserRuleCall_2_5() { return cALPHA_NUMERIC_CHARParserRuleCall_2_5; } } public class URL_NO_VXElements extends AbstractParserRuleElementFinder { private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.URL_NO_VX"); private final Group cGroup = (Group)rule.eContents().get(1); private final Alternatives cAlternatives_0 = (Alternatives)cGroup.eContents().get(0); - private final Keyword cHyphenMinusKeyword_0_0 = (Keyword)cAlternatives_0.eContents().get(0); - private final Keyword c_Keyword_0_1 = (Keyword)cAlternatives_0.eContents().get(1); + private final Keyword c_Keyword_0_0 = (Keyword)cAlternatives_0.eContents().get(0); + private final Keyword cHyphenMinusKeyword_0_1 = (Keyword)cAlternatives_0.eContents().get(1); private final RuleCall cLETTER_NO_VXParserRuleCall_0_2 = (RuleCall)cAlternatives_0.eContents().get(2); private final Alternatives cAlternatives_1 = (Alternatives)cGroup.eContents().get(1); - private final Keyword cHyphenMinusKeyword_1_0 = (Keyword)cAlternatives_1.eContents().get(0); - private final Keyword c_Keyword_1_1 = (Keyword)cAlternatives_1.eContents().get(1); - private final RuleCall cDIGITSTerminalRuleCall_1_2 = (RuleCall)cAlternatives_1.eContents().get(2); - private final RuleCall cLETTERParserRuleCall_1_3 = (RuleCall)cAlternatives_1.eContents().get(3); + private final Keyword c_Keyword_1_0 = (Keyword)cAlternatives_1.eContents().get(0); + private final RuleCall cALPHA_NUMERIC_CHARParserRuleCall_1_1 = (RuleCall)cAlternatives_1.eContents().get(1); private final Alternatives cAlternatives_2 = (Alternatives)cGroup.eContents().get(2); private final Keyword cSolidusKeyword_2_0 = (Keyword)cAlternatives_2.eContents().get(0); private final Keyword cFullStopKeyword_2_1 = (Keyword)cAlternatives_2.eContents().get(1); @@ -1034,51 +1125,43 @@ public class URL_NO_VXElements extends AbstractParserRuleElementFinder { private final Keyword cFullStopKeyword_3_1 = (Keyword)cAlternatives_3.eContents().get(1); private final Keyword cColonKeyword_3_2 = (Keyword)cAlternatives_3.eContents().get(2); private final Keyword cCommercialAtKeyword_3_3 = (Keyword)cAlternatives_3.eContents().get(3); - private final Keyword cHyphenMinusKeyword_3_4 = (Keyword)cAlternatives_3.eContents().get(4); - private final Keyword c_Keyword_3_5 = (Keyword)cAlternatives_3.eContents().get(5); - private final RuleCall cDIGITSTerminalRuleCall_3_6 = (RuleCall)cAlternatives_3.eContents().get(6); - private final RuleCall cLETTERParserRuleCall_3_7 = (RuleCall)cAlternatives_3.eContents().get(7); + private final Keyword c_Keyword_3_4 = (Keyword)cAlternatives_3.eContents().get(4); + private final RuleCall cALPHA_NUMERIC_CHARParserRuleCall_3_5 = (RuleCall)cAlternatives_3.eContents().get(5); //URL_NO_VX: - // ('-' | '_' | LETTER_NO_VX) - // ('-' | '_' | DIGITS | LETTER)* + // ('_' | '-' | LETTER_NO_VX) + // ('_' | ALPHA_NUMERIC_CHAR)* // ('/' | '.' | ':' | '@') - // ('/' | '.' | ':' | '@' | '-' | '_' | DIGITS | LETTER)* + // ('/' | '.' | ':' | '@' | '_' | ALPHA_NUMERIC_CHAR)* //; @Override public ParserRule getRule() { return rule; } - //('-' | '_' | LETTER_NO_VX) - //('-' | '_' | DIGITS | LETTER)* + //('_' | '-' | LETTER_NO_VX) + //('_' | ALPHA_NUMERIC_CHAR)* //('/' | '.' | ':' | '@') - //('/' | '.' | ':' | '@' | '-' | '_' | DIGITS | LETTER)* + //('/' | '.' | ':' | '@' | '_' | ALPHA_NUMERIC_CHAR)* public Group getGroup() { return cGroup; } - //('-' | '_' | LETTER_NO_VX) + //('_' | '-' | LETTER_NO_VX) public Alternatives getAlternatives_0() { return cAlternatives_0; } - //'-' - public Keyword getHyphenMinusKeyword_0_0() { return cHyphenMinusKeyword_0_0; } - //'_' - public Keyword get_Keyword_0_1() { return c_Keyword_0_1; } + public Keyword get_Keyword_0_0() { return c_Keyword_0_0; } + + //'-' + public Keyword getHyphenMinusKeyword_0_1() { return cHyphenMinusKeyword_0_1; } //LETTER_NO_VX public RuleCall getLETTER_NO_VXParserRuleCall_0_2() { return cLETTER_NO_VXParserRuleCall_0_2; } - //('-' | '_' | DIGITS | LETTER)* + //('_' | ALPHA_NUMERIC_CHAR)* public Alternatives getAlternatives_1() { return cAlternatives_1; } - //'-' - public Keyword getHyphenMinusKeyword_1_0() { return cHyphenMinusKeyword_1_0; } - //'_' - public Keyword get_Keyword_1_1() { return c_Keyword_1_1; } + public Keyword get_Keyword_1_0() { return c_Keyword_1_0; } - //DIGITS - public RuleCall getDIGITSTerminalRuleCall_1_2() { return cDIGITSTerminalRuleCall_1_2; } - - //LETTER - public RuleCall getLETTERParserRuleCall_1_3() { return cLETTERParserRuleCall_1_3; } + //ALPHA_NUMERIC_CHAR + public RuleCall getALPHA_NUMERIC_CHARParserRuleCall_1_1() { return cALPHA_NUMERIC_CHARParserRuleCall_1_1; } //('/' | '.' | ':' | '@') public Alternatives getAlternatives_2() { return cAlternatives_2; } @@ -1095,7 +1178,7 @@ public class URL_NO_VXElements extends AbstractParserRuleElementFinder { //'@' public Keyword getCommercialAtKeyword_2_3() { return cCommercialAtKeyword_2_3; } - //('/' | '.' | ':' | '@' | '-' | '_' | DIGITS | LETTER)* + //('/' | '.' | ':' | '@' | '_' | ALPHA_NUMERIC_CHAR)* public Alternatives getAlternatives_3() { return cAlternatives_3; } //'/' @@ -1110,105 +1193,155 @@ public class URL_NO_VXElements extends AbstractParserRuleElementFinder { //'@' public Keyword getCommercialAtKeyword_3_3() { return cCommercialAtKeyword_3_3; } - //'-' - public Keyword getHyphenMinusKeyword_3_4() { return cHyphenMinusKeyword_3_4; } - //'_' - public Keyword get_Keyword_3_5() { return c_Keyword_3_5; } - - //DIGITS - public RuleCall getDIGITSTerminalRuleCall_3_6() { return cDIGITSTerminalRuleCall_3_6; } + public Keyword get_Keyword_3_4() { return c_Keyword_3_4; } - //LETTER - public RuleCall getLETTERParserRuleCall_3_7() { return cLETTERParserRuleCall_3_7; } + //ALPHA_NUMERIC_CHAR + public RuleCall getALPHA_NUMERIC_CHARParserRuleCall_3_5() { return cALPHA_NUMERIC_CHARParserRuleCall_3_5; } } public class TAGElements extends AbstractParserRuleElementFinder { private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.TAG"); private final Group cGroup = (Group)rule.eContents().get(1); private final RuleCall cLETTER_NO_VXParserRuleCall_0 = (RuleCall)cGroup.eContents().get(0); - private final Alternatives cAlternatives_1 = (Alternatives)cGroup.eContents().get(1); - private final Keyword cHyphenMinusKeyword_1_0 = (Keyword)cAlternatives_1.eContents().get(0); - private final RuleCall cDIGITSTerminalRuleCall_1_1 = (RuleCall)cAlternatives_1.eContents().get(1); - private final RuleCall cLETTERParserRuleCall_1_2 = (RuleCall)cAlternatives_1.eContents().get(2); + private final RuleCall cALPHA_NUMERIC_CHARSParserRuleCall_1 = (RuleCall)cGroup.eContents().get(1); //TAG: - // (LETTER_NO_VX /*| LETTER_X*/) ('-' | DIGITS | LETTER)+ + // (LETTER_NO_VX /*| LETTER_X*/) ALPHA_NUMERIC_CHARS //; @Override public ParserRule getRule() { return rule; } - //(LETTER_NO_VX /*| LETTER_X*/) ('-' | DIGITS | LETTER)+ + //(LETTER_NO_VX /*| LETTER_X*/) ALPHA_NUMERIC_CHARS public Group getGroup() { return cGroup; } //(LETTER_NO_VX /*| LETTER_X*/) public RuleCall getLETTER_NO_VXParserRuleCall_0() { return cLETTER_NO_VXParserRuleCall_0; } - //('-' | DIGITS | LETTER)+ - public Alternatives getAlternatives_1() { return cAlternatives_1; } - - //'-' - public Keyword getHyphenMinusKeyword_1_0() { return cHyphenMinusKeyword_1_0; } - - //DIGITS - public RuleCall getDIGITSTerminalRuleCall_1_1() { return cDIGITSTerminalRuleCall_1_1; } - - //LETTER - public RuleCall getLETTERParserRuleCall_1_2() { return cLETTERParserRuleCall_1_2; } + //ALPHA_NUMERIC_CHARS + public RuleCall getALPHA_NUMERIC_CHARSParserRuleCall_1() { return cALPHA_NUMERIC_CHARSParserRuleCall_1; } } - public class ALPHA_NUMERIC_CHARSElements extends AbstractParserRuleElementFinder { - private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.ALPHA_NUMERIC_CHARS"); + public class WORKSPACE_VERSIONElements extends AbstractParserRuleElementFinder { + private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.WORKSPACE_VERSION"); private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1); - private final Keyword cHyphenMinusKeyword_0 = (Keyword)cAlternatives.eContents().get(0); - private final RuleCall cDIGITSTerminalRuleCall_1 = (RuleCall)cAlternatives.eContents().get(1); - private final RuleCall cLETTERParserRuleCall_2 = (RuleCall)cAlternatives.eContents().get(2); - - //ALPHA_NUMERIC_CHARS: - // ('-' | DIGITS | LETTER)+ + private final Keyword cSolidusKeyword_0 = (Keyword)cAlternatives.eContents().get(0); + private final Keyword cFullStopKeyword_1 = (Keyword)cAlternatives.eContents().get(1); + private final Keyword cColonKeyword_2 = (Keyword)cAlternatives.eContents().get(2); + private final Keyword cCommercialAtKeyword_3 = (Keyword)cAlternatives.eContents().get(3); + private final Keyword c_Keyword_4 = (Keyword)cAlternatives.eContents().get(4); + private final Keyword cEqualsSignKeyword_5 = (Keyword)cAlternatives.eContents().get(5); + private final Keyword cTildeKeyword_6 = (Keyword)cAlternatives.eContents().get(6); + private final Keyword cCircumflexAccentKeyword_7 = (Keyword)cAlternatives.eContents().get(7); + private final Keyword cLessThanSignKeyword_8 = (Keyword)cAlternatives.eContents().get(8); + private final Keyword cGreaterThanSignKeyword_9 = (Keyword)cAlternatives.eContents().get(9); + private final Keyword cLessThanSignEqualsSignKeyword_10 = (Keyword)cAlternatives.eContents().get(10); + private final Keyword cGreaterThanSignEqualsSignKeyword_11 = (Keyword)cAlternatives.eContents().get(11); + private final RuleCall cASTERIXTerminalRuleCall_12 = (RuleCall)cAlternatives.eContents().get(12); + private final RuleCall cALPHA_NUMERIC_CHARParserRuleCall_13 = (RuleCall)cAlternatives.eContents().get(13); + + //WORKSPACE_VERSION: + // ( '/' | '.' | ':' | '@' | '_' | '=' | '~' | '^' | '<' | '>' | '<=' | '>=' | ASTERIX | ALPHA_NUMERIC_CHAR)+ //; @Override public ParserRule getRule() { return rule; } - //('-' | DIGITS | LETTER)+ + //( '/' | '.' | ':' | '@' | '_' | '=' | '~' | '^' | '<' | '>' | '<=' | '>=' | ASTERIX | ALPHA_NUMERIC_CHAR)+ public Alternatives getAlternatives() { return cAlternatives; } - //'-' - public Keyword getHyphenMinusKeyword_0() { return cHyphenMinusKeyword_0; } + //'/' + public Keyword getSolidusKeyword_0() { return cSolidusKeyword_0; } - //DIGITS - public RuleCall getDIGITSTerminalRuleCall_1() { return cDIGITSTerminalRuleCall_1; } + //'.' + public Keyword getFullStopKeyword_1() { return cFullStopKeyword_1; } - //LETTER - public RuleCall getLETTERParserRuleCall_2() { return cLETTERParserRuleCall_2; } + //':' + public Keyword getColonKeyword_2() { return cColonKeyword_2; } + + //'@' + public Keyword getCommercialAtKeyword_3() { return cCommercialAtKeyword_3; } + + //'_' + public Keyword get_Keyword_4() { return c_Keyword_4; } + + //'=' + public Keyword getEqualsSignKeyword_5() { return cEqualsSignKeyword_5; } + + //'~' + public Keyword getTildeKeyword_6() { return cTildeKeyword_6; } + + //'^' + public Keyword getCircumflexAccentKeyword_7() { return cCircumflexAccentKeyword_7; } + + //'<' + public Keyword getLessThanSignKeyword_8() { return cLessThanSignKeyword_8; } + + //'>' + public Keyword getGreaterThanSignKeyword_9() { return cGreaterThanSignKeyword_9; } + + //'<=' + public Keyword getLessThanSignEqualsSignKeyword_10() { return cLessThanSignEqualsSignKeyword_10; } + + //'>=' + public Keyword getGreaterThanSignEqualsSignKeyword_11() { return cGreaterThanSignEqualsSignKeyword_11; } + + //ASTERIX + public RuleCall getASTERIXTerminalRuleCall_12() { return cASTERIXTerminalRuleCall_12; } + + //ALPHA_NUMERIC_CHAR + public RuleCall getALPHA_NUMERIC_CHARParserRuleCall_13() { return cALPHA_NUMERIC_CHARParserRuleCall_13; } } public class ALPHA_NUMERIC_CHARS_START_WITH_DIGITSElements extends AbstractParserRuleElementFinder { private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.ALPHA_NUMERIC_CHARS_START_WITH_DIGITS"); private final Group cGroup = (Group)rule.eContents().get(1); private final RuleCall cDIGITSTerminalRuleCall_0 = (RuleCall)cGroup.eContents().get(0); - private final Alternatives cAlternatives_1 = (Alternatives)cGroup.eContents().get(1); - private final Keyword cHyphenMinusKeyword_1_0 = (Keyword)cAlternatives_1.eContents().get(0); - private final RuleCall cDIGITSTerminalRuleCall_1_1 = (RuleCall)cAlternatives_1.eContents().get(1); - private final RuleCall cLETTERParserRuleCall_1_2 = (RuleCall)cAlternatives_1.eContents().get(2); + private final RuleCall cALPHA_NUMERIC_CHARSParserRuleCall_1 = (RuleCall)cGroup.eContents().get(1); //ALPHA_NUMERIC_CHARS_START_WITH_DIGITS: - // DIGITS ('-' | DIGITS | LETTER)+ + // DIGITS ALPHA_NUMERIC_CHARS //; @Override public ParserRule getRule() { return rule; } - //DIGITS ('-' | DIGITS | LETTER)+ + //DIGITS ALPHA_NUMERIC_CHARS public Group getGroup() { return cGroup; } //DIGITS public RuleCall getDIGITSTerminalRuleCall_0() { return cDIGITSTerminalRuleCall_0; } - //('-' | DIGITS | LETTER)+ - public Alternatives getAlternatives_1() { return cAlternatives_1; } + //ALPHA_NUMERIC_CHARS + public RuleCall getALPHA_NUMERIC_CHARSParserRuleCall_1() { return cALPHA_NUMERIC_CHARSParserRuleCall_1; } + } + public class ALPHA_NUMERIC_CHARSElements extends AbstractParserRuleElementFinder { + private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.ALPHA_NUMERIC_CHARS"); + private final RuleCall cALPHA_NUMERIC_CHARParserRuleCall = (RuleCall)rule.eContents().get(1); + + //ALPHA_NUMERIC_CHARS: + // ALPHA_NUMERIC_CHAR+ + //; + @Override public ParserRule getRule() { return rule; } + + //ALPHA_NUMERIC_CHAR+ + public RuleCall getALPHA_NUMERIC_CHARParserRuleCall() { return cALPHA_NUMERIC_CHARParserRuleCall; } + } + public class ALPHA_NUMERIC_CHARElements extends AbstractParserRuleElementFinder { + private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.ALPHA_NUMERIC_CHAR"); + private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1); + private final Keyword cHyphenMinusKeyword_0 = (Keyword)cAlternatives.eContents().get(0); + private final RuleCall cDIGITSTerminalRuleCall_1 = (RuleCall)cAlternatives.eContents().get(1); + private final RuleCall cLETTERParserRuleCall_2 = (RuleCall)cAlternatives.eContents().get(2); + + //ALPHA_NUMERIC_CHAR: + // '-' | DIGITS | LETTER + //; + @Override public ParserRule getRule() { return rule; } + + //'-' | DIGITS | LETTER + public Alternatives getAlternatives() { return cAlternatives; } //'-' - public Keyword getHyphenMinusKeyword_1_0() { return cHyphenMinusKeyword_1_0; } + public Keyword getHyphenMinusKeyword_0() { return cHyphenMinusKeyword_0; } //DIGITS - public RuleCall getDIGITSTerminalRuleCall_1_1() { return cDIGITSTerminalRuleCall_1_1; } + public RuleCall getDIGITSTerminalRuleCall_1() { return cDIGITSTerminalRuleCall_1; } //LETTER - public RuleCall getLETTERParserRuleCall_1_2() { return cLETTERParserRuleCall_1_2; } + public RuleCall getLETTERParserRuleCall_2() { return cLETTERParserRuleCall_2; } } public class WILDCARDElements extends AbstractParserRuleElementFinder { private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.WILDCARD"); @@ -1261,45 +1394,63 @@ public class LETTERElements extends AbstractParserRuleElementFinder { public class LETTER_NO_VXElements extends AbstractParserRuleElementFinder { private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_NO_VX"); private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1); - private final RuleCall cLETTER_STerminalRuleCall_0 = (RuleCall)cAlternatives.eContents().get(0); - private final RuleCall cLETTER_MTerminalRuleCall_1 = (RuleCall)cAlternatives.eContents().get(1); - private final RuleCall cLETTER_RTerminalRuleCall_2 = (RuleCall)cAlternatives.eContents().get(2); + private final RuleCall cLETTER_ATerminalRuleCall_0 = (RuleCall)cAlternatives.eContents().get(0); + private final RuleCall cLETTER_CTerminalRuleCall_1 = (RuleCall)cAlternatives.eContents().get(1); + private final RuleCall cLETTER_ETerminalRuleCall_2 = (RuleCall)cAlternatives.eContents().get(2); private final RuleCall cLETTER_FTerminalRuleCall_3 = (RuleCall)cAlternatives.eContents().get(3); private final RuleCall cLETTER_ITerminalRuleCall_4 = (RuleCall)cAlternatives.eContents().get(4); - private final RuleCall cLETTER_LTerminalRuleCall_5 = (RuleCall)cAlternatives.eContents().get(5); - private final RuleCall cLETTER_ETerminalRuleCall_6 = (RuleCall)cAlternatives.eContents().get(6); - private final RuleCall cLETTER_OTHERTerminalRuleCall_7 = (RuleCall)cAlternatives.eContents().get(7); + private final RuleCall cLETTER_KTerminalRuleCall_5 = (RuleCall)cAlternatives.eContents().get(5); + private final RuleCall cLETTER_LTerminalRuleCall_6 = (RuleCall)cAlternatives.eContents().get(6); + private final RuleCall cLETTER_MTerminalRuleCall_7 = (RuleCall)cAlternatives.eContents().get(7); + private final RuleCall cLETTER_OTerminalRuleCall_8 = (RuleCall)cAlternatives.eContents().get(8); + private final RuleCall cLETTER_PTerminalRuleCall_9 = (RuleCall)cAlternatives.eContents().get(9); + private final RuleCall cLETTER_RTerminalRuleCall_10 = (RuleCall)cAlternatives.eContents().get(10); + private final RuleCall cLETTER_STerminalRuleCall_11 = (RuleCall)cAlternatives.eContents().get(11); + private final RuleCall cLETTER_WTerminalRuleCall_12 = (RuleCall)cAlternatives.eContents().get(12); + private final RuleCall cLETTER_OTHERTerminalRuleCall_13 = (RuleCall)cAlternatives.eContents().get(13); //fragment LETTER_NO_VX: - // LETTER_S - // | LETTER_M - // | LETTER_R + // LETTER_A + // | LETTER_C + // | LETTER_E // | LETTER_F // | LETTER_I + // | LETTER_K // | LETTER_L - // | LETTER_E + // | LETTER_M + // | LETTER_O + // | LETTER_P + // | LETTER_R + // | LETTER_S + // | LETTER_W // | LETTER_OTHER //; @Override public ParserRule getRule() { return rule; } - //LETTER_S - //| LETTER_M - //| LETTER_R + //LETTER_A + //| LETTER_C + //| LETTER_E //| LETTER_F //| LETTER_I + //| LETTER_K //| LETTER_L - //| LETTER_E + //| LETTER_M + //| LETTER_O + //| LETTER_P + //| LETTER_R + //| LETTER_S + //| LETTER_W //| LETTER_OTHER public Alternatives getAlternatives() { return cAlternatives; } - //LETTER_S - public RuleCall getLETTER_STerminalRuleCall_0() { return cLETTER_STerminalRuleCall_0; } + //LETTER_A + public RuleCall getLETTER_ATerminalRuleCall_0() { return cLETTER_ATerminalRuleCall_0; } - //LETTER_M - public RuleCall getLETTER_MTerminalRuleCall_1() { return cLETTER_MTerminalRuleCall_1; } + //LETTER_C + public RuleCall getLETTER_CTerminalRuleCall_1() { return cLETTER_CTerminalRuleCall_1; } - //LETTER_R - public RuleCall getLETTER_RTerminalRuleCall_2() { return cLETTER_RTerminalRuleCall_2; } + //LETTER_E + public RuleCall getLETTER_ETerminalRuleCall_2() { return cLETTER_ETerminalRuleCall_2; } //LETTER_F public RuleCall getLETTER_FTerminalRuleCall_3() { return cLETTER_FTerminalRuleCall_3; } @@ -1307,14 +1458,32 @@ public class LETTER_NO_VXElements extends AbstractParserRuleElementFinder { //LETTER_I public RuleCall getLETTER_ITerminalRuleCall_4() { return cLETTER_ITerminalRuleCall_4; } + //LETTER_K + public RuleCall getLETTER_KTerminalRuleCall_5() { return cLETTER_KTerminalRuleCall_5; } + //LETTER_L - public RuleCall getLETTER_LTerminalRuleCall_5() { return cLETTER_LTerminalRuleCall_5; } + public RuleCall getLETTER_LTerminalRuleCall_6() { return cLETTER_LTerminalRuleCall_6; } - //LETTER_E - public RuleCall getLETTER_ETerminalRuleCall_6() { return cLETTER_ETerminalRuleCall_6; } + //LETTER_M + public RuleCall getLETTER_MTerminalRuleCall_7() { return cLETTER_MTerminalRuleCall_7; } + + //LETTER_O + public RuleCall getLETTER_OTerminalRuleCall_8() { return cLETTER_OTerminalRuleCall_8; } + + //LETTER_P + public RuleCall getLETTER_PTerminalRuleCall_9() { return cLETTER_PTerminalRuleCall_9; } + + //LETTER_R + public RuleCall getLETTER_RTerminalRuleCall_10() { return cLETTER_RTerminalRuleCall_10; } + + //LETTER_S + public RuleCall getLETTER_STerminalRuleCall_11() { return cLETTER_STerminalRuleCall_11; } + + //LETTER_W + public RuleCall getLETTER_WTerminalRuleCall_12() { return cLETTER_WTerminalRuleCall_12; } //LETTER_OTHER - public RuleCall getLETTER_OTHERTerminalRuleCall_7() { return cLETTER_OTHERTerminalRuleCall_7; } + public RuleCall getLETTER_OTHERTerminalRuleCall_13() { return cLETTER_OTHERTerminalRuleCall_13; } } public class VersionComparatorElements extends AbstractElementFinder.AbstractEnumRuleElementFinder { @@ -1322,36 +1491,36 @@ public class VersionComparatorElements extends AbstractElementFinder.AbstractEnu private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1); private final EnumLiteralDeclaration cEqualsEnumLiteralDeclaration_0 = (EnumLiteralDeclaration)cAlternatives.eContents().get(0); private final Keyword cEqualsEqualsSignKeyword_0_0 = (Keyword)cEqualsEnumLiteralDeclaration_0.eContents().get(0); - private final EnumLiteralDeclaration cSmallerEnumLiteralDeclaration_1 = (EnumLiteralDeclaration)cAlternatives.eContents().get(1); - private final Keyword cSmallerLessThanSignKeyword_1_0 = (Keyword)cSmallerEnumLiteralDeclaration_1.eContents().get(0); - private final EnumLiteralDeclaration cTildeEnumLiteralDeclaration_2 = (EnumLiteralDeclaration)cAlternatives.eContents().get(2); - private final Keyword cTildeTildeKeyword_2_0 = (Keyword)cTildeEnumLiteralDeclaration_2.eContents().get(0); - private final EnumLiteralDeclaration cCaretEnumLiteralDeclaration_3 = (EnumLiteralDeclaration)cAlternatives.eContents().get(3); - private final Keyword cCaretCircumflexAccentKeyword_3_0 = (Keyword)cCaretEnumLiteralDeclaration_3.eContents().get(0); - private final EnumLiteralDeclaration cSmallerEqualsEnumLiteralDeclaration_4 = (EnumLiteralDeclaration)cAlternatives.eContents().get(4); - private final Keyword cSmallerEqualsLessThanSignEqualsSignKeyword_4_0 = (Keyword)cSmallerEqualsEnumLiteralDeclaration_4.eContents().get(0); - private final EnumLiteralDeclaration cGreaterEnumLiteralDeclaration_5 = (EnumLiteralDeclaration)cAlternatives.eContents().get(5); - private final Keyword cGreaterGreaterThanSignKeyword_5_0 = (Keyword)cGreaterEnumLiteralDeclaration_5.eContents().get(0); + private final EnumLiteralDeclaration cTildeEnumLiteralDeclaration_1 = (EnumLiteralDeclaration)cAlternatives.eContents().get(1); + private final Keyword cTildeTildeKeyword_1_0 = (Keyword)cTildeEnumLiteralDeclaration_1.eContents().get(0); + private final EnumLiteralDeclaration cCaretEnumLiteralDeclaration_2 = (EnumLiteralDeclaration)cAlternatives.eContents().get(2); + private final Keyword cCaretCircumflexAccentKeyword_2_0 = (Keyword)cCaretEnumLiteralDeclaration_2.eContents().get(0); + private final EnumLiteralDeclaration cSmallerEnumLiteralDeclaration_3 = (EnumLiteralDeclaration)cAlternatives.eContents().get(3); + private final Keyword cSmallerLessThanSignKeyword_3_0 = (Keyword)cSmallerEnumLiteralDeclaration_3.eContents().get(0); + private final EnumLiteralDeclaration cGreaterEnumLiteralDeclaration_4 = (EnumLiteralDeclaration)cAlternatives.eContents().get(4); + private final Keyword cGreaterGreaterThanSignKeyword_4_0 = (Keyword)cGreaterEnumLiteralDeclaration_4.eContents().get(0); + private final EnumLiteralDeclaration cSmallerEqualsEnumLiteralDeclaration_5 = (EnumLiteralDeclaration)cAlternatives.eContents().get(5); + private final Keyword cSmallerEqualsLessThanSignEqualsSignKeyword_5_0 = (Keyword)cSmallerEqualsEnumLiteralDeclaration_5.eContents().get(0); private final EnumLiteralDeclaration cGreaterEqualsEnumLiteralDeclaration_6 = (EnumLiteralDeclaration)cAlternatives.eContents().get(6); private final Keyword cGreaterEqualsGreaterThanSignEqualsSignKeyword_6_0 = (Keyword)cGreaterEqualsEnumLiteralDeclaration_6.eContents().get(0); //enum VersionComparator: // Equals = '=' - //| Smaller = '<' //| Tilde = '~' //| Caret = '^' - //| SmallerEquals = '<=' + //| Smaller = '<' //| Greater = '>' + //| SmallerEquals = '<=' //| GreaterEquals = '>=' //; public EnumRule getRule() { return rule; } // Equals = '=' - //| Smaller = '<' //| Tilde = '~' //| Caret = '^' - //| SmallerEquals = '<=' + //| Smaller = '<' //| Greater = '>' + //| SmallerEquals = '<=' //| GreaterEquals = '>=' public Alternatives getAlternatives() { return cAlternatives; } @@ -1361,35 +1530,35 @@ public class VersionComparatorElements extends AbstractElementFinder.AbstractEnu //'=' public Keyword getEqualsEqualsSignKeyword_0_0() { return cEqualsEqualsSignKeyword_0_0; } - //Smaller = '<' - public EnumLiteralDeclaration getSmallerEnumLiteralDeclaration_1() { return cSmallerEnumLiteralDeclaration_1; } - - //'<' - public Keyword getSmallerLessThanSignKeyword_1_0() { return cSmallerLessThanSignKeyword_1_0; } - //Tilde = '~' - public EnumLiteralDeclaration getTildeEnumLiteralDeclaration_2() { return cTildeEnumLiteralDeclaration_2; } + public EnumLiteralDeclaration getTildeEnumLiteralDeclaration_1() { return cTildeEnumLiteralDeclaration_1; } //'~' - public Keyword getTildeTildeKeyword_2_0() { return cTildeTildeKeyword_2_0; } + public Keyword getTildeTildeKeyword_1_0() { return cTildeTildeKeyword_1_0; } //Caret = '^' - public EnumLiteralDeclaration getCaretEnumLiteralDeclaration_3() { return cCaretEnumLiteralDeclaration_3; } + public EnumLiteralDeclaration getCaretEnumLiteralDeclaration_2() { return cCaretEnumLiteralDeclaration_2; } //'^' - public Keyword getCaretCircumflexAccentKeyword_3_0() { return cCaretCircumflexAccentKeyword_3_0; } + public Keyword getCaretCircumflexAccentKeyword_2_0() { return cCaretCircumflexAccentKeyword_2_0; } - //SmallerEquals = '<=' - public EnumLiteralDeclaration getSmallerEqualsEnumLiteralDeclaration_4() { return cSmallerEqualsEnumLiteralDeclaration_4; } + //Smaller = '<' + public EnumLiteralDeclaration getSmallerEnumLiteralDeclaration_3() { return cSmallerEnumLiteralDeclaration_3; } - //'<=' - public Keyword getSmallerEqualsLessThanSignEqualsSignKeyword_4_0() { return cSmallerEqualsLessThanSignEqualsSignKeyword_4_0; } + //'<' + public Keyword getSmallerLessThanSignKeyword_3_0() { return cSmallerLessThanSignKeyword_3_0; } //Greater = '>' - public EnumLiteralDeclaration getGreaterEnumLiteralDeclaration_5() { return cGreaterEnumLiteralDeclaration_5; } + public EnumLiteralDeclaration getGreaterEnumLiteralDeclaration_4() { return cGreaterEnumLiteralDeclaration_4; } //'>' - public Keyword getGreaterGreaterThanSignKeyword_5_0() { return cGreaterGreaterThanSignKeyword_5_0; } + public Keyword getGreaterGreaterThanSignKeyword_4_0() { return cGreaterGreaterThanSignKeyword_4_0; } + + //SmallerEquals = '<=' + public EnumLiteralDeclaration getSmallerEqualsEnumLiteralDeclaration_5() { return cSmallerEqualsEnumLiteralDeclaration_5; } + + //'<=' + public Keyword getSmallerEqualsLessThanSignEqualsSignKeyword_5_0() { return cSmallerEqualsLessThanSignEqualsSignKeyword_5_0; } //GreaterEquals = '>=' public EnumLiteralDeclaration getGreaterEqualsEnumLiteralDeclaration_6() { return cGreaterEqualsEnumLiteralDeclaration_6; } @@ -1403,8 +1572,9 @@ public class VersionComparatorElements extends AbstractElementFinder.AbstractEnu private final URLVersionRequirementElements pURLVersionRequirement; private final URLVersionSpecifierElements pURLVersionSpecifier; private final URLSemverElements pURLSemver; - private final TagVersionRequirementElements pTagVersionRequirement; + private final WorkspaceVersionRequirementElements pWorkspaceVersionRequirement; private final GitHubVersionRequirementElements pGitHubVersionRequirement; + private final TagVersionRequirementElements pTagVersionRequirement; private final VersionRangeSetRequirementElements pVersionRangeSetRequirement; private final VersionRangeElements pVersionRange; private final HyphenVersionRangeElements pHyphenVersionRange; @@ -1416,24 +1586,33 @@ public class VersionComparatorElements extends AbstractElementFinder.AbstractEnu private final QualifierTagElements pQualifierTag; private final FILE_TAGElements pFILE_TAG; private final SEMVER_TAGElements pSEMVER_TAG; + private final WORKSPACE_TAGElements pWORKSPACE_TAG; private final PATHElements pPATH; private final URL_PROTOCOLElements pURL_PROTOCOL; private final URLElements pURL; private final URL_NO_VXElements pURL_NO_VX; private final TAGElements pTAG; - private final ALPHA_NUMERIC_CHARSElements pALPHA_NUMERIC_CHARS; + private final WORKSPACE_VERSIONElements pWORKSPACE_VERSION; private final ALPHA_NUMERIC_CHARS_START_WITH_DIGITSElements pALPHA_NUMERIC_CHARS_START_WITH_DIGITS; + private final ALPHA_NUMERIC_CHARSElements pALPHA_NUMERIC_CHARS; + private final ALPHA_NUMERIC_CHARElements pALPHA_NUMERIC_CHAR; private final WILDCARDElements pWILDCARD; private final LETTERElements pLETTER; private final LETTER_NO_VXElements pLETTER_NO_VX; - private final TerminalRule tLETTER_S; - private final TerminalRule tLETTER_M; - private final TerminalRule tLETTER_R; + private final TerminalRule tLETTER_A; + private final TerminalRule tLETTER_C; + private final TerminalRule tLETTER_E; private final TerminalRule tLETTER_F; private final TerminalRule tLETTER_I; + private final TerminalRule tLETTER_K; private final TerminalRule tLETTER_L; - private final TerminalRule tLETTER_E; + private final TerminalRule tLETTER_M; + private final TerminalRule tLETTER_O; + private final TerminalRule tLETTER_P; + private final TerminalRule tLETTER_R; + private final TerminalRule tLETTER_S; private final TerminalRule tLETTER_V; + private final TerminalRule tLETTER_W; private final TerminalRule tLETTER_X; private final TerminalRule tLETTER_OTHER; private final TerminalRule tASTERIX; @@ -1456,8 +1635,9 @@ public SemverGrammarAccess(GrammarProvider grammarProvider, this.pURLVersionRequirement = new URLVersionRequirementElements(); this.pURLVersionSpecifier = new URLVersionSpecifierElements(); this.pURLSemver = new URLSemverElements(); - this.pTagVersionRequirement = new TagVersionRequirementElements(); + this.pWorkspaceVersionRequirement = new WorkspaceVersionRequirementElements(); this.pGitHubVersionRequirement = new GitHubVersionRequirementElements(); + this.pTagVersionRequirement = new TagVersionRequirementElements(); this.pVersionRangeSetRequirement = new VersionRangeSetRequirementElements(); this.pVersionRange = new VersionRangeElements(); this.pHyphenVersionRange = new HyphenVersionRangeElements(); @@ -1469,24 +1649,33 @@ public SemverGrammarAccess(GrammarProvider grammarProvider, this.pQualifierTag = new QualifierTagElements(); this.pFILE_TAG = new FILE_TAGElements(); this.pSEMVER_TAG = new SEMVER_TAGElements(); + this.pWORKSPACE_TAG = new WORKSPACE_TAGElements(); this.pPATH = new PATHElements(); this.pURL_PROTOCOL = new URL_PROTOCOLElements(); this.pURL = new URLElements(); this.pURL_NO_VX = new URL_NO_VXElements(); this.pTAG = new TAGElements(); - this.pALPHA_NUMERIC_CHARS = new ALPHA_NUMERIC_CHARSElements(); + this.pWORKSPACE_VERSION = new WORKSPACE_VERSIONElements(); this.pALPHA_NUMERIC_CHARS_START_WITH_DIGITS = new ALPHA_NUMERIC_CHARS_START_WITH_DIGITSElements(); + this.pALPHA_NUMERIC_CHARS = new ALPHA_NUMERIC_CHARSElements(); + this.pALPHA_NUMERIC_CHAR = new ALPHA_NUMERIC_CHARElements(); this.pWILDCARD = new WILDCARDElements(); this.pLETTER = new LETTERElements(); this.pLETTER_NO_VX = new LETTER_NO_VXElements(); - this.tLETTER_S = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_S"); - this.tLETTER_M = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_M"); - this.tLETTER_R = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_R"); + this.tLETTER_A = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_A"); + this.tLETTER_C = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_C"); + this.tLETTER_E = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_E"); this.tLETTER_F = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_F"); this.tLETTER_I = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_I"); + this.tLETTER_K = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_K"); this.tLETTER_L = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_L"); - this.tLETTER_E = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_E"); + this.tLETTER_M = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_M"); + this.tLETTER_O = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_O"); + this.tLETTER_P = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_P"); + this.tLETTER_R = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_R"); + this.tLETTER_S = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_S"); this.tLETTER_V = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_V"); + this.tLETTER_W = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_W"); this.tLETTER_X = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_X"); this.tLETTER_OTHER = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.LETTER_OTHER"); this.tASTERIX = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.n4js.semver.Semver.ASTERIX"); @@ -1531,8 +1720,10 @@ public UnicodeGrammarAccess getUnicodeGrammarAccess() { // ( // =>LocalPathVersionRequirement // | ( =>URLVersionRequirement - // | GitHubVersionRequirement - // | TagVersionRequirement + // | ( =>WorkspaceVersionRequirement + // | GitHubVersionRequirement + // | TagVersionRequirement // this can be any string + // ) // ) // ) WS? //; @@ -1593,18 +1784,18 @@ public ParserRule getURLSemverRule() { return getURLSemverAccess().getRule(); } - ////URLCommitISH: - //// commitISH=ALPHA_NUMERIC_CHARS - ////; - //TagVersionRequirement: - // tagName=TAG + //WorkspaceVersionRequirement: + // (WORKSPACE_TAG) + // ( =>version=SimpleVersion + // | otherVersion=WORKSPACE_VERSION // fallback for various other version kinds + // ) //; - public TagVersionRequirementElements getTagVersionRequirementAccess() { - return pTagVersionRequirement; + public WorkspaceVersionRequirementElements getWorkspaceVersionRequirementAccess() { + return pWorkspaceVersionRequirement; } - public ParserRule getTagVersionRequirementRule() { - return getTagVersionRequirementAccess().getRule(); + public ParserRule getWorkspaceVersionRequirementRule() { + return getWorkspaceVersionRequirementAccess().getRule(); } //GitHubVersionRequirement: @@ -1618,6 +1809,20 @@ public ParserRule getGitHubVersionRequirementRule() { return getGitHubVersionRequirementAccess().getRule(); } + ////URLCommitISH: + //// commitISH=ALPHA_NUMERIC_CHARS + ////; + //TagVersionRequirement: + // tagName=TAG + //; + public TagVersionRequirementElements getTagVersionRequirementAccess() { + return pTagVersionRequirement; + } + + public ParserRule getTagVersionRequirementRule() { + return getTagVersionRequirementAccess().getRule(); + } + //VersionRangeSetRequirement: // {VersionRangeSetRequirement} (ranges+=VersionRange (WS? '||' WS? ranges+=VersionRange)* WS?)? //; @@ -1747,8 +1952,19 @@ public ParserRule getSEMVER_TAGRule() { return getSEMVER_TAGAccess().getRule(); } + //WORKSPACE_TAG: + // LETTER_W LETTER_O LETTER_R LETTER_K LETTER_S LETTER_P LETTER_A LETTER_C LETTER_E ':' + //; + public WORKSPACE_TAGElements getWORKSPACE_TAGAccess() { + return pWORKSPACE_TAG; + } + + public ParserRule getWORKSPACE_TAGRule() { + return getWORKSPACE_TAGAccess().getRule(); + } + //PATH: - // ('/' | '.' | '@' | '-' | '_' | DIGITS | LETTER)+ + // ('/' | '.' | '@' | '_' | ALPHA_NUMERIC_CHAR)+ //; public PATHElements getPATHAccess() { return pPATH; @@ -1770,9 +1986,9 @@ public ParserRule getURL_PROTOCOLRule() { } //URL: - // ('-' | '_' | DIGITS | LETTER)* + // ('_' | ALPHA_NUMERIC_CHAR)* // ('/' | '.' | ':' | '@') - // ('/' | '.' | ':' | '@' | '-' | '_' | DIGITS | LETTER)* + // ('/' | '.' | ':' | '@' | '_' | ALPHA_NUMERIC_CHAR)* //; public URLElements getURLAccess() { return pURL; @@ -1783,10 +1999,10 @@ public ParserRule getURLRule() { } //URL_NO_VX: - // ('-' | '_' | LETTER_NO_VX) - // ('-' | '_' | DIGITS | LETTER)* + // ('_' | '-' | LETTER_NO_VX) + // ('_' | ALPHA_NUMERIC_CHAR)* // ('/' | '.' | ':' | '@') - // ('/' | '.' | ':' | '@' | '-' | '_' | DIGITS | LETTER)* + // ('/' | '.' | ':' | '@' | '_' | ALPHA_NUMERIC_CHAR)* //; public URL_NO_VXElements getURL_NO_VXAccess() { return pURL_NO_VX; @@ -1797,7 +2013,7 @@ public ParserRule getURL_NO_VXRule() { } //TAG: - // (LETTER_NO_VX /*| LETTER_X*/) ('-' | DIGITS | LETTER)+ + // (LETTER_NO_VX /*| LETTER_X*/) ALPHA_NUMERIC_CHARS //; public TAGElements getTAGAccess() { return pTAG; @@ -1807,19 +2023,19 @@ public ParserRule getTAGRule() { return getTAGAccess().getRule(); } - //ALPHA_NUMERIC_CHARS: - // ('-' | DIGITS | LETTER)+ + //WORKSPACE_VERSION: + // ( '/' | '.' | ':' | '@' | '_' | '=' | '~' | '^' | '<' | '>' | '<=' | '>=' | ASTERIX | ALPHA_NUMERIC_CHAR)+ //; - public ALPHA_NUMERIC_CHARSElements getALPHA_NUMERIC_CHARSAccess() { - return pALPHA_NUMERIC_CHARS; + public WORKSPACE_VERSIONElements getWORKSPACE_VERSIONAccess() { + return pWORKSPACE_VERSION; } - public ParserRule getALPHA_NUMERIC_CHARSRule() { - return getALPHA_NUMERIC_CHARSAccess().getRule(); + public ParserRule getWORKSPACE_VERSIONRule() { + return getWORKSPACE_VERSIONAccess().getRule(); } //ALPHA_NUMERIC_CHARS_START_WITH_DIGITS: - // DIGITS ('-' | DIGITS | LETTER)+ + // DIGITS ALPHA_NUMERIC_CHARS //; public ALPHA_NUMERIC_CHARS_START_WITH_DIGITSElements getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess() { return pALPHA_NUMERIC_CHARS_START_WITH_DIGITS; @@ -1829,6 +2045,28 @@ public ParserRule getALPHA_NUMERIC_CHARS_START_WITH_DIGITSRule() { return getALPHA_NUMERIC_CHARS_START_WITH_DIGITSAccess().getRule(); } + //ALPHA_NUMERIC_CHARS: + // ALPHA_NUMERIC_CHAR+ + //; + public ALPHA_NUMERIC_CHARSElements getALPHA_NUMERIC_CHARSAccess() { + return pALPHA_NUMERIC_CHARS; + } + + public ParserRule getALPHA_NUMERIC_CHARSRule() { + return getALPHA_NUMERIC_CHARSAccess().getRule(); + } + + //ALPHA_NUMERIC_CHAR: + // '-' | DIGITS | LETTER + //; + public ALPHA_NUMERIC_CHARElements getALPHA_NUMERIC_CHARAccess() { + return pALPHA_NUMERIC_CHAR; + } + + public ParserRule getALPHA_NUMERIC_CHARRule() { + return getALPHA_NUMERIC_CHARAccess().getRule(); + } + //WILDCARD: // LETTER_X | ASTERIX //; @@ -1854,13 +2092,19 @@ public ParserRule getLETTERRule() { } //fragment LETTER_NO_VX: - // LETTER_S - // | LETTER_M - // | LETTER_R + // LETTER_A + // | LETTER_C + // | LETTER_E // | LETTER_F // | LETTER_I + // | LETTER_K // | LETTER_L - // | LETTER_E + // | LETTER_M + // | LETTER_O + // | LETTER_P + // | LETTER_R + // | LETTER_S + // | LETTER_W // | LETTER_OTHER //; public LETTER_NO_VXElements getLETTER_NO_VXAccess() { @@ -1871,25 +2115,25 @@ public ParserRule getLETTER_NO_VXRule() { return getLETTER_NO_VXAccess().getRule(); } - //terminal LETTER_S : - // 's' | 'S' + //terminal LETTER_A : + // 'a' | 'A' //; - public TerminalRule getLETTER_SRule() { - return tLETTER_S; + public TerminalRule getLETTER_ARule() { + return tLETTER_A; } - //terminal LETTER_M : - // 'm' | 'M' + //terminal LETTER_C : + // 'c' | 'C' //; - public TerminalRule getLETTER_MRule() { - return tLETTER_M; + public TerminalRule getLETTER_CRule() { + return tLETTER_C; } - //terminal LETTER_R : - // 'r' | 'R' + //terminal LETTER_E : + // 'e' | 'E' //; - public TerminalRule getLETTER_RRule() { - return tLETTER_R; + public TerminalRule getLETTER_ERule() { + return tLETTER_E; } //terminal LETTER_F : @@ -1906,6 +2150,13 @@ public TerminalRule getLETTER_IRule() { return tLETTER_I; } + //terminal LETTER_K : + // 'k' | 'K' + //; + public TerminalRule getLETTER_KRule() { + return tLETTER_K; + } + //terminal LETTER_L : // 'l' | 'L' //; @@ -1913,11 +2164,39 @@ public TerminalRule getLETTER_LRule() { return tLETTER_L; } - //terminal LETTER_E : - // 'e' | 'E' + //terminal LETTER_M : + // 'm' | 'M' //; - public TerminalRule getLETTER_ERule() { - return tLETTER_E; + public TerminalRule getLETTER_MRule() { + return tLETTER_M; + } + + //terminal LETTER_O : + // 'o' | 'O' + //; + public TerminalRule getLETTER_ORule() { + return tLETTER_O; + } + + //terminal LETTER_P : + // 'p' | 'P' + //; + public TerminalRule getLETTER_PRule() { + return tLETTER_P; + } + + //terminal LETTER_R : + // 'r' | 'R' + //; + public TerminalRule getLETTER_RRule() { + return tLETTER_R; + } + + //terminal LETTER_S : + // 's' | 'S' + //; + public TerminalRule getLETTER_SRule() { + return tLETTER_S; } //terminal LETTER_V : @@ -1927,6 +2206,13 @@ public TerminalRule getLETTER_VRule() { return tLETTER_V; } + //terminal LETTER_W : + // 'w' | 'W' + //; + public TerminalRule getLETTER_WRule() { + return tLETTER_W; + } + //terminal LETTER_X: // 'x' | 'X' //; @@ -1935,9 +2221,9 @@ public TerminalRule getLETTER_XRule() { } //terminal LETTER_OTHER: - // 'a' | 'A' - // | 'b' | 'B' - // | 'c' | 'C' + // // 'a' | 'A' // part of 'workspace' tag + // 'b' | 'B' + // // | 'c' | 'C' // part of 'workspace' tag // | 'd' | 'D' // // | 'e' | 'E' // part of 'semver' and/or 'file' tag // // | 'f' | 'F' // part of 'file' tag @@ -1945,19 +2231,19 @@ public TerminalRule getLETTER_XRule() { // | 'h' | 'H' // // | 'i' | 'I' // part of 'file' tag // | 'j' | 'J' - // | 'k' | 'K' + // // | 'k' | 'K' // part of 'workspace' tag // // | 'l' | 'L' // part of 'file' tag // // | 'm' | 'M' // part of 'semver' tag // | 'n' | 'N' - // | 'o' | 'O' - // | 'p' | 'P' + // // | 'o' | 'O' // part of 'workspace' tag + // // | 'p' | 'P' // part of 'workspace' tag // | 'q' | 'Q' // // | 'r' | 'R' // part of 'semver' tag // // | 's' | 'S' // part of 'semver' tag // | 't' | 'T' // | 'u' | 'U' // // | 'v' | 'V' // can be a prefix of a version and/or part of 'semver' tag - // | 'w' | 'W' + // // | 'w' | 'W' // part of 'workspace' tag // // | 'x' | 'X' // can be a wildcard // | 'y' | 'Y' // | 'z' | 'Z' @@ -1994,11 +2280,11 @@ public TerminalRule getEOLRule() { //enum VersionComparator: // Equals = '=' - //| Smaller = '<' //| Tilde = '~' //| Caret = '^' - //| SmallerEquals = '<=' + //| Smaller = '<' //| Greater = '>' + //| SmallerEquals = '<=' //| GreaterEquals = '>=' //; public VersionComparatorElements getVersionComparatorAccess() { diff --git a/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/Semver.xtext b/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/Semver.xtext index 6950d35b0b..073bbd9884 100644 --- a/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/Semver.xtext +++ b/plugins/org.eclipse.n4js.semver/src/org/eclipse/n4js/semver/Semver.xtext @@ -28,8 +28,10 @@ NPMVersionRequirement: ( =>LocalPathVersionRequirement | ( =>URLVersionRequirement - | GitHubVersionRequirement - | TagVersionRequirement + | ( =>WorkspaceVersionRequirement + | GitHubVersionRequirement + | TagVersionRequirement // this can be any string + ) ) ) WS? ; @@ -55,6 +57,17 @@ URLSemver: simpleVersion=SimpleVersion ; +WorkspaceVersionRequirement: + (WORKSPACE_TAG) + ( =>version=SimpleVersion + | otherVersion=WORKSPACE_VERSION // fallback for various other version kinds + ) +; + +GitHubVersionRequirement: + githubUrl=URL_NO_VX ('#' commitISH=ALPHA_NUMERIC_CHARS)? +; + //URLCommitISH: // commitISH=ALPHA_NUMERIC_CHARS //; @@ -63,10 +76,6 @@ TagVersionRequirement: tagName=TAG ; -GitHubVersionRequirement: - githubUrl=URL_NO_VX ('#' commitISH=ALPHA_NUMERIC_CHARS)? -; - VersionRangeSetRequirement: {VersionRangeSetRequirement} (ranges+=VersionRange (WS? '||' WS? ranges+=VersionRange)* WS?)? ; @@ -120,9 +129,13 @@ SEMVER_TAG: LETTER_S LETTER_E LETTER_M LETTER_V LETTER_E LETTER_R ':' ; +WORKSPACE_TAG: + LETTER_W LETTER_O LETTER_R LETTER_K LETTER_S LETTER_P LETTER_A LETTER_C LETTER_E ':' +; + PATH: - ('/' | '.' | '@' | '-' | '_' | DIGITS | LETTER)+ + ('/' | '.' | '@' | '_' | ALPHA_NUMERIC_CHAR)+ ; URL_PROTOCOL: @@ -130,28 +143,36 @@ URL_PROTOCOL: ; URL: - ('-' | '_' | DIGITS | LETTER)* + ('_' | ALPHA_NUMERIC_CHAR)* ('/' | '.' | ':' | '@') - ('/' | '.' | ':' | '@' | '-' | '_' | DIGITS | LETTER)* + ('/' | '.' | ':' | '@' | '_' | ALPHA_NUMERIC_CHAR)* ; URL_NO_VX: - ('-' | '_' | LETTER_NO_VX) - ('-' | '_' | DIGITS | LETTER)* + ('_' | '-' | LETTER_NO_VX) + ('_' | ALPHA_NUMERIC_CHAR)* ('/' | '.' | ':' | '@') - ('/' | '.' | ':' | '@' | '-' | '_' | DIGITS | LETTER)* + ('/' | '.' | ':' | '@' | '_' | ALPHA_NUMERIC_CHAR)* ; TAG: - (LETTER_NO_VX /*| LETTER_X*/) ('-' | DIGITS | LETTER)+ + (LETTER_NO_VX /*| LETTER_X*/) ALPHA_NUMERIC_CHARS ; -ALPHA_NUMERIC_CHARS: - ('-' | DIGITS | LETTER)+ +WORKSPACE_VERSION: + ( '/' | '.' | ':' | '@' | '_' | '=' | '~' | '^' | '<' | '>' | '<=' | '>=' | ASTERIX | ALPHA_NUMERIC_CHAR)+ ; ALPHA_NUMERIC_CHARS_START_WITH_DIGITS: - DIGITS ('-' | DIGITS | LETTER)+ + DIGITS ALPHA_NUMERIC_CHARS +; + +ALPHA_NUMERIC_CHARS: + ALPHA_NUMERIC_CHAR+ +; + +ALPHA_NUMERIC_CHAR: + '-' | DIGITS | LETTER ; WILDCARD: @@ -167,27 +188,33 @@ fragment LETTER: fragment LETTER_NO_VX: - LETTER_S - | LETTER_M - | LETTER_R + LETTER_A + | LETTER_C + | LETTER_E | LETTER_F | LETTER_I + | LETTER_K | LETTER_L - | LETTER_E + | LETTER_M + | LETTER_O + | LETTER_P + | LETTER_R + | LETTER_S + | LETTER_W | LETTER_OTHER ; -terminal LETTER_S : - 's' | 'S' +terminal LETTER_A : + 'a' | 'A' ; -terminal LETTER_M : - 'm' | 'M' +terminal LETTER_C : + 'c' | 'C' ; -terminal LETTER_R : - 'r' | 'R' +terminal LETTER_E : + 'e' | 'E' ; terminal LETTER_F : @@ -198,26 +225,50 @@ terminal LETTER_I : 'i' | 'I' ; +terminal LETTER_K : + 'k' | 'K' +; + terminal LETTER_L : 'l' | 'L' ; -terminal LETTER_E : - 'e' | 'E' +terminal LETTER_M : + 'm' | 'M' +; + +terminal LETTER_O : + 'o' | 'O' +; + +terminal LETTER_P : + 'p' | 'P' +; + +terminal LETTER_R : + 'r' | 'R' +; + +terminal LETTER_S : + 's' | 'S' ; terminal LETTER_V : 'v' | 'V' ; +terminal LETTER_W : + 'w' | 'W' +; + terminal LETTER_X: 'x' | 'X' ; terminal LETTER_OTHER: - 'a' | 'A' - | 'b' | 'B' - | 'c' | 'C' + // 'a' | 'A' // part of 'workspace' tag + 'b' | 'B' + // | 'c' | 'C' // part of 'workspace' tag | 'd' | 'D' // | 'e' | 'E' // part of 'semver' and/or 'file' tag // | 'f' | 'F' // part of 'file' tag @@ -225,19 +276,19 @@ terminal LETTER_OTHER: | 'h' | 'H' // | 'i' | 'I' // part of 'file' tag | 'j' | 'J' - | 'k' | 'K' + // | 'k' | 'K' // part of 'workspace' tag // | 'l' | 'L' // part of 'file' tag // | 'm' | 'M' // part of 'semver' tag | 'n' | 'N' - | 'o' | 'O' - | 'p' | 'P' + // | 'o' | 'O' // part of 'workspace' tag + // | 'p' | 'P' // part of 'workspace' tag | 'q' | 'Q' // | 'r' | 'R' // part of 'semver' tag // | 's' | 'S' // part of 'semver' tag | 't' | 'T' | 'u' | 'U' // | 'v' | 'V' // can be a prefix of a version and/or part of 'semver' tag - | 'w' | 'W' + // | 'w' | 'W' // part of 'workspace' tag // | 'x' | 'X' // can be a wildcard | 'y' | 'Y' | 'z' | 'Z' @@ -253,8 +304,6 @@ terminal DIGITS returns ecore::EInt: - - terminal WS: WHITESPACE_FRAGMENT+; @@ -264,12 +313,13 @@ terminal EOL: + enum VersionComparator: Equals = '=' -| Smaller = '<' | Tilde = '~' | Caret = '^' -| SmallerEquals = '<=' +| Smaller = '<' | Greater = '>' +| SmallerEquals = '<=' | GreaterEquals = '>=' ; diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/URIUtils.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/URIUtils.java index 75de44af4a..589b80d8ff 100644 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/URIUtils.java +++ b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/URIUtils.java @@ -23,7 +23,6 @@ import java.util.SortedMap; import java.util.regex.Pattern; -import org.eclipse.core.resources.IProject; import org.eclipse.emf.common.CommonPlugin; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; @@ -252,12 +251,6 @@ static private int doCompare(String s1, String s2) { return s1.compareTo(s2); } - /** @return a complete URI for a given project */ - public static URI toFileUri(IProject project) { - String pathStr = project.getLocation().toString(); - return toFileUri(pathStr); - } - /** @return absolute file URI for the given path. */ static public URI toFileUri(Path path) { return toFileUri(path.toFile()); diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/UtilN4.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/UtilN4.java index 5416a1e9e2..e9713974c6 100644 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/UtilN4.java +++ b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/UtilN4.java @@ -43,6 +43,8 @@ */ public class UtilN4 { + /** Files extension of JSON files (not including the separator dot). */ + public static final String JSON_FILE_EXTENSION = "json"; /** Files extension of JS source files (not including the separator dot). */ public static final String JS_FILE_EXTENSION = "js"; /** File extension of JS source files that contain ES6 modules (not including the separator dot). */ diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/xtext/resourceset/StandardResourceLocator.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/xtext/resourceset/StandardResourceLocator.java index ae72140192..916c6a3b4e 100644 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/xtext/resourceset/StandardResourceLocator.java +++ b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/xtext/resourceset/StandardResourceLocator.java @@ -14,7 +14,7 @@ * * This is used to avoid the mutation of the locator field in {@link #basicGetResource(URI, boolean)} */ -class StandardResourceLocator extends ResourceLocator { +public class StandardResourceLocator extends ResourceLocator { public StandardResourceLocator(ResourceSetImpl resourceSet) { super(resourceSet); diff --git a/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/build/ProjectStatePersister.java b/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/build/ProjectStatePersister.java index 3e62393c6e..0878a24240 100644 --- a/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/build/ProjectStatePersister.java +++ b/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/build/ProjectStatePersister.java @@ -43,6 +43,7 @@ import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.n4js.utils.URIUtils; import org.eclipse.n4js.xtext.ide.server.QueuedExecutorService; +import org.eclipse.n4js.xtext.ide.server.build.XIndexer.XResolvedResourceDescription; import org.eclipse.n4js.xtext.workspace.ProjectConfigSnapshot; import org.eclipse.xtext.build.Source2GeneratedMapping; import org.eclipse.xtext.diagnostics.Severity; @@ -209,6 +210,8 @@ private void writeResourceDescriptions(ImmutableProjectState state, URI baseURI, for (IResourceDescription description : descriptions) { if (description instanceof SerializableResourceDescription) { writeResourceDescription((SerializableResourceDescription) description, baseURI, output); + } else if (description instanceof XResolvedResourceDescription) { + // ignore } else { throw new IOException("Unexpected type: " + description.getClass().getName()); } diff --git a/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/build/XIndexer.java b/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/build/XIndexer.java index ff2168e332..42e5eddcf2 100644 --- a/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/build/XIndexer.java +++ b/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/build/XIndexer.java @@ -309,12 +309,13 @@ protected IResourceDescription.Delta addToIndex(LoadResult loadResult, boolean i IResourceDescription.Manager manager = serviceProvider.getResourceDescriptionManager(); Resource resource = loadResult.resource; + IResourceDescription oldDescription = oldIndex != null ? oldIndex.getResourceDescription(uri) : null; if (resource == null) { // loading of resource failed if (loadResult.isFileNotFound()) { // a source file was renamed/deleted and we did not get a 'didChangeWatchedFiles' notification // OR the rename/delete happened while the build was in progress - IResourceDescription oldDesc = oldIndex != null ? oldIndex.getResourceDescription(uri) : null; + IResourceDescription oldDesc = oldDescription; return oldDesc != null ? manager.createDelta(oldDesc, null) : null; } Throwables.throwIfUnchecked(loadResult.throwable); @@ -328,8 +329,7 @@ protected IResourceDescription.Delta addToIndex(LoadResult loadResult, boolean i IResourceDescription newDescription = manager.getResourceDescription(resource); IResourceDescription toBeAdded = new XIndexer.XResolvedResourceDescription(newDescription); - IResourceDescription.Delta delta = manager - .createDelta(oldIndex != null ? oldIndex.getResourceDescription(uri) : null, toBeAdded); + IResourceDescription.Delta delta = manager.createDelta(oldDescription, toBeAdded); return delta; } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/N4JSGlobals.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/N4JSGlobals.java index d6ae3d965e..2a370a9241 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/N4JSGlobals.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/N4JSGlobals.java @@ -67,6 +67,8 @@ public final class N4JSGlobals { */ public static final String HASHBANG_PREFIX = "#!"; + /** Files extension of JSON files (not including the separator dot). */ + public static final String JSON_FILE_EXTENSION = UtilN4.JSON_FILE_EXTENSION; /** Files extension of JS source files (not including the separator dot). */ public static final String JS_FILE_EXTENSION = UtilN4.JS_FILE_EXTENSION; /** File extension of JS source files that contain ES6 modules (not including the separator dot). */ @@ -274,6 +276,11 @@ public final class N4JSGlobals { */ public static final String TS_CONFIG = "tsconfig.json"; + /** + * The name of the pnpm-workspace.yaml file. + */ + public static final String PNPM_WORKSPACE = "pnpm-workspace.yaml"; + /** * All project names of n4js libraries. */ diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/AbstractSubGenerator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/AbstractSubGenerator.xtend index 7f6844ca05..56c17a092f 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/AbstractSubGenerator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/AbstractSubGenerator.xtend @@ -160,7 +160,7 @@ abstract class AbstractSubGenerator implements ISubGenerator, IGenerator2 { val ws = workspaceAccess.getWorkspaceConfig(input); val autobuildEnabled = isActive(input) - val isXPECTMode = N4JSGlobals.XT_FILE_EXTENSION == URIUtils.fileExtension(input.URI).toLowerCase + val isXPECTMode = N4JSGlobals.XT_FILE_EXTENSION.equals(URIUtils.fileExtension(input.URI).toLowerCase); val inputUri = input.URI val boolean result = (autobuildEnabled diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonHelper.java index c90bdf0e86..8102b2b7a6 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonHelper.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonHelper.java @@ -397,8 +397,7 @@ private void convertDependencies(ProjectDescriptionBuilder target, List sourceContainers = target.getSourceContainers(); SourceContainerDescription sourceContainerOfTypeSource = null; for (SourceContainerDescription sourceContainer : sourceContainers) { diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/projectDescription/ProjectDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/projectDescription/ProjectDescription.java index ebc1af0e34..cc9b986e7c 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/projectDescription/ProjectDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/projectDescription/ProjectDescription.java @@ -66,6 +66,7 @@ public class ProjectDescription extends ImmutableDataClass { private final boolean esm; private final boolean moduleProperty; private final boolean n4jsNature; + private final boolean pnpmWorkspaceRoot; private final boolean yarnWorkspaceRoot; private final boolean isGeneratorEnabledSourceMaps; private final boolean isGeneratorEnabledDts; @@ -86,8 +87,8 @@ public ProjectDescription(FileURI location, FileURI relatedRootlocation, Iterable implementedProjects, String outputPath, Iterable sourceContainers, Iterable moduleFilters, Iterable testedProjects, String definesPackage, boolean nestedNodeModulesFolder, - boolean esm, boolean moduleProperty, boolean n4jsNature, boolean yarnWorkspaceRoot, - boolean isGeneratorEnabledSourceMaps, boolean isGeneratorEnabledDts, + boolean esm, boolean moduleProperty, boolean n4jsNature, boolean pnpmWorkspaceRoot, + boolean yarnWorkspaceRoot, boolean isGeneratorEnabledSourceMaps, boolean isGeneratorEnabledDts, Map generatorRewriteModuleSpecifiers, boolean isGeneratorEnabledRewriteCjsImports, Iterable workspaces, Iterable tsFiles, Iterable tsInclude, Iterable tsExclude) { @@ -121,6 +122,7 @@ public ProjectDescription(FileURI location, FileURI relatedRootlocation, this.esm = esm; this.moduleProperty = moduleProperty; this.n4jsNature = n4jsNature; + this.pnpmWorkspaceRoot = pnpmWorkspaceRoot; this.yarnWorkspaceRoot = yarnWorkspaceRoot; this.isGeneratorEnabledSourceMaps = isGeneratorEnabledSourceMaps; this.isGeneratorEnabledDts = isGeneratorEnabledDts; @@ -162,6 +164,7 @@ public ProjectDescription(ProjectDescription template) { this.esm = template.esm; this.moduleProperty = template.moduleProperty; this.n4jsNature = template.n4jsNature; + this.pnpmWorkspaceRoot = template.pnpmWorkspaceRoot; this.yarnWorkspaceRoot = template.yarnWorkspaceRoot; this.isGeneratorEnabledSourceMaps = template.isGeneratorEnabledSourceMaps; this.isGeneratorEnabledDts = template.isGeneratorEnabledDts; @@ -207,6 +210,7 @@ public ProjectDescriptionBuilder change() { builder.setESM(esm); builder.setModuleProperty(moduleProperty); builder.setN4JSNature(n4jsNature); + builder.setPnpmWorkspaceRoot(pnpmWorkspaceRoot); builder.setYarnWorkspaceRoot(yarnWorkspaceRoot); builder.setGeneratorEnabledSourceMaps(isGeneratorEnabledSourceMaps); builder.setGeneratorEnabledDts(isGeneratorEnabledDts); @@ -378,6 +382,13 @@ public boolean hasN4JSNature() { return n4jsNature; } + /** + * True iff the project represented by this project description is the root of either a yarn or pnpm workspace. + */ + public boolean isWorkspaceRoot() { + return isYarnWorkspaceRoot() || isPnpmWorkspaceRoot(); + } + /** * Tells whether the project represented by this project description is the root of a yarn workspace. This flag will * be {@code true} iff the package.json contains yarn's top-level property "workspaces", no matter the value (i.e. @@ -387,6 +398,16 @@ public boolean isYarnWorkspaceRoot() { return yarnWorkspaceRoot; } + /** + * True iff the project represented by this project description is the root of a pnpm workspace. This flag will be + * {@code true} iff the directory containing a package.json also contains the pnpm-workspace.yaml file with the + * top-level property "packages", no matter the value (i.e. will be {@code true} even if the value is the empty + * array). + */ + public boolean isPnpmWorkspaceRoot() { + return pnpmWorkspaceRoot; + } + /** Returns true iff source maps should be emitted. */ public boolean isGeneratorEnabledSourceMaps() { return isGeneratorEnabledSourceMaps; @@ -471,6 +492,7 @@ protected int computeHashCode() { esm, moduleProperty, n4jsNature, + pnpmWorkspaceRoot, yarnWorkspaceRoot, isGeneratorEnabledSourceMaps, isGeneratorEnabledDts, @@ -513,6 +535,7 @@ protected boolean computeEquals(Object obj) { && esm == other.esm && moduleProperty == other.moduleProperty && n4jsNature == other.n4jsNature + && pnpmWorkspaceRoot == other.pnpmWorkspaceRoot && yarnWorkspaceRoot == other.yarnWorkspaceRoot && isGeneratorEnabledSourceMaps == other.isGeneratorEnabledSourceMaps && isGeneratorEnabledDts == other.isGeneratorEnabledDts @@ -578,6 +601,9 @@ public void toStringAdditionalProperties(StringBuilder sb) { if (definesPackage != null) { sb.append(" definesPackage: " + definesPackage + "\n"); } + if (pnpmWorkspaceRoot) { + sb.append(" pnpmWorkspaceRoot: true\n"); + } if (yarnWorkspaceRoot) { sb.append(" yarnWorkspaceRoot: true\n"); } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/projectDescription/ProjectDescriptionBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/projectDescription/ProjectDescriptionBuilder.java index cff7a0a6af..bfaec8c668 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/projectDescription/ProjectDescriptionBuilder.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/projectDescription/ProjectDescriptionBuilder.java @@ -57,6 +57,7 @@ public class ProjectDescriptionBuilder { private boolean esm; private boolean moduleProperty; private boolean n4jsNature; + private boolean pnpmWorkspaceRoot; private boolean yarnWorkspaceRoot; private Boolean isGeneratorEnabledSourceMaps; private Boolean isGeneratorEnabledDts; @@ -84,7 +85,7 @@ public ProjectDescription build() { exports, extendedRuntimeEnvironment, providedRuntimeLibraries, requiredRuntimeLibraries, dependencies, implementationId, implementedProjects, outputPath, sourceContainers, moduleFilters, testedProjects, definesPackage, - nestedNodeModulesFolder, esm, moduleProperty, n4jsNature, yarnWorkspaceRoot, + nestedNodeModulesFolder, esm, moduleProperty, n4jsNature, pnpmWorkspaceRoot, yarnWorkspaceRoot, isGeneratorEnabledSourceMaps, isGeneratorEnabledDts, generatorRewriteModuleSpecifiers, isGeneratorEnabledRewriteCjsImports, workspaces, tsFiles, tsInclude, tsExclude); } @@ -378,10 +379,23 @@ public ProjectDescriptionBuilder setN4JSNature(boolean n4jsNature) { return this; } + public boolean isWorkspaceRoot() { + return isYarnWorkspaceRoot() || isPnpmWorkspaceRoot(); + } + + public boolean isPnpmWorkspaceRoot() { + return pnpmWorkspaceRoot; + } + public boolean isYarnWorkspaceRoot() { return yarnWorkspaceRoot; } + public ProjectDescriptionBuilder setPnpmWorkspaceRoot(boolean pnpmWorkspaceRoot) { + this.pnpmWorkspaceRoot = pnpmWorkspaceRoot; + return this; + } + public ProjectDescriptionBuilder setYarnWorkspaceRoot(boolean yarnWorkspaceRoot) { this.yarnWorkspaceRoot = yarnWorkspaceRoot; return this; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSResource.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSResource.java index 33cca2ff63..a5de481604 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSResource.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSResource.java @@ -407,6 +407,11 @@ public boolean isReconciled() { return module != null && module.isReconciled(); } + /** Returns true iff an error occurred while this resource was loaded. */ + public boolean isLoadedWithFailure() { + return this.isLoadedWithFailure; + } + @Override public synchronized EList getContents() { if (!removingAdapters) { diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/xtext/resourceset/XtextResourceLocator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/XtextResourceLocator.java similarity index 88% rename from plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/xtext/resourceset/XtextResourceLocator.java rename to plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/XtextResourceLocator.java index 88d44a40ba..76e9e71ffe 100644 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/xtext/resourceset/XtextResourceLocator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/XtextResourceLocator.java @@ -1,10 +1,11 @@ -package org.eclipse.n4js.xtext.resourceset; +package org.eclipse.n4js.resource; import java.lang.reflect.Field; import java.util.Map; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.n4js.xtext.resourceset.StandardResourceLocator; import org.eclipse.xtext.resource.XtextResourceSet; /** @@ -75,6 +76,13 @@ public Resource getResource(URI uri, boolean loadOnDemand) { demandLoadHelper(resource); + if (resource instanceof N4JSResource && ((N4JSResource) resource).isLoadedWithFailure()) { + if (resource.getResourceSet() != null) { + resource.getResourceSet().getResources().remove(resource); + } + return null; + } + return resource; } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/builtin/ConfiguredResourceSetProvider.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/builtin/ConfiguredResourceSetProvider.java index 9f79ea804f..369c320eca 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/builtin/ConfiguredResourceSetProvider.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/builtin/ConfiguredResourceSetProvider.java @@ -14,8 +14,8 @@ import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.ResourceLocator; +import org.eclipse.n4js.resource.XtextResourceLocator; import org.eclipse.n4js.xtext.resourceset.EmptyAuthorityAddingNormalizer; -import org.eclipse.n4js.xtext.resourceset.XtextResourceLocator; import org.eclipse.xtext.resource.SynchronizedXtextResourceSet; import org.eclipse.xtext.util.UriExtensions; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/builtin/ResourceSetWithBuiltInSchemeProvider.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/builtin/ResourceSetWithBuiltInSchemeProvider.java index acea11ca08..654e068770 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/builtin/ResourceSetWithBuiltInSchemeProvider.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/builtin/ResourceSetWithBuiltInSchemeProvider.java @@ -12,8 +12,8 @@ import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.ResourceLocator; +import org.eclipse.n4js.resource.XtextResourceLocator; import org.eclipse.n4js.xtext.resourceset.EmptyAuthorityAddingNormalizer; -import org.eclipse.n4js.xtext.resourceset.XtextResourceLocator; import org.eclipse.xtext.resource.SynchronizedXtextResourceSet; import org.eclipse.xtext.util.UriExtensions; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/NodeModulesDiscoveryHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/NodeModulesDiscoveryHelper.java index 86f9e40c8c..932e7d535a 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/NodeModulesDiscoveryHelper.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/NodeModulesDiscoveryHelper.java @@ -276,7 +276,7 @@ private List getWorkspacesOfYarnWorkspaceProject(File yarnProjectFolder, .loadProjectDescriptionAtLocation(location, null); return pd; }); - final List workspaces = (prjDescr != null && prjDescr.isYarnWorkspaceRoot()) + final List workspaces = (prjDescr != null && prjDescr.isWorkspaceRoot()) ? prjDescr.getWorkspaces() : null; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDescriptionLoader.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDescriptionLoader.java index d518a4aa52..ca9ddd160d 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDescriptionLoader.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDescriptionLoader.java @@ -23,11 +23,13 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.regex.Pattern; +import org.apache.log4j.Logger; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.common.util.WrappedException; import org.eclipse.emf.ecore.EObject; @@ -54,10 +56,10 @@ import org.eclipse.xtext.resource.XtextResourceSet; import org.eclipse.xtext.util.LazyStringInputStream; import org.eclipse.xtext.util.Pair; -import org.eclipse.xtext.util.RuntimeIOException; import org.eclipse.xtext.util.Strings; import org.eclipse.xtext.util.Tuples; +import com.google.common.collect.Multimap; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -73,6 +75,7 @@ */ @Singleton public class ProjectDescriptionLoader { + private final static Logger LOGGER = Logger.getLogger(ProjectDescriptionLoader.class); @Inject private Provider resourceSetProvider; @@ -111,6 +114,7 @@ public ProjectDescription loadProjectDescriptionAtLocation(FileURI location, URI if (pdbFromPackageJSON != null) { setInformationFromFileSystem(location, pdbFromPackageJSON); setInformationFromTSConfig(location, pdbFromPackageJSON); + setInformationFromPnpmWorkspace(location, pdbFromPackageJSON); pdbFromPackageJSON.setLocation(location); pdbFromPackageJSON.setRelatedRootLocation(relatedRootLocation); @@ -228,7 +232,7 @@ private void setInformationFromFileSystem(FileURI location, ProjectDescriptionBu } /** - * Store some information from {@code tsconfig.json} files iff existent in the project folders root. + * Store some information from {@code tsconfig.json} file iff existent in the project folders root. */ private void setInformationFromTSConfig(FileURI location, ProjectDescriptionBuilder target) { ProjectType type = target.getProjectType(); @@ -248,7 +252,7 @@ private void setInformationFromTSConfig(FileURI location, ProjectDescriptionBuil } } JSONDocument tsconfig = loadJSONAtLocation(path); - JSONValue content = tsconfig.getContent(); + JSONValue content = tsconfig == null ? null : tsconfig.getContent(); if (!(content instanceof JSONObject)) { return; } @@ -273,6 +277,34 @@ private void setInformationFromTSConfig(FileURI location, ProjectDescriptionBuil } } + /** + * Store some information from {@code pnpm-workspaces.yaml} file iff existent in the project folders root. + */ + private void setInformationFromPnpmWorkspace(FileURI location, ProjectDescriptionBuilder target) { + Path path = location.appendSegment(N4JSGlobals.PNPM_WORKSPACE).toFileSystemPath(); + if (!Files.isReadable(path)) { + path = location.appendSegment(N4JSGlobals.PNPM_WORKSPACE + "." + N4JSGlobals.XT_FILE_EXTENSION) + .toFileSystemPath(); + if (!Files.isReadable(path)) { + return; + } + } + + Multimap pnpmWorkspacesYaml = YamlUtil.loadYamlAtLocation(path); + Collection packagesEntries = pnpmWorkspacesYaml.get("packages"); + if (!packagesEntries.isEmpty()) { + // check for property discussed here: https://github.com/pnpm/pnpm/issues/2255#issuecomment-576866891 + Collection useYarnConfigEntries = pnpmWorkspacesYaml.get("useYarnConfig"); + if (useYarnConfigEntries.isEmpty() + || !"true".equals(useYarnConfigEntries.iterator().next().toString().toLowerCase())) { + + target.setPnpmWorkspaceRoot(true); + target.getWorkspaces().clear(); + target.getWorkspaces().addAll(packagesEntries); + } + } + } + private JSONDocument loadPackageJSONAtLocation(FileURI location) { Path path = location.appendSegment(N4JSGlobals.PACKAGE_JSON).toFileSystemPath(); if (!Files.isReadable(path)) { @@ -299,7 +331,8 @@ private JSONDocument loadJSONAtLocation(Path path) { return packageJSON; } } catch (IOException e) { - throw new RuntimeIOException(e); + LOGGER.error("Could not load " + path.toString(), e); + return null; } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDiscoveryHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDiscoveryHelper.java index 23c581cfac..f627ee01ed 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDiscoveryHelper.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDiscoveryHelper.java @@ -516,6 +516,9 @@ private Path findDependencyLocation(NodeModulesFolder nodeModulesFolder, Path pr } for (File currNMF : nodeModulesFolder.getNodeModulesFoldersInOrderOfPriority()) { File depLocation = new File(currNMF, depName); + if (SemanticDependencySupplier.isSymbolicLink(depLocation.toPath())) { + depLocation = SemanticDependencySupplier.resolveSymbolicLink(depLocation.toPath()).toFile(); + } if (depLocation.isDirectory()) { return depLocation.toPath(); } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/YamlUtil.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/YamlUtil.java new file mode 100644 index 0000000000..64da04b64d --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/YamlUtil.java @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2024 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.utils; + +import static com.google.common.base.Strings.isNullOrEmpty; +import static org.eclipse.n4js.utils.Strings.join; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; + +/** + * Utility for loading yaml files + */ +public class YamlUtil { + private final static Logger LOGGER = Logger.getLogger(YamlUtil.class); + + /** Loads a yaml file from the give location */ + static public Multimap loadYamlAtLocation(Path path) { + try { + List lines = Files.readAllLines(path, StandardCharsets.UTF_8); + return loadYamlFromLines(lines); + + } catch (IOException e) { + LOGGER.error("Could not load " + path.toString(), e); + } + return LinkedHashMultimap.create(); + } + + /** Loads yaml content from the given string */ + static public Multimap loadYamlFromString(String str) { + return loadYamlFromLines(Arrays.asList(str.split("\n"))); + } + + /** Loads yaml content from the given lines */ + static public Multimap loadYamlFromLines(List lines) { + Multimap result = LinkedHashMultimap.create(); + Map stack = new LinkedHashMap<>(); + for (String line : lines) { + if (line.startsWith("---") || line.startsWith("#")) { + continue; + } + int commentIdx = line.indexOf("#"); + if (commentIdx >= 0) { + line = line.substring(0, commentIdx); + } + int leadingSpaces = line.indexOf(line.trim()); + line = line.trim(); + + if (line.startsWith("-")) { + line = line.substring(1).trim(); + } + int propNameIdx = line.indexOf(":"); + if (propNameIdx >= 0) { + String propName = line.substring(0, propNameIdx).trim(); + + stack.put(leadingSpaces, propName); + stack.keySet().removeIf(k -> k > leadingSpaces); + + String value = line.substring(propNameIdx + 1).trim(); + if (!isNullOrEmpty(value)) { + value = trimQuotes(value); + String qpn = join(":", stack.values()); + result.put(qpn, value); + } + } else { + line = trimQuotes(line); + String qpn = join(":", e -> e.getValue(), filter(stack.entrySet(), e -> e.getKey() <= leadingSpaces)); + result.put(qpn, line); + } + } + return result; + } + + static private String trimQuotes(String str) { + if (str.startsWith("\"") && str.endsWith("\"")) { + return str.substring(1, str.length() - 1); // no trim + } else if (str.startsWith("'") && str.endsWith("'")) { + return str.substring(1, str.length() - 1); // no trim + } + return str; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java index ea670ca3f8..ee1c86abf1 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java @@ -2060,6 +2060,10 @@ public enum IssueCodes { PKGJ_REWRITE_MODULE_SPECIFIERS__INVALID_VALUE(ERROR, "String expected (i.e. the module specifier to use in the output code)."), + /** no parameters */ + PKGJ_PNPM_WORKSPACES_OVERRIDE(WARNING, + "This property is overridden by property 'packages' in file pnpm-workspaces.yaml."), + /** 0: dependency cycle */ LTD_ILLEGAL_LOADTIME_REFERENCE(ERROR, "Load-time references to the same or other modules are not allowed within a runtime dependency cycle (except in extends/implements clauses).{0}"), diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/N4JSProjectSetupJsonValidatorExtension.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/N4JSProjectSetupJsonValidatorExtension.xtend index 2bc35b0df2..93516c03eb 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/N4JSProjectSetupJsonValidatorExtension.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/packagejson/N4JSProjectSetupJsonValidatorExtension.xtend @@ -762,6 +762,17 @@ public class N4JSProjectSetupJsonValidatorExtension extends AbstractPackageJSONV holdsValidModuleSpecifiers(filterSpecifierTraceables, project); } + /** + * Checks if there is a pnpm-worspaces.yaml file that overrides the workspaces property. + */ + @CheckProperty(property = WORKSPACES_ARRAY) // also works for WORKSPACES_OBJECT + def checkWorspaceDefinitionArray(JSONValue workspacesValue) { + val description = getProjectDescription(); + if (description.isPnpmWorkspaceRoot) { + addIssue(workspacesValue.eContainer, JSONPackage.Literals.NAME_VALUE_PAIR__NAME, PKGJ_PNPM_WORKSPACES_OVERRIDE.toIssueItem()); + } + } + private def holdsValidModuleSpecifiers(Iterable> moduleFilterSpecifiers, N4JSProjectConfigSnapshot project) { val validFilterSpecifier = new ArrayList>(); diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/FileSystemScannerAceptor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/FileSystemScannerAceptor.java new file mode 100644 index 0000000000..ed3a05c10d --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/FileSystemScannerAceptor.java @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2024 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.workspace; + +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.n4js.N4JSGlobals; +import org.eclipse.n4js.utils.URIUtils; +import org.eclipse.n4js.workspace.utils.FileSystemScanner.IFileSystemScannerAcceptor; + +/** + * File acceptor that skips nested workspace projects. + */ +public class FileSystemScannerAceptor implements IFileSystemScannerAcceptor { + static final Set ACCEPTED_EXTENSIONS = new LinkedHashSet<>() { + { + this.addAll(N4JSGlobals.ALL_N4_FILE_EXTENSIONS); + this.add(N4JSGlobals.JSON_FILE_EXTENSION); + } + }; + + private final List pathMatchers; + private List sources = new ArrayList<>(); + + /** + * Constructor + */ + @SuppressWarnings("resource") + public FileSystemScannerAceptor(URI uri, List workspaces) { + super(); + this.pathMatchers = new ArrayList<>(); + Path root = Path.of(uri.toFileString()); + if (workspaces != null) { + for (String glob : workspaces) { + pathMatchers.add(FileSystems.getDefault().getPathMatcher("glob:" + root.resolve(glob))); + } + } + } + + @Override + public void accept(URI uri) { + if (sources != null && ACCEPTED_EXTENSIONS.contains(URIUtils.fileExtension(uri))) { + sources.add(uri); + } + } + + @Override + public FileVisitResult acceptFile(URI uri) { + accept(uri); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult acceptDirectory(URI uri) { + for (PathMatcher pathMatcher : pathMatchers) { + if (pathMatcher.matches(Path.of(uri.toFileString()))) { + return FileVisitResult.SKIP_SUBTREE; + } + } + return FileVisitResult.CONTINUE; + } + + /** Returns the sources and resets the internal sources list. */ + public List getSources() { + try { + return sources; + } finally { + this.sources = new ArrayList<>(); + } + } + + /** */ + public List getPathMatchers() { + return pathMatchers; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSProjectConfig.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSProjectConfig.java index 634b6de895..ef392268dc 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSProjectConfig.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSProjectConfig.java @@ -187,7 +187,7 @@ public N4JSPackageName getN4JSPackageName() { /** Tells whether this project is a yarn workspace project. */ public boolean isWorkspaceProject() { - return projectDescription.isYarnWorkspaceRoot() + return projectDescription.isWorkspaceRoot() && projectDescription.getWorkspaces() != null && !projectDescription.getWorkspaces().isEmpty(); } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSSourceFolder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSSourceFolder.java index 38500582f6..81c7cf2d2b 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSSourceFolder.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSSourceFolder.java @@ -10,7 +10,8 @@ */ package org.eclipse.n4js.workspace; -import java.util.ArrayList; +import java.nio.file.Path; +import java.nio.file.PathMatcher; import java.util.List; import java.util.Objects; @@ -24,11 +25,12 @@ * Wrapper around {@link SourceContainerDescription}. */ public class N4JSSourceFolder implements IN4JSSourceFolder { - private final N4JSProjectConfig project; private final SourceContainerType type; private final String relativePath; private final FileURI absolutePath; + private final List workspaces; + private final FileSystemScannerAceptor fssAcceptor; /** * Constructor @@ -38,6 +40,8 @@ public N4JSSourceFolder(N4JSProjectConfig project, SourceContainerType type, Str this.type = Objects.requireNonNull(type); this.relativePath = Objects.requireNonNull(relativePath); this.absolutePath = project.getAbsolutePath(relativePath); + this.workspaces = project.getProjectDescription().getWorkspaces(); + this.fssAcceptor = new FileSystemScannerAceptor(getPath(), workspaces); } @Override @@ -70,11 +74,30 @@ public FileURI getPathAsFileURI() { return absolutePath; } + /** */ + public List getWorkspaces() { + return workspaces; + } + @Override public List getAllResources(IFileSystemScanner scanner) { - List sources = new ArrayList<>(); - scanner.scan(getPath(), sources::add); - return sources; + scanner.scan(getPath(), fssAcceptor); // assumes a FileSystemScanner + return fssAcceptor.getSources(); + } + + @SuppressWarnings("restriction") + @Override + public boolean contains(URI uri) { + if (!IN4JSSourceFolder.super.contains(uri)) { + return false; + } + for (PathMatcher pathMatcher : fssAcceptor.getPathMatchers()) { + if (pathMatcher.matches(Path.of(uri.toFileString()))) { + return false; + } + } + + return true; } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSSourceFolderSnapshot.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSSourceFolderSnapshot.java index 47e7d6d54e..a12d8283c0 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSSourceFolderSnapshot.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSSourceFolderSnapshot.java @@ -10,12 +10,16 @@ */ package org.eclipse.n4js.workspace; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.util.List; import java.util.Objects; import org.eclipse.emf.common.util.URI; import org.eclipse.n4js.packagejson.projectDescription.SourceContainerType; import org.eclipse.n4js.workspace.locations.FileURI; import org.eclipse.n4js.xtext.workspace.SourceFolderSnapshot; +import org.eclipse.xtext.util.IFileSystemScanner; import org.eclipse.xtext.util.UriExtensions; /** @@ -25,12 +29,16 @@ public class N4JSSourceFolderSnapshot extends SourceFolderSnapshot { private final SourceContainerType type; private final String relativeLocation; + private final FileSystemScannerAceptor fssAcceptor; /** Creates a new {@link N4JSSourceFolderSnapshot}. */ - public N4JSSourceFolderSnapshot(String name, URI path, SourceContainerType type, String relativeLocation) { + public N4JSSourceFolderSnapshot(String name, URI path, SourceContainerType type, String relativeLocation, + List workspaces) { + super(name, path); this.type = type; this.relativeLocation = relativeLocation; + this.fssAcceptor = new FileSystemScannerAceptor(path, workspaces); } /** The {@link SourceContainerType type}. */ @@ -67,6 +75,25 @@ public String toString() { + ", path: " + getPath() + " }"; } + @Override + public List getAllResources(IFileSystemScanner scanner) { + scanner.scan(getPath(), fssAcceptor); + return fssAcceptor.getSources(); + } + + @Override + public boolean contains(URI uri) { + if (!super.contains(uri)) { + return false; + } + for (PathMatcher pathMatcher : fssAcceptor.getPathMatchers()) { + if (pathMatcher.matches(Path.of(uri.toFileString()))) { + return false; + } + } + + return true; + } // ============================================================================================================== // Convenience and utility methods (do not introduce additional data) diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSSourceFolderSnapshotForPackageJson.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSSourceFolderSnapshotForPackageJson.java index 0e56a5e103..601ce14d16 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSSourceFolderSnapshotForPackageJson.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSSourceFolderSnapshotForPackageJson.java @@ -26,7 +26,7 @@ public class N4JSSourceFolderSnapshotForPackageJson extends N4JSSourceFolderSnap /** Creates a new {@link N4JSSourceFolderSnapshotForPackageJson}. */ public N4JSSourceFolderSnapshotForPackageJson(N4JSSourceFolderForPackageJson sourceFolder) { super(sourceFolder.getName(), sourceFolder.getPath(), sourceFolder.getType(), - sourceFolder.getRelativePath()); + sourceFolder.getRelativePath(), null); this.packageJsonURI = sourceFolder.getPackageJsonURI(); } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSWorkspaceConfig.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSWorkspaceConfig.java index 4f6b8b94cb..3680b562b0 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSWorkspaceConfig.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/N4JSWorkspaceConfig.java @@ -42,9 +42,9 @@ import org.eclipse.xtext.xbase.lib.IterableExtensions; import com.google.common.collect.FluentIterable; -import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; +import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Sets; /** @@ -70,7 +70,8 @@ public class N4JSWorkspaceConfig implements XIWorkspaceConfig { /** All projects registered in this workspace by their id. */ protected final Map projectID2ProjectConfig = new LinkedHashMap<>(); /** All projects by their package name. */ - protected final HashMultimap packageName2ProjectConfigs = HashMultimap.create(); + protected final LinkedHashMultimap packageName2ProjectConfigs = LinkedHashMultimap + .create(); /** Map between definition projects and their defined projects. */ protected final DefinitionProjectMap definitionProjects = new DefinitionProjectMap(); /** Set of all runtime-library project ids in the workspace. */ diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/utils/FileSystemScanner.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/utils/FileSystemScanner.java index f0d84ed619..4a5c1f5bd4 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/utils/FileSystemScanner.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/utils/FileSystemScanner.java @@ -32,7 +32,7 @@ import com.google.inject.Singleton; /** - * A file system scanner that is aware of {@link FileVisitingAcceptor} to cut the traversal short. + * A file system scanner that is aware of {@link IFileSystemScannerAcceptor} to cut the traversal short. * * Compared to the default, it relies internally on {@link Files#walkFileTree(Path, java.nio.file.FileVisitor)} rather * than manual traversal based on the {@link File file API}. @@ -40,6 +40,21 @@ @Singleton public class FileSystemScanner implements IFileSystemScanner { + /** An {@link IAcceptor} that supports skipping subtrees when walking the file tree. */ + public interface IFileSystemScannerAcceptor extends IAcceptor { + /** Callback on every visited directory */ + default FileVisitResult acceptDirectory(T t) { + accept(t); + return FileVisitResult.CONTINUE; + } + + /** Callback on every visited file */ + default FileVisitResult acceptFile(T t) { + accept(t); + return FileVisitResult.CONTINUE; + } + } + @Override public void scan(URI root, IAcceptor acceptor) { File rootFile = URIUtils.toFile(root); @@ -56,10 +71,14 @@ public void scan(URI root, IAcceptor acceptor) { } static class N4JSFileVisitor implements FileVisitor { + final IFileSystemScannerAcceptor fssAcceptor; final IAcceptor acceptor; N4JSFileVisitor(IAcceptor acceptor) { this.acceptor = acceptor; + this.fssAcceptor = (acceptor instanceof IFileSystemScannerAcceptor) + ? (IFileSystemScannerAcceptor) acceptor + : null; } @Override @@ -67,13 +86,21 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th if (dir.endsWith(N4JSGlobals.NODE_MODULES)) { return FileVisitResult.SKIP_SUBTREE; } + if (fssAcceptor != null) { + return fssAcceptor.acceptDirectory(new FileURI(dir.toFile()).toURI()); + } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - acceptor.accept(new FileURI(file.toFile()).toURI()); - return FileVisitResult.CONTINUE; + URI uri = new FileURI(file.toFile()).toURI(); + if (fssAcceptor != null) { + return fssAcceptor.acceptFile(uri); + } else { + acceptor.accept(uri); + return FileVisitResult.CONTINUE; + } } @Override @@ -83,8 +110,9 @@ public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOExce @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - if (exc != null) + if (exc != null) { throw exc; + } return FileVisitResult.CONTINUE; } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/utils/FileVisitingAcceptor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/utils/FileVisitingAcceptor.java deleted file mode 100644 index 932c913f99..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/utils/FileVisitingAcceptor.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright (c) 2019 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.workspace.utils; - -import java.io.IOException; -import java.nio.file.FileVisitResult; -import java.nio.file.FileVisitor; -import java.nio.file.Path; -import java.nio.file.attribute.BasicFileAttributes; - -import org.eclipse.emf.common.util.URI; -import org.eclipse.n4js.N4JSGlobals; -import org.eclipse.n4js.workspace.locations.FileURI; -import org.eclipse.xtext.util.IAcceptor; - -/** - * A specialized acceptor that can be passed into the {@link FileSystemScanner} to get control over the scanned contents - * of the file tree. - * - * It allows skipping parts of the project, e.g. skipping traversal of node modules. - */ -public interface FileVisitingAcceptor extends FileVisitor, IAcceptor { - - @Override - void accept(URI uri); - - @Override - public default FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) - throws IOException { - if (dir.endsWith(N4JSGlobals.NODE_MODULES)) { - return FileVisitResult.SKIP_SUBTREE; - } - return FileVisitResult.CONTINUE; - } - - @Override - public default FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - throws IOException { - accept(new FileURI(file.toFile()).toURI()); - return FileVisitResult.CONTINUE; - } - - @Override - public default FileVisitResult visitFileFailed(Path file, IOException exc) - throws IOException { - throw exc; - } - - @Override - public default FileVisitResult postVisitDirectory(Path dir, IOException exc) - throws IOException { - if (exc != null) - throw exc; - return FileVisitResult.CONTINUE; - } -} \ No newline at end of file diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/utils/SemanticDependencySupplier.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/utils/SemanticDependencySupplier.java index d5ce2368ba..28534bde28 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/utils/SemanticDependencySupplier.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/workspace/utils/SemanticDependencySupplier.java @@ -180,6 +180,7 @@ private Path getPathToDependency(Path relatedRootLocation, Path projectLocation, // Second check if it is a dependency in the node_modules folder for (File nodeModulesDir : nodeModulesFolder.getNodeModulesFoldersInOrderOfPriority()) { Path absDepPath = nodeModulesDir.toPath().resolve(depName); + absDepPath = resolveSymbolicLinkOrDefault(absDepPath); if (candidatePaths.contains(absDepPath)) { // dependency in a node_modules folder return absDepPath; diff --git a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtSetupParser.java b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtSetupParser.java index 63b1cc9406..4ab18e65aa 100644 --- a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtSetupParser.java +++ b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtSetupParser.java @@ -268,6 +268,16 @@ private static XtWorkspace parseWorkspace(TokenStream tokens, File xtFile, Strin LOOP: while (tokens.hasNext()) { switch (tokens.next()) { + case "File": { // could be the package.json file of the workspace + FolderBuilder folderBuilder = yarnProjectBuilder.getOrAddFolder("."); + parseFile(tokens, xtFile, xtFileContent, false, folderBuilder); + break; + } + case "ThisFile": { // could be the package.json file of the workspace + FolderBuilder folderBuilder = yarnProjectBuilder.getOrAddFolder("."); + parseFile(tokens, xtFile, xtFileContent, true, folderBuilder); + break; + } case "Project": case "JavaProject": parseYarnProject(tokens, xtFile, xtFileContent, yarnProjectBuilder, false); diff --git a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/helper/mock/MockWorkspaceSupplier.java b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/helper/mock/MockWorkspaceSupplier.java index d8a2c572c8..4dfbf9e827 100644 --- a/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/helper/mock/MockWorkspaceSupplier.java +++ b/testhelpers/org.eclipse.n4js.tests.helper/src/org/eclipse/n4js/tests/helper/mock/MockWorkspaceSupplier.java @@ -146,7 +146,7 @@ protected List createSourceFolders(FileURI projectPath for (String path : sc.getPaths()) { sourceFolders.add(new N4JSSourceFolderSnapshot(path, projectPath.appendPath(path).withTrailingPathDelimiter().toURI(), sc.getType(), - path)); + path, null)); } } return sourceFolders; diff --git a/tests/org.eclipse.n4js.ide.tests/PDTs/yarnSymLinksInNodeModulesFolder1.pdt b/tests/org.eclipse.n4js.ide.tests/PDTs/yarnSymLinksInNodeModulesFolder1.pdt index 8e7e3cfa57..bf22368e25 100644 --- a/tests/org.eclipse.n4js.ide.tests/PDTs/yarnSymLinksInNodeModulesFolder1.pdt +++ b/tests/org.eclipse.n4js.ide.tests/PDTs/yarnSymLinksInNodeModulesFolder1.pdt @@ -17,5 +17,5 @@ FOLDERS EXPECT - mainLocation/P1 - mainLocation/P1/node_modules/P2 -- mainLocation/P1/node_modules/PX - mainLocation/P1/packages/P3 +- otherLocation/PX diff --git a/tests/org.eclipse.n4js.ide.tests/PDTs/yarnSymLinksInNodeModulesFolder2.pdt b/tests/org.eclipse.n4js.ide.tests/PDTs/yarnSymLinksInNodeModulesFolder2.pdt index 2fb98ff37d..08347ffd3b 100644 --- a/tests/org.eclipse.n4js.ide.tests/PDTs/yarnSymLinksInNodeModulesFolder2.pdt +++ b/tests/org.eclipse.n4js.ide.tests/PDTs/yarnSymLinksInNodeModulesFolder2.pdt @@ -20,5 +20,5 @@ FOLDERS EXPECT - mainLocation/P1 - mainLocation/P1/node_modules/P2 -- mainLocation/P1/node_modules/@someScope/PX - mainLocation/P1/packages/P3 +- otherLocation/@someScope/PX diff --git a/tests/org.eclipse.n4js.ide.tests/PDTs/yarnSymLinksInNodeModulesFolder3.pdt b/tests/org.eclipse.n4js.ide.tests/PDTs/yarnSymLinksInNodeModulesFolder3.pdt index 20dcf68fc9..8cb96d8d58 100644 --- a/tests/org.eclipse.n4js.ide.tests/PDTs/yarnSymLinksInNodeModulesFolder3.pdt +++ b/tests/org.eclipse.n4js.ide.tests/PDTs/yarnSymLinksInNodeModulesFolder3.pdt @@ -19,5 +19,5 @@ FOLDERS EXPECT - mainLocation/P1 - mainLocation/P1/node_modules/P2 -- mainLocation/P1/node_modules/@someScope/PX - mainLocation/P1/packages/P3 +- otherLocation/@someScope/PX diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/BuilderYarnWorkspaceTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/BuilderYarnWorkspaceTest.java index e98f571bba..601cc8da6e 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/BuilderYarnWorkspaceTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/BuilderYarnWorkspaceTest.java @@ -73,11 +73,12 @@ public m() {} }, "n4js": { "projectType": "library", - "mainModule": "src/folder/Other", + "mainModule": "folder/Other", "vendorId": "org.eclipse.n4js", + "output": "src-gen", "sources": { "source": [ - "." + "src" ] } } @@ -85,7 +86,7 @@ public m() {} """.formatted(otherProjectName)), "MainProject", Map.of( "Main1", """ - import {Other} from "src/folder/Other"; + import {Other} from "folder/Other"; new Other().m(); """, "Main2", """ diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/SymbolicLinkInWorkspaceTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/SymbolicLinkInWorkspaceTest.java index a4cfddd2af..c41427ffe8 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/SymbolicLinkInWorkspaceTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/SymbolicLinkInWorkspaceTest.java @@ -18,7 +18,6 @@ import org.eclipse.n4js.ide.tests.helper.server.AbstractIdeTest; import org.eclipse.n4js.utils.io.FileCopier; import org.eclipse.n4js.utils.io.FileDeleter; -import org.eclipse.n4js.utils.io.FileUtils; import org.junit.Test; /** @@ -33,7 +32,7 @@ public class SymbolicLinkInWorkspaceTest extends AbstractIdeTest { @Test public void testSymLinkInNodeModulesFolder() throws Exception { createYarnWorkspaceWithProjectMainWithDependencyTo("ProjectOther"); - Path other = createProjectOutsideWorkspace("ProjectOther", "Other"); + Path other = createProjectInPnpmFolder("ProjectOther", "Other"); Path nodeModulesFolder = getNodeModulesFolder().toPath(); Files.createSymbolicLink(nodeModulesFolder.resolve("ProjectOther"), other); startAndWaitForLspServer(); @@ -41,7 +40,7 @@ public void testSymLinkInNodeModulesFolder() throws Exception { assertProjectsInWorkspace( "yarn-test-project", "yarn-test-project/node_modules/n4js-runtime", - "yarn-test-project/node_modules/ProjectOther", + "yarn-test-project/node_modules/.pnpm/ProjectOther", "yarn-test-project/packages/ProjectMain"); assertNoIssues(); } @@ -49,7 +48,7 @@ public void testSymLinkInNodeModulesFolder() throws Exception { @Test public void testSymLinkInNodeModulesFolder_withScope01() throws Exception { createYarnWorkspaceWithProjectMainWithDependencyTo("@someScope/ProjectOther"); - Path other = createProjectOutsideWorkspace("@someScope/ProjectOther", "Other"); + Path other = createProjectInPnpmFolder("@someScope/ProjectOther", "Other"); Path nodeModulesFolder = getNodeModulesFolder().toPath(); Files.createSymbolicLink(nodeModulesFolder.resolve("@someScope"), other.getParent()); startAndWaitForLspServer(); @@ -57,7 +56,7 @@ public void testSymLinkInNodeModulesFolder_withScope01() throws Exception { assertProjectsInWorkspace( "yarn-test-project", "yarn-test-project/node_modules/n4js-runtime", - "yarn-test-project/node_modules/@someScope/ProjectOther", + "yarn-test-project/node_modules/.pnpm/@someScope/ProjectOther", "yarn-test-project/packages/ProjectMain"); assertNoIssues(); } @@ -65,7 +64,7 @@ public void testSymLinkInNodeModulesFolder_withScope01() throws Exception { @Test public void testSymLinkInNodeModulesFolder_withScope02() throws Exception { createYarnWorkspaceWithProjectMainWithDependencyTo("@someScope/ProjectOther"); - Path other = createProjectOutsideWorkspace("@someScope/ProjectOther", "Other"); + Path other = createProjectInPnpmFolder("@someScope/ProjectOther", "Other"); Path nodeModulesFolder = getNodeModulesFolder().toPath(); Files.createDirectory(nodeModulesFolder.resolve("@someScope")); Files.createSymbolicLink(nodeModulesFolder.resolve("@someScope").resolve("ProjectOther"), other); @@ -74,7 +73,7 @@ public void testSymLinkInNodeModulesFolder_withScope02() throws Exception { assertProjectsInWorkspace( "yarn-test-project", "yarn-test-project/node_modules/n4js-runtime", - "yarn-test-project/node_modules/@someScope/ProjectOther", + "yarn-test-project/node_modules/.pnpm/@someScope/ProjectOther", "yarn-test-project/packages/ProjectMain"); assertNoIssues(); } @@ -82,7 +81,7 @@ public void testSymLinkInNodeModulesFolder_withScope02() throws Exception { @Test public void testSymLinkInPackagesFolder() throws Exception { createYarnWorkspaceWithProjectMainWithDependencyTo("ProjectOther"); - Path other = createProjectOutsideWorkspace("ProjectOther", "Other"); + Path other = createProjectInPnpmFolder("ProjectOther", "Other"); Path packagesFolder = getProjectLocation().toPath(); Files.createSymbolicLink(packagesFolder.resolve("ProjectOther"), other); startAndWaitForLspServer(); @@ -98,7 +97,7 @@ public void testSymLinkInPackagesFolder() throws Exception { @Test public void testSymLinkInPackagesFolder_withScope01() throws Exception { createYarnWorkspaceWithProjectMainWithDependencyTo("@someScope/ProjectOther"); - Path other = createProjectOutsideWorkspace("@someScope/ProjectOther", "Other"); + Path other = createProjectInPnpmFolder("@someScope/ProjectOther", "Other"); Path packagesFolder = getProjectLocation().toPath(); Files.createSymbolicLink(packagesFolder.resolve("@someScope"), other.getParent()); startAndWaitForLspServer(); @@ -114,7 +113,7 @@ public void testSymLinkInPackagesFolder_withScope01() throws Exception { @Test public void testSymLinkInPackagesFolder_withScope02() throws Exception { createYarnWorkspaceWithProjectMainWithDependencyTo("@someScope/ProjectOther"); - Path other = createProjectOutsideWorkspace("@someScope/ProjectOther", "Other"); + Path other = createProjectInPnpmFolder("@someScope/ProjectOther", "Other"); Path packagesFolder = getProjectLocation().toPath(); Files.createDirectory(packagesFolder.resolve("@someScope")); Files.createSymbolicLink(packagesFolder.resolve("@someScope").resolve("ProjectOther"), other); @@ -131,7 +130,7 @@ public void testSymLinkInPackagesFolder_withScope02() throws Exception { @Test public void testSymLinkInProject_sourceFolderIsSymLink() throws Exception { createYarnWorkspaceWithProjectMainWithDependencyTo("ProjectOther"); - Path other = createProjectOutsideWorkspace("ProjectOther", "Other"); + Path other = createProjectInPnpmFolder("ProjectOther", "Other"); Path packagesFolder = getProjectLocation().toPath(); Path otherInWorkspace = packagesFolder.resolve("ProjectOther"); FileCopier.copy(other, otherInWorkspace); @@ -144,7 +143,7 @@ public void testSymLinkInProject_sourceFolderIsSymLink() throws Exception { @Test public void testSymLinkInProject_subFolderOfSourceFolderIsSymLink() throws Exception { createYarnWorkspaceWithProjectMainWithDependencyTo("ProjectOther"); - Path other = createProjectOutsideWorkspace("ProjectOther", "Other"); + Path other = createProjectInPnpmFolder("ProjectOther", "Other"); Path packagesFolder = getProjectLocation().toPath(); Path otherInWorkspace = packagesFolder.resolve("ProjectOther"); FileCopier.copy(other, otherInWorkspace); @@ -166,9 +165,10 @@ private void createYarnWorkspaceWithProjectMainWithDependencyTo(CharSequence dep CFG_DEPENDENCIES, dependenciesOfProjectMain))); } - private Path createProjectOutsideWorkspace(String projectName, String nameSuffix) throws IOException { - Path tempFolder = FileUtils.createTempDirectory(this.getClass().getSimpleName() + "_"); - Path projectFolder = tempFolder.resolve(projectName); // note: supports npm scopes! + private Path createProjectInPnpmFolder(String projectName, String nameSuffix) throws IOException { + // Path tempFolder = FileUtils.createTempDirectory(this.getClass().getSimpleName() + "_"); + Path pnpmFolder = getProjectLocation().getParentFile().toPath().resolve("node_modules/.pnpm"); + Path projectFolder = pnpmFolder.resolve(projectName); // note: supports npm scopes! Path srcFolder = projectFolder.resolve("src"); Path srcFolderABC = srcFolder.resolve("a").resolve("b").resolve("c"); Files.createDirectories(projectFolder); diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/buildorder/BuildOrderToDtsTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/buildorder/BuildOrderToDtsTest.java index 1e9f65a527..258a4757d5 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/buildorder/BuildOrderToDtsTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/buildorder/BuildOrderToDtsTest.java @@ -113,7 +113,7 @@ public void testNmfDepsToPlainJS_Def() { public void testPackagesDepsToPlainJS_A() { test("yarn-test-project, " + "yarn-test-project/node_modules/n4js-runtime, " + - "yarn-test-project/node_modules/PlainJS2, " + // PlainJS2 not ignored + "yarn-test-project/packages/PlainJS2, " + // PlainJS2 not ignored "yarn-test-project/packages/PlainJS1, " + "yarn-test-project/packages/MyProject", diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/xtext/workspace/ProjectSetTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/xtext/workspace/ProjectSetTest.java index caa70a2748..04524a0505 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/xtext/workspace/ProjectSetTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/xtext/workspace/ProjectSetTest.java @@ -61,7 +61,7 @@ private N4JSProjectConfigSnapshot createProjectConfig(URI path) { .setVersion(SemverUtils.createVersionNumber(0, 0, 1)) .build(); N4JSSourceFolderSnapshot srcFolder = new N4JSSourceFolderSnapshot("src", path.appendSegment("src"), - SourceContainerType.SOURCE, "src"); + SourceContainerType.SOURCE, "src", null); return new N4JSProjectConfigSnapshot(pd, path, false, true, Collections.emptyList(), Collections.singleton(srcFolder), Map.of()); } diff --git a/tests/org.eclipse.n4js.semver.tests/src/org/eclipse/n4js/semver/tests/parser/SemverParserTest.java b/tests/org.eclipse.n4js.semver.tests/src/org/eclipse/n4js/semver/tests/parser/SemverParserTest.java index cf7298abce..26e3eac0cf 100644 --- a/tests/org.eclipse.n4js.semver.tests/src/org/eclipse/n4js/semver/tests/parser/SemverParserTest.java +++ b/tests/org.eclipse.n4js.semver.tests/src/org/eclipse/n4js/semver/tests/parser/SemverParserTest.java @@ -25,6 +25,7 @@ import org.eclipse.n4js.semver.Semver.TagVersionRequirement; import org.eclipse.n4js.semver.Semver.URLVersionRequirement; import org.eclipse.n4js.semver.Semver.VersionRangeSetRequirement; +import org.eclipse.n4js.semver.Semver.WorkspaceVersionRequirement; import org.eclipse.xtext.serializer.ISerializer; import org.eclipse.xtext.testing.InjectWith; import org.eclipse.xtext.testing.XtextRunner; @@ -185,6 +186,16 @@ public class SemverParserTest { "latest" ); + List workspaceData =List.of( + "workspace:*", + "workspace:~", + "workspace:^", + "workspace:^1.0.5", + "workspace:foo@*", + "workspace:2.0.0", + "workspace:../foo" + ); + List errorData =List.of( "001tag", "1s", @@ -236,6 +247,12 @@ public void testNPMTagParseAndToString() throws Exception { internalTestParseAndToString(tagData, TagVersionRequirement.class, (s) -> s); } + /** Checks other NPM supported versions. */ + @Test + public void testNPMWorkspaceParseAndToString() throws Exception { + internalTestParseAndToString(workspaceData, WorkspaceVersionRequirement.class, (s) -> s); + } + /** Checks other NPM supported versions. */ @Test public void testNPMError() throws Exception { diff --git a/tests/org.eclipse.n4js.utils.tests/src/org/eclipse/n4js/utils/YamlUtilTest.java b/tests/org.eclipse.n4js.utils.tests/src/org/eclipse/n4js/utils/YamlUtilTest.java new file mode 100644 index 0000000000..74b51464fb --- /dev/null +++ b/tests/org.eclipse.n4js.utils.tests/src/org/eclipse/n4js/utils/YamlUtilTest.java @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2024 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.utils; + +import org.junit.Assert; +import org.junit.Test; + +import com.google.common.collect.Multimap; + +/** + * + */ +public class YamlUtilTest { + + @Test + public void testPnpmWorkspaceYaml() { + Multimap map = YamlUtil.loadYamlFromString(""" + # NOTE: Experimental, local packages from the workspace are preferred over packages from the registry + prefer-workspace-packages: true + packages: + - 'packages/*' + """); + + String result = Strings.join("\n", e -> e.getKey() + " => " + e.getValue(), map.entries()); + + Assert.assertEquals(""" + prefer-workspace-packages => true + packages => packages/*""", result); + } + + @Test + public void testYaml1() { + Multimap map = YamlUtil.loadYamlFromString(""" + --- + # A sample yaml file + company: spacelift + domain: + - devops + - devsecops + tutorial: + - yaml: + name: "YAML Ain't Markup Language" + type: awesome + born: 2001 + - json: + name: JavaScript Object Notation + type: great + born: 2001 + - xml: + name: Extensible Markup Language + type: good + born: 1996 + author: omkarbirade + published: true + """); + + String result = Strings.join("\n", e -> e.getKey() + " => " + e.getValue(), map.entries()); + + Assert.assertEquals(""" + company => spacelift + domain => devops + domain => devsecops + tutorial:yaml:name => YAML Ain't Markup Language + tutorial:yaml:type => awesome + tutorial:yaml:born => 2001 + tutorial:json:name => JavaScript Object Notation + tutorial:json:type => great + tutorial:json:born => 2001 + tutorial:xml:name => Extensible Markup Language + tutorial:xml:type => good + tutorial:xml:born => 1996 + author => omkarbirade + published => true""", result); + } + + @Test + public void testYaml1WithComments() { + Multimap map = YamlUtil.loadYamlFromString(""" + --- + # key: value [mapping] + company: spacelift + # key: value is an array [sequence] + domain: + - devops + - devsecops + tutorial: + - yaml: + name: "YAML Ain't Markup Language" #string [literal] + type: awesome #string [literal] + born: 2001 #number [literal] + - json: + name: JavaScript Object Notation #string [literal] + type: great #string [literal] + born: 2001 #number [literal] + - xml: + name: Extensible Markup Language #string [literal] + type: good #string [literal] + born: 1996 #number [literal] + author: omkarbirade + published: true + """); + + String result = Strings.join("\n", e -> e.getKey() + " => " + e.getValue(), map.entries()); + + Assert.assertEquals(""" + company => spacelift + domain => devops + domain => devsecops + tutorial:yaml:name => YAML Ain't Markup Language + tutorial:yaml:type => awesome + tutorial:yaml:born => 2001 + tutorial:json:name => JavaScript Object Notation + tutorial:json:type => great + tutorial:json:born => 2001 + tutorial:xml:name => Extensible Markup Language + tutorial:xml:type => good + tutorial:xml:born => 1996 + author => omkarbirade + published => true""", result); + } + + /** Actually this is not correct since the multi line string should be a single entry */ + @Test + public void testYamlSimpleMultiline() { + Multimap map = YamlUtil.loadYamlFromString(""" + message: this is + a real multiline + message + """); + + String result = Strings.join("\n", e -> e.getKey() + " => " + e.getValue(), map.entries()); + + Assert.assertEquals(""" + message => this is + message => a real multiline + message => message""", result); + } + + @Test + public void testYamlBacktrack() { + Multimap map = YamlUtil.loadYamlFromString(""" + tutorial: + - yaml: + - one: empty + - two: empty + - json: empty + - xml: empty + """); + + String result = Strings.join("\n", e -> e.getKey() + " => " + e.getValue(), map.entries()); + + Assert.assertEquals(""" + tutorial:yaml:one => empty + tutorial:yaml:two => empty + tutorial:json => empty + tutorial:xml => empty""", result); + } +} diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_arr.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_arr.xt new file mode 100644 index 0000000000..1d6da243d8 --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_arr.xt @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 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 + */ + +/* + XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest + + + Workspace { + ThisFile "package.json" {} + File "pnpm-workspace.yaml" { from="pnpm-workspace.yaml" } + } + + + File "pnpm-workspace.yaml" { +packages: + - 'packages/*' + } + + END_SETUP + */ + + +{ + "author": "Enfore AG", + "license": "UNLICENSED", + "private": true, + "type": "module", + "engines": { + "node": ">=20.2", + "pnpm": ">=8" + }, + "pnpm": { + "patchedDependencies": { + "pdf-parse@1.1.1": "patches/pdf-parse@1.1.1.patch" + } + }, + // XPECT warnings --> "This property is overridden by property 'packages' in file pnpm-workspaces.yaml." at "\"workspaces\"" + "workspaces": [ + "packages/*" + ] +} diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_obj.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_obj.xt new file mode 100644 index 0000000000..05fecebfd2 --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_obj.xt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 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 + */ + +/* + XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest + + + Workspace { + ThisFile "package.json" {} + File "pnpm-workspace.yaml" { from="pnpm-workspace.yaml" } + } + + + File "pnpm-workspace.yaml" { +packages: + - 'packages/*' + } + + END_SETUP + */ + + +{ + "author": "Enfore AG", + "license": "UNLICENSED", + "private": true, + "type": "module", + "engines": { + "node": ">=20.2", + "pnpm": ">=8" + }, + "pnpm": { + "patchedDependencies": { + "pdf-parse@1.1.1": "patches/pdf-parse@1.1.1.patch" + } + }, + // XPECT warnings --> "This property is overridden by property 'packages' in file pnpm-workspaces.yaml." at "\"workspaces\"" + "workspaces": { + "packages": [ + "packages/*" + ], + "nohoist": [ + "**/source-map" + ] + } +} diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_prefer_yarn.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_prefer_yarn.xt new file mode 100644 index 0000000000..75dbd26b9d --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_prefer_yarn.xt @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 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 + */ + +/* + XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest + + + Workspace { + ThisFile "package.json" {} + File "pnpm-workspace.yaml" { from="pnpm-workspace.yaml" } + } + + + File "pnpm-workspace.yaml" { +useYarnConfig: true +packages: + - 'packages/*' + } + + END_SETUP + */ + + +{ + "author": "Enfore AG", + "license": "UNLICENSED", + "private": true, + "type": "module", + "engines": { + "node": ">=20.2", + "pnpm": ">=8" + }, + "pnpm": { + "patchedDependencies": { + "pdf-parse@1.1.1": "patches/pdf-parse@1.1.1.patch" + } + }, + // XPECT nowarnings --> "This property is overridden by property 'packages' in file pnpm-workspaces.yaml." at "\"workspaces\"" + "workspaces": [ + "packages/*" + ] +} diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_prefer_yarn_false.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_prefer_yarn_false.xt new file mode 100644 index 0000000000..f1695c4c38 --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/packagejson_pnpm/package.json_workspace_prefer_yarn_false.xt @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 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 + */ + +/* + XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest + + + Workspace { + ThisFile "package.json" {} + File "pnpm-workspace.yaml" { from="pnpm-workspace.yaml" } + } + + + File "pnpm-workspace.yaml" { +useYarnConfig: false +packages: + - 'packages/*' + } + + END_SETUP + */ + + +{ + "author": "Enfore AG", + "license": "UNLICENSED", + "private": true, + "type": "module", + "engines": { + "node": ">=20.2", + "pnpm": ">=8" + }, + "pnpm": { + "patchedDependencies": { + "pdf-parse@1.1.1": "patches/pdf-parse@1.1.1.patch" + } + }, + // XPECT warnings --> "This property is overridden by property 'packages' in file pnpm-workspaces.yaml." at "\"workspaces\"" + "workspaces": [ + "packages/*" + ] +} From d3ba9f4c7788c77aec843c283803113e4f5bd9fe Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Wed, 17 Jan 2024 13:30:42 +0100 Subject: [PATCH 11/26] GH-2592: As a smith I want to update node in the docker image (and fix extended tests) (#2594) * bump node dependency version * support for pnpm * fix copy/paste issue --- .../src/org/eclipse/n4js/N4JSGlobals.java | 2 +- .../org/eclipse/n4js/cli/helper/CliTools.java | 7 ++ .../n4js/cli/helper/TestProcessBuilder.java | 16 +++++ .../n4js/cli/helper/TestProcessExecuter.java | 5 ++ .../n4js/cli/utils/BinariesConstants.java | 29 ++++++++ .../n4js/cli/utils/BinariesLocatorHelper.java | 66 +++++++++++++++++++ 6 files changed, 124 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/N4JSGlobals.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/N4JSGlobals.java index 2a370a9241..bbfb51a7d6 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/N4JSGlobals.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/N4JSGlobals.java @@ -44,7 +44,7 @@ public final class N4JSGlobals { * * If it contains fewer than three version segments, all numbers for the remaining segments are deemed compatible. */ - public static final String NODE_VERSION = "20.3"; + public static final String NODE_VERSION = "20.10"; /** URL of the public npm registry. */ public static final String NPMJS_URL = "https://registry.npmjs.org/"; diff --git a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/CliTools.java b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/CliTools.java index 322f047fc5..be37d0bb35 100644 --- a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/CliTools.java +++ b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/CliTools.java @@ -213,6 +213,13 @@ public ProcessResult yarnRun(Path workingDir, String... options) { }); } + /** see {@link TestProcessExecuter#pnpmRun(Path, Map, String[])} */ + public ProcessResult pnpmRun(Path workingDir, String... options) { + return withoutCorruptingGlobalState(() -> { + return getExProcessExecuter().pnpmRun(workingDir, environment, options); + }); + } + /** see {@link TestProcessExecuter#gitRun(Path, Map, String[])} */ public ProcessResult gitRun(Path workingDir, String... options) { return withoutCorruptingGlobalState(() -> { diff --git a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/TestProcessBuilder.java b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/TestProcessBuilder.java index 1ba2773928..fbaed26faf 100644 --- a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/TestProcessBuilder.java +++ b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/TestProcessBuilder.java @@ -57,6 +57,12 @@ public ProcessBuilder yarnRun(Path workingDirectory, Map environ return createProcessBuilder(workingDirectory, cmd, environment); } + /** @return a process: {@code pnpm install} */ + public ProcessBuilder pnpmRun(Path workingDirectory, Map environment, String[] options) { + final String[] cmd = createCommandPnpmRun(environment, options); + return createProcessBuilder(workingDirectory, cmd, environment); + } + /** @return a process: {@code git OPTIONS} */ public ProcessBuilder gitRun(Path workingDirectory, Map environment, String[] options) { final String[] cmd = createCommandGitRun(environment, options); @@ -110,6 +116,16 @@ private String[] createCommandYarnRun(Map output_env, String[] o return cmd.toArray(new String[0]); } + private String[] createCommandPnpmRun(Map output_env, String[] options) { + List cmd = getCommands(output_env, binariesLocatorHelper.getPnpmBinary(), options); + + // yarn will invoke node, so node must be on the path: + Path nodePath = binariesLocatorHelper.getNodeBinary().toAbsolutePath().getParent(); + prependToPathString(output_env, nodePath); + + return cmd.toArray(new String[0]); + } + private String[] createCommandGitRun(Map output_env, String[] options) { List cmd = getCommands(output_env, binariesLocatorHelper.getGitBinary(), options); diff --git a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/TestProcessExecuter.java b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/TestProcessExecuter.java index 276efd30f1..f90e99b99a 100644 --- a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/TestProcessExecuter.java +++ b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/TestProcessExecuter.java @@ -72,6 +72,11 @@ public ProcessResult yarnRun(Path workingDir, Map environment, S return joinProcess("yarn", () -> testProcessBuilder.yarnRun(workingDir, environment, options)); } + /** Runs pnpm OPTIONS in the given {@code workingDir} */ + public ProcessResult pnpmRun(Path workingDir, Map environment, String... options) { + return joinProcess("pnpm", () -> testProcessBuilder.pnpmRun(workingDir, environment, options)); + } + /** Runs git OPTIONS in the given {@code workingDir} */ public ProcessResult gitRun(Path workingDir, Map environment, String... options) { return joinProcess("git", () -> testProcessBuilder.gitRun(workingDir, environment, options)); diff --git a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/utils/BinariesConstants.java b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/utils/BinariesConstants.java index 03fa894d38..c73cb30f24 100644 --- a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/utils/BinariesConstants.java +++ b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/utils/BinariesConstants.java @@ -57,6 +57,11 @@ public final class BinariesConstants { */ public static final String DEFAULT_YARN_PATH_VM_ARG = "org.eclipse.n4js.defaultYarnPath"; + /** + * Default pnpm path, similar to {@code DEFAULT_NODE_PATH_VM_ARG} + */ + public static final String DEFAULT_PNPM_PATH_VM_ARG = "org.eclipse.n4js.defaultPnpmPath"; + /** * Default git path, similar to {@code DEFAULT_NODE_PATH_VM_ARG} */ @@ -87,6 +92,16 @@ public final class BinariesConstants { */ public static final String YARN_PATH_ENV = "YARN_PATH"; + /** + * Jenkins environment variable for the {@code pnpm} binary path. Points to the actual binary (with an absolute + * path) instead of pointing to the folder containing the binary. + * + *

+ * Even if it is available the {@link #DEFAULT_PNPM_PATH_VM_ARG org.eclipse.n4js.defaultPnpmPath} VM + * argument might override this configuration. + */ + public static final String PNPM_PATH_ENV = "PNPM_PATH"; + /** * Jenkins environment variable for the {@code git} binary path. Points to the actual binary (with an absolute path) * instead of pointing to the folder containing the binary. @@ -131,6 +146,18 @@ public final class BinariesConstants { ? new File("C:" + separator + "Program Files" + separator + "yarn").getAbsolutePath() : new File(separator + "usr" + File.separator + "local" + separator + "bin").getAbsolutePath(); + /** + * The (fallback) built-in default {@code pnpm} path if the above VM or ENV property is not specified. + * + *

    + *
  • On Windows systems: {@code C:\Program Files\pnpm}
  • + *
  • On Unix systems: {@code /usr/local/bin}
  • + *
+ */ + public static final String BUILT_IN_DEFAULT_PNPM_PATH = isWindows() + ? new File("C:" + separator + "Program Files" + separator + "pnpm").getAbsolutePath() + : new File(separator + "usr" + File.separator + "local" + separator + "bin").getAbsolutePath(); + /** * The (fallback) built-in default {@code git} path if the above VM or ENV property is not specified. * @@ -179,6 +206,8 @@ public final class BinariesConstants { public static final String YARN_LABEL = "Yarn"; /** The {@code yarn} binary name without file extension. */ public static final String YARN_BINARY_NAME = "yarn"; + /** The {@code pnpm} binary name without file extension. */ + public static final String PNPM_BINARY_NAME = "pnpm"; /** The {@code git} binary name without file extension. */ public static final String GIT_BINARY_NAME = "git"; /** The minimum {@code yarn} version. */ diff --git a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/utils/BinariesLocatorHelper.java b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/utils/BinariesLocatorHelper.java index 92ac421e2d..c3f28c3472 100644 --- a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/utils/BinariesLocatorHelper.java +++ b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/utils/BinariesLocatorHelper.java @@ -55,6 +55,7 @@ public class BinariesLocatorHelper { private Path memoizedNodePath = null; private Path memoizedNpmPath = null; private Path memoizedYarnPath = null; + private Path memoizedPnpmPath = null; private Path memoizedGitPath = null; /** Returns the path to the Java binary. */ @@ -89,6 +90,14 @@ public Path getYarnBinary() { return memoizedYarnPath; } + /** Returns the path to the pnpm binary. */ + public Path getPnpmBinary() { + if (memoizedPnpmPath == null) { + memoizedPnpmPath = findPnpmPath().resolve(BinariesConstants.PNPM_BINARY_NAME); + } + return memoizedPnpmPath; + } + /** Returns the path to the yarn binary. */ public Path getGitBinary() { if (memoizedGitPath == null) { @@ -229,6 +238,63 @@ private Path findYarnPath() { return yarnPathCandidate; } + /** + * Like {@link #findNodePath()}, but for the pnpm binary. + * + * @return string with absolute path to the binary + */ + private Path findPnpmPath() { + Path pnpmPathCandidate = null; + + // 1. lookup by DEFAULT_YARN_PATH_VM_ARG + pnpmPathCandidate = resolveFolderContaingBinary( + tryGetEnvOrSystemVariable(BinariesConstants.DEFAULT_PNPM_PATH_VM_ARG)); + if (pnpmPathCandidate != null) { + info("User specified default pnpm path will be used: '" + pnpmPathCandidate + + ".' based on the '" + BinariesConstants.DEFAULT_PNPM_PATH_VM_ARG + "' VM argument."); + return pnpmPathCandidate; + } + debug("Could not resolve pnpm path from '" + BinariesConstants.DEFAULT_PNPM_PATH_VM_ARG + + "' VM argument."); + + // 2. lookup by YARN_PATH_ENV + pnpmPathCandidate = resolveFolderContaingBinary( + tryGetEnvOrSystemVariable(BinariesConstants.PNPM_PATH_ENV)); + if (pnpmPathCandidate != null) { + info("User specified default pnpm path will be used: '" + pnpmPathCandidate + + ".' based on the '" + BinariesConstants.PNPM_PATH_ENV + "' environment argument."); + return pnpmPathCandidate; + } + debug("Could not resolve pnpm path from '" + BinariesConstants.PNPM_PATH_ENV); + + // 3. lookup by PATH + pnpmPathCandidate = resolveFolderContaingBinary( + ExecutableLookupUtil.findInPath(BinariesConstants.PNPM_BINARY_NAME)); + if (pnpmPathCandidate != null) { + info("Obtained pnpm path will be used: '" + pnpmPathCandidate + + ".' based on the OS PATH."); + return pnpmPathCandidate; + } + debug("Could not resolve pnpm path from OS PATH variable."); + + // 4. lookup by OS query + pnpmPathCandidate = resolveFolderContaingBinary( + lookForBinary(BinariesConstants.PNPM_BINARY_NAME)); + if (pnpmPathCandidate != null) { + info("Obtained pnpm path will be used: '" + pnpmPathCandidate + + ".' based on the OS dynamic lookup."); + return pnpmPathCandidate; + + } + debug("Could not resolve pnpm path from OS dynamic lookup."); + + // 5. use default, whether it is correct or not. + info("Could not resolve pnpm path. Falling back to default path: " + pnpmPathCandidate); + pnpmPathCandidate = new File(BinariesConstants.BUILT_IN_DEFAULT_PNPM_PATH).toPath(); + + return pnpmPathCandidate; + } + /** * Like {@link #findNodePath()}, but for the git binary. * From fa8bd2322ce69acd1de57ea9701ebe6d507cb936 Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Thu, 18 Jan 2024 16:38:45 +0100 Subject: [PATCH 12/26] GH-2588: Exported d.ts files contain non-public elements (#2591) * add tests * support pnpm for project discovery tests * fix bug in node_modules identification * fix project discovery and ide tests --- .../utils/NodeModulesDiscoveryHelper.java | 12 ++- .../n4js/utils/ProjectDiscoveryHelper.java | 19 +++-- .../helper/server/TestWorkspaceManager.java | 15 +++- .../helper/mock/MockWorkspaceSupplier.java | 2 +- .../PDTs/pnpmDependency1.pdt | 19 +++++ .../PDTs/pnpmDependency2.pdt | 25 +++++++ .../PDTs/pnpmSimple1.pdt | 15 ++++ .../PDTs/pnpmSimple2.pdt | 18 +++++ .../IncrementalBuilderCopiedProjectTest.java | 4 +- .../buildorder/AbstractBuildOrderTest.java | 8 +- .../BuildOrderDependenciesTest.java | 5 +- .../OrganizeImportsAddMissingTest.java | 1 - .../CreateProjectStructureUtils.java | 75 +++++++++++++------ 13 files changed, 175 insertions(+), 43 deletions(-) create mode 100644 tests/org.eclipse.n4js.ide.tests/PDTs/pnpmDependency1.pdt create mode 100644 tests/org.eclipse.n4js.ide.tests/PDTs/pnpmDependency2.pdt create mode 100644 tests/org.eclipse.n4js.ide.tests/PDTs/pnpmSimple1.pdt create mode 100644 tests/org.eclipse.n4js.ide.tests/PDTs/pnpmSimple2.pdt diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/NodeModulesDiscoveryHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/NodeModulesDiscoveryHelper.java index 932e7d535a..1bbec41944 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/NodeModulesDiscoveryHelper.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/NodeModulesDiscoveryHelper.java @@ -85,13 +85,21 @@ public boolean isYarnWorkspace() { return this.workspaceNodeModulesFolder != null; } - /** @return the related root of this project */ - public Path getRelatedRoot() { + /** @return the local root of this project */ + public Path getLocalRoot() { if (isYarnWorkspaceRoot || isYarnWorkspaceMember || isYarnWorkspaceDependency) { return workspaceNodeModulesFolder.getParentFile().toPath(); } return localNodeModulesFolder.getParentFile().toPath(); } + + /** @return the workspace root of this project */ + public Path getWorkspaceRoot() { + if (workspaceNodeModulesFolder != null) { + return workspaceNodeModulesFolder.getParentFile().toPath(); + } + return localNodeModulesFolder.getParentFile().toPath(); + } } /** @return the node_modules folder of the given project including a flag if this is a yarn workspace. */ diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDiscoveryHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDiscoveryHelper.java index f627ee01ed..560fd3330f 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDiscoveryHelper.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDiscoveryHelper.java @@ -431,7 +431,8 @@ private Set collectNecessaryDependencies(Set allProjectDirs, Map allProjectDirs, Path projectDir, Map pdCache, Set dependencies) { - NodeModulesFolder nodeModulesFolder = nodeModulesDiscoveryHelper.getNodeModulesFolder(projectDir, pdCache); + Path wsRoot = nodeModulesDiscoveryHelper.getNodeModulesFolder(projectDir, pdCache).getWorkspaceRoot(); + LinkedHashSet workList = new LinkedHashSet<>(); workList.add(projectDir); while (!workList.isEmpty()) { @@ -439,16 +440,18 @@ private void collectProjectDependencies(Set allProjectDirs, Path projectDi Path nextProject = iterator.next(); iterator.remove(); - findDependencies(allProjectDirs, nextProject, nodeModulesFolder, pdCache, workList, dependencies); + NodeModulesFolder nodeModulesFolder = nodeModulesDiscoveryHelper.getNodeModulesFolder(nextProject, pdCache); + findDependencies(allProjectDirs, nextProject, wsRoot, nodeModulesFolder, pdCache, workList, dependencies); } } - private void findDependencies(Set allProjectDirs, Path prjDir, NodeModulesFolder nodeModulesFolder, - Map pdCache, Set workList, Set dependencies) { + private void findDependencies(Set allProjectDirs, Path prjDir, Path wsRoot, + NodeModulesFolder nodeModulesFolder, Map pdCache, Set workList, + Set dependencies) { - Path relatedRoot = nodeModulesFolder.getRelatedRoot(); + // Path wsRoot = nodeModulesFolder.getWorkspaceRoot(); Path prjNodeModules = prjDir.resolve(N4JSGlobals.NODE_MODULES); - ProjectDescription prjDescr = getOrCreateProjectDescription(prjDir, relatedRoot, pdCache); + ProjectDescription prjDescr = getOrCreateProjectDescription(prjDir, wsRoot, pdCache); if (prjDescr == null) { return; } @@ -457,8 +460,8 @@ private void findDependencies(Set allProjectDirs, Path prjDir, NodeModules String depName = dependency.getPackageName(); Path depLocation = findDependencyLocation(nodeModulesFolder, prjNodeModules, depName); - if (isNewDependency(allProjectDirs, prjDir, pdCache, depLocation, relatedRoot)) { - addDependency(depLocation, relatedRoot, pdCache, workList, dependencies); + if (isNewDependency(allProjectDirs, prjDir, pdCache, depLocation, wsRoot)) { + addDependency(depLocation, wsRoot, pdCache, workList, dependencies); } } } diff --git a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/TestWorkspaceManager.java b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/TestWorkspaceManager.java index 27371cf37e..8c164f392c 100644 --- a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/TestWorkspaceManager.java +++ b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/TestWorkspaceManager.java @@ -582,6 +582,7 @@ private Project createSimpleProject(String projectName, Map> cy throw new RuntimeException("Never happens since toString never throws an exception. Bogus xtext warning", exc); } - assertEquals(cycles.size(), projectBuildOrderInfo.getProjectCycles().size()); + ImmutableCollection> projectCycles = projectBuildOrderInfo.getProjectCycles(); + assertEquals("Cycle: " + Strings.join(", ", projectCycles), cycles.size(), projectCycles.size()); Set expectedCycles = cycles.stream().map(it -> Strings.join(", ", it)).collect(Collectors.toSet()); - for (List cycle : projectBuildOrderInfo.getProjectCycles()) { + for (List cycle : projectCycles) { String detectedCycle = Strings.join(", ", cycle); assertTrue("Cycle " + detectedCycle + " not found in " + expectedCycles, expectedCycles.contains(detectedCycle)); diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/buildorder/BuildOrderDependenciesTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/buildorder/BuildOrderDependenciesTest.java index 7e7b437ba3..71c0ba20a1 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/buildorder/BuildOrderDependenciesTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/buildorder/BuildOrderDependenciesTest.java @@ -17,13 +17,13 @@ /** * Test for build order */ - public class BuildOrderDependenciesTest extends AbstractBuildOrderTest { @Test public void testSingleDependency1() { testProject( "test-project/node_modules/n4js-runtime, " + + "test-project/node_modules/D2/node_modules/n4js-runtime, " + "test-project/node_modules/D2, " + "test-project/node_modules/D1, " + "test-project", @@ -45,8 +45,9 @@ public void testSingleDependency1() { @Test public void testSingleDependency2() { testProject( - "test-project/node_modules/n4js-runtime, " + + "test-project/node_modules/@scope/D2/node_modules/n4js-runtime, " + "test-project/node_modules/@scope/D2, " + + "test-project/node_modules/n4js-runtime, " + "test-project/node_modules/D1, " + "test-project", Map.of( diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/codeActions/OrganizeImportsAddMissingTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/codeActions/OrganizeImportsAddMissingTest.java index 9a2f7c364a..8f7b5ee4ff 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/codeActions/OrganizeImportsAddMissingTest.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/codeActions/OrganizeImportsAddMissingTest.java @@ -18,7 +18,6 @@ /** * Like {@link OrganizeImportsTest}, but covers cases in which a missing import has to be added during organize imports. */ - public class OrganizeImportsAddMissingTest extends AbstractOrganizeImportsTest { @Test diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/projectdiscovery/CreateProjectStructureUtils.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/projectdiscovery/CreateProjectStructureUtils.java index 0479144e29..a19fd17c46 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/projectdiscovery/CreateProjectStructureUtils.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/projectdiscovery/CreateProjectStructureUtils.java @@ -30,13 +30,18 @@ */ public class CreateProjectStructureUtils { + enum WorkspaceType { + Yarn, Pnpm + } + static class Folder { final Folder parent; final String folderName; final boolean isWorkingDir; final boolean isProject; final boolean isPlainJS; - final String yarnWorkspacesFolder; + final WorkspaceType workspaceType; + final String workspacesFolder; // either yarn or pnpm final String name; final String dependencies; final String packagejson; @@ -47,14 +52,16 @@ static class Folder { final Path symLinkTarget; Folder(Folder parent, String folderName, boolean isWorkingDir, boolean isProject, boolean isPlainJS, - String yarnWorkspacesFolder, String name, String dependencies, Path symLinkTarget, String packagejson) { + WorkspaceType workspaceType, String workspacesFolder, String name, String dependencies, + Path symLinkTarget, String packagejson) { this.parent = parent; this.folderName = folderName; this.isWorkingDir = isWorkingDir; this.isProject = isProject; this.isPlainJS = isPlainJS; - this.yarnWorkspacesFolder = yarnWorkspacesFolder; + this.workspaceType = workspaceType; + this.workspacesFolder = workspacesFolder; this.name = name; this.dependencies = dependencies; this.symLinkTarget = symLinkTarget; @@ -76,7 +83,7 @@ public String toString() { str += folderName; if (isProject) { str += "[PROJECT"; - str += (yarnWorkspacesFolder == null) ? "" : " workspaces= " + yarnWorkspacesFolder + " "; + str += (workspacesFolder == null) ? "" : " workspaces= " + workspacesFolder + " "; str += (name == null) ? "" : " name= " + name + " "; str += (dependencies == null) ? "" : " dependencies= " + dependencies + " "; str += (packagejson == null) ? "" : " package.json= " + packagejson + " "; @@ -205,7 +212,8 @@ private static Folder readFolder(String folderStr, List parents) { boolean isProject = false; boolean isPlainJS = false; - String yarnWorkspacesFolder = null; + WorkspaceType workspaceType = WorkspaceType.Yarn; + String workspacesFolder = null; String dependencies = null; String name = null; Path symLinkTarget = null; @@ -246,11 +254,21 @@ private static Folder readFolder(String folderStr, List parents) { if (restLine.startsWith("workspaces")) { restLine = restLine.substring("workspaces".length()).trim(); + if (restLine.startsWith("-yarn")) { + // default + restLine = restLine.substring("-yarn".length()).trim(); + workspaceType = WorkspaceType.Yarn; + } + if (restLine.startsWith("-pnpm")) { + restLine = restLine.substring("-pnpm".length()).trim(); + workspaceType = WorkspaceType.Pnpm; + } if (restLine.startsWith("=")) { restLine = restLine.substring(1).trim(); int startIndex = restLine.indexOf("["); int endIndex = restLine.indexOf("]"); - yarnWorkspacesFolder = restLine.substring(startIndex, endIndex + 1); + // includes brackets + workspacesFolder = restLine.substring(startIndex, endIndex + 1); restLine = restLine.substring(endIndex + 1).trim(); } @@ -280,25 +298,26 @@ private static Folder readFolder(String folderStr, List parents) { } } - return new Folder(parent, folderName, isWorkingDir, isProject, isPlainJS, yarnWorkspacesFolder, name, - dependencies, - symLinkTarget, packagejson); + return new Folder(parent, folderName, isWorkingDir, isProject, isPlainJS, workspaceType, workspacesFolder, name, + dependencies, symLinkTarget, packagejson); } /** Creates the folder structure specified by {@link ProjectDiscoveryTestData} in the given dir */ public static void createFolderStructure(File dir, ProjectDiscoveryTestData pdtd) { for (Folder folder : pdtd.folders) { - String folderPath = folder.getPath(); - File folderFile = new File(dir, folderPath); - if (folder.symLinkTarget != null) { - createSymbolicLink(dir, folderFile, folder.symLinkTarget); - } else { + if (folder.symLinkTarget == null) { + File folderFile = new File(dir, folder.getPath()); folderFile.mkdir(); if (folder.isProject) { createPackageJson(folderFile, folder); } } } + for (Folder folder : pdtd.folders) { + if (folder.symLinkTarget != null) { + createSymbolicLink(dir, new File(dir, folder.getPath()), folder.symLinkTarget); + } + } } private static void createSymbolicLink(File root, File folderFile, Path symLinkTarget) { @@ -319,7 +338,7 @@ private static void createPackageJson(File folderFile, Folder folder) { contents = folder.packagejson; } else { contents = "{"; - if (folder.yarnWorkspacesFolder == null) { + if (folder.workspacesFolder == null) { String projectName = folder.folderName; if (folder.parent != null && folder.parent.folderName.startsWith("@")) { projectName = folder.parent.folderName + "/" + projectName; @@ -328,19 +347,29 @@ private static void createPackageJson(File folderFile, Folder folder) { if (!folder.isPlainJS) { contents += "\"n4js\": {\"projectType\": \"library\"}"; } - } else { - contents += "\"private\": true, \"workspaces\": " + folder.yarnWorkspacesFolder + ""; + } else if (folder.workspaceType == WorkspaceType.Yarn) { + contents += "\"private\": true, \"workspaces\": " + folder.workspacesFolder + ""; + } else if (folder.workspaceType == WorkspaceType.Pnpm) { + File pnpmWorkspaceYaml = new File(folderFile, N4JSGlobals.PNPM_WORKSPACE); + try (PrintWriter printWriter = new PrintWriter(new FileWriter(pnpmWorkspaceYaml))) { + String workspacesFolder = folder.workspacesFolder.substring(1, + folder.workspacesFolder.length() - 1); + printWriter.println("packages:\n - " + workspacesFolder); + } catch (IOException e) { + throw new WrappedException("exception while creating a package.json file", e); + } } contents += (folder.dependencies == null) ? "" : ", \"dependencies\":" + folder.dependencies; contents += "}"; } - File packageJson = new File(folderFile, N4JSGlobals.PACKAGE_JSON); - - try (PrintWriter printWriter = new PrintWriter(new FileWriter(packageJson))) { - printWriter.println(contents); - } catch (IOException e) { - throw new WrappedException("exception while creating a package.json file", e); + if (!contents.isBlank()) { + File packageJson = new File(folderFile, N4JSGlobals.PACKAGE_JSON); + try (PrintWriter printWriter = new PrintWriter(new FileWriter(packageJson))) { + printWriter.println(contents); + } catch (IOException e) { + throw new WrappedException("exception while creating a package.json file", e); + } } } } From 3d420f1d89a6d861c8cb3e9560e126792faaf4b7 Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Tue, 23 Jan 2024 11:01:22 +0100 Subject: [PATCH 13/26] GH-2595: The d.ts export should append .js file extensions in import statements (#2598) * d.ts exports emit type imports including file extension * respect existing file extension * add test * fix fileExtension() * fix xt framework * respect bare imports * add test --- .../dts/print/PrettyPrinterDts.java | 13 ++++ .../src/org/eclipse/n4js/utils/URIUtils.java | 5 ++ .../ide/tests/helper/server/xt/XtIdeTest.java | 4 +- .../ReferenceToNonDtsProject.n4js.xt | 2 +- .../dts-export/imports/BareImport.n4js.xt | 40 +++++++++++ .../imports/DefaultAsImport.n4js.xt | 2 +- .../imports/ImportForLiteralType1.n4js.xt | 8 +-- .../imports/ImportForLiteralType2.n4js.xt | 8 +-- .../imports/ImportMustBeAdded1.n4js.xt | 2 +- .../ImportMustBeAdded2_withAlias.n4js.xt | 2 +- ...BeAdded3_forIndirectlyExportedElem.n4js.xt | 2 +- .../imports/ImportWithExtension.n4js.xt | 70 +++++++++++++++++++ .../imports/ModuleSpecifiers.n4js.xt | 4 +- .../imports/NamespaceAccess.n4js.xt | 2 +- .../UseExistingNamespaceImport.n4js.xt | 2 +- .../inferredTypes/InferredTypes2.n4js.xt | 2 +- ...InferredTypesImportUsedInStatement.n4js.xt | 2 +- .../inferredTypes/ReplaceWildcard.n4js.xt | 4 +- .../inferredTypes/UpperBounds.n4js.xt | 6 +- 19 files changed, 155 insertions(+), 25 deletions(-) create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/BareImport.n4js.xt create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportWithExtension.n4js.xt diff --git a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/print/PrettyPrinterDts.java b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/print/PrettyPrinterDts.java index 5a6650d623..2bc5c6a22d 100644 --- a/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/print/PrettyPrinterDts.java +++ b/plugins/org.eclipse.n4js.transpiler.dts/src/org/eclipse/n4js/transpiler/dts/print/PrettyPrinterDts.java @@ -43,6 +43,7 @@ import org.eclipse.n4js.n4JS.ImportDeclaration; import org.eclipse.n4js.n4JS.ImportSpecifier; import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName; +import org.eclipse.n4js.n4JS.ModuleSpecifierForm; import org.eclipse.n4js.n4JS.N4ClassDeclaration; import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; import org.eclipse.n4js.n4JS.N4EnumDeclaration; @@ -89,6 +90,7 @@ import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; import org.eclipse.n4js.utils.N4JSLanguageUtils; import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind; +import org.eclipse.n4js.utils.URIUtils; import org.eclipse.n4js.utils.parser.conversion.ValueConverterUtils; import org.eclipse.xtext.EcoreUtil2; @@ -214,8 +216,19 @@ public Boolean caseImportDeclaration(ImportDeclaration original) { ? original.getModuleSpecifierAsText().replace("%3A", ":") // see ModuleSpecifierValueConverter : original.getModule().getQualifiedName(); + if (original.getModuleSpecifierForm() != ModuleSpecifierForm.PROJECT + && Strings.isNullOrEmpty(URIUtils.fileExtension(URIUtils.toFileUri(moduleSpecifier)))) { + + String extension = original.isBare() ? N4JSGlobals.JS_FILE_EXTENSION : N4JSGlobals.DTS_FILE_EXTENSION; + moduleSpecifier += "." + extension; + } + processAnnotations(original.getAnnotations()); write("import "); + if (!original.isBare()) { + write("type "); + } + // 1) import specifiers List importSpecifiers = new ArrayList<>(original.getImportSpecifiers()); if (!importSpecifiers.isEmpty() && importSpecifiers.get(0) instanceof DefaultImportSpecifier) { diff --git a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/URIUtils.java b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/URIUtils.java index 589b80d8ff..612b850d49 100644 --- a/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/URIUtils.java +++ b/plugins/org.eclipse.n4js.utils/src/org/eclipse/n4js/utils/URIUtils.java @@ -93,12 +93,17 @@ static private int fileExtensionIndex(URI uri) { if (firstIdx < 0) { return -1; } + boolean foundDot = false; for (int idx = firstIdx; idx > 0; idx--) { if (lastSegment.charAt(idx) == '.') { + foundDot = true; firstIdx = idx + 1; break; } } + if (!foundDot) { + return -1; + } String ext1 = lastSegment.substring(firstIdx); if (extensionPrefixes.containsKey(ext1)) { int scndIdx = firstIdx - 2; diff --git a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtIdeTest.java b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtIdeTest.java index d4912189fb..2b998542b6 100644 --- a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtIdeTest.java +++ b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/xt/XtIdeTest.java @@ -773,10 +773,12 @@ public void generated_dts(XtMethodData data) throws IOException { for (Project project : allProjectsWithGenerateDts) { File workingDir = getProjectRoot(project.getName()); + Path wdSrcDir = workingDir.toPath().resolve("src-gen"); + wdSrcDir.toFile().mkdirs(); // might not exist e.g. if is a definition project // copy n4jsglobals.d.ts to output dir to make d.ts globals available Path n4jsGlobalsDTS = N4jsLibsAccess.getN4JSGlobalsDTS(); - Files.copy(n4jsGlobalsDTS, workingDir.toPath().resolve("src-gen/n4jsglobals.d.ts")); + Files.copy(n4jsGlobalsDTS, wdSrcDir.resolve("n4jsglobals.d.ts")); ProcessResult result; try { diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/cutOffReferences/ReferenceToNonDtsProject.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/cutOffReferences/ReferenceToNonDtsProject.n4js.xt index 54f0ce532d..5a5a2027cc 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/cutOffReferences/ReferenceToNonDtsProject.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/cutOffReferences/ReferenceToNonDtsProject.n4js.xt @@ -51,7 +51,7 @@ export public class Cls1 extends ClassWithDts {} export public class Cls2 extends ClassWithoutDts {} /* XPECT generated_dts --- -import {ClassWithDts} from 'ProjectOtherWithDts/src-gen/OtherWithDts' +import type {ClassWithDts} from 'ProjectOtherWithDts/src-gen/OtherWithDts.d.ts' export let v1: ClassWithDts; export let v2: any; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/BareImport.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/BareImport.n4js.xt new file mode 100644 index 0000000000..5a5b1aff60 --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/BareImport.n4js.xt @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest + + Workspace { + Project "TestProject" { + Folder "src" { + ThisFile {} + File "BareImportMe.js" { } + } + } + } + + File "BareImportMe.js" { + export public class CP {} + } + + GENERATE_DTS + +END_SETUP */ + + + +import "BareImportMe"; + + + +/* XPECT generated_dts --- +import './BareImportMe.js' + +--- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/DefaultAsImport.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/DefaultAsImport.n4js.xt index 2b63bbb7f9..59fc56e903 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/DefaultAsImport.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/DefaultAsImport.n4js.xt @@ -34,7 +34,7 @@ export public class Dummy extends MyClass {} // ensures that the import is not r /* XPECT generated_dts --- -import {default as MyClass} from './Other' +import type {default as MyClass} from './Other.d.ts' export class Dummy extends MyClass {} --- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportForLiteralType1.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportForLiteralType1.n4js.xt index 92984a903e..2ae867d1ff 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportForLiteralType1.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportForLiteralType1.n4js.xt @@ -38,10 +38,10 @@ export public const redStringBased = ColorStringBased.RED; /* XPECT generated_dts --- -import {Color} from './Other' -import {ColorWithLiteralValues} from './Other' -import {ColorNumberBased} from './Other' -import {ColorStringBased} from './Other' +import type {Color} from './Other.d.ts' +import type {ColorWithLiteralValues} from './Other.d.ts' +import type {ColorNumberBased} from './Other.d.ts' +import type {ColorStringBased} from './Other.d.ts' export const red: Color; export const redWithLiteralValues: ColorWithLiteralValues; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportForLiteralType2.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportForLiteralType2.n4js.xt index ae8ec42eee..18a28f899a 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportForLiteralType2.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportForLiteralType2.n4js.xt @@ -38,10 +38,10 @@ export public const redStringBased = getRedStringBased(); /* XPECT generated_dts --- -import {ColorStringBased} from './Other' -import {ColorNumberBased} from './Other' -import {ColorWithLiteralValues} from './Other' -import {Color} from './Other' +import type {ColorStringBased} from './Other.d.ts' +import type {ColorNumberBased} from './Other.d.ts' +import type {ColorWithLiteralValues} from './Other.d.ts' +import type {Color} from './Other.d.ts' export const red: Color; export const redWithLiteralValues: ColorWithLiteralValues; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportMustBeAdded1.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportMustBeAdded1.n4js.xt index 16553ff463..d6cbc6a26e 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportMustBeAdded1.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportMustBeAdded1.n4js.xt @@ -32,7 +32,7 @@ export const C = F(); /* XPECT generated_dts --- -import {Cls} from './Other' +import type {Cls} from './Other.d.ts' export const C: Cls; --- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportMustBeAdded2_withAlias.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportMustBeAdded2_withAlias.n4js.xt index ea9e4715de..21d13e0678 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportMustBeAdded2_withAlias.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportMustBeAdded2_withAlias.n4js.xt @@ -37,7 +37,7 @@ class Cls { /* XPECT generated_dts --- -import {Cls as Cls2} from './Other' +import type {Cls as Cls2} from './Other.d.ts' export const C: Cls2; declare class Cls {} diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportMustBeAdded3_forIndirectlyExportedElem.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportMustBeAdded3_forIndirectlyExportedElem.n4js.xt index d8ec8d886b..9dc41b4194 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportMustBeAdded3_forIndirectlyExportedElem.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportMustBeAdded3_forIndirectlyExportedElem.n4js.xt @@ -43,7 +43,7 @@ export const C = F(); /* XPECT generated_dts --- -import {ClsExportedName} from './Other' +import type {ClsExportedName} from './Other.d.ts' export const C: ClsExportedName; --- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportWithExtension.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportWithExtension.n4js.xt new file mode 100644 index 0000000000..3d194a8606 --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ImportWithExtension.n4js.xt @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest + + Workspace { + Project "TestProject" { + Folder "src" { + ThisFile {} + } + DEPENDS_ON "ImportMe" + } + Project "ImportMe" { + Folder "src" { + File "index.n4js" { } + } + File "package.json" {} + } + } + + File "index.n4js" { + export public class CP {} + } + + File "package.json" { + { + "name": "ImportMe", + "version": "1.0.0", + "type": "module", + "types": "src-gen/index.d.ts", + "scripts": {}, + "n4js": { + "vendorId": "VENDOR", + "vendorName": "VENDOR_NAME", + "projectType": "library", + "output": "src-gen", + "generator": { "d.ts": true }, + "sources": { + "source": ["./src"] + } + }, + "dependencies": { + "n4js-runtime": "" + } + } + } + + GENERATE_DTS + +END_SETUP */ + + +import * as TS from "ImportMe"; + +export public class CPX extends TS.CP {} + + +/* XPECT generated_dts --- +import type * as TS from 'ImportMe' + +export class CPX extends TS.CP {} +--- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ModuleSpecifiers.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ModuleSpecifiers.n4js.xt index 7ad8dbe387..688acc7358 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ModuleSpecifiers.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/ModuleSpecifiers.n4js.xt @@ -43,8 +43,8 @@ export let clsOtherLocal: ClsOtherLocal; /* XPECT generated_dts --- -import {ClsOther as ClsOtherRemote} from 'ProjectOther/src-gen/RemoteOther' -import {ClsOther as ClsOtherLocal} from './LocalOther' +import type {ClsOther as ClsOtherRemote} from 'ProjectOther/src-gen/RemoteOther.d.ts' +import type {ClsOther as ClsOtherLocal} from './LocalOther.d.ts' export let clsOtherRemote: ClsOtherRemote; export let clsOtherLocal: ClsOtherLocal; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/NamespaceAccess.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/NamespaceAccess.n4js.xt index ba63efebe5..e0add12c13 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/NamespaceAccess.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/NamespaceAccess.n4js.xt @@ -36,7 +36,7 @@ export public class Cls extends NS.SomeClass {} /* XPECT generated_dts --- -import * as NS from './Other' +import type * as NS from './Other.d.ts' export let x: NS.SomeClass; export function foo(p: NS.SomeClass): NS.SomeClass; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/UseExistingNamespaceImport.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/UseExistingNamespaceImport.n4js.xt index 228f6837ca..06709ba431 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/UseExistingNamespaceImport.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/imports/UseExistingNamespaceImport.n4js.xt @@ -30,7 +30,7 @@ export public let x = NS.foo(); /* XPECT generated_dts --- -import * as NS from './Other' +import type * as NS from './Other.d.ts' export let x: NS.ClsOther; --- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/InferredTypes2.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/InferredTypes2.n4js.xt index e0ae62d480..08d88eebd5 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/InferredTypes2.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/InferredTypes2.n4js.xt @@ -58,7 +58,7 @@ export class ClassWithFields { /* XPECT generated_dts --- -import {ClassDirectExported} from 'ProjectOtherDirect/src-gen/OtherDirect' +import type {ClassDirectExported} from 'ProjectOtherDirect/src-gen/OtherDirect.d.ts' export let v1: ClassDirectExported; export let v2: any; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/InferredTypesImportUsedInStatement.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/InferredTypesImportUsedInStatement.n4js.xt index fadb21228c..e46cb9c6cd 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/InferredTypesImportUsedInStatement.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/InferredTypesImportUsedInStatement.n4js.xt @@ -37,7 +37,7 @@ export class ClassWithFields { /* XPECT generated_dts --- -import {ClassOther} from './Other' +import type {ClassOther} from './Other.d.ts' export let v: ClassOther; export class ClassWithFields { diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/ReplaceWildcard.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/ReplaceWildcard.n4js.xt index e8e6fe0e28..0aee3d89ee 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/ReplaceWildcard.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/ReplaceWildcard.n4js.xt @@ -29,8 +29,8 @@ import {C} from "Other"; const c: C = null /* XPECT generated_dts --- -import {D} from './Other' -import {C} from './Other' +import type {D} from './Other.d.ts' +import type {C} from './Other.d.ts' declare const c: C; --- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/UpperBounds.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/UpperBounds.n4js.xt index b14a9dc340..88f4eb0872 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/UpperBounds.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/dts-export/inferredTypes/UpperBounds.n4js.xt @@ -43,9 +43,9 @@ export class ClassWithFields { /* XPECT generated_dts --- -import {ClassExported} from 'ProjectOther/src-gen/Other' -import {GenClassOfClassExported} from 'ProjectOther/src-gen/Other' -import {GenClassOfClassNotExported} from 'ProjectOther/src-gen/Other' +import type {ClassExported} from 'ProjectOther/src-gen/Other.d.ts' +import type {GenClassOfClassExported} from 'ProjectOther/src-gen/Other.d.ts' +import type {GenClassOfClassNotExported} from 'ProjectOther/src-gen/Other.d.ts' export let v1: GenClassOfClassExported; export let v2: GenClassOfClassNotExported; From 5f1fb548149fa51755a5b7f11470ae7fae6f4623 Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Tue, 6 Feb 2024 15:58:47 +0100 Subject: [PATCH 14/26] GH-2600: N4JS-Mangelhaft is unable to load test modules when used in a pnpm workspace (#2601) * support globs, remove obsolete modules, adjust catalog discovery * preparation to replace TestInfo#origin by TestCatalogInfo#packageName * fix comment * fix start-up and clean-up instrumentation * fix glob support, refactor file resolution * fix test * several refactorings * fix test * improve test runner output * minor unrelated changes * rename test method --- n4js-libs/npm-test.sh | 8 +- .../mangelhaft/runner/node/NodeTestAPI.n4js | 89 -------- .../mangelhaft/runner/node/NodeTestCLI.n4js | 15 +- .../mangelhaft/runner/node/NodeTestMain.n4js | 10 +- .../runner/node/NodeTestOptions.n4js | 10 +- .../runner/node/NodeTestRunner.n4js | 208 +++++++++++------- .../runner/node/ProjectDiscoverer.n4js | 93 -------- .../src/n4js/n4js/lang/N4Injector.n4js | 2 +- .../PreconditionNotMetConstructorTest.n4js | 35 +++ .../reporter/xunit/XUnitReporter.n4js | 1 + .../n4js/mangelhaft/TestController.n4js | 47 ++-- .../n4js/mangelhaft/types/ResultGroup.n4js | 1 + .../n4js/mangelhaft/types/ResultGroups.n4js | 29 ++- .../mangelhaft/types/TestCatalogInfo.n4js | 25 +++ .../n4js/mangelhaft/types/TestInfo.n4js | 9 +- .../n4js/mangelhaft/types/TestInfos.n4js | 17 -- .../eclipse/n4js/cli/init/InitResources.java | 7 +- .../tests/cli/compile/N4jscInitTest.java | 11 +- 18 files changed, 270 insertions(+), 347 deletions(-) delete mode 100644 n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestAPI.n4js delete mode 100644 n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/ProjectDiscoverer.n4js create mode 100644 n4js-libs/packages/org.eclipse.n4js.mangelhaft.assert.test/test/n4js/org/eclipse/n4js/mangelhaft/assert/test/precondition/PreconditionNotMetConstructorTest.n4js create mode 100644 n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestCatalogInfo.n4js delete mode 100644 n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestInfos.n4js diff --git a/n4js-libs/npm-test.sh b/n4js-libs/npm-test.sh index 666fd783d9..e77299e450 100755 --- a/n4js-libs/npm-test.sh +++ b/n4js-libs/npm-test.sh @@ -18,15 +18,13 @@ echo "========= Running tests defined in the individual packages of yarn workspa echo "========= Running mangelhaft tests for all packages in yarn workspace 'n4js-libs' ..." -REPORT_NAME="./build/report.xml" mkdir -p "./build" echo "Run mangelhaft ..." -packages/n4js-mangelhaft-cli/src-gen/org/eclipse/n4js/mangelhaft/runner/node/NodeTestMain.js \ - ./packages/org.eclipse.n4js.mangelhaft.test/test-catalog.json \ - --xunitReportFile $REPORT_NAME \ +yarn run n4js-mangelhaft \ + packages/* \ + --xunitReportFile "./build/report.xml" \ --sonarTestExecutionReportFile ./build/sqreport.xml \ --xunitReportName test-report \ --xunitReportPackage n4js-libs-report \ --nycCoveragePath ./build/coverage.json echo "Done running mangehaft." -echo "Saved test report at: ${REPORT_NAME}" diff --git a/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestAPI.n4js b/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestAPI.n4js deleted file mode 100644 index 2e388af24c..0000000000 --- a/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestAPI.n4js +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2018 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 - */ - -import debug from "debug"; -import {NodeTestCLI} from "org/eclipse/n4js/mangelhaft/runner/node/NodeTestCLI"; -import NodeTestOptions from "org/eclipse/n4js/mangelhaft/runner/node/NodeTestOptions"; -import {fsSafeAccessSync} from "org/eclipse/n4js/mangelhaft/util/fs"; -import {readJsonFile} from "org/eclipse/n4js/mangelhaft/util/fs"; -import {PACKAGE_JSON} from "org/eclipse/n4js/mangelhaft/util/npm"; -import * as child_process from "child_process"; -import * as lib_path from "path"; -import * as lib_url from "url"; - -const __dirname = lib_path.dirname(lib_url.fileURLToPath(import.meta.url)); - -const log = debug("n4js-mangelhaft:api"); -const rlog = debug("n4js-mangelhaft:test-run"); - -function readPackageJson(prjPath: string): Object+ { - const packageJsonPath = lib_path.join(prjPath, PACKAGE_JSON); - return fsSafeAccessSync(packageJsonPath) ? readJsonFile(packageJsonPath) : null; -} - -export default public class NodeTestAPI { - /** - * Executes a test run (might include compilation) with the given set of test options. - */ - public static async exec(options: NodeTestOptions): void { - log("options: %O", options); - - // try to resolve file: - const file = lib_path.resolve(process.cwd(), options.testCatalog); - if (fsSafeAccessSync(file)) { - options.testCatalog = file; - } else { // try to resolve via NPM - try { - options.testCatalog = require.resolve(options.testCatalog); - } catch (exc) { - throw new Error(`Cannot resolve test catalog: ${options.testCatalog}`); - } - } - - log("testing with test catalog:", options.testCatalog); - - await new Promise((resolve, reject) => { - rlog("execPath:", process.execPath); - const modulePath = lib_path.join(__dirname, "NodeTestRunner.js"); - rlog("modulePath:", modulePath); - - const execArgv = process.execArgv.slice(); - - if (options.nodeOptions) { - const optsAsArr = options.nodeOptions.split(/\s+/); - for (const opt of optsAsArr) { - execArgv.push(opt); - } - } - if (options.inspectBrk) { - execArgv.push(`--inspect-brk=${options.inspectBrk}`); - } - rlog("execArgv:", execArgv); - const args = NodeTestCLI.toCommandLine(options); // fodder in same args - rlog("args:", args); - - //rlog("env:", process.env); - - child_process.fork(modulePath, args, { - stdio: "inherit", - execArgv: execArgv, - env: process.env - }).on("close", code => { - rlog("exit code:", code); - if (code === 0) { - resolve(code); - } else { - reject(code); - } - }); - }); - } -} diff --git a/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestCLI.n4js b/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestCLI.n4js index 985d321072..0a2d60b393 100644 --- a/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestCLI.n4js +++ b/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestCLI.n4js @@ -17,18 +17,23 @@ const cwd = process.cwd(); const resolvePath = (p: string): string => lib_path.resolve(cwd, p); const nomnomOptions: Object = { - testCatalog: { + testCatalogs: { position: 0, - list: false, - default: ".", - metavar: "PATH|NPM-relpath", - help: "Test catalog (JSON) or project location to be inspected for test cases." + list: true, + default: ["."], + metavar: "PATH|NPM-relpath|glob", + help: "Test catalog (JSON) or project location(s) to be inspected for test catalog(s)." }, filter: { abbr: "f", list: true, help: "Filter for matching test cases." }, + mergeResult: { + abbr: "mr", + flag: true, + help: "Merge all results into a single file stored in CWD." + }, xunitReportFile: { metavar: "PATH", transform: resolvePath, diff --git a/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestMain.n4js b/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestMain.n4js index 416bddaa83..11a69b83bd 100644 --- a/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestMain.n4js +++ b/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestMain.n4js @@ -10,13 +10,5 @@ * NumberFour AG - Initial API and implementation */ -import NodeTestAPI from "org/eclipse/n4js/mangelhaft/runner/node/NodeTestAPI"; -import {NodeTestCLI} from "org/eclipse/n4js/mangelhaft/runner/node/NodeTestCLI"; -import {waitAndExitProcess} from "org/eclipse/n4js/mangelhaft/util/proc"; -waitAndExitProcess(async () => { - const options = NodeTestCLI.parseCommandLine(); - if (options) { - await NodeTestAPI.exec(options); - } -}); +import("./NodeTestRunner.js"); diff --git a/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestOptions.n4js b/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestOptions.n4js index a39cf683b9..3626a7f843 100644 --- a/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestOptions.n4js +++ b/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestOptions.n4js @@ -15,14 +15,20 @@ import { XUnitReportSpec } from "org/eclipse/n4js/mangelhaft/reporter/xunit/XUni */ export default public class NodeTestOptions extends XUnitReportSpec { /** - * Test catalog to be tested. + * One or more files/directories/globs pointing to the test catalog to be tested. */ - public testCatalog: string; + public testCatalogs: string[]; + /** * Filter for matching test cases. */ public filter: string[]; + /** + * Merge all results into a single file stored in CWD. + */ + public mergeResult: boolean; + /** * Sonar base dir. */ diff --git a/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestRunner.n4js b/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestRunner.n4js index ff9bc36c58..604c6cb490 100644 --- a/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestRunner.n4js +++ b/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/NodeTestRunner.n4js @@ -9,32 +9,36 @@ * NumberFour AG - Initial API and implementation */ +import * as lib_fs from "fs"; import {Module} from "module"; +import * as lib_glob from "glob"; +import * as lib_path from "path"; +import cli_color_+ from "cli-color"; +import * as lib_coverage+ from "istanbul-lib-coverage"; +import {NodeTestCLI} from "org/eclipse/n4js/mangelhaft/runner/node/NodeTestCLI"; import {N4Injector} from "n4js/lang/N4Injector"; import {FIXME1} from "org/eclipse/n4js/mangelhaft/Test"; import {FIXME2} from "org/eclipse/n4js/mangelhaft/Test"; import {IFIXME} from "org/eclipse/n4js/mangelhaft/Test"; import {IFIXME2} from "org/eclipse/n4js/mangelhaft/Test"; import {TestController} from "org/eclipse/n4js/mangelhaft/TestController"; -import {ConsoleReporter} from "org/eclipse/n4js/mangelhaft/reporter/console/ConsoleReporter"; -import {XUnitReporter} from "org/eclipse/n4js/mangelhaft/reporter/xunit/XUnitReporter"; -import {NodeTestCLI} from "org/eclipse/n4js/mangelhaft/runner/node/NodeTestCLI"; import {ITestReporter} from "org/eclipse/n4js/mangelhaft/types/ITestReporter"; +import {ResultGroups} from "org/eclipse/n4js/mangelhaft/types/ResultGroups"; +import {TestCatalogInfo} from "org/eclipse/n4js/mangelhaft/types/TestCatalogInfo"; import {TestDIComponent} from "org/eclipse/n4js/mangelhaft/types/TestDIComponent"; import {TestInfo} from "org/eclipse/n4js/mangelhaft/types/TestInfo"; -import {TestInfos} from "org/eclipse/n4js/mangelhaft/types/TestInfos"; +import {mkdirp} from "org/eclipse/n4js/mangelhaft/util/fs"; import {readJsonFile} from "org/eclipse/n4js/mangelhaft/util/fs"; import {waitAndExitProcess} from "org/eclipse/n4js/mangelhaft/util/proc"; -import {findProjectDirectories} from "org/eclipse/n4js/mangelhaft/runner/node/ProjectDiscoverer"; -import cli_color_+ from "cli-color"; -import * as lib_path from "path"; -import * as lib_fs from "fs"; -import * as lib_coverage+ from "istanbul-lib-coverage"; +import {ConsoleReporter} from "org/eclipse/n4js/mangelhaft/reporter/console/ConsoleReporter"; import {SonarReporter} from "org/eclipse/n4js/mangelhaft/reporter/sonar/SonarReporter"; -import {mkdirp} from "org/eclipse/n4js/mangelhaft/util/fs"; +import {XUnitReporter} from "org/eclipse/n4js/mangelhaft/reporter/xunit/XUnitReporter"; + +const DEFAULT_TEST_CATALOG_NAME = "test-catalog.json"; + +export public class NodeTestRunner { -class NodeTestRunner { @Inject controller: TestController; @Inject @@ -51,60 +55,38 @@ class NodeTestRunner { } const log = options.quiet ? function(...p) {} : console.log.bind(console); - let testCatalog: TestInfos; - - const stat = lib_fs.statSync(options.testCatalog); - if (stat.isFile()) { - testCatalog = loadTestCatalog(log, options.testCatalog); - } else if (stat.isDirectory()) { - const projectDirs : string[] = findProjectDirectories(options.testCatalog); - const testCatalogs : TestInfos[] = loadTestCatalogsInDirectories(log, projectDirs); - testCatalog = mergeTestCatalogs(testCatalogs); - if (!testCatalog) { - log("Did not find any test catalogs in: " + projectDirs); - return; - } - } else { - throw "Unsupported value for option 'testCatalog': " + options.testCatalog; - } + let testCatalogs: TestCatalogInfo[] = []; - if (options.filter && options.filter.length) { // filter out tests - const filters = options.filter.slice(0).sort(); - const descriptors: TestInfo[] = []; - - for (const info of testCatalog.testDescriptors) { - let methods = new Set(); - for (const filter of filters) { - const [fqnFilter, methodFilter] = filter.split("#"); - if (!fqnFilter || info.fqn.indexOf(fqnFilter) >= 0) { - if (methodFilter) { // filter methods - for (const method of info.testMethods) { - if (method.indexOf(methodFilter) >= 0) { - methods.add(method); - } - } - } else { - methods = new Set(info.testMethods); // take all - break; - } + for (let testCatalogArg of options.testCatalogs) { + const newTestCatalogs = await findTestCatalogs(testCatalogArg, log); + if (options.filter && options.filter.length) { + for (let testCatalog of newTestCatalogs) { + filterTestCatalog(testCatalog, options.filter); + if (testCatalog.testDescriptors.length > 0) { + testCatalogs.push(testCatalog); } } - if (methods.size > 0) { - info.testMethods = Array.from(methods); - descriptors.push(info); + } else { + if (newTestCatalogs.length > 0) { + testCatalogs = testCatalogs.concat(newTestCatalogs); } } - testCatalog.testDescriptors = descriptors; + } + + if (testCatalogs.length == 0) { + log("\nNo tests found."); } this.consoleReporter.cliColor = cli_color_; this.consoleReporter.setLogger(log); const reporters: ITestReporter[] = [this.consoleReporter]; + const allResultGroups : ResultGroups[] = []; + let updateXUnitReportPackage = false; if (options.xunitReportFile) { if (!options.xunitReportPackage) { - options.xunitReportPackage = lib_path.dirname(options.testCatalog); + updateXUnitReportPackage = true; } this.xunitReporter.spec = options; reporters.push(this.xunitReporter); @@ -117,17 +99,33 @@ class NodeTestRunner { } this.controller.reporters = reporters; - - const resGroups = await this.controller.runGroups(testCatalog, 420187, options.testScope); const cliColor = this.consoleReporter.cliColor; const success = cliColor.green.bind(cliColor); const fail = cliColor.red.bind(cliColor); const skipped = cliColor.cyan.bind(cliColor); - log(`\nTesting completed: ${success("SUCCESSES")}: ${resGroups.successes}, ${fail("FAILURES")}: ${resGroups.failures}, ${fail("ERRORS")}: ${resGroups.errors}, ${skipped("SKIPPED")}: ${resGroups.skipped}`); - const failed = (resGroups.failures !== 0) || (resGroups.errors !== 0); + + for (let testCatalog of testCatalogs) { + if (updateXUnitReportPackage) { + options.xunitReportPackage = lib_path.dirname(testCatalog.location); + } + + const resGroups = await this.controller.runGroups(testCatalog, 420187, options.testScope); + allResultGroups.push(resGroups); + + if (testCatalogs.length > 1) { + log(`\nTested ${testCatalog.location}\nTesting results: ${success("SUCCESSES")}: ${resGroups.successes}, ${fail("FAILURES")}: ${resGroups.failures}, ${fail("ERRORS")}: ${resGroups.errors}, ${skipped("SKIPPED")}: ${resGroups.skipped}`); + } + } + + const concatResultGroups = ResultGroups.concatArray(allResultGroups); + log(`\nTesting completed: ${success("SUCCESSES")}: ${concatResultGroups.successes}, ${fail("FAILURES")}: ${concatResultGroups.failures}, ${fail("ERRORS")}: ${concatResultGroups.errors}, ${skipped("SKIPPED")}: ${concatResultGroups.skipped}`); + + const failed = (concatResultGroups.failures !== 0) || (concatResultGroups.errors !== 0); if (failed) { - log(`${fail("Test run failed.")} To rerun just the failing tests use the command: \n n4js-mangelhaft ${this.consoleReporter.unsuccessfulTests.map(test => `\\\n -f ${test}`).join(" ")}`); + const optionCmdLine = NodeTestCLI.toCommandLine(options); + const failedTests = this.consoleReporter.unsuccessfulTests.map(test => `\\\n -f ${test}`).join(" "); + log(`${fail("Test run failed.")} To rerun the failing tests only, execute: \n n4js-mangelhaft ${optionCmdLine} ${failedTests}`); } const nycCoveragePath = options.nycCoveragePath; @@ -154,38 +152,92 @@ class NodeTestRunner { } } -function loadTestCatalog(log: {function(any):void}, testCatalogFile: string) : TestInfos { - log("Loading test catalog: " + testCatalogFile); - return readJsonFile(testCatalogFile); +async function findTestCatalogs(testCatalogArg: string, log: {function(...any):void}) : TestCatalogInfo[] { + const testCatalogLocations = resolveGlob(process.cwd(), testCatalogArg); + const testCatalogs : TestCatalogInfo[] = []; + for (const testCatalogLocation of testCatalogLocations) { + let testCatalog = resolveTestCatalog(testCatalogLocation, log); + if (testCatalog) { + testCatalogs.push(testCatalog); + } + } + return testCatalogs; } -function loadTestCatalogsInDirectories(log: {function(any):void}, projectDirs: string[]) : TestInfos[] { - const catalogs : TestInfos[] = []; - for (const pd of projectDirs) { - const potentialTestCatalogFile = lib_path.resolve(pd, "test-catalog.json"); - if (lib_fs.existsSync(potentialTestCatalogFile) && lib_fs.statSync(potentialTestCatalogFile).isFile()) { - const catalog = loadTestCatalog(log, potentialTestCatalogFile); - catalogs.push(catalog); +function resolveGlob(root: string, glob: string) : string[] { + const testCatalogLocations : string[] = []; + const options = { cwd: root, absolute: true, sync: true }; + const ee = new lib_glob.Glob(glob, options); + const foundLocs = ee.found; + + for (const foundLoc of foundLocs) { + if (lib_fs.existsSync(foundLoc)) { + const locStat = lib_fs.statSync(foundLoc); + if (locStat.isFile()) { + testCatalogLocations.push(foundLoc); + } else if (locStat.isDirectory()) { + const testCatalogFile = lib_path.join(foundLoc, DEFAULT_TEST_CATALOG_NAME); + testCatalogLocations.push(testCatalogFile); + } } } - return catalogs; + return testCatalogLocations; } -function mergeTestCatalogs(testCatalogs: TestInfos[]) : TestInfos { - if (!testCatalogs || testCatalogs.length === 0) { - return null; - } - const mergedTI = new TestInfos(); - mergedTI.endpoint = testCatalogs[0].endpoint; - mergedTI.sessionId = testCatalogs[0].sessionId; - for (const ti of testCatalogs) { - for (const td of ti.testDescriptors) { - mergedTI.testDescriptors.push(td); +function resolveTestCatalog(fileLocation: string, log: {function(...any):void}) : TestCatalogInfo { + if (lib_fs.existsSync(fileLocation)) { + const stat = lib_fs.statSync(fileLocation); + if (stat.isFile()) { + return loadTestCatalog(log, fileLocation); + } else if (stat.isDirectory()) { + const potentialTestCatalogFile = lib_path.resolve(fileLocation, DEFAULT_TEST_CATALOG_NAME); + if (lib_fs.existsSync(potentialTestCatalogFile) && lib_fs.statSync(potentialTestCatalogFile).isFile()) { + return loadTestCatalog(log, potentialTestCatalogFile); + } } } - return mergedTI; + log("No test catalog in: " + fileLocation); + return null; } +function loadTestCatalog(log: {function(any):void}, testCatalogFile: string) : TestCatalogInfo { + log("Loading test catalog: " + testCatalogFile); + let testCatalog : TestCatalogInfo = readJsonFile(testCatalogFile); + testCatalog.location = lib_path.dirname(testCatalogFile); + testCatalog.fileName = lib_path.basename(testCatalogFile); + testCatalog.testDescriptors = testCatalog.testDescriptors || []; + return testCatalog; +} + +/** filter out tests */ +function filterTestCatalog(testCatalog: TestCatalogInfo, filter: Array) { + const filters = filter.slice(0).sort(); + const descriptors: TestInfo[] = []; + + for (const info of testCatalog.testDescriptors) { + let methods = new Set(); + for (const filter of filters) { + const [fqnFilter, methodFilter] = filter.split("#"); + if (!fqnFilter || info.fqn.indexOf(fqnFilter) >= 0) { + if (methodFilter) { // filter methods + for (const method of info.testMethods) { + if (method.indexOf(methodFilter) >= 0) { + methods.add(method); + } + } + } else { + methods = new Set(info.testMethods); // take all + break; + } + } + } + if (methods.size > 0) { + info.testMethods = Array.from(methods); + descriptors.push(info); + } + } + testCatalog.testDescriptors = descriptors; +} @Bind(IFIXME, FIXME1) @Bind(IFIXME2, FIXME2) diff --git a/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/ProjectDiscoverer.n4js b/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/ProjectDiscoverer.n4js deleted file mode 100644 index 464a8f7fb7..0000000000 --- a/n4js-libs/packages/n4js-mangelhaft-cli/src/n4js/org/eclipse/n4js/mangelhaft/runner/node/ProjectDiscoverer.n4js +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2020 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 - */ - -import * as lib_path from "path"; -import * as lib_fs from "fs"; -import { minimatch } from "minimatch"; -import * as lib_glob from "glob"; - - - -/** - * @param {string} [initial] - * @return {string|null} - */ -export public function findProjectDirectories(dir: string) : string[] { - const projects : string[] = []; - const parentProjectDir = findParentProjectDir(dir); - - if (parentProjectDir) { - projects.push(parentProjectDir); - const workspacesGlobs = getWorkspacesGlobs(parentProjectDir, dir); - const options = { cwd: parentProjectDir, absolute: true, sync: true }; - - for (const workspacesGlob of workspacesGlobs) { - const ee = new lib_glob.Glob(workspacesGlob, options); - const foundLocs = ee.found; - for (const subProjectDir of foundLocs) { - const manifestFile = lib_path.join(subProjectDir, 'package.json'); - if (lib_fs.existsSync(manifestFile)) { - projects.push(subProjectDir); - } - } - } - } - return projects; -} - -/** - * @param {string} [initial] - * @return {string|null} - */ -function findParentProjectDir(initialDir: string) : string { - let previousDir = null; - let currentDir = lib_path.normalize(initialDir); - - do { - const manifest = readPackageJSON(currentDir); - if (manifest) { - return currentDir; - } - - previousDir = currentDir; - currentDir = lib_path.dirname(currentDir); - } while (currentDir !== previousDir); - - return null; -} - -function getWorkspacesGlobs(yarnworkspaceDir:string, subprojectDir: string) : string[] { - const manifest = readPackageJSON(yarnworkspaceDir); - const workspaces = extractWorkspaces(manifest); - if (workspaces) { - // is yarn workspaces project - const relativePath = lib_path.relative(yarnworkspaceDir, subprojectDir); - for (const workspacesEntry of workspaces) { - if (relativePath === '' || minimatch(relativePath, workspacesEntry)) { - return workspaces; - } - } - } - return []; -} - -function readPackageJSON(dir: string) : Object { - const file = lib_path.join(dir, 'package.json'); - if (lib_fs.existsSync(file)) { - return JSON.parse(lib_fs.readFileSync(file, {encoding : 'utf8'})) as Object; - } - return null; -} - -function extractWorkspaces(manifest : any+) : string[] { - const workspaces = manifest?.workspaces; - return (workspaces?.packages) || ((Array.isArray(workspaces) ? workspaces : null)); -} diff --git a/n4js-libs/packages/n4js-runtime/src/n4js/n4js/lang/N4Injector.n4js b/n4js-libs/packages/n4js-runtime/src/n4js/n4js/lang/N4Injector.n4js index ca7cd62c90..1949a5bd7d 100644 --- a/n4js-libs/packages/n4js-runtime/src/n4js/n4js/lang/N4Injector.n4js +++ b/n4js-libs/packages/n4js-runtime/src/n4js/n4js/lang/N4Injector.n4js @@ -482,7 +482,7 @@ export public class N4Injector{ if(!meta.typeVar){ throw new DIConfigurationError('Cannot create provider ' + meta.type + " typelet is " + meta.typeVar); } - return this.createAnonymousProvider(meta.typeVar) as N4Object; + return this.createAnonymousProvider(meta.typeVar); } return this.internalCreate(meta.type, delegate, cachedInstances); } diff --git a/n4js-libs/packages/org.eclipse.n4js.mangelhaft.assert.test/test/n4js/org/eclipse/n4js/mangelhaft/assert/test/precondition/PreconditionNotMetConstructorTest.n4js b/n4js-libs/packages/org.eclipse.n4js.mangelhaft.assert.test/test/n4js/org/eclipse/n4js/mangelhaft/assert/test/precondition/PreconditionNotMetConstructorTest.n4js new file mode 100644 index 0000000000..20bb6575cc --- /dev/null +++ b/n4js-libs/packages/org.eclipse.n4js.mangelhaft.assert.test/test/n4js/org/eclipse/n4js/mangelhaft/assert/test/precondition/PreconditionNotMetConstructorTest.n4js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 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 + */ + +import {Precondition} from "org/eclipse/n4js/mangelhaft/precondition/Precondition"; + +@Singleton +class InjectMe {} + +class MySuperClass { + constructor() { + Precondition.fail("supposed to be skipped"); + } +} + +export public class PreconditionNotMetConstructorTest extends MySuperClass { + @Inject + im: InjectMe; + + constructor() { + throw 3; + } + + @Test + public skippedTest() { + // skipped test + } +} \ No newline at end of file diff --git a/n4js-libs/packages/org.eclipse.n4js.mangelhaft.reporter.xunit/src/n4js/org/eclipse/n4js/mangelhaft/reporter/xunit/XUnitReporter.n4js b/n4js-libs/packages/org.eclipse.n4js.mangelhaft.reporter.xunit/src/n4js/org/eclipse/n4js/mangelhaft/reporter/xunit/XUnitReporter.n4js index 3cfee9acaf..539094ae23 100644 --- a/n4js-libs/packages/org.eclipse.n4js.mangelhaft.reporter.xunit/src/n4js/org/eclipse/n4js/mangelhaft/reporter/xunit/XUnitReporter.n4js +++ b/n4js-libs/packages/org.eclipse.n4js.mangelhaft.reporter.xunit/src/n4js/org/eclipse/n4js/mangelhaft/reporter/xunit/XUnitReporter.n4js @@ -121,6 +121,7 @@ export public class XUnitReporter implements ITestReporter { this.spy.testingFinished.add(async (resultGroups: ResultGroups) => { this.endTime = new Date(); outputTextFile(this.spec.xunitReportFile, await this.createXunitReport(resultGroups)); + console.log("Saved test report at: " + this.spec.xunitReportFile); }); return this; } diff --git a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/TestController.n4js b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/TestController.n4js index 2bfcb7842c..5e11ec0377 100644 --- a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/TestController.n4js +++ b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/TestController.n4js @@ -19,7 +19,7 @@ import {ResultGroup} from "org/eclipse/n4js/mangelhaft/types/ResultGroup"; import {ResultGroups} from "org/eclipse/n4js/mangelhaft/types/ResultGroups"; import {TestFunctionType} from "org/eclipse/n4js/mangelhaft/types/TestFunctionType"; import {TestInfo} from "org/eclipse/n4js/mangelhaft/types/TestInfo"; -import {TestInfos} from "org/eclipse/n4js/mangelhaft/types/TestInfos"; +import {TestCatalogInfo} from "org/eclipse/n4js/mangelhaft/types/TestCatalogInfo"; import {TestMethodDescriptor} from "org/eclipse/n4js/mangelhaft/types/TestMethodDescriptor"; import {TestResult} from "org/eclipse/n4js/mangelhaft/types/TestResult"; import {TestSpy} from "org/eclipse/n4js/mangelhaft/types/TestSpy"; @@ -63,7 +63,7 @@ export public class TestController { * Entry point to running tests. Called from a test runner with the test meta information. Any configured reporters * will get updated with progress of tests. */ - public async runGroups(testCatalog: TestInfos, numTests: number=, scope: string=): ResultGroups { + public async runGroups(testCatalog: TestCatalogInfo, numTests: number=, scope: string=): ResultGroups { if (!testCatalog) { throw new Error("TestController::runGroups called with a null testCatalog"); } @@ -82,13 +82,13 @@ export public class TestController { console.log("testingStarted.dispatch is bad", ex); } - const res = await this.runInBatches(testInfos, scope); + const res = await this.runInBatches(testCatalog, testInfos, scope); await this.spy.testingFinished.dispatch([res]); return res; } /** Runs provided tests in batches, */ - private async runInBatches(testInfos: TestInfo[], scope: string=): ResultGroups { + private async runInBatches(testCatalog: TestCatalogInfo, testInfos: TestInfo[], scope: string=): ResultGroups { let res: ResultGroups; // groups tests into batches to execute @@ -98,27 +98,12 @@ export public class TestController { batchedTestInfos.push(batch); } - // utils - const mapper: (TestInfo) => Promise = async (testInfo) => await this - .instrument(testInfo); - const flatten = (arr: InstrumentedTest[][]): InstrumentedTest[] => Array.prototype.concat.apply([], - arr) as InstrumentedTest[]; - const instrumentBatch = async function(testInfosBatch: TestInfo[]): InstrumentedTest[] { - const instrumentedBatches = testInfosBatch.map(mapper).filter(notNull); - const instrumentedTestsBatch1d = await Promise.all(instrumentedBatches); - const instrumentedTestsBatch2d = await Promise - .resolve(instrumentedTestsBatch1d); - const instrumentedTestsBatch = flatten(instrumentedTestsBatch2d); - - return instrumentedTestsBatch; - }; - const resultGroups: ResultGroups[] = []; // execute batched groups for (let numOfBatches = 0; numOfBatches < batchedTestInfos.length; ++numOfBatches) { try { const testInfosBatch = batchedTestInfos[numOfBatches]; - const instrumentedTestsBatch = await instrumentBatch(testInfosBatch); + const instrumentedTestsBatch = await this.instrumentBatch(testCatalog, testInfosBatch); res = await this.executor.runTestsAsync(instrumentedTestsBatch, scope); resultGroups.push(res); } catch (er) { @@ -131,21 +116,31 @@ export public class TestController { return res; } - private async instrument(info: TestInfo): InstrumentedTest[] { + private async instrumentBatch(testCatalog: TestCatalogInfo, testInfosBatch: TestInfo[]): InstrumentedTest[] { + let result: InstrumentedTest[] = []; + for (const testInfo of testInfosBatch) { + const instrumentedTest = await this.instrument(testCatalog, testInfo); + result = result.concat(instrumentedTest); + } + return result; + } + + private async instrument(testCatalog: TestCatalogInfo, info: TestInfo): InstrumentedTest[] { let testClasses: constructor{N4Object}[]; + const originOrPackageName = info.origin || testCatalog.packageName; // TODO: remove when origin is not set by n4jsc anymore const parts = info.fqn.split("/"); const ctorName = parts.pop(); const moduleName = parts.join("/"); try { let groupModule: Object; try { - const mod = `${info.origin}/${moduleName}.js`; + const mod = `${testCatalog.location}/${moduleName}.js`; groupModule = await import(mod); info.filePath = Module.createRequire(import.meta.url).resolve(mod); } catch (exc) { // find package.json const packageJsonPath = findPackageJson(process.cwd()); - if (!packageJsonPath || readJsonFile(packageJsonPath).name !== info.origin) { + if (!packageJsonPath || readJsonFile(packageJsonPath).name !== originOrPackageName) { throw exc; } const parts = moduleName.split("/"); @@ -155,17 +150,17 @@ export public class TestController { } testClasses = [groupModule[ctorName] as constructor{N4Object}]; } catch (ex) { - await this.errorGroup(info, info.origin + "/" + moduleName, null, ex); + await this.errorGroup(info, originOrPackageName + "/" + moduleName, null, ex); return null; } if (!testClasses) { - await this.errorGroup(info, info.origin + "/" + parts.join("/")); + await this.errorGroup(info, originOrPackageName + "/" + parts.join("/")); return null; } let instrumentedTests: IInstrumentedTest[] = []; for (const testClass of testClasses) { if (!testClass) { - await this.errorGroup(info, info.origin + "/" + moduleName, null, + await this.errorGroup(info, originOrPackageName + "/" + moduleName, null, new Error("Empty object loaded (is the test class exported?)")); continue; } diff --git a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/ResultGroup.n4js b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/ResultGroup.n4js index 828e45b689..c01b738042 100644 --- a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/ResultGroup.n4js +++ b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/ResultGroup.n4js @@ -11,6 +11,7 @@ import {TestResult} from "org/eclipse/n4js/mangelhaft/types/TestResult"; import {TestStatus} from "org/eclipse/n4js/mangelhaft/types/TestStatus"; + export public class ResultGroup { public description?: string = ""; public testResults?: TestResult[] = []; diff --git a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/ResultGroups.n4js b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/ResultGroups.n4js index 8bb7138188..4c3151b5a5 100644 --- a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/ResultGroups.n4js +++ b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/ResultGroups.n4js @@ -15,6 +15,7 @@ import {ResultGroup} from "org/eclipse/n4js/mangelhaft/types/ResultGroup"; import {TestResult} from "org/eclipse/n4js/mangelhaft/types/TestResult"; import {aggregateTestStatuses} from "org/eclipse/n4js/mangelhaft/types/TestStatus"; + export public class ResultGroups { public results: ResultGroup[]; public successes: number = 0; @@ -24,7 +25,7 @@ export public class ResultGroups { public constructor(results: ResultGroup[]) { this.results = results; - ResultGroups.accumulateResults(this, results); + this.accumulateResults(results); } /** * Aggregates ResultGroups into a single ResultGroup. tests with the same name are collapsed with @@ -51,17 +52,14 @@ export public class ResultGroups { result = new ResultGroup(Array.from(trMap.values()), description); return result; } - private static accumulateResults(target:ResultGroups, results:(? extends ~~ResultGroup)[]): ResultGroups { + + private accumulateResults(results: ResultGroup[]): void { for (let result of results) { - target.successes += result.successes; - target.failures += result.failures; - target.errors += result.errors; - target.skipped += result.skipped; - if (result instanceof ResultGroups) { - target.results = target.results.concat(result.results); // joe TODO consider refactoring of ResultGroup and ResultGroups - } + this.successes += result.successes; + this.failures += result.failures; + this.errors += result.errors; + this.skipped += result.skipped; } - return target; } /** @@ -72,10 +70,19 @@ export public class ResultGroups { public static concat(...resultGroups: ResultGroups): ResultGroups { return this.concatArray(resultGroups); } + /** * same as concat but takes a whole array */ public static concatArray(resultGroupss: ResultGroups[]): ResultGroups { - return this.accumulateResults(new ResultGroups([]), (resultGroupss as Object) as (? extends ~~ResultGroup)[]); // joe TODO consider refactoring of ResultGroup and ResultGroups + const newResultGroups = new ResultGroups([]); + for (let resultGroup of resultGroupss) { + newResultGroups.successes += resultGroup.successes; + newResultGroups.failures += resultGroup.failures; + newResultGroups.errors += resultGroup.errors; + newResultGroups.skipped += resultGroup.skipped; + newResultGroups.results = newResultGroups.results.concat(resultGroup.results); + } + return newResultGroups; } } diff --git a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestCatalogInfo.n4js b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestCatalogInfo.n4js new file mode 100644 index 0000000000..a390c4fcc5 --- /dev/null +++ b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestCatalogInfo.n4js @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017 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 + */ + import {TestInfo} from "org/eclipse/n4js/mangelhaft/types/TestInfo"; + + export public interface ~TestCatalogInfo { + /** Test descriptors for each module */ + public testDescriptors: TestInfo[]; + /** Directory of the test catalog */ + public location?: string; + /** File name of the test catalog */ + public fileName?: string; + /** Package name this test catalog refers to */ + public packageName?: string; + public sessionId?: string; + public endpoint?: string; + } + \ No newline at end of file diff --git a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestInfo.n4js b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestInfo.n4js index 0696a427fc..40b6e8ae3a 100644 --- a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestInfo.n4js +++ b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestInfo.n4js @@ -10,11 +10,13 @@ */ /** Describes given test class to be executed. */ -export public class TestInfo { +export public interface ~TestInfo { /** set in case class has been loaded from disk */ public filePath?: string; - - /** origin used for dynamic loading of the test class */ + /** + * @Deprecated: instead use TestCatalogInfo#packageName + * origin used for dynamic loading of the test class + */ public origin: string; /** test class fqn used for dynamic loading */ public fqn?: string; @@ -23,5 +25,4 @@ export public class TestInfo { /** names of the test methods from a given class to be executed */ public testMethods?: string[]; - public constructor(@Spec spec: ~i~this) {} } diff --git a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestInfos.n4js b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestInfos.n4js deleted file mode 100644 index 012563d1f1..0000000000 --- a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestInfos.n4js +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2017 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 - */ -import {TestInfo} from "org/eclipse/n4js/mangelhaft/types/TestInfo"; - -export public class TestInfos { - public sessionId?: string; - public endpoint?: string; - public testDescriptors: TestInfo[] = []; -} diff --git a/plugins/org.eclipse.n4js.cli/src/org/eclipse/n4js/cli/init/InitResources.java b/plugins/org.eclipse.n4js.cli/src/org/eclipse/n4js/cli/init/InitResources.java index 2e3e75451e..4245cad81a 100644 --- a/plugins/org.eclipse.n4js.cli/src/org/eclipse/n4js/cli/init/InitResources.java +++ b/plugins/org.eclipse.n4js.cli/src/org/eclipse/n4js/cli/init/InitResources.java @@ -55,7 +55,8 @@ public class InitResources { private static final String NPM_RUN_N4JSC = "n4jsc"; private static final String NPM_RUN_BUILD = "n4jsc compile . --clean || true"; - private static final String NPM_RUN_TEST = "n4js-mangelhaft"; + private static final String NPM_RUN_TEST_NPM = "n4js-mangelhaft"; + private static final String NPM_RUN_TEST_YARN = "n4js-mangelhaft packages/*"; static class YarnPackageJsonContents { transient boolean exists = false; @@ -136,7 +137,7 @@ private static String[] getWorkspaces(JsonObject rootObj) { } YarnPackageJsonContents defaultsTested() { - scripts.put("test", NPM_RUN_TEST); + scripts.put("test", NPM_RUN_TEST_YARN); devDependencies.put("n4js-mangelhaft-cli", ""); devDependencies.put("org.eclipse.n4js.mangelhaft", ""); devDependencies.put("org.eclipse.n4js.mangelhaft.assert", ""); @@ -208,7 +209,7 @@ PackageJsonContents helloWorld() { } PackageJsonContents helloWorldTests() { - scripts.put("test", NPM_RUN_TEST); + scripts.put("test", NPM_RUN_TEST_NPM); devDependencies.put("n4js-mangelhaft-cli", ""); devDependencies.put("org.eclipse.n4js.mangelhaft", ""); devDependencies.put("org.eclipse.n4js.mangelhaft.assert", ""); diff --git a/tests/org.eclipse.n4js.integration.tests/src/org/eclipse/n4js/integration/tests/cli/compile/N4jscInitTest.java b/tests/org.eclipse.n4js.integration.tests/src/org/eclipse/n4js/integration/tests/cli/compile/N4jscInitTest.java index e83ae62985..7d8b96715c 100644 --- a/tests/org.eclipse.n4js.integration.tests/src/org/eclipse/n4js/integration/tests/cli/compile/N4jscInitTest.java +++ b/tests/org.eclipse.n4js.integration.tests/src/org/eclipse/n4js/integration/tests/cli/compile/N4jscInitTest.java @@ -183,8 +183,9 @@ public void helloWorldTested() throws Exception { assertEquals("Hello World", resultNodejs.getStdOut()); ProcessResult resultTest = npmRun(cwd.toPath(), "run", "test"); - assertTrue(resultTest.getStdOut().contains( - "Testing completed: SUCCESSES: 1, FAILURES: 0, ERRORS: 0, SKIPPED: 0")); + String expect = "Testing completed: SUCCESSES: 1, FAILURES: 0, ERRORS: 0, SKIPPED: 0"; + assertTrue("Did not find: " + expect + "\nin output:\n" + resultTest.getStdOut(), + resultTest.getStdOut().contains(expect)); } /** test another project name */ @@ -362,8 +363,10 @@ public void yarnHelloWorldTested() throws Exception { assertEquals("Hello World", resultNodejs.getStdOut()); ProcessResult resultTest = yarnRun(cwd.toPath(), "run", "test"); - assertTrue(resultTest.getStdOut().contains( - "Testing completed: SUCCESSES: 1, FAILURES: 0, ERRORS: 0, SKIPPED: 0")); + + String expect = "Testing completed: SUCCESSES: 1, FAILURES: 0, ERRORS: 0, SKIPPED: 0"; + assertTrue("Did not find: " + expect + "\nin output:\n" + resultTest.getStdOut(), + resultTest.getStdOut().contains(expect)); } /** test yarn create */ From 5e99990ec6d8c4a9c72b351bebaac7f99fb24ab3 Mon Sep 17 00:00:00 2001 From: mmews Date: Wed, 7 Feb 2024 10:25:59 +0100 Subject: [PATCH 15/26] Hotfix GH-2600 fix call to n4js-mangelhaft --- n4js-libs/npm-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/n4js-libs/npm-test.sh b/n4js-libs/npm-test.sh index e77299e450..0e089b619e 100755 --- a/n4js-libs/npm-test.sh +++ b/n4js-libs/npm-test.sh @@ -20,7 +20,7 @@ echo "========= Running tests defined in the individual packages of yarn workspa echo "========= Running mangelhaft tests for all packages in yarn workspace 'n4js-libs' ..." mkdir -p "./build" echo "Run mangelhaft ..." -yarn run n4js-mangelhaft \ +./packages/n4js-mangelhaft-cli/src-gen/org/eclipse/n4js/mangelhaft/runner/node/NodeTestMain.js \ packages/* \ --xunitReportFile "./build/report.xml" \ --sonarTestExecutionReportFile ./build/sqreport.xml \ From 5a79f6f72dcb673b585c766a8e24499488b7e0f4 Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Wed, 14 Feb 2024 10:35:00 +0100 Subject: [PATCH 16/26] GH-2596: As a developer I need React jsx files using the new JSX transform (#2602) * rename folder * add transpile test * add tests * related changes * main change * adjust tests * fix fragment support, import specifier * fix side effect on target * fix react test imports * add validation and test * use spread instead of Object.assign * revert unintended change * fix missing value for boolean prop * fix test expectation * fix treatment of wrapped cancellation exception --- .../es/transform/JSXTransformation.java | 174 +++++++++--------- .../ModuleSpecifierTransformation.java | 14 ++ .../SanitizeImportsTransformation.java | 4 + .../transpiler/TranspilerBuilderBlocks.java | 7 + .../n4js/transpiler/TranspilerComponent.java | 7 + .../transpiler/TranspilerStateOperations.java | 26 +++ .../ide/server/QueuedExecutorService.java | 9 +- .../n4js/tooling/react/ReactHelper.xtend | 4 + .../eclipse/n4js/validation/IssueCodes.java | 4 + .../validators/N4JSXValidator.xtend | 23 ++- .../n4js/cli/helper/SystemOutRedirecter.java | 2 + .../tests/helper/server/AbstractIdeTest.java | 16 +- .../xt-tests/react/jsx-runtime.js | 15 ++ .../Cmp_00_Simple.n4jsx.xt | 48 +++-- .../Cmp_08_ShortSyntaxReactFragment.n4jsx.xt | 38 ++-- .../Cmp_20_FunctionComponent.n4jsx.xt | 6 +- .../Cmp_40_ClassComponent.n4jsx.xt | 11 +- ...Cmp_60_AnonymousFunctionComponent.n4jsx.xt | 6 +- ...MindOrderWrtOverlappingProperties.n4jsx.xt | 13 +- ...ionOfPropsAndOrderingOfAttributes.n4jsx.xt | 29 ++- .../{compile => react_run}/replacer.n4js | 0 .../react_transpile/jsx_fragments.n4jsx.xt | 74 ++++++++ .../jsx_transpile_children.n4jsx.xt | 83 +++++++++ .../jsx_transpile_elements.n4jsx.xt | 72 ++++++++ .../jsx_transpile_properties.n4jsx.xt | 111 +++++++++++ .../non-conforming/jsx-runtime.js | 15 ++ .../valid/jsx-runtime.js | 15 ++ .../xt-tests/JSXFragments.n4jsx.xt | 40 +++- 28 files changed, 676 insertions(+), 190 deletions(-) create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/react/jsx-runtime.js rename tests/org.eclipse.n4js.spec.tests/xt-tests/{compile => react_run}/Cmp_00_Simple.n4jsx.xt (81%) rename tests/org.eclipse.n4js.spec.tests/xt-tests/{compile => react_run}/Cmp_08_ShortSyntaxReactFragment.n4jsx.xt (78%) rename tests/org.eclipse.n4js.spec.tests/xt-tests/{compile => react_run}/Cmp_20_FunctionComponent.n4jsx.xt (94%) rename tests/org.eclipse.n4js.spec.tests/xt-tests/{compile => react_run}/Cmp_40_ClassComponent.n4jsx.xt (94%) rename tests/org.eclipse.n4js.spec.tests/xt-tests/{compile => react_run}/Cmp_60_AnonymousFunctionComponent.n4jsx.xt (94%) rename tests/org.eclipse.n4js.spec.tests/xt-tests/{compile => react_run}/GHOLD372_JSXSpreadOperatorDoesntMindOrderWrtOverlappingProperties.n4jsx.xt (82%) rename tests/org.eclipse.n4js.spec.tests/xt-tests/{compile => react_run}/GHOLD413_CombinationOfPropsAndOrderingOfAttributes.n4jsx.xt (91%) rename tests/org.eclipse.n4js.spec.tests/xt-tests/{compile => react_run}/replacer.n4js (100%) create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_fragments.n4jsx.xt create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_children.n4jsx.xt create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_elements.n4jsx.xt create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_properties.n4jsx.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/react-implementations/non-conforming/jsx-runtime.js create mode 100644 tests/org.eclipse.n4js.xpect.tests/react-implementations/valid/jsx-runtime.js diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.java index 7ef14e5728..bd05bafea6 100644 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.java +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.java @@ -10,11 +10,16 @@ */ package org.eclipse.n4js.transpiler.es.transform; +import static org.eclipse.n4js.tooling.react.ReactHelper.REACT_ELEMENT_PROPERTY_CHILDREN_NAME; +import static org.eclipse.n4js.tooling.react.ReactHelper.REACT_ELEMENT_PROPERTY_KEY_NAME; +import static org.eclipse.n4js.tooling.react.ReactHelper.REACT_JSX_RUNTIME_NAME; +import static org.eclipse.n4js.tooling.react.ReactHelper.REACT_JSX_TRANSFORM_NAME; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrLit; import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr; -import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._NULL; import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ObjLit; import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr; import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyNameValuePair; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertySpread; import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._StringLiteral; import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._TRUE; import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; @@ -22,8 +27,10 @@ import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import org.eclipse.emf.common.util.EList; import org.eclipse.n4js.n4JS.Expression; import org.eclipse.n4js.n4JS.ImportDeclaration; import org.eclipse.n4js.n4JS.JSXAbstractElement; @@ -35,18 +42,17 @@ import org.eclipse.n4js.n4JS.JSXPropertyAttribute; import org.eclipse.n4js.n4JS.JSXSpreadAttribute; import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; -import org.eclipse.n4js.n4JS.ObjectLiteral; import org.eclipse.n4js.n4JS.ParameterizedCallExpression; import org.eclipse.n4js.n4JS.PropertyAssignment; -import org.eclipse.n4js.n4JS.PropertyNameValuePair; import org.eclipse.n4js.tooling.react.ReactHelper; import org.eclipse.n4js.transpiler.Transformation; import org.eclipse.n4js.transpiler.im.IdentifierRef_IM; +import org.eclipse.n4js.transpiler.im.ImFactory; import org.eclipse.n4js.transpiler.im.Script_IM; import org.eclipse.n4js.transpiler.im.SymbolTableEntry; +import org.eclipse.n4js.transpiler.im.SymbolTableEntryInternal; import org.eclipse.n4js.transpiler.im.SymbolTableEntryOriginal; import org.eclipse.n4js.ts.types.IdentifiableElement; -import org.eclipse.n4js.ts.types.TFunction; import org.eclipse.n4js.ts.types.TModule; import org.eclipse.n4js.utils.ResourceType; import org.eclipse.xtext.EcoreUtil2; @@ -69,9 +75,10 @@ *
*/ public class JSXTransformation extends Transformation { + /** Alias for React transform */ + public static final String JSX_ALIAS = "$" + REACT_JSX_TRANSFORM_NAME; private SymbolTableEntryOriginal steForJsxBackendNamespace; - private SymbolTableEntryOriginal steForJsxBackendElementFactoryFunction; private SymbolTableEntryOriginal steForJsxBackendFragmentComponent; @Inject @@ -124,24 +131,29 @@ public void transform() { return; // this transformation is not applicable } - // Transform JSXFragments and JSXElements + // note: we are passing 'true' to #collectNodes(), i.e. we are searching for nested elements List jsxAbstractElements = collectNodes(getState().im, JSXAbstractElement.class, true); if (jsxAbstractElements.isEmpty()) { // Nothing to transform return; } - steForJsxBackendNamespace = prepareImportOfJsxBackend(); - steForJsxBackendElementFactoryFunction = prepareElementFactoryFunction(); + createImportOfJsx(); + steForJsxBackendNamespace = createImportOfJsxBackend(); // will be removed if obsolete steForJsxBackendFragmentComponent = prepareFragmentComponent(); - // note: we are passing 'true' to #collectNodes(), i.e. we are searching for nested elements + // Transform JSXFragments and JSXElements for (JSXAbstractElement jsxElem : jsxAbstractElements) { transformJSXAbstractElement(jsxElem); } } - private SymbolTableEntryOriginal prepareImportOfJsxBackend() { + private void createImportOfJsx() { + ImportDeclaration impDecl = addNamedImport(REACT_JSX_TRANSFORM_NAME, JSX_ALIAS, REACT_JSX_RUNTIME_NAME); + impDecl.getImportSpecifiers().forEach(is -> is.setFlaggedUsedInCode(true)); + } + + private SymbolTableEntryOriginal createImportOfJsxBackend() { TModule jsxBackendModule = reactHelper.getJsxBackendModule(getState().resource); if (jsxBackendModule == null) { throw new RuntimeException("cannot locate JSX backend for N4JSX resource " + getState().resource.getURI()); @@ -169,15 +181,6 @@ private SymbolTableEntryOriginal prepareImportOfJsxBackend() { return addNamespaceImport(jsxBackendModule, reactHelper.getJsxBackendNamespaceName()); } - private SymbolTableEntryOriginal prepareElementFactoryFunction() { - TFunction elementFactoryFunction = reactHelper.getJsxBackendElementFactoryFunction(getState().resource); - if (elementFactoryFunction == null) { - throw new RuntimeException("cannot locate element factory function of JSX backend for N4JSX resource " - + getState().resource.getURI()); - } - return getSymbolTableEntryOriginal(elementFactoryFunction, true); - } - private SymbolTableEntryOriginal prepareFragmentComponent() { IdentifiableElement fragmentComponent = reactHelper.getJsxBackendFragmentComponent(getState().resource); if (fragmentComponent == null) { @@ -202,90 +205,95 @@ private ParameterizedCallExpression convertJSXAbstractElement(JSXAbstractElement if (elem instanceof JSXElement) { JSXElement jsxElem = (JSXElement) elem; args.add(getTagNameFromElement(jsxElem)); - args.add(convertJSXAttributes(jsxElem.getJsxAttributes())); - } else { + args.add(convertJSXAttributes(jsxElem.getJsxAttributes(), elem.getJsxChildren())); + Expression keysValue = findKeysAttribute(jsxElem.getJsxAttributes()); + if (keysValue != null) { + args.add(keysValue); + } + } else if (elem instanceof JSXFragment) { args.add(_PropertyAccessExpr(steForJsxBackendNamespace, steForJsxBackendFragmentComponent)); - args.add(_NULL()); + args.add(convertJSXAttributes(Collections.emptyList(), elem.getJsxChildren())); } - args.addAll(toList(map(elem.getJsxChildren(), child -> convertJSXChild(child)))); - return _CallExpr( - _PropertyAccessExpr(steForJsxBackendNamespace, steForJsxBackendElementFactoryFunction), - args.toArray(new Expression[0])); + IdentifierRef_IM idRef = ImFactory.eINSTANCE.createIdentifierRef_IM(); + idRef.setIdAsText(JSX_ALIAS); + SymbolTableEntryInternal ste = getSymbolTableEntryInternal(idRef.getIdAsText(), true); + idRef.setId_IM(ste); + return _CallExpr(idRef, args.toArray(new Expression[0])); } - private Expression convertJSXChild(JSXChild child) { - if (child instanceof JSXElement) { - return convertJSXAbstractElement((JSXElement) child); - } - if (child instanceof JSXFragment) { - return convertJSXAbstractElement((JSXFragment) child); - } - if (child instanceof JSXExpression) { - return ((JSXExpression) child).getExpression(); + private Expression findKeysAttribute(EList jsxAttributes) { + for (JSXAttribute attr : jsxAttributes) { + if (attr instanceof JSXPropertyAttribute) { + JSXPropertyAttribute pa = (JSXPropertyAttribute) attr; + // https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md#motivation + // notes that the key property will not be extracted from attributes + // at some time in the future + if (REACT_ELEMENT_PROPERTY_KEY_NAME.equals(pa.getPropertyAsText())) { + return pa.getJsxAttributeValue(); + } + } } return null; } - // Generate Object.assign({}, {foo, bar: "Hi"}, spr) - private Expression convertJSXAttributes(List attrs) { - if (attrs.isEmpty()) { - return _NULL(); - } else if (attrs.size() == 1 && attrs.get(0) instanceof JSXSpreadAttribute) { + // Generate {foo:foo, ...spread, bar: "Hi", children: []} + private Expression convertJSXAttributes(List attrs, List children) { + if (children.isEmpty() && attrs.isEmpty()) { + return _ObjLit(); + } + if (children.isEmpty() && attrs.size() == 1 && attrs.get(0) instanceof JSXSpreadAttribute) { // Special case: if only a single spread operator is passed, we pass it directly, e.g. spr instead of - // cloning with Object.assign. + // cloning. return ((JSXSpreadAttribute) attrs.get(0)).getExpression(); - } else { + } + + List pas = new ArrayList<>(); - List spreadIndices = new ArrayList<>(); - for (int idx = 0; idx < attrs.size(); idx++) { - if (attrs.get(idx) instanceof JSXSpreadAttribute) { - spreadIndices.add(idx); + for (JSXAttribute attr : attrs) { + if (attr instanceof JSXSpreadAttribute) { + JSXSpreadAttribute sAttr = (JSXSpreadAttribute) attr; + pas.add(_PropertySpread(sAttr.getExpression())); + } else if (attr instanceof JSXPropertyAttribute) { + JSXPropertyAttribute pAttr = (JSXPropertyAttribute) attr; + if (!children.isEmpty() && REACT_ELEMENT_PROPERTY_CHILDREN_NAME.equals(pAttr.getPropertyAsText())) { + continue; } - } - // GHOLD-413: We have to make sure that the only properties locating next to each other are combined. - // Moreover, the order of properties as well as spread operators must be preserved! - List props = new ArrayList<>(); - if (attrs.get(0) instanceof JSXSpreadAttribute) { - // The first attribute is a spread object, the target must be {}. - } else { - // Otherwise, the target is of the form {foo: true, bar: "Hi"} - int firstSpreadIndex = (!spreadIndices.isEmpty()) ? spreadIndices.get(0) : attrs.size(); - for (int i = 0; i < firstSpreadIndex; i++) { - props.add(convertJSXAttribute((JSXPropertyAttribute) attrs.get(i))); + if (REACT_ELEMENT_PROPERTY_KEY_NAME.equals(pAttr.getPropertyAsText())) { + continue; } + pas.add(_PropertyNameValuePair( + getNameFromPropertyAttribute(pAttr), + getValueExpressionFromPropertyAttribute(pAttr))); } - ObjectLiteral target = _ObjLit(props.toArray(new PropertyNameValuePair[0])); - - List parameters = new ArrayList<>(); - parameters.add(target); + } - for (int i = 0; i < spreadIndices.size(); i++) { - int curSpreadIdx = spreadIndices.get(i); - // Spread expression passed is used directly - parameters.add(((JSXSpreadAttribute) attrs.get(curSpreadIdx)).getExpression()); - // Combine properties between spread intervals - int nextSpreadIdx = (i < spreadIndices.size() - 1) ? spreadIndices.get(i + 1) - : attrs.size(); - List propsBetweenTwoSpreads = attrs.subList(curSpreadIdx + 1, nextSpreadIdx); - if (!propsBetweenTwoSpreads.isEmpty()) { - List props2 = new ArrayList<>(); - for (JSXAttribute attr : propsBetweenTwoSpreads) { - props2.add(convertJSXAttribute((JSXPropertyAttribute) attr)); - } - parameters.add(_ObjLit(props2.toArray(new PropertyAssignment[0]))); - } + if (!children.isEmpty()) { + Expression childrenValue; + if (children.size() == 1) { + childrenValue = convertJSXChild(children.get(0)); + } else { + childrenValue = _ArrLit( + toList(map(children, child -> convertJSXChild(child))).toArray(new Expression[0])); } - - return _CallExpr(_PropertyAccessExpr(steFor_Object(), steFor_Object_assign()), - parameters.toArray(new Expression[0])); + // this will cause any other custom property children to be overwritten + pas.add(_PropertyNameValuePair(REACT_ELEMENT_PROPERTY_CHILDREN_NAME, childrenValue)); } + + return _ObjLit(pas.toArray(new PropertyAssignment[0])); } - private PropertyNameValuePair convertJSXAttribute(JSXPropertyAttribute attr) { - return _PropertyNameValuePair( - getNameFromPropertyAttribute(attr), - getValueExpressionFromPropertyAttribute(attr)); + private Expression convertJSXChild(JSXChild child) { + if (child instanceof JSXElement) { + return convertJSXAbstractElement((JSXElement) child); + } + if (child instanceof JSXFragment) { + return convertJSXAbstractElement((JSXFragment) child); + } + if (child instanceof JSXExpression) { + return ((JSXExpression) child).getExpression(); + } + return null; } private Expression getTagNameFromElement(JSXElement elem) { diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleSpecifierTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleSpecifierTransformation.java index ca8ee2a596..b35a1d182b 100644 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleSpecifierTransformation.java +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/ModuleSpecifierTransformation.java @@ -16,9 +16,11 @@ import java.util.Map; import java.util.Objects; +import org.apache.log4j.Logger; import org.eclipse.n4js.n4JS.ImportDeclaration; import org.eclipse.n4js.n4JS.ModuleSpecifierForm; import org.eclipse.n4js.packagejson.projectDescription.ProjectType; +import org.eclipse.n4js.tooling.react.ReactHelper; import org.eclipse.n4js.transpiler.Transformation; import org.eclipse.n4js.ts.types.TModule; import org.eclipse.n4js.utils.DeclMergingUtils; @@ -39,6 +41,7 @@ * For details, see {@link #computeModuleSpecifierForOutputCode(ImportDeclaration)}. */ public class ModuleSpecifierTransformation extends Transformation { + private final static Logger LOGGER = Logger.getLogger(ModuleSpecifierTransformation.class); @Inject private WorkspaceAccess workspaceAccess; @@ -121,6 +124,17 @@ private void transformImportDecl(ImportDeclaration importDeclIM) { private String computeModuleSpecifierForOutputCode(ImportDeclaration importDeclIM) { TModule targetModule = getState().info.getImportedModule(importDeclIM); + if (targetModule == null) { + if (ReactHelper.REACT_JSX_RUNTIME_NAME.equals(importDeclIM.getModuleSpecifierAsText())) { + // expected to happen since this import was added by JSXTransformation + return importDeclIM.getModuleSpecifierAsText(); + } + // fallback, should not happen + LOGGER.error("targetModule is null at import declaration with module specifier: " + + importDeclIM.getModuleSpecifierAsText()); + return importDeclIM.getModuleSpecifierAsText(); + } + if (URIUtils.isVirtualResourceURI(targetModule.eResource().getURI()) && !DeclMergingUtils.isModuleAugmentation(targetModule)) { // SPECIAL CASE #1a diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.java index eebfe197e2..f6be3f4c0a 100644 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.java +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.java @@ -158,6 +158,10 @@ private boolean isUsed(ImportSpecifier importSpec) { // add new usages of an existing import) // -> therefore simply return false (i.e. unused) return false; + } else if (importSpec instanceof NamedImportSpecifier + && JSXTransformation.JSX_ALIAS.equals(((NamedImportSpecifier) importSpec).getAlias())) { + // special case for import that is added in JSXTransformation + return true; } else { // for performance reasons, we do not require the flaggedUsedInCode to be set to false if usages are removed // -> therefore have to check for references now diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerBuilderBlocks.java b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerBuilderBlocks.java index 1840cbeb79..ead46fedd2 100644 --- a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerBuilderBlocks.java +++ b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerBuilderBlocks.java @@ -89,6 +89,7 @@ import org.eclipse.n4js.n4JS.PropertyNameKind; import org.eclipse.n4js.n4JS.PropertyNameOwner; import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.n4JS.PropertySpread; import org.eclipse.n4js.n4JS.RelationalExpression; import org.eclipse.n4js.n4JS.RelationalOperator; import org.eclipse.n4js.n4JS.ReturnStatement; @@ -474,6 +475,12 @@ public static PropertyNameValuePair _PropertyNameValuePair(LiteralOrComputedProp return result; } + public static PropertySpread _PropertySpread(Expression value) { + PropertySpread result = N4JSFactory.eINSTANCE.createPropertySpread(); + result.setExpression(value); + return result; + } + public static PropertyGetterDeclaration _PropertyGetterDecl(String name, Statement... stmnts) { PropertyGetterDeclaration result = N4JSFactory.eINSTANCE.createPropertyGetterDeclaration(); result.setDeclaredName(_LiteralOrComputedPropertyName(name)); diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerComponent.java b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerComponent.java index 746941abf3..442070d47e 100644 --- a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerComponent.java +++ b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerComponent.java @@ -21,6 +21,7 @@ import org.eclipse.n4js.n4JS.FormalParameter; import org.eclipse.n4js.n4JS.FunctionDeclaration; import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.ImportDeclaration; import org.eclipse.n4js.n4JS.ImportSpecifier; import org.eclipse.n4js.n4JS.N4ClassDeclaration; import org.eclipse.n4js.n4JS.N4EnumDeclaration; @@ -108,6 +109,12 @@ public void addNamedImport(SymbolTableEntryOriginal steOfElementToImport, String TranspilerStateOperations.addNamedImport(state, steOfElementToImport, aliasOrNull); } + /** See {@link TranspilerStateOperations#addNamedImport(TranspilerState, String, String, String)}. */ + public ImportDeclaration addNamedImport(String elementNameToImport, String aliasOrNull, + String moduleSpecifierName) { + return TranspilerStateOperations.addNamedImport(state, elementNameToImport, aliasOrNull, moduleSpecifierName); + } + /** See {@link TranspilerStateOperations#addEmptyImport(TranspilerState, String)}. */ public void addEmptyImport(String moduleSpecifier) { TranspilerStateOperations.addEmptyImport(state, moduleSpecifier); diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.java b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.java index d7c090b1f2..918a866000 100644 --- a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.java +++ b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.java @@ -186,6 +186,32 @@ public static void addNamedImport(TranspilerState state, SymbolTableEntryOrigina state.info.setImportedModule(importDecl, moduleOfOriginalTarget); } + /** + * Creates a new named import for the given STE and adds it to the intermediate model of the given transpiler state. + * Note that this method does not perform a binding to an existing target module. + *

+ * IMPORTANT: this method does not check if the given element name or alias is unique (i.e. does not avoid name + * clashes!). + */ + public static ImportDeclaration addNamedImport(TranspilerState state, String elementNameToImport, + String aliasOrNull, String moduleSpecifierName) { + + // 1) create import declaration & specifier + NamedImportSpecifier importSpec = _NamedImportSpecifier(elementNameToImport, aliasOrNull, true); + ImportDeclaration importDecl = _ImportDecl(importSpec); + importDecl.setModuleSpecifierAsText(moduleSpecifierName); + + // 2) add import to intermediate model + EList scriptElements = state.im.getScriptElements(); + if (scriptElements.isEmpty()) { + scriptElements.add(importDecl); + } else { + insertBefore(scriptElements.get(0), importDecl); + } + + return importDecl; + } + /** * Adds an "empty" import to the intermediate model, i.e. an import of the form: * diff --git a/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/QueuedExecutorService.java b/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/QueuedExecutorService.java index a0563a5892..4208fa1740 100644 --- a/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/QueuedExecutorService.java +++ b/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/QueuedExecutorService.java @@ -312,8 +312,15 @@ public synchronized void cancelAll(Object queueId) { while ((allTasks = allTasksOrNull()) != null) { try { allTasks.join(); - } catch (CompletionException | CancellationException e) { + } catch (CancellationException e) { + System.out.println(); // ignore cancellations + } catch (CompletionException e) { + if (e.getCause() instanceof CancellationException) { + // ignore cancellations + } else { + throw e; + } } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend index 2cea376f29..28969ebcae 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend @@ -61,7 +61,11 @@ class ReactHelper { public final static String REACT_FRAGMENT_NAME = "Fragment"; public final static String REACT_NAMESPACE_NAME = REACT_PROJECT_ID.toFirstUpper; + public final static String REACT_JSX_TRANSFORM_NAME = "jsx"; public final static String REACT_ELEMENT_FACTORY_FUNCTION_NAME = "createElement"; + public final static String REACT_ELEMENT_PROPERTY_KEY_NAME = "key"; + public final static String REACT_ELEMENT_PROPERTY_CHILDREN_NAME = "children"; + public final static String REACT_JSX_RUNTIME_NAME = "react/jsx-runtime.js"; private final static String REACT_KEY = "KEY__" + REACT_PROJECT_ID diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java index ee1c86abf1..8a87c609a9 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java @@ -1899,6 +1899,10 @@ public enum IssueCodes { JSX_JSXSPROPERTYATTRIBUTE_NOT_DECLARED_IN_PROPS(WARNING, "Attribute {0} is not a declared property in the props of {1}."), + /** No parameter */ + JSX_JSXSPROPERTYATTRIBUTE_CHILDREN(WARNING, + "Attribute 'children' will be overwritten by jsx child elements."), + /** 0: JSX element in non-JSX file */ JSX_JSXELEMENT_IN_NON_JSX_RESOURCE(ERROR, "JSX element is expected to be placed in JSX like resource, was {0}."), diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSXValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSXValidator.xtend index ce7a7cace4..1372d629f3 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSXValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSXValidator.xtend @@ -96,7 +96,7 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { val firstJSXAbstractElement = script.eAllContents.findFirst[it instanceof JSXAbstractElement] if (firstJSXAbstractElement !== null && reactHelper.getJsxBackendModule(script.eResource) === null) - addIssue(firstJSXAbstractElement, JSX_REACT_NOT_RESOLVED.toIssueItem()); + addIssue(firstJSXAbstractElement, JSX_REACT_NOT_RESOLVED); } /** Make sure the namespace to react module is React. */ @@ -111,7 +111,7 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { val importedModule = importSpecifier.importedModule; if (reactModule !== null && importedModule === reactModule) { if (importSpecifier.alias != ReactHelper.REACT_NAMESPACE_NAME) { - addIssue(importSpecifier, JSX_REACT_NAMESPACE_NOT_ALLOWED.toIssueItem()); + addIssue(importSpecifier, JSX_REACT_NAMESPACE_NOT_ALLOWED); } } } @@ -257,7 +257,7 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { val actualTypeRef = TypeUtils.createTypeRef(tclass, TypingStrategy.DEFAULT, true); val resultSubType = ts.subtype(G, actualTypeRef, expectedTypeRef) if (resultSubType.failure) { - addIssue(expr, JSX_REACT_ELEMENT_CLASS_NOT_REACT_ELEMENT_ERROR.toIssueItem()); + addIssue(expr, JSX_REACT_ELEMENT_CLASS_NOT_REACT_ELEMENT_ERROR); } } @@ -287,6 +287,23 @@ class N4JSXValidator extends AbstractN4JSDeclarativeValidator { } } + @Check + def public void checkChildrenJSXPropertyAttribute(JSXPropertyAttribute propertyAttribute) { + if (!ReactHelper.REACT_ELEMENT_PROPERTY_CHILDREN_NAME.equals(propertyAttribute.propertyAsText)) { + return; + } + val jsxElem = propertyAttribute.eContainer as JSXElement; + if (jsxElem.jsxChildren.isEmpty) { + return; + } + + addIssue( + propertyAttribute, + JSX_PROPERTY_ATTRIBUTE__PROPERTY, + JSX_JSXSPROPERTYATTRIBUTE_CHILDREN.toIssueItem() + ); + } + /** * Check the type conformity of types of spread operator's attributes against "props" types * See Req. IDE-241119 diff --git a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/SystemOutRedirecter.java b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/SystemOutRedirecter.java index efe5f5c36a..5cf60a3744 100644 --- a/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/SystemOutRedirecter.java +++ b/testhelpers/org.eclipse.n4js.cli.tests.helper/src/org/eclipse/n4js/cli/helper/SystemOutRedirecter.java @@ -97,6 +97,7 @@ public PrintStream getOriginalSystemErr() { public void clearSystemOut() { ByteArrayOutputStream baos = redirectOut; if (baos != null) { + System.out.flush(); baos.reset(); } } @@ -117,6 +118,7 @@ public String getSystemOut() { public void clearSystemErr() { ByteArrayOutputStream baos = redirectErr; if (baos != null) { + System.err.flush(); baos.reset(); } } diff --git a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/AbstractIdeTest.java b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/AbstractIdeTest.java index e685512ae6..2d286c9542 100644 --- a/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/AbstractIdeTest.java +++ b/testhelpers/org.eclipse.n4js.ide.tests.helper/src/org/eclipse/n4js/ide/tests/helper/server/AbstractIdeTest.java @@ -203,18 +203,6 @@ static final public void restoreGlobalRegistries() { oldGlobalState.restoreGlobalState(); } - /** Catch outputs on console to an internal buffer */ - @BeforeClass - static final public void redirectPrintStreams() { - SYSTEM_OUT_REDIRECTER.set(false); - } - - /** Reset redirection */ - @AfterClass - static final public void resetPrintStreams() { - SYSTEM_OUT_REDIRECTER.unset(); - } - /** */ @Inject protected BuilderFrontend lspBuilder; @@ -267,6 +255,7 @@ public void cleanupTestDataFolder() throws IOException { if (root.exists()) { FileUtils.delete(root); } + SYSTEM_OUT_REDIRECTER.set(false); } /** Deletes the test project in case it exists. */ @@ -281,8 +270,7 @@ final public void deleteTestProject() throws IOException { if (languageServer != null) { // only if LSP server was started shutdownLspServer(); } - SYSTEM_OUT_REDIRECTER.clearSystemOut(); - SYSTEM_OUT_REDIRECTER.clearSystemErr(); + SYSTEM_OUT_REDIRECTER.unset(); // note that thrown exceptions will now be written to System.err // clear the state related to the test testWorkspaceManager.deleteTestFromDiskIfCreated(); } diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/react/jsx-runtime.js b/tests/org.eclipse.n4js.spec.tests/xt-tests/react/jsx-runtime.js new file mode 100644 index 0000000000..e4fcfe9322 --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react/jsx-runtime.js @@ -0,0 +1,15 @@ +/* + * 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 + */ + +//Mock implementation for jsx +export function jsx(type, config, maybeKey) { + return {type: type, config: config, maybeKey: maybeKey}; +} diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_00_Simple.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_00_Simple.n4jsx.xt similarity index 81% rename from tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_00_Simple.n4jsx.xt rename to tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_00_Simple.n4jsx.xt index 75c5dfff09..3aacb8f8ae 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_00_Simple.n4jsx.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_00_Simple.n4jsx.xt @@ -22,6 +22,7 @@ Project "react" { File "index.n4jsd" { from = "../react/index.n4jsd" } File "index.js" { from = "../react/index.js" } + File "jsx-runtime.js" { from = "../react/jsx-runtime.js" } File "package.json" { from = "../react/package.json" } } } @@ -33,44 +34,40 @@ simple self-closing { "type": "div", - "props": null, - "children": [] + "config": {} } simple open close { "type": "div", - "props": null, - "children": [] + "config": {} } nested { "type": "div", - "props": { + "config": { "prop1": true, "prop2": "hello", - "prop3": 42 - }, - "children": [ - 42, - { - "type": "a", - "props": null, - "children": [ - 42 - ] - }, - 42, - { - "type": "p", - "props": null, - "children": [] - } - ] + "prop3": 42, + "children": [ + 42, + { + "type": "a", + "config": { + "children": 42 + } + }, + 42, + { + "type": "p", + "config": {} + } + ] + } } spead operator { "type": "div", - "props": { + "config": { "prop0": "0", "prop1": "hi", "prop2": 42, @@ -78,8 +75,7 @@ spead operator "prop4": "hi", "prop5": 42, "prop6": true - }, - "children": [] + } } --- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_08_ShortSyntaxReactFragment.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_08_ShortSyntaxReactFragment.n4jsx.xt similarity index 78% rename from tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_08_ShortSyntaxReactFragment.n4jsx.xt rename to tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_08_ShortSyntaxReactFragment.n4jsx.xt index 4883c9a712..3ba4e89b0d 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_08_ShortSyntaxReactFragment.n4jsx.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_08_ShortSyntaxReactFragment.n4jsx.xt @@ -22,6 +22,7 @@ Project "react" { File "index.n4jsd" { from = "../react/index.n4jsd" } File "index.js" { from = "../react/index.js" } + File "jsx-runtime.js" { from = "../react/jsx-runtime.js" } File "package.json" { from = "../react/package.json" } } } @@ -32,33 +33,30 @@ /* XPECT output --- empty React fragment { - "props": null, - "children": [] + "config": {} } simple open close { - "props": null, - "children": [] + "config": {} } nested { - "props": null, - "children": [ - { - "type": "div", - "props": { - "prop1": "hello" + "config": { + "children": [ + { + "type": "div", + "config": { + "prop1": "hello" + } }, - "children": [] - }, - { - "type": "div", - "props": { - "prop2": "world" - }, - "children": [] - } - ] + { + "type": "div", + "config": { + "prop2": "world" + } + } + ] + } } --- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_20_FunctionComponent.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_20_FunctionComponent.n4jsx.xt similarity index 94% rename from tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_20_FunctionComponent.n4jsx.xt rename to tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_20_FunctionComponent.n4jsx.xt index fd04e2e0c6..d63f84a92e 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_20_FunctionComponent.n4jsx.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_20_FunctionComponent.n4jsx.xt @@ -22,6 +22,7 @@ Project "react" { File "index.n4jsd" { from = "../react/index.n4jsd" } File "index.js" { from = "../react/index.js" } + File "jsx-runtime.js" { from = "../react/jsx-runtime.js" } File "package.json" { from = "../react/package.json" } } } @@ -33,10 +34,9 @@ Pure function element { "type": "PureFnComponent", - "props": { + "config": { "myProp": "This is my propsss" - }, - "children": [] + } } --- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_40_ClassComponent.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_40_ClassComponent.n4jsx.xt similarity index 94% rename from tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_40_ClassComponent.n4jsx.xt rename to tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_40_ClassComponent.n4jsx.xt index 70967a4fd6..d60a0d789f 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_40_ClassComponent.n4jsx.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_40_ClassComponent.n4jsx.xt @@ -22,6 +22,7 @@ Project "react" { File "index.n4jsd" { from = "../react/index.n4jsd" } File "index.js" { from = "../react/index.js" } + File "jsx-runtime.js" { from = "../react/jsx-runtime.js" } File "package.json" { from = "../react/package.json" } } } @@ -33,18 +34,16 @@ Lower component { "type": "LowerComponent", - "props": { + "config": { "whatTextShouldIShow": "lcShadow" - }, - "children": [] + } } My component { "type": "MyComponent", - "props": { + "config": { "aProp": "mcAPop" - }, - "children": [] + } } --- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_60_AnonymousFunctionComponent.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_60_AnonymousFunctionComponent.n4jsx.xt similarity index 94% rename from tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_60_AnonymousFunctionComponent.n4jsx.xt rename to tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_60_AnonymousFunctionComponent.n4jsx.xt index 51d6938ef8..df2d3d6002 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/Cmp_60_AnonymousFunctionComponent.n4jsx.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/Cmp_60_AnonymousFunctionComponent.n4jsx.xt @@ -22,6 +22,7 @@ Project "react" { File "index.n4jsd" { from = "../react/index.n4jsd" } File "index.js" { from = "../react/index.js" } + File "jsx-runtime.js" { from = "../react/jsx-runtime.js" } File "package.json" { from = "../react/package.json" } } } @@ -32,12 +33,11 @@ /* XPECT output --- { "type": "MyReactFuncComponent", - "props": { + "config": { "a": 1, "x": 2, "y": "Hi" - }, - "children": [] + } } --- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/GHOLD372_JSXSpreadOperatorDoesntMindOrderWrtOverlappingProperties.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/GHOLD372_JSXSpreadOperatorDoesntMindOrderWrtOverlappingProperties.n4jsx.xt similarity index 82% rename from tests/org.eclipse.n4js.spec.tests/xt-tests/compile/GHOLD372_JSXSpreadOperatorDoesntMindOrderWrtOverlappingProperties.n4jsx.xt rename to tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/GHOLD372_JSXSpreadOperatorDoesntMindOrderWrtOverlappingProperties.n4jsx.xt index 3d6644e994..daa0121941 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/GHOLD372_JSXSpreadOperatorDoesntMindOrderWrtOverlappingProperties.n4jsx.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/GHOLD372_JSXSpreadOperatorDoesntMindOrderWrtOverlappingProperties.n4jsx.xt @@ -22,6 +22,7 @@ Project "react" { File "index.n4jsd" { from = "../react/index.n4jsd" } File "index.js" { from = "../react/index.js" } + File "jsx-runtime.js" { from = "../react/jsx-runtime.js" } File "package.json" { from = "../react/package.json" } } } @@ -31,10 +32,10 @@ */ /* XPECT output --- -r1.props[foo] == 1 -r2.props[foo] == 2 +r1.config[foo] == 1 +r2.config[foo] == 2 i2[foo] == 0 -o3.props[foo] == 3 +o3.config[foo] == 3 d3[foo] == 0 --- */ @@ -45,14 +46,14 @@ zzzz; let r1 : ~Object+ =

; // output --> 1 -console.log("r1.props[foo] == " + r1.props["foo"]); +console.log("r1.config[foo] == " + r1.config["foo"]); let i2 = {foo: 0, bar : 0}; let r2 : ~Object+ =
; // output --> 2 -console.log("r2.props[foo] == " + r2.props["foo"]); +console.log("r2.config[foo] == " + r2.config["foo"]); // output --> 0 console.log("i2[foo] == " + i2["foo"]); @@ -66,7 +67,7 @@ let d3 : D+ = new D(); let o3 : ~Object+ =
; // output --> 3 -console.log("o3.props[foo] == " + o3.props["foo"]); +console.log("o3.config[foo] == " + o3.config["foo"]); // output --> 0 console.log("d3[foo] == " + d3["foo"]); diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/GHOLD413_CombinationOfPropsAndOrderingOfAttributes.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/GHOLD413_CombinationOfPropsAndOrderingOfAttributes.n4jsx.xt similarity index 91% rename from tests/org.eclipse.n4js.spec.tests/xt-tests/compile/GHOLD413_CombinationOfPropsAndOrderingOfAttributes.n4jsx.xt rename to tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/GHOLD413_CombinationOfPropsAndOrderingOfAttributes.n4jsx.xt index dd35ae657f..1bc69c6704 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/GHOLD413_CombinationOfPropsAndOrderingOfAttributes.n4jsx.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/GHOLD413_CombinationOfPropsAndOrderingOfAttributes.n4jsx.xt @@ -23,6 +23,7 @@ Project "react" { File "index.n4jsd" { from = "../react/index.n4jsd" } File "index.js" { from = "../react/index.js" } + File "jsx-runtime.js" { from = "../react/jsx-runtime.js" } File "package.json" { from = "../react/package.json" } } } @@ -42,57 +43,51 @@ const baz = { baz: "MyBaz" } Zero attribute: { "type": "div", - "props": null, - "children": [] + "config": {} } One property attribute: { "type": "div", - "props": { + "config": { "foo": "Hi" - }, - "children": [] + } } One spread: { "type": "div", - "props": { + "config": { "baz": "MyBaz" - }, - "children": [] + } } Spread as first attribute: { "type": "div", - "props": { + "config": { "baz": "MyBaz", "foo": true, "qux": "tt", "tux": 5 - }, - "children": [] + } } Spread between props: { "type": "div", - "props": { + "config": { "foo": true, "baz": "MyBaz", "qux": "tt", "tux": 5 - }, - "children": [] + } } Spread as last attribute: { "type": "div", - "props": { + "config": { "foo": true, "qux": "tt", "tux": 5, "baz": "MyBaz" - }, - "children": [] + } } --- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/compile/replacer.n4js b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/replacer.n4js similarity index 100% rename from tests/org.eclipse.n4js.spec.tests/xt-tests/compile/replacer.n4js rename to tests/org.eclipse.n4js.spec.tests/xt-tests/react_run/replacer.n4js diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_fragments.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_fragments.n4jsx.xt new file mode 100644 index 0000000000..d0a1eea435 --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_fragments.n4jsx.xt @@ -0,0 +1,74 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest + + Workspace { + Project "N4JSXSpecTest" { + Folder "src" { + ThisFile {} + } + File "package.json" { from="../../package_default.json" } + } + Project "react" { + File "index.n4jsd" { from = "../react/index.n4jsd" } + File "index.js" { from = "../react/index.js" } + File "jsx-runtime.js" { from = "../react/jsx-runtime.js" } + File "package.json" { from = "../react/package.json" } + } + } + + END_SETUP + */ + + +console.log( + <> +
+ +); + + +console.log( +
+ <> +
+); + + +let elem: any+ = +
+ <> +
+ +
; + + +/* XPECT compileResult --- +// Generated by N4JS transpiler; for copyright see original N4JS source file. + +import 'n4js-runtime' +import * as React from 'react' +import {jsx as $jsx} from 'react/jsx-runtime.js' + +console.log($jsx(React.Fragment, { + children: $jsx('div', {}) +})); +console.log($jsx('div', { + children: $jsx(React.Fragment, {}) +})); +let elem = $jsx('div', { + children: $jsx(React.Fragment, { + children: $jsx('div', {}) + }) +}); +//# sourceMappingURL=jsx_fragments.map +--- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_children.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_children.n4jsx.xt new file mode 100644 index 0000000000..a9d3d1f46d --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_children.n4jsx.xt @@ -0,0 +1,83 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest + + Workspace { + Project "N4JSXSpecTest" { + Folder "src" { + ThisFile {} + } + File "package.json" { from="../../package_default.json" } + } + Project "react" { + File "index.n4jsd" { from = "../react/index.n4jsd" } + File "index.js" { from = "../react/index.js" } + File "jsx-runtime.js" { from = "../react/jsx-runtime.js" } + File "package.json" { from = "../react/package.json" } + } + } + + END_SETUP + */ + + +// XPECT noerrors --> +// XPECT nowarnings --> +const MyDiv1 =
; +MyDiv1; + +// XPECT warnings --> "Attribute 'children' will be overwritten by jsx child elements." at "children" +const MyDiv2 =
{"Guten Tag"}
; +MyDiv2; + +// XPECT warnings --> "Attribute 'children' will be overwritten by jsx child elements." at "children" +const MyDiv3 =

; +MyDiv3; + +// XPECT nowarnings --> +const props4 = {a1: 1, a2: 2} +const MyDiv4 =

; +MyDiv4; + + + + +/* XPECT compileResult --- +// Generated by N4JS transpiler; for copyright see original N4JS source file. + +import 'n4js-runtime' +import {jsx as $jsx} from 'react/jsx-runtime.js' + +const MyDiv1 = $jsx('div', { + children: "Hello World" +}); +MyDiv1; +const MyDiv2 = $jsx('div', { + children: "Guten Tag" +}); +MyDiv2; +const MyDiv3 = $jsx('div', { + children: $jsx('h2', {}) +}); +MyDiv3; +const props4 = { + a1: 1, + a2: 2 +}; +const MyDiv4 = $jsx('div', { + ...props4, + ref: "x", + children: $jsx('h2', {}) +}, 1); +MyDiv4; +//# sourceMappingURL=jsx_transpile_children.map +--- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_elements.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_elements.n4jsx.xt new file mode 100644 index 0000000000..7e0be05ede --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_elements.n4jsx.xt @@ -0,0 +1,72 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest + + Workspace { + Project "N4JSXSpecTest" { + Folder "src" { + ThisFile {} + } + File "package.json" { from="../../package_default.json" } + } + Project "react" { + File "index.n4jsd" { from = "../react/index.n4jsd" } + File "index.js" { from = "../react/index.js" } + File "jsx-runtime.js" { from = "../react/jsx-runtime.js" } + File "package.json" { from = "../react/package.json" } + } + } + + END_SETUP + */ + + +// XPECT noerrors --> +const MyDiv =
; +MyDiv; + +const MyDivText =
{"Hello World"}
; +MyDivText; + +const MyDivWithChild =

; +MyDivWithChild; + +const MyDivWithChildren =

; +MyDivWithChildren; + + + +/* XPECT compileResult --- +// Generated by N4JS transpiler; for copyright see original N4JS source file. + +import 'n4js-runtime' +import {jsx as $jsx} from 'react/jsx-runtime.js' + +const MyDiv = $jsx('div', {}); +MyDiv; +const MyDivText = $jsx('div', { + children: "Hello World" +}); +MyDivText; +const MyDivWithChild = $jsx('div', { + children: $jsx('h1', {}) +}); +MyDivWithChild; +const MyDivWithChildren = $jsx('div', { + children: [ + $jsx('h1', {}), + $jsx('h2', {}) + ] +}); +MyDivWithChildren; +//# sourceMappingURL=jsx_transpile_elements.map +--- */ diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_properties.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_properties.n4jsx.xt new file mode 100644 index 0000000000..4f0c600039 --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_properties.n4jsx.xt @@ -0,0 +1,111 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest + + Workspace { + Project "N4JSXSpecTest" { + Folder "src" { + ThisFile {} + } + File "package.json" { from="../../package_default.json" } + } + Project "react" { + File "index.n4jsd" { from = "../react/index.n4jsd" } + File "index.js" { from = "../react/index.js" } + File "jsx-runtime.js" { from = "../react/jsx-runtime.js" } + File "package.json" { from = "../react/package.json" } + } + } + + END_SETUP + */ + + +// XPECT noerrors --> +const MyDiv1 =
; +MyDiv1; + +const MyDiv2 =
; +MyDiv2; + +const props3 = {a1: 1, a2: 2} +const MyDiv3 =
; +MyDiv3; + +const props4 = {a1: 1, a2: 2} +const MyDiv4 =
; +MyDiv4; + +const props5 = {a1: 1, a2: 2} +const MyDiv5 =
; +MyDiv5; + +const props6 = {a1: 1, a2: 2} +const MyDiv6 =
; +MyDiv6; + +const MyDiv7 =
; +MyDiv7; + + +/* XPECT compileResult --- +// Generated by N4JS transpiler; for copyright see original N4JS source file. + +import 'n4js-runtime' +import {jsx as $jsx} from 'react/jsx-runtime.js' + +const MyDiv1 = $jsx('div', {}, 1); +MyDiv1; +const MyDiv2 = $jsx('div', { + ref: "x" +}, 1); +MyDiv2; +const props3 = { + a1: 1, + a2: 2 +}; +const MyDiv3 = $jsx('div', { + ref: "x", + ...props3 +}, 1); +MyDiv3; +const props4 = { + a1: 1, + a2: 2 +}; +const MyDiv4 = $jsx('div', { + ...props4, + ref: "x" +}, 1); +MyDiv4; +const props5 = { + a1: 1, + a2: 2 +}; +const MyDiv5 = $jsx('div', { + ...props5, + ...props4, + ref: "x" +}, 1); +MyDiv5; +const props6 = { + a1: 1, + a2: 2 +}; +const MyDiv6 = $jsx('div', props6); +MyDiv6; +const MyDiv7 = $jsx('div', { + trueProp: true +}); +MyDiv7; +//# sourceMappingURL=jsx_transpile_properties.map +--- */ diff --git a/tests/org.eclipse.n4js.xpect.tests/react-implementations/non-conforming/jsx-runtime.js b/tests/org.eclipse.n4js.xpect.tests/react-implementations/non-conforming/jsx-runtime.js new file mode 100644 index 0000000000..e4fcfe9322 --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/react-implementations/non-conforming/jsx-runtime.js @@ -0,0 +1,15 @@ +/* + * 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 + */ + +//Mock implementation for jsx +export function jsx(type, config, maybeKey) { + return {type: type, config: config, maybeKey: maybeKey}; +} diff --git a/tests/org.eclipse.n4js.xpect.tests/react-implementations/valid/jsx-runtime.js b/tests/org.eclipse.n4js.xpect.tests/react-implementations/valid/jsx-runtime.js new file mode 100644 index 0000000000..e4fcfe9322 --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/react-implementations/valid/jsx-runtime.js @@ -0,0 +1,15 @@ +/* + * 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 + */ + +//Mock implementation for jsx +export function jsx(type, config, maybeKey) { + return {type: type, config: config, maybeKey: maybeKey}; +} diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/JSXFragments.n4jsx.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/JSXFragments.n4jsx.xt index 5fce78da11..791a0ebd87 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/JSXFragments.n4jsx.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/JSXFragments.n4jsx.xt @@ -21,6 +21,7 @@ Project "react" { File "index.n4jsd" { from = "../react-implementations/valid/index.n4jsd" } File "index.js" { from = "../react-implementations/valid/index.js" } + File "jsx-runtime.js" { from = "../react-implementations/valid/jsx-runtime.js" } File "package.json" { from = "../react-implementations/valid/package.json" } } } @@ -52,9 +53,17 @@ let elem: any+ = <>
+ <> +
+
; + +console.log("elem: "); console.log(elem); -console.log(elem.children[0].children); +console.log("children: "); +console.log(elem.config.children); +console.log("child of child: "); +console.log(elem.config.children[0].config.children); console.log('===================================='); @@ -63,21 +72,36 @@ console.log('===================================='); ==================================== { type: undefined, - props: null, - children: [ { type: 'div', props: null, children: [] } ] + config: { children: { type: 'div', config: {}, maybeKey: undefined } }, + maybeKey: undefined } ==================================== { type: 'div', - props: null, - children: [ { type: undefined, props: null, children: [] } ] + config: { children: { type: undefined, config: {}, maybeKey: undefined } }, + maybeKey: undefined } ==================================== +elem: { type: 'div', - props: null, - children: [ { type: undefined, props: null, children: [Array] } ] + config: { children: [ [Object], [Object] ] }, + maybeKey: undefined } -[ { type: 'div', props: null, children: [] } ] +children: +[ + { + type: undefined, + config: { children: [Object] }, + maybeKey: undefined + }, + { + type: undefined, + config: { children: [Object] }, + maybeKey: undefined + } +] +child of child: +{ type: 'div', config: {}, maybeKey: undefined } ==================================== --- */ From 60bebd70f11f22b741f24a88f3eb1884735a3b8a Mon Sep 17 00:00:00 2001 From: mmews Date: Wed, 14 Feb 2024 12:58:25 +0100 Subject: [PATCH 17/26] GH-2596: Fix NPE --- .../es/transform/CommonJsImportsTransformation.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/CommonJsImportsTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/CommonJsImportsTransformation.java index 57b9c7168e..2ddca09498 100644 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/CommonJsImportsTransformation.java +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/CommonJsImportsTransformation.java @@ -41,6 +41,7 @@ import org.eclipse.n4js.n4JS.VariableStatement; import org.eclipse.n4js.n4JS.VariableStatementKeyword; import org.eclipse.n4js.packagejson.PackageJsonProperties; +import org.eclipse.n4js.tooling.react.ReactHelper; import org.eclipse.n4js.transpiler.Transformation; import org.eclipse.n4js.transpiler.TransformationDependency.ExcludesAfter; import org.eclipse.n4js.transpiler.TransformationDependency.ExcludesBefore; @@ -100,7 +101,9 @@ public void transform() { ImmutableListMultimap importDeclsPerImportedModule = FluentIterable .from(getState().im.getScriptElements()) .filter(ImportDeclaration.class) - .filter(id -> !id.isBare()) // ignore bare imports + // ignore bare imports and special jsx import + .filter(id -> !id.isBare() + && !ReactHelper.REACT_JSX_RUNTIME_NAME.equals(id.getModuleSpecifierAsText())) .index(importDecl -> getState().info.getImportedModule(importDecl)); List varStmnts = new ArrayList<>(); From cb43820edfa774d3adbd25d24d3f09498a758bf8 Mon Sep 17 00:00:00 2001 From: mmews Date: Thu, 15 Feb 2024 09:41:41 +0100 Subject: [PATCH 18/26] HOTFIX (GH-2596): adjust import module specifier for jsx --- .../src/org/eclipse/n4js/tooling/react/ReactHelper.xtend | 2 +- .../xt-tests/react/package.json | 7 +++++++ .../xt-tests/react_transpile/jsx_fragments.n4jsx.xt | 2 +- .../react_transpile/jsx_transpile_children.n4jsx.xt | 2 +- .../react_transpile/jsx_transpile_elements.n4jsx.xt | 2 +- .../react_transpile/jsx_transpile_properties.n4jsx.xt | 2 +- .../react-implementations/valid/package.json | 7 +++++++ 7 files changed, 19 insertions(+), 5 deletions(-) diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend index 28969ebcae..ac4f517269 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend @@ -65,7 +65,7 @@ class ReactHelper { public final static String REACT_ELEMENT_FACTORY_FUNCTION_NAME = "createElement"; public final static String REACT_ELEMENT_PROPERTY_KEY_NAME = "key"; public final static String REACT_ELEMENT_PROPERTY_CHILDREN_NAME = "children"; - public final static String REACT_JSX_RUNTIME_NAME = "react/jsx-runtime.js"; + public final static String REACT_JSX_RUNTIME_NAME = "react/jsx-runtime"; private final static String REACT_KEY = "KEY__" + REACT_PROJECT_ID diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/react/package.json b/tests/org.eclipse.n4js.spec.tests/xt-tests/react/package.json index f33333de57..a7878222b8 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/react/package.json +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react/package.json @@ -3,6 +3,13 @@ "version": "17.0.1", "type": "module", "main": "./index.js", + "exports": { + ".": { + "default": "./index.js" + }, + "./package.json": "./package.json", + "./jsx-runtime": "./jsx-runtime.js" + }, "n4js": { "projectType": "library", "vendorId": "npm", diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_fragments.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_fragments.n4jsx.xt index d0a1eea435..33ebe20311 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_fragments.n4jsx.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_fragments.n4jsx.xt @@ -57,7 +57,7 @@ let elem: any+ = import 'n4js-runtime' import * as React from 'react' -import {jsx as $jsx} from 'react/jsx-runtime.js' +import {jsx as $jsx} from 'react/jsx-runtime' console.log($jsx(React.Fragment, { children: $jsx('div', {}) diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_children.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_children.n4jsx.xt index a9d3d1f46d..a56297ab74 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_children.n4jsx.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_children.n4jsx.xt @@ -55,7 +55,7 @@ MyDiv4; // Generated by N4JS transpiler; for copyright see original N4JS source file. import 'n4js-runtime' -import {jsx as $jsx} from 'react/jsx-runtime.js' +import {jsx as $jsx} from 'react/jsx-runtime' const MyDiv1 = $jsx('div', { children: "Hello World" diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_elements.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_elements.n4jsx.xt index 7e0be05ede..0d02515809 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_elements.n4jsx.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_elements.n4jsx.xt @@ -49,7 +49,7 @@ MyDivWithChildren; // Generated by N4JS transpiler; for copyright see original N4JS source file. import 'n4js-runtime' -import {jsx as $jsx} from 'react/jsx-runtime.js' +import {jsx as $jsx} from 'react/jsx-runtime' const MyDiv = $jsx('div', {}); MyDiv; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_properties.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_properties.n4jsx.xt index 4f0c600039..b3871083d2 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_properties.n4jsx.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_properties.n4jsx.xt @@ -61,7 +61,7 @@ MyDiv7; // Generated by N4JS transpiler; for copyright see original N4JS source file. import 'n4js-runtime' -import {jsx as $jsx} from 'react/jsx-runtime.js' +import {jsx as $jsx} from 'react/jsx-runtime' const MyDiv1 = $jsx('div', {}, 1); MyDiv1; diff --git a/tests/org.eclipse.n4js.xpect.tests/react-implementations/valid/package.json b/tests/org.eclipse.n4js.xpect.tests/react-implementations/valid/package.json index f33333de57..a7878222b8 100644 --- a/tests/org.eclipse.n4js.xpect.tests/react-implementations/valid/package.json +++ b/tests/org.eclipse.n4js.xpect.tests/react-implementations/valid/package.json @@ -3,6 +3,13 @@ "version": "17.0.1", "type": "module", "main": "./index.js", + "exports": { + ".": { + "default": "./index.js" + }, + "./package.json": "./package.json", + "./jsx-runtime": "./jsx-runtime.js" + }, "n4js": { "projectType": "library", "vendorId": "npm", From 8e6eab1c0292020e0737311997aaaacd1279f564 Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Fri, 16 Feb 2024 13:39:19 +0100 Subject: [PATCH 19/26] GH-2606: A workspace project should not have the its root folder as a default source folder (#2607) * no default source folder for workspace projects * related adjustments * add comment * fix, refactor test * added/renamed/enabled tests --- .../n4js/packagejson/PackageJsonHelper.java | 40 +- .../n4js/utils/ProjectDescriptionLoader.java | 8 +- .../n4js/utils/ProjectDiscoveryHelper.java | 4 +- ...AbstractPackageJSONValidatorExtension.java | 2 +- .../ide/dts/tests/TsConfigRespectTest.java | 386 +++++++++--------- ...orkspaceNoDefaultSourceFolderPnpmTest.java | 64 +++ ...orkspaceNoDefaultSourceFolderYarnTest.java | 77 ++++ ...ava => YarnDifferentPackageNamesTest.java} | 2 +- ...ava => YarnProjectDuplicateNamesTest.java} | 2 +- .../packagejson/PackageJsonHelperTest.java | 7 +- 10 files changed, 379 insertions(+), 213 deletions(-) create mode 100644 tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/WorkspaceNoDefaultSourceFolderPnpmTest.java create mode 100644 tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/WorkspaceNoDefaultSourceFolderYarnTest.java rename tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/{YarnDifferentPackageNames.java => YarnDifferentPackageNamesTest.java} (97%) rename tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/{YarnProjectDuplicateNames.java => YarnProjectDuplicateNamesTest.java} (97%) diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonHelper.java index 8102b2b7a6..725a6ab499 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonHelper.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonHelper.java @@ -78,9 +78,28 @@ public class PackageJsonHelper { private VersionNumber cachedJSDefaultVersionNumber = null; /** - * Transform the given {@code packageJSON} into an equivalent {@link ProjectDescriptionBuilder} instance. If no - * further adjustments are required, the client can immediately invoke the {@code #build()} method to obtain the - * corresponding {@link ProjectDescription}. + * Transform the given {@code packageJSON} into an equivalent {@link ProjectDescriptionBuilder} instance. + * + * @param packageJSON + * the JSON document to convert (should be the representation of a valid {@code package.json} file). + * @return the project description converted from the given JSON document or null if the root value of + * the given JSON document is not a {@link JSONObject}. + */ + public ProjectDescriptionBuilder convertToProjectDescription(JSONDocument packageJSON) { + JSONValue rootValue = packageJSON.getContent(); + if (!(rootValue instanceof JSONObject)) { + return null; + } + + ProjectDescriptionBuilder target = new ProjectDescriptionBuilder(); + List rootPairs = ((JSONObject) rootValue).getNameValuePairs(); + convertRootPairs(target, rootPairs); + + return target; + } + + /** + * Adjusts the given target and applies default values. *

* Note: this method does not implement the package.json feature that a "main" path may point to a folder and then a * file "index.js" in that folder will be used as main module (for details see @@ -88,6 +107,8 @@ public class PackageJsonHelper { * * @param packageJSON * the JSON document to convert (should be the representation of a valid {@code package.json} file). + * @param target + * target that will be adjusted * @param applyDefaultValues * whether default values should be applied to the project description after conversion. * @param defaultProjectName @@ -95,18 +116,14 @@ public class PackageJsonHelper { * @return the project description converted from the given JSON document or null if the root value of * the given JSON document is not a {@link JSONObject}. */ - public ProjectDescriptionBuilder convertToProjectDescription(JSONDocument packageJSON, boolean applyDefaultValues, - String defaultProjectName) { + public ProjectDescriptionBuilder adjustAndApplyDefaults(JSONDocument packageJSON, ProjectDescriptionBuilder target, + boolean applyDefaultValues, String defaultProjectName) { JSONValue rootValue = packageJSON.getContent(); if (!(rootValue instanceof JSONObject)) { return null; } - ProjectDescriptionBuilder target = new ProjectDescriptionBuilder(); - List rootPairs = ((JSONObject) rootValue).getNameValuePairs(); - convertRootPairs(target, rootPairs); - String valueOfPropMain = asNonEmptyStringOrNull(getProperty((JSONObject) rootValue, MAIN.name).orElse(null)); adjustProjectDescriptionAfterConversion(target, applyDefaultValues, defaultProjectName, valueOfPropMain); @@ -484,7 +501,10 @@ private void applyPlainJSDefaults(ProjectDescriptionBuilder target, String defau trimProjectExports(target.getExports(), target.getTypesVersions()); } } - setSourceContainer(target, (String) OUTPUT.defaultValue, false); + if (!target.isWorkspaceRoot()) { + // workspace projects my contain unrelated sources hence do not use the default source folder + setSourceContainer(target, (String) OUTPUT.defaultValue, false); + } if (mainOrTypesModulePath != null) { if (mainOrTypesModulePath.startsWith("./")) { diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDescriptionLoader.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDescriptionLoader.java index ca9ddd160d..df4de4f949 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDescriptionLoader.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDescriptionLoader.java @@ -109,15 +109,19 @@ public ProjectDescription loadProjectDescriptionAtLocation(FileURI location, URI adjustMainPath(location, packageJSON); ProjectDescriptionBuilder pdbFromPackageJSON = packageJSON != null - ? packageJsonHelper.convertToProjectDescription(packageJSON, true, null) + ? packageJsonHelper.convertToProjectDescription(packageJSON) : null; if (pdbFromPackageJSON != null) { + // the order is important here: + setInformationFromFileSystem(location, pdbFromPackageJSON); - setInformationFromTSConfig(location, pdbFromPackageJSON); setInformationFromPnpmWorkspace(location, pdbFromPackageJSON); pdbFromPackageJSON.setLocation(location); pdbFromPackageJSON.setRelatedRootLocation(relatedRootLocation); + packageJsonHelper.adjustAndApplyDefaults(packageJSON, pdbFromPackageJSON, true, null); + setInformationFromTSConfig(location, pdbFromPackageJSON); + ProjectDescription result = pdbFromPackageJSON.build(); return result; } else { diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDiscoveryHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDiscoveryHelper.java index 560fd3330f..c13e6edb47 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDiscoveryHelper.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/ProjectDiscoveryHelper.java @@ -229,9 +229,7 @@ private void collectYarnWorkspaceProjects(Path yarnProjectRoot, Map> testData = Map.of( + "main-project", Map.of( + "MainModule", """ + // empty + """, + CFG_DEPENDENCIES, """ + library-project-other-name + """), + "library-project", Map.of( + "LibraryModule", """ + // empty + """)); + + @Test + public void test() throws Exception { + testWorkspaceManager.createTestOnDisk(testData); + + startAndWaitForLspServer(); + + ProjectConfigSnapshot pc = concurrentIndex.getProjectConfig(TestWorkspaceManager.YARN_TEST_PROJECT); + Assert.assertNotNull(pc); + + ImmutableSet sfs = pc.getSourceFolders(); + + Assert.assertEquals(1, sfs.size()); + Assert.assertTrue(sfs.iterator().next() instanceof N4JSSourceFolderSnapshotForPackageJson); + } + +} diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/WorkspaceNoDefaultSourceFolderYarnTest.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/WorkspaceNoDefaultSourceFolderYarnTest.java new file mode 100644 index 0000000000..9711cc5f91 --- /dev/null +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/WorkspaceNoDefaultSourceFolderYarnTest.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2020 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.ide.tests.builder; + +import java.nio.file.Path; +import java.util.Map; + +import org.eclipse.n4js.ide.tests.helper.server.AbstractIdeTest; +import org.eclipse.n4js.ide.tests.helper.server.TestWorkspaceManager; +import org.eclipse.n4js.utils.URIUtils; +import org.eclipse.n4js.workspace.N4JSSourceFolderSnapshotForPackageJson; +import org.eclipse.n4js.workspace.WorkspaceAccess; +import org.eclipse.n4js.workspace.locations.FileURI; +import org.eclipse.n4js.xtext.workspace.ProjectConfigSnapshot; +import org.eclipse.n4js.xtext.workspace.SourceFolderSnapshot; +import org.eclipse.xtext.xbase.lib.Pair; +import org.junit.Assert; +import org.junit.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.Inject; + +/** + * Test if the workspace project does not have the default source folder '.'. + */ + +public class WorkspaceNoDefaultSourceFolderYarnTest extends AbstractIdeTest { + + @Inject + WorkspaceAccess workspaceAccess; + + private static Map> testData = Map.of( + "main-project", Map.of( + "MainModule", """ + // empty + """, + CFG_DEPENDENCIES, """ + library-project-other-name + """), + "library-project", Map.of( + "LibraryModule", """ + // empty + """)); + + @Test + public void test() throws Exception { + testWorkspaceManager.createTestOnDisk(testData); + + Path pnpmws = Path.of(getRoot().toString(), TestWorkspaceManager.YARN_TEST_PROJECT, "pnpm-workspace.yaml"); + FileURI pnpmwsUri = new FileURI(URIUtils.toFileUri(pnpmws)); + createFileOnDiskWithoutNotification(pnpmwsUri, "packages:\n" + + " - 'packages/*'"); + + Path pckjws = Path.of(getRoot().toString(), TestWorkspaceManager.YARN_TEST_PROJECT, "package.json"); + FileURI pckjUri = new FileURI(URIUtils.toFileUri(pckjws)); + changeFileOnDiskWithoutNotification(pckjUri, Pair.of("\"workspaces\"", "\"ignore_me\"")); + + startAndWaitForLspServer(); + + ProjectConfigSnapshot pc = concurrentIndex.getProjectConfig(TestWorkspaceManager.YARN_TEST_PROJECT); + Assert.assertNotNull(pc); + + ImmutableSet sfs = pc.getSourceFolders(); + + Assert.assertEquals(1, sfs.size()); + Assert.assertTrue(sfs.iterator().next() instanceof N4JSSourceFolderSnapshotForPackageJson); + } + +} diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnDifferentPackageNames.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnDifferentPackageNamesTest.java similarity index 97% rename from tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnDifferentPackageNames.java rename to tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnDifferentPackageNamesTest.java index 03b341b558..d679c0ae5c 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnDifferentPackageNames.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnDifferentPackageNamesTest.java @@ -21,7 +21,7 @@ * Test two cases of projects with the same project name within a yarn setup */ -public class YarnDifferentPackageNames extends AbstractIncrementalBuilderTest { +public class YarnDifferentPackageNamesTest extends AbstractIncrementalBuilderTest { private static Map> testData = Map.of( "main-project", Map.of( diff --git a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnProjectDuplicateNames.java b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnProjectDuplicateNamesTest.java similarity index 97% rename from tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnProjectDuplicateNames.java rename to tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnProjectDuplicateNamesTest.java index 71d345d25e..77e5f237da 100644 --- a/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnProjectDuplicateNames.java +++ b/tests/org.eclipse.n4js.ide.tests/src/org/eclipse/n4js/ide/tests/builder/YarnProjectDuplicateNamesTest.java @@ -29,7 +29,7 @@ * Test two cases of projects with the same project name within a yarn setup */ @SuppressWarnings("unchecked") -public class YarnProjectDuplicateNames extends AbstractIncrementalBuilderTest { +public class YarnProjectDuplicateNamesTest extends AbstractIncrementalBuilderTest { private static Map> testData1 = Map.of( TestWorkspaceManager.YARN_TEST_PROJECT, Map.of( diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/packagejson/PackageJsonHelperTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/packagejson/PackageJsonHelperTest.java index 138ff48cc1..f3424e45e7 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/packagejson/PackageJsonHelperTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/tests/packagejson/PackageJsonHelperTest.java @@ -35,6 +35,7 @@ import org.eclipse.n4js.packagejson.projectDescription.ModuleFilterType; import org.eclipse.n4js.packagejson.projectDescription.ProjectDependency; import org.eclipse.n4js.packagejson.projectDescription.ProjectDescription; +import org.eclipse.n4js.packagejson.projectDescription.ProjectDescriptionBuilder; import org.eclipse.n4js.packagejson.projectDescription.ProjectType; import org.eclipse.n4js.packagejson.projectDescription.SourceContainerDescription; import org.eclipse.n4js.packagejson.projectDescription.SourceContainerType; @@ -333,8 +334,10 @@ private ProjectDescription parseAndConvert(CharSequence jsonSource, boolean appl JSONDocument jsonDocument; try { jsonDocument = jsonParseHelper.parseSuccessfully(jsonSource); - ProjectDescription pd = packageJsonHelper - .convertToProjectDescription(jsonDocument, applyDefaultValues, defaultProjectName).build(); + ProjectDescriptionBuilder preInitPD = packageJsonHelper.convertToProjectDescription(jsonDocument); + packageJsonHelper.adjustAndApplyDefaults(jsonDocument, preInitPD, applyDefaultValues, defaultProjectName); + ProjectDescription pd = preInitPD.build(); + return pd; } catch (Exception e) { e.printStackTrace(); From f2b2ce136a9b3211c088bb086772c29fa582aab4 Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Tue, 20 Feb 2024 15:05:28 +0100 Subject: [PATCH 20/26] GH-2608: Fix jsx transpiler wrt jsxs (#2609) * use jsxs when passing an array of children * adjust tests * fix test fixture --- .../es/transform/JSXTransformation.java | 33 ++++++++++++++----- .../SanitizeImportsTransformation.java | 6 ++-- .../n4js/transpiler/TranspilerComponent.java | 7 ++-- .../transpiler/TranspilerStateOperations.java | 11 +++---- .../n4js/tooling/react/ReactHelper.xtend | 1 + .../xt-tests/react/jsx-runtime.js | 5 +++ .../react_transpile/jsx_fragments.n4jsx.xt | 2 +- .../jsx_transpile_elements.n4jsx.xt | 4 +-- .../non-conforming/jsx-runtime.js | 5 +++ .../valid/jsx-runtime.js | 5 +++ 10 files changed, 56 insertions(+), 23 deletions(-) diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.java index bd05bafea6..5008d437a2 100644 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.java +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/JSXTransformation.java @@ -12,10 +12,12 @@ import static org.eclipse.n4js.tooling.react.ReactHelper.REACT_ELEMENT_PROPERTY_CHILDREN_NAME; import static org.eclipse.n4js.tooling.react.ReactHelper.REACT_ELEMENT_PROPERTY_KEY_NAME; +import static org.eclipse.n4js.tooling.react.ReactHelper.REACT_JSXS_TRANSFORM_NAME; import static org.eclipse.n4js.tooling.react.ReactHelper.REACT_JSX_RUNTIME_NAME; import static org.eclipse.n4js.tooling.react.ReactHelper.REACT_JSX_TRANSFORM_NAME; import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ArrLit; import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._CallExpr; +import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._NamedImportSpecifier; import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._ObjLit; import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyAccessExpr; import static org.eclipse.n4js.transpiler.TranspilerBuilderBlocks._PropertyNameValuePair; @@ -28,7 +30,10 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import org.eclipse.emf.common.util.EList; import org.eclipse.n4js.n4JS.Expression; @@ -41,6 +46,7 @@ import org.eclipse.n4js.n4JS.JSXFragment; import org.eclipse.n4js.n4JS.JSXPropertyAttribute; import org.eclipse.n4js.n4JS.JSXSpreadAttribute; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; import org.eclipse.n4js.n4JS.ParameterizedCallExpression; import org.eclipse.n4js.n4JS.PropertyAssignment; @@ -71,13 +77,15 @@ * will be transformed to * *

- * React.createElement('div', Object.assign({attr: "value"}));
+ * $jsv('div', {attr: "value"});
  * 
*/ public class JSXTransformation extends Transformation { - /** Alias for React transform */ - public static final String JSX_ALIAS = "$" + REACT_JSX_TRANSFORM_NAME; + static final Map ALIAS_MAP = Map.of( + REACT_JSX_TRANSFORM_NAME, "$" + REACT_JSX_TRANSFORM_NAME, + REACT_JSXS_TRANSFORM_NAME, "$" + REACT_JSXS_TRANSFORM_NAME); + private final Set necessaryImports = new LinkedHashSet<>(); private SymbolTableEntryOriginal steForJsxBackendNamespace; private SymbolTableEntryOriginal steForJsxBackendFragmentComponent; @@ -138,7 +146,6 @@ public void transform() { return; } - createImportOfJsx(); steForJsxBackendNamespace = createImportOfJsxBackend(); // will be removed if obsolete steForJsxBackendFragmentComponent = prepareFragmentComponent(); @@ -146,11 +153,18 @@ public void transform() { for (JSXAbstractElement jsxElem : jsxAbstractElements) { transformJSXAbstractElement(jsxElem); } + createNecessaryImportsOfJsx(); } - private void createImportOfJsx() { - ImportDeclaration impDecl = addNamedImport(REACT_JSX_TRANSFORM_NAME, JSX_ALIAS, REACT_JSX_RUNTIME_NAME); - impDecl.getImportSpecifiers().forEach(is -> is.setFlaggedUsedInCode(true)); + private void createNecessaryImportsOfJsx() { + List importSpecifierNames = new ArrayList<>(necessaryImports); + NamedImportSpecifier[] importSpecs = new NamedImportSpecifier[importSpecifierNames.size()]; + for (int i = 0; i < importSpecifierNames.size(); i++) { + String isn = importSpecifierNames.get(i); + String alias = ALIAS_MAP.get(isn); + importSpecs[i] = _NamedImportSpecifier(isn, alias, true); + } + addNamedImport(REACT_JSX_RUNTIME_NAME, importSpecs); } private SymbolTableEntryOriginal createImportOfJsxBackend() { @@ -216,7 +230,10 @@ private ParameterizedCallExpression convertJSXAbstractElement(JSXAbstractElement } IdentifierRef_IM idRef = ImFactory.eINSTANCE.createIdentifierRef_IM(); - idRef.setIdAsText(JSX_ALIAS); + String isn = elem.getJsxChildren().size() > 1 ? REACT_JSXS_TRANSFORM_NAME : REACT_JSX_TRANSFORM_NAME; + necessaryImports.add(isn); + String jsxAlias = ALIAS_MAP.get(isn); + idRef.setIdAsText(jsxAlias); SymbolTableEntryInternal ste = getSymbolTableEntryInternal(idRef.getIdAsText(), true); idRef.setId_IM(ste); return _CallExpr(idRef, args.toArray(new Expression[0])); diff --git a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.java b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.java index f6be3f4c0a..7de8a574df 100644 --- a/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.java +++ b/plugins/org.eclipse.n4js.transpiler.es/src/org/eclipse/n4js/transpiler/es/transform/SanitizeImportsTransformation.java @@ -10,6 +10,7 @@ */ package org.eclipse.n4js.transpiler.es.transform; +import static org.eclipse.n4js.tooling.react.ReactHelper.REACT_JSX_RUNTIME_NAME; import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; @@ -158,8 +159,9 @@ private boolean isUsed(ImportSpecifier importSpec) { // add new usages of an existing import) // -> therefore simply return false (i.e. unused) return false; - } else if (importSpec instanceof NamedImportSpecifier - && JSXTransformation.JSX_ALIAS.equals(((NamedImportSpecifier) importSpec).getAlias())) { + } else if (importSpec.eContainer() instanceof ImportDeclaration + && REACT_JSX_RUNTIME_NAME + .equals(((ImportDeclaration) importSpec.eContainer()).getModuleSpecifierAsText())) { // special case for import that is added in JSXTransformation return true; } else { diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerComponent.java b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerComponent.java index 442070d47e..c74d4c663d 100644 --- a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerComponent.java +++ b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerComponent.java @@ -109,10 +109,9 @@ public void addNamedImport(SymbolTableEntryOriginal steOfElementToImport, String TranspilerStateOperations.addNamedImport(state, steOfElementToImport, aliasOrNull); } - /** See {@link TranspilerStateOperations#addNamedImport(TranspilerState, String, String, String)}. */ - public ImportDeclaration addNamedImport(String elementNameToImport, String aliasOrNull, - String moduleSpecifierName) { - return TranspilerStateOperations.addNamedImport(state, elementNameToImport, aliasOrNull, moduleSpecifierName); + /** See {@link TranspilerStateOperations#addNamedImport(TranspilerState, String, NamedImportSpecifier...)}. */ + public ImportDeclaration addNamedImport(String moduleSpecifierName, NamedImportSpecifier... importSpecifiers) { + return TranspilerStateOperations.addNamedImport(state, moduleSpecifierName, importSpecifiers); } /** See {@link TranspilerStateOperations#addEmptyImport(TranspilerState, String)}. */ diff --git a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.java b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.java index 918a866000..8bff9d96e7 100644 --- a/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.java +++ b/plugins/org.eclipse.n4js.transpiler/src/org/eclipse/n4js/transpiler/TranspilerStateOperations.java @@ -187,18 +187,17 @@ public static void addNamedImport(TranspilerState state, SymbolTableEntryOrigina } /** - * Creates a new named import for the given STE and adds it to the intermediate model of the given transpiler state. - * Note that this method does not perform a binding to an existing target module. + * Creates a new named import for the given names. It does not add it to the intermediate model of the given + * transpiler state. Note that this method does not perform a binding to an existing target module. *

* IMPORTANT: this method does not check if the given element name or alias is unique (i.e. does not avoid name * clashes!). */ - public static ImportDeclaration addNamedImport(TranspilerState state, String elementNameToImport, - String aliasOrNull, String moduleSpecifierName) { + public static ImportDeclaration addNamedImport(TranspilerState state, String moduleSpecifierName, + NamedImportSpecifier... importSpecifiers) { // 1) create import declaration & specifier - NamedImportSpecifier importSpec = _NamedImportSpecifier(elementNameToImport, aliasOrNull, true); - ImportDeclaration importDecl = _ImportDecl(importSpec); + ImportDeclaration importDecl = _ImportDecl(importSpecifiers); importDecl.setModuleSpecifierAsText(moduleSpecifierName); // 2) add import to intermediate model diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend index ac4f517269..23f11003e8 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend @@ -62,6 +62,7 @@ class ReactHelper { public final static String REACT_NAMESPACE_NAME = REACT_PROJECT_ID.toFirstUpper; public final static String REACT_JSX_TRANSFORM_NAME = "jsx"; + public final static String REACT_JSXS_TRANSFORM_NAME = "jsxs"; public final static String REACT_ELEMENT_FACTORY_FUNCTION_NAME = "createElement"; public final static String REACT_ELEMENT_PROPERTY_KEY_NAME = "key"; public final static String REACT_ELEMENT_PROPERTY_CHILDREN_NAME = "children"; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/react/jsx-runtime.js b/tests/org.eclipse.n4js.spec.tests/xt-tests/react/jsx-runtime.js index e4fcfe9322..1ab4e2efab 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/react/jsx-runtime.js +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react/jsx-runtime.js @@ -13,3 +13,8 @@ export function jsx(type, config, maybeKey) { return {type: type, config: config, maybeKey: maybeKey}; } + +//Mock implementation for jsxs +export function jsxs(type, config, maybeKey) { + return {type: type, config: config, maybeKey: maybeKey}; +} diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_fragments.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_fragments.n4jsx.xt index 33ebe20311..4514eb255b 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_fragments.n4jsx.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_fragments.n4jsx.xt @@ -56,8 +56,8 @@ let elem: any+ = // Generated by N4JS transpiler; for copyright see original N4JS source file. import 'n4js-runtime' -import * as React from 'react' import {jsx as $jsx} from 'react/jsx-runtime' +import * as React from 'react' console.log($jsx(React.Fragment, { children: $jsx('div', {}) diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_elements.n4jsx.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_elements.n4jsx.xt index 0d02515809..26a567d1ef 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_elements.n4jsx.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/react_transpile/jsx_transpile_elements.n4jsx.xt @@ -49,7 +49,7 @@ MyDivWithChildren; // Generated by N4JS transpiler; for copyright see original N4JS source file. import 'n4js-runtime' -import {jsx as $jsx} from 'react/jsx-runtime' +import {jsx as $jsx, jsxs as $jsxs} from 'react/jsx-runtime' const MyDiv = $jsx('div', {}); MyDiv; @@ -61,7 +61,7 @@ const MyDivWithChild = $jsx('div', { children: $jsx('h1', {}) }); MyDivWithChild; -const MyDivWithChildren = $jsx('div', { +const MyDivWithChildren = $jsxs('div', { children: [ $jsx('h1', {}), $jsx('h2', {}) diff --git a/tests/org.eclipse.n4js.xpect.tests/react-implementations/non-conforming/jsx-runtime.js b/tests/org.eclipse.n4js.xpect.tests/react-implementations/non-conforming/jsx-runtime.js index e4fcfe9322..1ab4e2efab 100644 --- a/tests/org.eclipse.n4js.xpect.tests/react-implementations/non-conforming/jsx-runtime.js +++ b/tests/org.eclipse.n4js.xpect.tests/react-implementations/non-conforming/jsx-runtime.js @@ -13,3 +13,8 @@ export function jsx(type, config, maybeKey) { return {type: type, config: config, maybeKey: maybeKey}; } + +//Mock implementation for jsxs +export function jsxs(type, config, maybeKey) { + return {type: type, config: config, maybeKey: maybeKey}; +} diff --git a/tests/org.eclipse.n4js.xpect.tests/react-implementations/valid/jsx-runtime.js b/tests/org.eclipse.n4js.xpect.tests/react-implementations/valid/jsx-runtime.js index e4fcfe9322..1ab4e2efab 100644 --- a/tests/org.eclipse.n4js.xpect.tests/react-implementations/valid/jsx-runtime.js +++ b/tests/org.eclipse.n4js.xpect.tests/react-implementations/valid/jsx-runtime.js @@ -13,3 +13,8 @@ export function jsx(type, config, maybeKey) { return {type: type, config: config, maybeKey: maybeKey}; } + +//Mock implementation for jsxs +export function jsxs(type, config, maybeKey) { + return {type: type, config: config, maybeKey: maybeKey}; +} From 9ba86771923180a50200f94e4a64df7bfc13c31e Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Thu, 7 Mar 2024 13:27:51 +0100 Subject: [PATCH 21/26] GH-2603: As a smith I want to migrate some Xtend files to Java (part 8) (#2605) * some migrations * migrate formatter * more migrations * migrate migrate * migrate migrate * some fixes * fix recursion * fix recursion * fix wrong cast * migrate migrate * migrate migrate * fix * migrate migrate * migrate migrate * migrate migrate * migrate migrate * migrate migrate * migrate * fix * migrate N4JSScopeProvider * migrate migrate * migrate MemberScopingHelper * migrate migrate * migrate migrate * fix * migrate more * migrate * fix * migrate * migrate * migrate * migrate * my great migrate * migrate * migrate the migratable * migrate * migrate * migrate --- .../compileTime/CompileTimeEvaluator.java | 521 ++++ .../compileTime/CompileTimeEvaluator.xtend | 447 ---- .../n4js/formatting2/N4JSFormatter.java | 2379 +++++++++++++++++ .../n4js/formatting2/N4JSFormatter.xtend | 1441 ---------- .../N4JSFormatterPreferenceKeys.java | 42 + .../N4JSFormatterPreferenceKeys.xtend | 31 - .../formatting2/N4JSGenericFormatter.java | 368 +++ .../formatting2/N4JSGenericFormatter.xtend | 257 -- ...xtend => TypeExpressionFormatterNoOp.java} | 17 +- .../TypeExpressionsFormatter.java} | 14 +- .../n4js/generator/AbstractSubGenerator.java | 539 ++++ .../n4js/generator/AbstractSubGenerator.xtend | 482 ---- ...r.xtend => GeneratorExceptionHandler.java} | 16 +- .../n4js/packagejson/PackageJsonBuilder.java | 380 +++ .../n4js/packagejson/PackageJsonBuilder.xtend | 358 --- .../PackageJsonContentProvider.java | 241 ++ .../PackageJsonContentProvider.xtend | 210 -- .../n4js/postprocessing/ASTProcessor.java | 563 ++++ .../n4js/postprocessing/ASTProcessor.xtend | 540 ---- .../postprocessing/AbstractPolyProcessor.java | 336 +++ .../AbstractPolyProcessor.xtend | 289 -- .../postprocessing/AbstractProcessor.java | 270 ++ .../postprocessing/AbstractProcessor.xtend | 247 -- .../CompileTimeExpressionProcessor.java | 72 + .../CompileTimeExpressionProcessor.xtend | 70 - .../postprocessing/ComputedNameProcessor.java | 127 + .../ComputedNameProcessor.xtend | 131 - .../postprocessing/DestructureProcessor.java | 143 + .../postprocessing/DestructureProcessor.xtend | 137 - .../n4js/postprocessing/PolyProcessor.java | 267 ++ .../n4js/postprocessing/PolyProcessor.xtend | 260 -- .../PolyProcessor_ArrayLiteral.java | 400 +++ .../PolyProcessor_ArrayLiteral.xtend | 361 --- .../PolyProcessor_CallExpression.java | 198 ++ .../PolyProcessor_CallExpression.xtend | 177 -- .../PolyProcessor_FunctionExpression.java | 457 ++++ .../PolyProcessor_FunctionExpression.xtend | 413 --- .../PolyProcessor_ObjectLiteral.java | 407 +++ .../PolyProcessor_ObjectLiteral.xtend | 378 --- .../RuntimeDependencyProcessor.java | 252 ++ .../RuntimeDependencyProcessor.xtend | 218 -- .../postprocessing/TypeDeferredProcessor.java | 170 ++ .../TypeDeferredProcessor.xtend | 164 -- .../n4js/postprocessing/TypeProcessor.java | 480 ++++ .../n4js/postprocessing/TypeProcessor.xtend | 456 ---- .../n4js/postprocessing/TypeRefProcessor.java | 201 ++ .../postprocessing/TypeRefProcessor.xtend | 182 -- .../resource/N4JSDerivedStateComputer.java | 71 + .../resource/N4JSDerivedStateComputer.xtend | 62 - .../n4js/resource/N4JSDescriptionUtils.java | 28 + .../resource/N4JSLocationInFileProvider.java | 223 ++ .../resource/N4JSLocationInFileProvider.xtend | 196 -- .../n4js/resource/N4JSPreProcessor.java | 132 + .../n4js/resource/N4JSPreProcessor.xtend | 109 - ...ckageJsonResourceDescriptionExtension.java | 380 +++ ...kageJsonResourceDescriptionExtension.xtend | 344 --- .../XpectAwareFileExtensionCalculator.java | 97 + .../XpectAwareFileExtensionCalculator.xtend | 95 - .../n4js/scoping/N4JSScopeProvider.java | 1121 ++++++++ .../n4js/scoping/N4JSScopeProvider.xtend | 977 ------- .../diagnosing/N4JSScopingDiagnostician.java | 131 + .../diagnosing/N4JSScopingDiagnostician.xtend | 116 - .../ImportedElementsScopingHelper.java | 506 ++++ .../ImportedElementsScopingHelper.xtend | 471 ---- .../imports/SingleImportedElementsMap.java | 53 + .../imports/SingleImportedElementsMap.xtend | 50 - .../scoping/members/MemberScopingHelper.java | 565 ++++ .../scoping/members/MemberScopingHelper.xtend | 469 ---- .../scoping/utils/ExpressionExtensions.java | 135 + .../scoping/utils/ExpressionExtensions.xtend | 118 - .../utils/LocallyKnownTypesScopingHelper.java | 187 ++ .../LocallyKnownTypesScopingHelper.xtend | 170 -- .../n4js/scoping/utils/ScopesHelper.java | 94 + .../n4js/scoping/utils/ScopesHelper.xtend | 89 - .../tooling/organizeImports/DIUtility.java | 189 ++ .../tooling/organizeImports/DIUtility.xtend | 151 -- .../organizeImports/ImportSpecifiersUtil.java | 209 ++ .../ImportSpecifiersUtil.xtend | 191 -- .../ImportStateCalculator.java | 318 +++ .../ImportStateCalculator.xtend | 243 -- .../InjectedTypesResolverUtility.java | 146 + .../InjectedTypesResolverUtility.xtend | 114 - .../organizeImports/RecordingImportState.java | 176 ++ .../RecordingImportState.xtend | 161 -- .../tooling/organizeImports/RefNameUtil.java | 76 + .../tooling/organizeImports/RefNameUtil.xtend | 68 - .../ScriptDependencyResolver.java | 423 +++ .../ScriptDependencyResolver.xtend | 339 --- .../n4js/tooling/react/ReactHelper.java | 396 +++ .../n4js/tooling/react/ReactHelper.xtend | 344 --- .../eclipse/n4js/types/utils/LambdaUtils.java | 96 + .../n4js/types/utils/LambdaUtils.xtend | 88 - .../eclipse/n4js/types/utils/TypeHelper.java | 211 ++ .../eclipse/n4js/types/utils/TypeHelper.xtend | 194 -- ...bstractFunctionDefinitionTypesBuilder.java | 140 + ...stractFunctionDefinitionTypesBuilder.xtend | 125 - .../N4JSClassDeclarationTypesBuilder.java | 135 + .../N4JSClassDeclarationTypesBuilder.xtend | 122 - ...N4JSClassifierDeclarationTypesBuilder.java | 167 ++ ...4JSClassifierDeclarationTypesBuilder.xtend | 136 - .../N4JSEnumDeclarationTypesBuilder.java | 145 + .../N4JSEnumDeclarationTypesBuilder.xtend | 126 - .../N4JSExportDefinitionTypesBuilder.java | 144 + .../N4JSExportDefinitionTypesBuilder.xtend | 125 - .../typesbuilder/N4JSFieldTypesBuilder.java | 90 + .../typesbuilder/N4JSFieldTypesBuilder.xtend | 87 - .../N4JSFormalParameterTypesBuilder.java | 97 + .../N4JSFormalParameterTypesBuilder.xtend | 88 - .../N4JSFunctionDefinitionTypesBuilder.java | 213 ++ .../N4JSFunctionDefinitionTypesBuilder.xtend | 184 -- .../typesbuilder/N4JSGetterTypesBuilder.java | 106 + .../typesbuilder/N4JSGetterTypesBuilder.xtend | 99 - .../typesbuilder/N4JSImportTypesBuilder.java | 203 ++ .../typesbuilder/N4JSImportTypesBuilder.xtend | 178 -- .../N4JSInterfaceDeclarationTypesBuilder.java | 88 + ...N4JSInterfaceDeclarationTypesBuilder.xtend | 80 - .../typesbuilder/N4JSMethodTypesBuilder.java | 173 ++ .../typesbuilder/N4JSMethodTypesBuilder.xtend | 166 -- .../N4JSNamespaceDeclarationTypesBuilder.java | 63 + ...N4JSNamespaceDeclarationTypesBuilder.xtend | 60 - .../N4JSObjectLiteralTypesBuilder.java | 206 ++ .../N4JSObjectLiteralTypesBuilder.xtend | 164 -- .../typesbuilder/N4JSSetterTypesBuilder.java | 112 + .../typesbuilder/N4JSSetterTypesBuilder.xtend | 99 - .../N4JSTypeAliasDeclarationTypesBuilder.java | 66 + ...N4JSTypeAliasDeclarationTypesBuilder.xtend | 61 - .../N4JSTypeVariableTypesBuilder.java | 84 + .../N4JSTypeVariableTypesBuilder.xtend | 74 - .../n4js/typesbuilder/N4JSTypesBuilder.java | 685 +++++ .../n4js/typesbuilder/N4JSTypesBuilder.xtend | 519 ---- .../typesbuilder/N4JSTypesBuilderHelper.java | 306 +++ .../typesbuilder/N4JSTypesBuilderHelper.xtend | 265 -- .../N4JSTypesFromTypeRefBuilder.java | 199 ++ .../N4JSTypesFromTypeRefBuilder.xtend | 162 -- .../N4JSVariableStatementTypesBuilder.java | 222 ++ .../N4JSVariableStatementTypesBuilder.xtend | 207 -- .../validators/N4JSImportValidator.xtend | 2 +- .../validators/N4JSLambdaValidator.java | 3 +- 138 files changed, 18443 insertions(+), 15564 deletions(-) create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/compileTime/CompileTimeEvaluator.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/compileTime/CompileTimeEvaluator.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatter.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatter.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatterPreferenceKeys.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatterPreferenceKeys.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSGenericFormatter.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSGenericFormatter.xtend rename plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/{TypeExpressionsFormatter.xtend => TypeExpressionFormatterNoOp.java} (61%) rename plugins/org.eclipse.n4js/src/org/eclipse/n4js/{resource/N4JSDescriptionUtils.xtend => formatting2/TypeExpressionsFormatter.java} (55%) create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/AbstractSubGenerator.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/AbstractSubGenerator.xtend rename plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/{GeneratorExceptionHandler.xtend => GeneratorExceptionHandler.java} (58%) create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonContentProvider.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonContentProvider.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ASTProcessor.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ASTProcessor.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractPolyProcessor.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractPolyProcessor.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractProcessor.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractProcessor.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/CompileTimeExpressionProcessor.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/CompileTimeExpressionProcessor.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ComputedNameProcessor.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ComputedNameProcessor.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/DestructureProcessor.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/DestructureProcessor.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ArrayLiteral.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ArrayLiteral.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_CallExpression.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_CallExpression.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_FunctionExpression.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_FunctionExpression.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ObjectLiteral.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ObjectLiteral.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/RuntimeDependencyProcessor.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/RuntimeDependencyProcessor.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeDeferredProcessor.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeDeferredProcessor.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeProcessor.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeProcessor.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeRefProcessor.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeRefProcessor.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDerivedStateComputer.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDerivedStateComputer.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDescriptionUtils.java create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSLocationInFileProvider.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSLocationInFileProvider.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSPreProcessor.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSPreProcessor.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/PackageJsonResourceDescriptionExtension.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/PackageJsonResourceDescriptionExtension.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/XpectAwareFileExtensionCalculator.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/XpectAwareFileExtensionCalculator.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/N4JSScopeProvider.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/N4JSScopeProvider.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingDiagnostician.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingDiagnostician.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/ImportedElementsScopingHelper.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/ImportedElementsScopingHelper.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/SingleImportedElementsMap.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/SingleImportedElementsMap.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/MemberScopingHelper.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/MemberScopingHelper.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ExpressionExtensions.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ExpressionExtensions.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/LocallyKnownTypesScopingHelper.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/LocallyKnownTypesScopingHelper.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ScopesHelper.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ScopesHelper.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/DIUtility.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/DIUtility.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportSpecifiersUtil.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportSpecifiersUtil.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportStateCalculator.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportStateCalculator.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/InjectedTypesResolverUtility.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/InjectedTypesResolverUtility.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RecordingImportState.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RecordingImportState.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RefNameUtil.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RefNameUtil.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ScriptDependencyResolver.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ScriptDependencyResolver.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/LambdaUtils.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/LambdaUtils.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/TypeHelper.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/TypeHelper.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/AbstractFunctionDefinitionTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/AbstractFunctionDefinitionTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassDeclarationTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassDeclarationTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassifierDeclarationTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassifierDeclarationTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSEnumDeclarationTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSEnumDeclarationTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSExportDefinitionTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSExportDefinitionTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFieldTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFieldTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFunctionDefinitionTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFunctionDefinitionTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSGetterTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSGetterTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSImportTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSImportTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSInterfaceDeclarationTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSInterfaceDeclarationTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSMethodTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSMethodTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSNamespaceDeclarationTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSNamespaceDeclarationTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSObjectLiteralTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSObjectLiteralTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSSetterTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSSetterTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeAliasDeclarationTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeAliasDeclarationTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeVariableTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeVariableTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilderHelper.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilderHelper.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesFromTypeRefBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesFromTypeRefBuilder.xtend create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSVariableStatementTypesBuilder.java delete mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSVariableStatementTypesBuilder.xtend diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/compileTime/CompileTimeEvaluator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/compileTime/CompileTimeEvaluator.java new file mode 100644 index 0000000000..bc4edaec4d --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/compileTime/CompileTimeEvaluator.java @@ -0,0 +1,521 @@ +/** + * Copyright (c) 2017 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.compileTime; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.symbolObjectType; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filterNull; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.n4js.compileTime.CompileTimeValue.ValueBoolean; +import org.eclipse.n4js.compileTime.CompileTimeValue.ValueInvalid; +import org.eclipse.n4js.compileTime.CompileTimeValue.ValueNumber; +import org.eclipse.n4js.n4JS.AdditiveExpression; +import org.eclipse.n4js.n4JS.BinaryLogicalExpression; +import org.eclipse.n4js.n4JS.BooleanLiteral; +import org.eclipse.n4js.n4JS.ConditionalExpression; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.n4JS.MultiplicativeExpression; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.NullLiteral; +import org.eclipse.n4js.n4JS.NumericLiteral; +import org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression; +import org.eclipse.n4js.n4JS.ParenExpression; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.n4JS.StringLiteral; +import org.eclipse.n4js.n4JS.TemplateLiteral; +import org.eclipse.n4js.n4JS.TemplateSegment; +import org.eclipse.n4js.n4JS.UnaryExpression; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.postprocessing.ASTMetaInfoCache; +import org.eclipse.n4js.postprocessing.ASTMetaInfoUtils; +import org.eclipse.n4js.postprocessing.ASTProcessor; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.SyntaxRelatedTElement; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TConstableElement; +import org.eclipse.n4js.ts.types.TEnum; +import org.eclipse.n4js.ts.types.TEnumLiteral; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TypesPackage; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.utils.ContainerTypesHelper; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind; +import org.eclipse.n4js.utils.RecursionGuard; +import org.eclipse.n4js.utils.Strings; +import org.eclipse.n4js.validation.N4JSElementKeywordProvider; +import org.eclipse.n4js.validation.validators.N4JSExpressionValidator; +import org.eclipse.xtext.xbase.lib.IterableExtensions; + +import com.google.inject.Inject; + +/** + * Helper class to evaluate compile-time expressions. + *

+ * IMPORTANT IMPLEMENTATION NOTES: + *

    + *
  • It is a design decision1 to handle compile-time evaluation and computed property names as a separate, + * up-front phase during post-processing before the main AST traversal begins (for details about the phases of + * post-processing, see method {@link ASTProcessor#processAST(RuleEnvironment, Script, ASTMetaInfoCache)}). + *
  • To achieve this, we must avoid using type information during compile-time evaluation, because typing is + * part of main AST traversal, so typing an AST node would inevitably start the main AST traversal. + *
  • the only place where this limitation becomes tricky is the evaluation of property access expressions, see + * {@link #eval(RuleEnvironment, ParameterizedPropertyAccessExpression, RecursionGuard)}. + *
+ * + * 1 main rationale for this decision was to keep the handling of computed property names from complicating + * the scoping and main AST traversal. Without resolving computed property names beforehand, all the code in scoping, + * AST traversal, type system, and helper classes such as {@link ContainerTypesHelper} would have to cope with + * unresolved property names, i.e. {@code #getName()} on a property or member would return null or trigger + * some potentially complex computation in the background that might confuse AST traversal. + */ +public class CompileTimeEvaluator { + + @Inject + private N4JSElementKeywordProvider keywordProvider; + + /** + * IMPORTANT: CLIENT CODE SHOULD NOT CALL THIS METHOD!
+ * Instead, read compile-time values from the cache using method + * {@link ASTMetaInfoUtils#getCompileTimeValue(Expression)}.
+ * If the evaluation result of the expression you are interested in is not being cached, add your use case to method + * {@link N4JSLanguageUtils#isProcessedAsCompileTimeExpression(Expression)}. Only expressions for which this method + * returns true will be evaluated and cached during post-processing.
+ *

+ * Computes and returns the value of the given expression as a {@link CompileTimeValue}. If the given expression is + * not a valid compile-time expression, the returned value will be {@link CompileTimeValue#isValid() invalid}. Never + * returns null. + */ + public CompileTimeValue evaluateCompileTimeExpression(RuleEnvironment G, Expression expr) { + return eval(G, expr, new RecursionGuard<>()); + } + + // --------------------------------------------------------------------------------------------------------------- + + // catch-all case for expression not handled by any of the more specific dispatch methods + private CompileTimeValue eval(RuleEnvironment G, Expression expr, RecursionGuard guard) { + if (expr instanceof ParenExpression) { + Expression expression = ((ParenExpression) expr).getExpression(); + if (expression == null) { + return CompileTimeValue.error(); + } + return eval(G, expression, guard); + } + if (expr instanceof NullLiteral) { + return CompileTimeValue.NULL; + } + if (expr instanceof BooleanLiteral) { + return CompileTimeValue.of(((BooleanLiteral) expr).isTrue()); + } + if (expr instanceof NumericLiteral) { + return CompileTimeValue.of(((NumericLiteral) expr).getValue()); + } + if (expr instanceof StringLiteral) { + return CompileTimeValue.of(((StringLiteral) expr).getValue()); + } + if (expr instanceof TemplateSegment) { + return CompileTimeValue.of(((TemplateSegment) expr).getValue()); + } + if (expr instanceof TemplateLiteral) { + return eval(G, (TemplateLiteral) expr, guard); + } + if (expr instanceof UnaryExpression) { + return eval(G, (UnaryExpression) expr, guard); + } + if (expr instanceof AdditiveExpression) { + return eval(G, (AdditiveExpression) expr, guard); + } + if (expr instanceof MultiplicativeExpression) { + return eval(G, (MultiplicativeExpression) expr, guard); + } + if (expr instanceof BinaryLogicalExpression) { + return eval(G, (BinaryLogicalExpression) expr, guard); + } + if (expr instanceof ConditionalExpression) { + return eval(G, (ConditionalExpression) expr, guard); + } + if (expr instanceof IdentifierRef) { + return eval(G, (IdentifierRef) expr, guard); + } + if (expr instanceof ParameterizedPropertyAccessExpression) { + return eval(G, (ParameterizedPropertyAccessExpression) expr, guard); + } + + return CompileTimeValue.error(keywordProvider.keywordWithIndefiniteArticle(expr) + + " is never a compile-time expression", expr); + } + + private CompileTimeValue eval(RuleEnvironment G, TemplateLiteral expr, RecursionGuard guard) { + StringBuilder buff = new StringBuilder(); + List invalidValues = new ArrayList<>(); + for (Expression seg : expr.getSegments()) { + CompileTimeValue segValue = eval(G, seg, guard); + if (segValue.isValid()) { + buff.append(segValue.toString()); + } else { + invalidValues.add(segValue); + } + } + if (!invalidValues.isEmpty()) { + return CompileTimeValue.combineErrors(invalidValues.toArray(new CompileTimeValue[0])); + } + return CompileTimeValue.of(buff.toString()); + } + + private CompileTimeValue eval(RuleEnvironment G, UnaryExpression expr, RecursionGuard guard) { + CompileTimeValue value = (expr.getExpression() != null) ? eval(G, expr.getExpression(), guard) : null; + switch (expr.getOp()) { + case NOT: + return CompileTimeValue.invert(value, expr.getExpression()); + case POS: { + ValueInvalid tmpV = CompileTimeValue.requireValueType(value, ValueNumber.class, "operand must be a number", + expr.getExpression()); + return tmpV != null ? tmpV : value; + } + case NEG: + return CompileTimeValue.negate(value, expr.getExpression()); + case VOID: + return CompileTimeValue.UNDEFINED; + default: + return CompileTimeValue.error("invalid operator: " + expr.getOp(), expr); + } + } + + private CompileTimeValue eval(RuleEnvironment G, AdditiveExpression expr, RecursionGuard guard) { + Expression lhs = expr.getLhs(); + Expression rhs = expr.getRhs(); + CompileTimeValue leftValue = (lhs != null) ? eval(G, lhs, guard) : null; + CompileTimeValue rightValue = (rhs != null) ? eval(G, rhs, guard) : null; + switch (expr.getOp()) { + case ADD: + return CompileTimeValue.add(leftValue, rightValue, expr); + case SUB: + return CompileTimeValue.subtract(leftValue, rightValue, lhs, rhs); + default: + return CompileTimeValue.error("invalid operator: " + expr.getOp(), expr); + } + } + + private CompileTimeValue eval(RuleEnvironment G, MultiplicativeExpression expr, RecursionGuard guard) { + Expression lhs = expr.getLhs(); + Expression rhs = expr.getRhs(); + CompileTimeValue leftValue = (lhs != null) ? eval(G, lhs, guard) : null; + CompileTimeValue rightValue = (rhs != null) ? eval(G, rhs, guard) : null; + switch (expr.getOp()) { + case TIMES: + return CompileTimeValue.multiply(leftValue, rightValue, lhs, rhs); + case DIV: + return CompileTimeValue.divide(leftValue, rightValue, lhs, rhs); + case MOD: + return CompileTimeValue.remainder(leftValue, rightValue, lhs, rhs); + default: + return CompileTimeValue.error("invalid operator: " + expr.getOp(), expr); + } + } + + private CompileTimeValue eval(RuleEnvironment G, BinaryLogicalExpression expr, RecursionGuard guard) { + Expression lhs = expr.getLhs(); + Expression rhs = expr.getRhs(); + CompileTimeValue leftValue = (lhs != null) ? eval(G, lhs, guard) : null; + CompileTimeValue rightValue = (rhs != null) ? eval(G, rhs, guard) : null; + switch (expr.getOp()) { + case AND: + return CompileTimeValue.and(leftValue, rightValue, lhs, rhs); + case OR: + return CompileTimeValue.or(leftValue, rightValue, lhs, rhs); + default: + return CompileTimeValue.error("invalid operator: " + expr.getOp(), expr); + } + } + + private CompileTimeValue eval(RuleEnvironment G, ConditionalExpression expr, RecursionGuard guard) { + Expression condition = expr.getExpression(); + Expression trueExpr = expr.getTrueExpression(); + Expression falseExpr = expr.getFalseExpression(); + CompileTimeValue conditionValue = (condition != null) ? eval(G, condition, guard) : null; + CompileTimeValue trueValue = (trueExpr != null) ? eval(G, trueExpr, guard) : null; + CompileTimeValue falseValue = (falseExpr != null) ? eval(G, falseExpr, guard) : null; + ValueInvalid requireValueType = CompileTimeValue.requireValueType(conditionValue, ValueBoolean.class, + "condition must be a boolean", + expr.getExpression()); + ValueInvalid error = CompileTimeValue.combineErrors(requireValueType, trueValue, falseValue); + if (error != null) { + return error; + } + return (conditionValue != null && ((ValueBoolean) conditionValue).getValue()) ? trueValue : falseValue; + } + + private CompileTimeValue eval(RuleEnvironment G, IdentifierRef expr, RecursionGuard guard) { + if (N4JSLanguageUtils.isUndefinedLiteral(G, expr)) { + return CompileTimeValue.UNDEFINED; + } + IdentifiableElement id = expr.getId(); + // ^^ triggers scoping; this is unproblematic, because the scoping of IdentifierRefs does not + // require type information and will thus not interfere with our goal of handling compile-time expressions and + // computed property names as an up-front preparatory step before main AST traversal. + if (id != null && !id.eIsProxy()) { + return obtainValueIfConstFieldOrVariable(G, id, expr, guard); + } + return CompileTimeValue.error(); + } + + /** + * Handles compile-time evaluation of property access expressions. + *

+ * IMPORTANT IMPLEMENTATION NOTES: + *

    + *
  • We must not make use of type information during compile-time evaluation (see {@link CompileTimeEvaluator} for + * details why this rule exists). + *
  • Since scoping of property access requires type information, we cannot use this form of scoping. + *
  • Since this scoping would be triggered when invoking {@code #getProperty()} on the given property access + * expression, we cannot make use of that property in this method. + *
  • APPROACH: avoid using (ordinary) scoping but instead implement custom member lookup for the very limited + * cases supported by compile-time expressions. + *
+ * YES, this approach introduces an unfortunate duplication of logic, but greatly simplifies other parts of the + * system, i.e. (ordinary) scoping, AST traversal, type system. + */ + private CompileTimeValue eval(RuleEnvironment G, ParameterizedPropertyAccessExpression expr, + RecursionGuard guard) { + Expression targetExpr = expr.getTarget(); + String propName = expr.getPropertyAsText(); // IMPORTANT: don't invoke expr.getProperty()!! + EObject targetElem = null; + if (targetExpr instanceof IdentifierRef) { + if (targetExpr.eIsProxy()) { + return CompileTimeValue.error("Expression is a proxy '" + propName + "'", expr); + } + targetElem = ((IdentifierRef) targetExpr).getId(); + } + EObject sym = symbolObjectType(G); + if (targetElem == sym) { + // A) Is 'expr' an access to a built-in symbol, e.g. Symbol.iterator? + // IMPORTANT: pass in 'false', to disallow proxy resolution (which would trigger scoping, type inference, + // etc.) + TMember memberInSym = N4JSLanguageUtils.getAccessedBuiltInSymbol(G, expr, false); + if (memberInSym != null) { + // yes, it is! + return CompileTimeValue.of(memberInSym); + } else { + return CompileTimeValue.error("Unknown Symbol property '" + propName + "'", expr); + } + } else if (targetElem instanceof TEnum) { + // B) Is 'expr' an access to the literal of a @NumberBased or @StringBased enum? + EnumKind enumKind = N4JSLanguageUtils.getEnumKind((TEnum) targetElem); + if (enumKind != EnumKind.Normal) { + // custom scoping logic! + TEnumLiteral litInEnum = IterableExtensions.findFirst(((TEnum) targetElem).getLiterals(), + l -> Objects.equals(l.getName(), propName)); + if (litInEnum != null) { + // yes, it is! + switch (enumKind) { + case Normal: + throw new IllegalStateException("cannot happen"); + case NumberBased: + return CompileTimeValue.of(litInEnum.getValueNumber()); + case StringBased: + return CompileTimeValue.of(litInEnum.getValueString()); + } + } + } + } else if (targetElem instanceof TClassifier) { + // C) Is 'expr' an access to a const field initialized by a compile-time expression? + // custom scoping logic! + TMember member = findFirst(filterNull(((TClassifier) targetElem).getOwnedMembers()), + m -> Objects.equals(m.getName(), propName) && m.isReadable() && m.isStatic()); + // IMPORTANT: don't use "targetElem.findOwnedMember(memberName, false, true)" in previous line, because + // #findOwnedMember() will create and cache a MemberByNameAndAccessMap, which will be incomplete if the + // TClassifier contains members with unresolved computed property names! + if (member instanceof TField && !((TField) member).isHasComputedName()) { + // yes, it is! + return obtainValueIfConstFieldOrVariable(G, member, expr, guard); + } else { + // we get here in two cases: + // + // 1) member not found + // -> there are a number of possible reasons: + // 1.a) member has a computed property name which was not yet evaluated, + // 1.b) member is inherited, consumed, polyfilled, etc., + // 1.c) member does not exist at all. + // At this point, i.e. before computed names are processed, we cannot distinguish between these + // cases. So we create a dummy error here that will be improved later. + // + // 2) member was found but it has a (resolved) computed property name (since processing of computed + // property names for the current resource has not started yet, this happens only if the member is + // located in another file an its full type information, including its name, was found in the index) + // -> for consistency with 1.a above, we have to raise an error also in this case + return CompileTimeValue.error(new UnresolvedPropertyAccessError(expr)); + } + } + // D) all other cases: + if (targetElem != sym && !(targetElem instanceof TClassifier || targetElem instanceof TEnum)) { + return CompileTimeValue.error( + "target of a property access must be a direct reference to a class, interface, or enum", expr, + N4JSPackage.Literals.EXPRESSION_WITH_TARGET__TARGET); + } + return CompileTimeValue.error( + "property access must point to const fields, literals of @NumberBased/@StringBased enums, or built-in symbols", + expr); + } + + // --------------------------------------------------------------------------------------------------------------- + + /** + * Iff the given element is a const field or variable with a valid compile-time expression as initializer, then this + * method returns its compile-time value; otherwise, an invalid compile-time value with an appropriate error message + * is returned. Never returns null. + *

+ * This method only handles infinite recursion; main logic in + * {@link #obtainValueIfConstFieldOrVariableUnguarded(RuleEnvironment, IdentifiableElement, EObject, RecursionGuard)}. + */ + private CompileTimeValue obtainValueIfConstFieldOrVariable(RuleEnvironment G, IdentifiableElement targetElem, + EObject astNodeForErrorMessage, RecursionGuard guard) { + + if (guard.tryNext(targetElem)) { + try { + return obtainValueIfConstFieldOrVariableUnguarded(G, targetElem, astNodeForErrorMessage, guard); + } finally { + guard.done(targetElem); + } + } else { + return CompileTimeValue.error("cyclic definition of compile-time expression", astNodeForErrorMessage); + } + } + + private CompileTimeValue obtainValueIfConstFieldOrVariableUnguarded(RuleEnvironment G, + IdentifiableElement targetElem, EObject astNodeForErrorMessage, RecursionGuard guard) { + + boolean targetElemIsConst = false; + if (targetElem instanceof TConstableElement) { + targetElemIsConst = ((TConstableElement) targetElem).isConst(); + } + if (targetElem instanceof N4FieldDeclaration) { + targetElemIsConst = ((N4FieldDeclaration) targetElem).isConst(); + } + if (targetElem instanceof VariableDeclaration) { + targetElemIsConst = ((VariableDeclaration) targetElem).isConst(); + } + if (!targetElemIsConst) { + return CompileTimeValue.error( + keywordProvider.keyword(targetElem) + " " + targetElem.getName() + " is not const", + astNodeForErrorMessage); + } + + CompileTimeValue valueOfTargetElem = obtainCompileTimeValueOfTargetElement(G, + astNodeForErrorMessage.eResource(), targetElem, guard); + if (valueOfTargetElem != null) { + if (valueOfTargetElem instanceof ValueInvalid) { + String baseMsg = keywordProvider.keyword(targetElem) + " " + targetElem.getName() + + " is const but does not have a compile-time expression as initializer"; + String msg = combineErrorMessageWithNestedErrors(baseMsg, + ((ValueInvalid) valueOfTargetElem).getErrors().toArray(new CompileTimeEvaluationError[0])); + EReference feature = null; + if (astNodeForErrorMessage instanceof ParameterizedPropertyAccessExpression) { + feature = N4JSPackage.eINSTANCE.getParameterizedPropertyAccessExpression_Property(); + } + return CompileTimeValue.error(msg, astNodeForErrorMessage, feature); + } + return valueOfTargetElem; + } + return CompileTimeValue.error( + "only references to const variables with a compile-time expression as initializer are allowed", + astNodeForErrorMessage); + } + + private CompileTimeValue obtainCompileTimeValueOfTargetElement(RuleEnvironment G, Resource currentResource, + IdentifiableElement targetElem, RecursionGuard guard) { + + if (targetElem.eResource() == currentResource || hasLoadedASTElement(targetElem)) { + // 'targetElem' is in same resource OR is in a different resource that already has a fully-loaded AST + // -> compute value from the initializer expression of 'targetElem' + EObject astNodeOfTargetElem = (targetElem instanceof SyntaxRelatedTElement) + ? ((SyntaxRelatedTElement) targetElem).getAstElement() + // NOTE: this will never trigger demand-loading of an AST, because above we + // ensured that we are still in 'currentResource' OR method #hasLoadedASTElement() has returned true + : targetElem // here we simply assume that elem is already an AST node + ; + Expression expressionOfTargetElem = null; + if (astNodeOfTargetElem instanceof N4FieldDeclaration) { + expressionOfTargetElem = ((N4FieldDeclaration) astNodeOfTargetElem).getExpression(); + } + if (astNodeOfTargetElem instanceof VariableDeclaration) { + expressionOfTargetElem = ((VariableDeclaration) astNodeOfTargetElem).getExpression(); + } + if (expressionOfTargetElem != null) { + return eval(G, expressionOfTargetElem, guard); + } + } else { + // 'targetElem' is in another resource with an AST proxy + // -> read value from TModule to avoid demand-loading of AST + if (targetElem instanceof TConstableElement) { + return CompileTimeValue.deserialize(((TConstableElement) targetElem).getCompileTimeValue()); + } + } + return null; // no value found + } + + /** + * Tells if given element has an AST element in an already loaded AST (i.e. it is safe to invoke method + * {@code #getASTElement()} without triggering a demand-load of the AST). + */ + private static boolean hasLoadedASTElement(IdentifiableElement elem) { + EObject astElemNonResolved = null; + if (elem instanceof SyntaxRelatedTElement) { + astElemNonResolved = (EObject) elem.eGet(TypesPackage.eINSTANCE.getSyntaxRelatedTElement_AstElement(), + false); + } + return astElemNonResolved != null && !astElemNonResolved.eIsProxy(); + } + + private static String combineErrorMessageWithNestedErrors(String mainMessage, + CompileTimeEvaluationError... nestedErrors) { + + if (nestedErrors.length == 0) { + return mainMessage; + } else if (nestedErrors.length == 1) { + return mainMessage + ": " + nestedErrors[0].getMessageWithLocation(); + } else { + return mainMessage + ":\n- " + + Strings.join("\n- ", map(List.of(nestedErrors), e -> e.getMessageWithLocation())); + } + } + + // --------------------------------------------------------------------------------------------------------------- + + /** + * Special kind of {@link CompileTimeEvaluationError} used to denote a particular case in which the + * {@link CompileTimeEvaluator} cannot come up with the correct error message and thus delegates finding a proper + * message to the validation, i.e. to class {@link N4JSExpressionValidator}. + */ + public static final class UnresolvedPropertyAccessError extends CompileTimeEvaluationError { + + /***/ + public UnresolvedPropertyAccessError(ParameterizedPropertyAccessExpression astNode) { + super("*** UnresolvedPropertyAccessError ***", astNode, + N4JSPackage.eINSTANCE.getParameterizedPropertyAccessExpression_Property()); + } + + /***/ + public ParameterizedPropertyAccessExpression getAstNodeCasted() { + return (ParameterizedPropertyAccessExpression) astNode; + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/compileTime/CompileTimeEvaluator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/compileTime/CompileTimeEvaluator.xtend deleted file mode 100644 index 0f4ebefe9d..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/compileTime/CompileTimeEvaluator.xtend +++ /dev/null @@ -1,447 +0,0 @@ -/** - * Copyright (c) 2017 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.compileTime - -import com.google.inject.Inject -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.resource.Resource -import org.eclipse.n4js.compileTime.CompileTimeValue.ValueBoolean -import org.eclipse.n4js.compileTime.CompileTimeValue.ValueInvalid -import org.eclipse.n4js.compileTime.CompileTimeValue.ValueNumber -import org.eclipse.n4js.n4JS.AdditiveExpression -import org.eclipse.n4js.n4JS.BinaryLogicalExpression -import org.eclipse.n4js.n4JS.BooleanLiteral -import org.eclipse.n4js.n4JS.ConditionalExpression -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.IdentifierRef -import org.eclipse.n4js.n4JS.MultiplicativeExpression -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.N4JSPackage -import org.eclipse.n4js.n4JS.NullLiteral -import org.eclipse.n4js.n4JS.NumericLiteral -import org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression -import org.eclipse.n4js.n4JS.ParenExpression -import org.eclipse.n4js.n4JS.StringLiteral -import org.eclipse.n4js.n4JS.TemplateLiteral -import org.eclipse.n4js.n4JS.TemplateSegment -import org.eclipse.n4js.n4JS.UnaryExpression -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.postprocessing.ASTMetaInfoUtils -import org.eclipse.n4js.postprocessing.ASTProcessor -import org.eclipse.n4js.ts.types.IdentifiableElement -import org.eclipse.n4js.ts.types.SyntaxRelatedTElement -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TConstableElement -import org.eclipse.n4js.ts.types.TEnum -import org.eclipse.n4js.ts.types.TField -import org.eclipse.n4js.ts.types.TypesPackage -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.utils.ContainerTypesHelper -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind -import org.eclipse.n4js.utils.RecursionGuard -import org.eclipse.n4js.validation.N4JSElementKeywordProvider -import org.eclipse.n4js.validation.validators.N4JSExpressionValidator - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * Helper class to evaluate compile-time expressions. - *

- * IMPORTANT IMPLEMENTATION NOTES: - *

    - *
  • It is a design decision1 to handle compile-time evaluation and computed property names as a separate, - * up-front phase during post-processing before the main AST traversal begins (for details about the phases of - * post-processing, see method {@link ASTProcessor#processAST(RuleEnvironment, Script, ASTMetaInfoCache)}). - *
  • To achieve this, we must avoid using type information during compile-time evaluation, because typing - * is part of main AST traversal, so typing an AST node would inevitably start the main AST traversal. - *
  • the only place where this limitation becomes tricky is the evaluation of property access expressions, see - * {@link #eval(RuleEnvironment, ParameterizedPropertyAccessExpression, RecursionGuard)}. - *
- * - * 1 main rationale for this decision was to keep the handling of computed property names from complicating - * the scoping and main AST traversal. Without resolving computed property names beforehand, all the code in scoping, - * AST traversal, type system, and helper classes such as {@link ContainerTypesHelper} would have to cope with - * unresolved property names, i.e. {@code #getName()} on a property or member would return null or trigger - * some potentially complex computation in the background that might confuse AST traversal. - */ -class CompileTimeEvaluator { - - @Inject - private N4JSElementKeywordProvider keywordProvider; - - - /** - * - * IMPORTANT: CLIENT CODE SHOULD NOT CALL THIS METHOD!
- * Instead, read compile-time values from the cache using method {@link ASTMetaInfoUtils#getCompileTimeValue(Expression)}.
- * If the evaluation result of the expression you are interested in is not being cached, add your use case to method - * {@link N4JSLanguageUtils#isProcessedAsCompileTimeExpression(Expression)}. Only expressions for which this method - * returns true will be evaluated and cached during post-processing. - *
- *

- * Computes and returns the value of the given expression as a {@link CompileTimeValue}. If the given expression is - * not a valid compile-time expression, the returned value will be {@link CompileTimeValue#isValid() invalid}. Never - * returns null. - */ - def public CompileTimeValue evaluateCompileTimeExpression(RuleEnvironment G, Expression expr) { - return eval(G, expr, new RecursionGuard()); - } - - - // --------------------------------------------------------------------------------------------------------------- - - - // catch-all case for expression not handled by any of the more specific dispatch methods - def private dispatch CompileTimeValue eval(RuleEnvironment G, Expression expr, RecursionGuard guard) { - return CompileTimeValue.error(keywordProvider.keywordWithIndefiniteArticle(expr) - + " is never a compile-time expression", expr); - } - - def private dispatch CompileTimeValue eval(RuleEnvironment G, ParenExpression expr, RecursionGuard guard) { - if (expr.expression === null) - return CompileTimeValue.error(); - return eval(G, expr.expression, guard); - } - - def private dispatch CompileTimeValue eval(RuleEnvironment G, NullLiteral expr, RecursionGuard guard) { - return CompileTimeValue.NULL; - } - - def private dispatch CompileTimeValue eval(RuleEnvironment G, BooleanLiteral expr, RecursionGuard guard) { - return CompileTimeValue.of(expr.isTrue); - } - - def private dispatch CompileTimeValue eval(RuleEnvironment G, NumericLiteral expr, RecursionGuard guard) { - return CompileTimeValue.of(expr.value); - } - - def private dispatch CompileTimeValue eval(RuleEnvironment G, StringLiteral expr, RecursionGuard guard) { - return CompileTimeValue.of(expr.value); - } - - def private dispatch CompileTimeValue eval(RuleEnvironment G, TemplateSegment expr, RecursionGuard guard) { - return CompileTimeValue.of(expr.value); - } - - def private dispatch CompileTimeValue eval(RuleEnvironment G, TemplateLiteral expr, RecursionGuard guard) { - val buff = new StringBuilder; - val invalidValues = newArrayList; - for (seg : expr.segments) { - val segValue = eval(G, seg, guard); - if (segValue.valid) { - buff.append(segValue.toString); - } else { - invalidValues += segValue; - } - } - if (!invalidValues.empty) { - return CompileTimeValue.combineErrors(invalidValues); - } - return CompileTimeValue.of(buff.toString); - } - - def private dispatch CompileTimeValue eval(RuleEnvironment G, UnaryExpression expr, RecursionGuard guard) { - val value = if (expr.expression !== null) eval(G, expr.expression, guard); - return switch (expr.op) { - case NOT: CompileTimeValue.invert(value, expr.expression) - case POS: CompileTimeValue.requireValueType(value, ValueNumber, "operand must be a number", expr.expression) ?: value - case NEG: CompileTimeValue.negate(value, expr.expression) - case VOID: CompileTimeValue.UNDEFINED - default: CompileTimeValue.error("invalid operator: " + expr.op, expr) - }; - } - - def private dispatch CompileTimeValue eval(RuleEnvironment G, AdditiveExpression expr, RecursionGuard guard) { - val lhs = expr.lhs; - val rhs = expr.rhs; - val leftValue = if (lhs !== null) eval(G, lhs, guard); - val rightValue = if (rhs !== null) eval(G, rhs, guard); - return switch (expr.op) { - case ADD: CompileTimeValue.add(leftValue, rightValue, expr) - case SUB: CompileTimeValue.subtract(leftValue, rightValue, lhs, rhs) - default: CompileTimeValue.error("invalid operator: " + expr.op, expr) - }; - } - - def private dispatch CompileTimeValue eval(RuleEnvironment G, MultiplicativeExpression expr, RecursionGuard guard) { - val lhs = expr.lhs; - val rhs = expr.rhs; - val leftValue = if (lhs !== null) eval(G, lhs, guard); - val rightValue = if (rhs !== null) eval(G, rhs, guard); - return switch (expr.op) { - case TIMES: CompileTimeValue.multiply(leftValue, rightValue, lhs, rhs) - case DIV: CompileTimeValue.divide(leftValue, rightValue, lhs, rhs) - case MOD: CompileTimeValue.remainder(leftValue, rightValue, lhs, rhs) - default: CompileTimeValue.error("invalid operator: " + expr.op, expr) - }; - } - - def private dispatch CompileTimeValue eval(RuleEnvironment G, BinaryLogicalExpression expr, RecursionGuard guard) { - val lhs = expr.lhs; - val rhs = expr.rhs; - val leftValue = if (lhs !== null) eval(G, lhs, guard); - val rightValue = if (rhs !== null) eval(G, rhs, guard); - return switch (expr.op) { - case AND: CompileTimeValue.and(leftValue, rightValue, lhs, rhs) - case OR: CompileTimeValue.or(leftValue, rightValue, lhs, rhs) - default: CompileTimeValue.error("invalid operator: " + expr.op, expr) - }; - } - - def private dispatch CompileTimeValue eval(RuleEnvironment G, ConditionalExpression expr, RecursionGuard guard) { - val condition = expr.expression; - val trueExpr = expr.trueExpression; - val falseExpr = expr.falseExpression; - val conditionValue = if (condition !== null) eval(G, condition, guard); - val trueValue = if (trueExpr !== null) eval(G, trueExpr, guard); - val falseValue = if (falseExpr !== null) eval(G, falseExpr, guard); - val error = CompileTimeValue.combineErrors( - CompileTimeValue.requireValueType(conditionValue, ValueBoolean, "condition must be a boolean", - expr.expression), trueValue, falseValue); - if (error !== null) { - return error; - } - return if ((conditionValue as ValueBoolean).getValue()) trueValue else falseValue; - } - - def private dispatch CompileTimeValue eval(RuleEnvironment G, IdentifierRef expr, RecursionGuard guard) { - if (N4JSLanguageUtils.isUndefinedLiteral(G, expr)) { - return CompileTimeValue.UNDEFINED; - } - val id = expr.id; // <-- triggers scoping; this is unproblematic, because the scoping of IdentifierRefs does not - // require type information and will thus not interfere with our goal of handling compile-time expressions and - // computed property names as an up-front preparatory step before main AST traversal. - if (id !== null && !id.eIsProxy) { - return obtainValueIfConstFieldOrVariable(G, id, expr, guard); - } - return CompileTimeValue.error(); - } - - /** - * Handles compile-time evaluation of property access expressions. - *

- * IMPORTANT IMPLEMENTATION NOTES: - *

    - *
  • We must not make use of type information during compile-time evaluation (see {@link CompileTimeEvaluator} - * for details why this rule exists). - *
  • Since scoping of property access requires type information, we cannot use this form of scoping. - *
  • Since this scoping would be triggered when invoking {@code #getProperty()} on the given property access - * expression, we cannot make use of that property in this method. - *
  • APPROACH: avoid using (ordinary) scoping but instead implement custom member lookup for the very limited cases - * supported by compile-time expressions. - *
- * YES, this approach introduces an unfortunate duplication of logic, but greatly simplifies other parts of the - * system, i.e. (ordinary) scoping, AST traversal, type system. - */ - def private dispatch CompileTimeValue eval(RuleEnvironment G, ParameterizedPropertyAccessExpression expr, RecursionGuard guard) { - val targetExpr = expr.target; - val propName = expr.propertyAsText; // IMPORTANT: don't invoke expr.getProperty()!! - val targetElem = if (targetExpr instanceof IdentifierRef) { - if (targetExpr.eIsProxy) { - return CompileTimeValue.error("Expression is a proxy '"+ propName +"'", expr); - } - targetExpr.id; - } - val sym = G.symbolObjectType; - if (targetElem === sym) { - // A) Is 'expr' an access to a built-in symbol, e.g. Symbol.iterator? - val memberInSym = N4JSLanguageUtils.getAccessedBuiltInSymbol(G, expr, false); // IMPORTANT: pass in 'false', to disallow proxy resolution (which would trigger scoping, type inference, etc.) - if (memberInSym !== null) { - // yes, it is! - return CompileTimeValue.of(memberInSym); - } else { - return CompileTimeValue.error("Unknown Symbol property '"+ propName +"'", expr); - } - } else if (targetElem instanceof TEnum) { - // B) Is 'expr' an access to the literal of a @NumberBased or @StringBased enum? - val enumKind = N4JSLanguageUtils.getEnumKind(targetElem); - if (enumKind !== EnumKind.Normal) { - val litInEnum = targetElem.literals.findFirst[name == propName]; // custom scoping logic! - if (litInEnum !== null) { - // yes, it is! - return switch (enumKind) { - case Normal: - throw new IllegalStateException("cannot happen") - case NumberBased: - CompileTimeValue.of(litInEnum.valueNumber) - case StringBased: - CompileTimeValue.of(litInEnum.valueString) - }; - } - } - } else if (targetElem instanceof TClassifier) { - // C) Is 'expr' an access to a const field initialized by a compile-time expression? - val member = targetElem.ownedMembers.filterNull.findFirst[name == propName && readable && static]; // custom scoping logic! - // IMPORTANT: don't use "targetElem.findOwnedMember(memberName, false, true)" in previous line, because - // #findOwnedMember() will create and cache a MemberByNameAndAccessMap, which will be incomplete if the - // TClassifier contains members with unresolved computed property names! - if (member instanceof TField && !(member as TField).hasComputedName) { - // yes, it is! - return obtainValueIfConstFieldOrVariable(G, member, expr, guard); - } else { - // we get here in two cases: - // - // 1) member not found - // -> there are a number of possible reasons: - // 1.a) member has a computed property name which was not yet evaluated, - // 1.b) member is inherited, consumed, polyfilled, etc., - // 1.c) member does not exist at all. - // At this point, i.e. before computed names are processed, we cannot distinguish between these - // cases. So we create a dummy error here that will be improved later. - // - // 2) member was found but it has a (resolved) computed property name (since processing of computed - // property names for the current resource has not started yet, this happens only if the member is - // located in another file an its full type information, including its name, was found in the index) - // -> for consistency with 1.a above, we have to raise an error also in this case - return CompileTimeValue.error(new UnresolvedPropertyAccessError(expr)); - } - } - // D) all other cases: - if (targetElem !== sym && !(targetElem instanceof TClassifier || targetElem instanceof TEnum)) { - return CompileTimeValue.error( - "target of a property access must be a direct reference to a class, interface, or enum", expr, - N4JSPackage.Literals.EXPRESSION_WITH_TARGET__TARGET); - } - return CompileTimeValue.error("property access must point to const fields, literals of @NumberBased/@StringBased enums, or built-in symbols", expr); - } - - - // --------------------------------------------------------------------------------------------------------------- - - - /** - * Iff the given element is a const field or variable with a valid compile-time expression as initializer, then this - * method returns its compile-time value; otherwise, an invalid compile-time value with an appropriate error message - * is returned. Never returns null. - *

- * This method only handles infinite recursion; main logic in - * {@link #obtainValueIfConstFieldOrVariableUnguarded(RuleEnvironment, IdentifiableElement, EObject, RecursionGuard)}. - */ - def private CompileTimeValue obtainValueIfConstFieldOrVariable(RuleEnvironment G, IdentifiableElement targetElem, - EObject astNodeForErrorMessage, RecursionGuard guard) { - - if (guard.tryNext(targetElem)) { - try { - return obtainValueIfConstFieldOrVariableUnguarded(G, targetElem, astNodeForErrorMessage, guard); - } finally { - guard.done(targetElem); - } - } else { - return CompileTimeValue.error("cyclic definition of compile-time expression", astNodeForErrorMessage); - } - } - - def private CompileTimeValue obtainValueIfConstFieldOrVariableUnguarded(RuleEnvironment G, - IdentifiableElement targetElem, EObject astNodeForErrorMessage, RecursionGuard guard) { - - val targetElemIsConst = switch (targetElem) { - TConstableElement: targetElem.const - N4FieldDeclaration: targetElem.const - VariableDeclaration: targetElem.const - }; - if (!targetElemIsConst) { - return CompileTimeValue.error( - keywordProvider.keyword(targetElem) + " " + targetElem.name + " is not const", - astNodeForErrorMessage); - } - - val valueOfTargetElem = obtainCompileTimeValueOfTargetElement(G, astNodeForErrorMessage.eResource, targetElem, guard); - if (valueOfTargetElem !== null) { - if (valueOfTargetElem instanceof ValueInvalid) { - val baseMsg = keywordProvider.keyword(targetElem) + " " + targetElem.name + - " is const but does not have a compile-time expression as initializer"; - val msg = combineErrorMessageWithNestedErrors(baseMsg, valueOfTargetElem.errors); - val feature = if (astNodeForErrorMessage instanceof ParameterizedPropertyAccessExpression) { - N4JSPackage.eINSTANCE.parameterizedPropertyAccessExpression_Property - }; - return CompileTimeValue.error(msg, astNodeForErrorMessage, feature); - } - return valueOfTargetElem; - } - return CompileTimeValue.error( - "only references to const variables with a compile-time expression as initializer are allowed", - astNodeForErrorMessage); - } - - def private CompileTimeValue obtainCompileTimeValueOfTargetElement(RuleEnvironment G, Resource currentResource, - IdentifiableElement targetElem, RecursionGuard guard) { - - if (targetElem.eResource === currentResource || hasLoadedASTElement(targetElem)) { - // 'targetElem' is in same resource OR is in a different resource that already has a fully-loaded AST - // -> compute value from the initializer expression of 'targetElem' - val astNodeOfTargetElem = if (targetElem instanceof SyntaxRelatedTElement) { - targetElem.astElement // NOTE: this will never trigger demand-loading of an AST, because above we - // ensured that we are still in 'currentResource' OR method #hasLoadedASTElement() has returned true - } else { - targetElem // here we simply assume that elem is already an AST node - }; - val expressionOfTargetElem = switch (astNodeOfTargetElem) { - N4FieldDeclaration: astNodeOfTargetElem.expression - VariableDeclaration: astNodeOfTargetElem.expression - }; - if (expressionOfTargetElem !== null) { - return eval(G, expressionOfTargetElem, guard); - } - } else { - // 'targetElem' is in another resource with an AST proxy - // -> read value from TModule to avoid demand-loading of AST - if (targetElem instanceof TConstableElement) { - return CompileTimeValue.deserialize(targetElem.compileTimeValue); - } - } - return null; // no value found - } - - /** - * Tells if given element has an AST element in an already loaded AST (i.e. it is safe to invoke method - * {@code #getASTElement()} without triggering a demand-load of the AST). - */ - def private static boolean hasLoadedASTElement(IdentifiableElement elem) { - val astElemNonResolved = if (elem instanceof SyntaxRelatedTElement) { - elem.eGet(TypesPackage.eINSTANCE.syntaxRelatedTElement_AstElement, false) as EObject - }; - return astElemNonResolved !== null && !astElemNonResolved.eIsProxy; - } - - def private static String combineErrorMessageWithNestedErrors(String mainMessage, - CompileTimeEvaluationError... nestedErrors) { - - if (nestedErrors.length == 0) { - return mainMessage; - } else if (nestedErrors.length == 1) { - return mainMessage + ": " + nestedErrors.get(0).messageWithLocation; - } else { - return mainMessage + ":\n- " + nestedErrors.map[messageWithLocation].join("\n- "); - } - } - - - // --------------------------------------------------------------------------------------------------------------- - - - /** - * Special kind of {@link CompileTimeEvaluationError} used to denote a particular case in which the - * {@link CompileTimeEvaluator} cannot come up with the correct error message and thus delegates finding a proper - * message to the validation, i.e. to class {@link N4JSExpressionValidator}. - */ - public static final class UnresolvedPropertyAccessError extends CompileTimeEvaluationError { - - public new(ParameterizedPropertyAccessExpression astNode) { - super("*** UnresolvedPropertyAccessError ***", astNode, - N4JSPackage.eINSTANCE.getParameterizedPropertyAccessExpression_Property()); - } - - def public ParameterizedPropertyAccessExpression getAstNodeCasted() { - return astNode as ParameterizedPropertyAccessExpression; - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatter.java new file mode 100644 index 0000000000..b2dc12c9b1 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatter.java @@ -0,0 +1,2379 @@ +/** + * 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.formatting2; + +import static org.eclipse.n4js.formatting2.N4JSFormatterPreferenceKeys.FORMAT_AUTO_WRAP_IN_FRONT_OF_LOGICAL_OPERATOR; +import static org.eclipse.n4js.formatting2.N4JSFormatterPreferenceKeys.FORMAT_MAX_CONSECUTIVE_NEWLINES; +import static org.eclipse.n4js.formatting2.N4JSFormatterPreferenceKeys.FORMAT_PARENTHESIS; +import static org.eclipse.n4js.formatting2.N4JSFormatterPreferenceKeys.FORMAT_SURROUND_IMPORT_LIST_WITH_SPACE; +import static org.eclipse.n4js.formatting2.N4JSGenericFormatter.PRIO_3; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.head; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.last; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.tail; + +import java.util.function.Function; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.formatting2.N4JSGenericFormatter.IndentHandlingTextReplaceMerger; +import org.eclipse.n4js.n4JS.AbstractAnnotationList; +import org.eclipse.n4js.n4JS.AbstractCaseClause; +import org.eclipse.n4js.n4JS.AdditiveExpression; +import org.eclipse.n4js.n4JS.AnnotableExpression; +import org.eclipse.n4js.n4JS.AnnotableN4MemberDeclaration; +import org.eclipse.n4js.n4JS.AnnotablePropertyAssignment; +import org.eclipse.n4js.n4JS.AnnotableScriptElement; +import org.eclipse.n4js.n4JS.Annotation; +import org.eclipse.n4js.n4JS.AnnotationList; +import org.eclipse.n4js.n4JS.Argument; +import org.eclipse.n4js.n4JS.ArrayElement; +import org.eclipse.n4js.n4JS.ArrayLiteral; +import org.eclipse.n4js.n4JS.ArrowFunction; +import org.eclipse.n4js.n4JS.AssignmentExpression; +import org.eclipse.n4js.n4JS.AwaitExpression; +import org.eclipse.n4js.n4JS.BinaryBitwiseExpression; +import org.eclipse.n4js.n4JS.BinaryLogicalExpression; +import org.eclipse.n4js.n4JS.BindingPattern; +import org.eclipse.n4js.n4JS.Block; +import org.eclipse.n4js.n4JS.BooleanLiteral; +import org.eclipse.n4js.n4JS.CastExpression; +import org.eclipse.n4js.n4JS.CatchBlock; +import org.eclipse.n4js.n4JS.CommaExpression; +import org.eclipse.n4js.n4JS.ConditionalExpression; +import org.eclipse.n4js.n4JS.EqualityExpression; +import org.eclipse.n4js.n4JS.ExportDeclaration; +import org.eclipse.n4js.n4JS.ExportableElement; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ExpressionStatement; +import org.eclipse.n4js.n4JS.FieldAccessor; +import org.eclipse.n4js.n4JS.FinallyBlock; +import org.eclipse.n4js.n4JS.ForStatement; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.FunctionDeclaration; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor; +import org.eclipse.n4js.n4JS.GenericDeclaration; +import org.eclipse.n4js.n4JS.GetterDeclaration; +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.n4JS.IfStatement; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.IndexedAccessExpression; +import org.eclipse.n4js.n4JS.IntLiteral; +import org.eclipse.n4js.n4JS.JSXElement; +import org.eclipse.n4js.n4JS.MultiplicativeExpression; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4EnumDeclaration; +import org.eclipse.n4js.n4JS.N4EnumLiteral; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.N4SetterDeclaration; +import org.eclipse.n4js.n4JS.N4TypeVariable; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.NewExpression; +import org.eclipse.n4js.n4JS.NullLiteral; +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression; +import org.eclipse.n4js.n4JS.ParenExpression; +import org.eclipse.n4js.n4JS.PostfixExpression; +import org.eclipse.n4js.n4JS.PromisifyExpression; +import org.eclipse.n4js.n4JS.PropertyAssignment; +import org.eclipse.n4js.n4JS.RegularExpressionLiteral; +import org.eclipse.n4js.n4JS.RelationalExpression; +import org.eclipse.n4js.n4JS.ReturnStatement; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.n4JS.ScriptElement; +import org.eclipse.n4js.n4JS.ShiftExpression; +import org.eclipse.n4js.n4JS.Statement; +import org.eclipse.n4js.n4JS.StringLiteral; +import org.eclipse.n4js.n4JS.SuperLiteral; +import org.eclipse.n4js.n4JS.SwitchStatement; +import org.eclipse.n4js.n4JS.TaggedTemplateString; +import org.eclipse.n4js.n4JS.TemplateLiteral; +import org.eclipse.n4js.n4JS.TemplateSegment; +import org.eclipse.n4js.n4JS.ThisLiteral; +import org.eclipse.n4js.n4JS.ThrowStatement; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.n4JS.UnaryExpression; +import org.eclipse.n4js.n4JS.UnaryOperator; +import org.eclipse.n4js.n4JS.VariableBinding; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.VariableDeclarationOrBinding; +import org.eclipse.n4js.n4JS.VariableStatement; +import org.eclipse.n4js.n4JS.YieldExpression; +import org.eclipse.n4js.services.N4JSGrammarAccess; +import org.eclipse.n4js.ts.typeRefs.IntersectionTypeExpression; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.StaticBaseTypeRef; +import org.eclipse.n4js.ts.typeRefs.StructuralTypeRef; +import org.eclipse.n4js.ts.typeRefs.ThisTypeRef; +import org.eclipse.n4js.ts.typeRefs.ThisTypeRefStructural; +import org.eclipse.n4js.ts.typeRefs.TypeArgument; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRefsPackage; +import org.eclipse.n4js.ts.typeRefs.UnionTypeExpression; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TStructMember; +import org.eclipse.n4js.ts.types.TypesPackage; +import org.eclipse.xtext.AbstractRule; +import org.eclipse.xtext.Keyword; +import org.eclipse.xtext.formatting2.IAutowrapFormatter; +import org.eclipse.xtext.formatting2.IFormattableDocument; +import org.eclipse.xtext.formatting2.IHiddenRegionFormatter; +import org.eclipse.xtext.formatting2.IHiddenRegionFormatting; +import org.eclipse.xtext.formatting2.ITextReplacer; +import org.eclipse.xtext.formatting2.internal.SinglelineCodeCommentReplacer; +import org.eclipse.xtext.formatting2.internal.SinglelineDocCommentReplacer; +import org.eclipse.xtext.formatting2.regionaccess.IComment; +import org.eclipse.xtext.formatting2.regionaccess.IEObjectRegion; +import org.eclipse.xtext.formatting2.regionaccess.IHiddenRegion; +import org.eclipse.xtext.formatting2.regionaccess.ILineRegion; +import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion; +import org.eclipse.xtext.formatting2.regionaccess.ISequentialRegion; +import org.eclipse.xtext.formatting2.regionaccess.ITextSegment; +import org.eclipse.xtext.resource.XtextResource; +import org.eclipse.xtext.xbase.lib.Pair; +import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; +import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.simpleExpressions.NumberLiteral; + +import com.google.inject.Inject; + +/***/ +@SuppressWarnings("restriction") +public class N4JSFormatter extends TypeExpressionsFormatter { + private final static Logger LOGGER = Logger.getLogger(TypeExpressionsFormatter.class); + + /** Debug switch */ + private static boolean debug = false; + + @Inject + N4JSGrammarAccess grammarAccess; + + /** + * PRIO_4 = -7 - still very low. Standard priorities in the formatter are: + *

    + *
  • lowPriority = -1; == PRIO_10 + *
  • normal priority = 0; == PRIO_11 + *
  • high priority = +1; == PRIO_12 + *
+ */ + static int PRIO_4 = PRIO_3 + 1; + static int PRIO_13 = IHiddenRegionFormatter.HIGH_PRIORITY + 1; + + @Override + public void format(Object clazz, IFormattableDocument document) { + if (clazz instanceof N4ClassDeclaration) { + _format((N4ClassDeclaration) clazz, document); + return; + } else if (clazz instanceof N4InterfaceDeclaration) { + _format((N4InterfaceDeclaration) clazz, document); + return; + } else if (clazz instanceof ArrowFunction) { + _format((ArrowFunction) clazz, document); + return; + } else if (clazz instanceof N4EnumDeclaration) { + _format((N4EnumDeclaration) clazz, document); + return; + } else if (clazz instanceof TemplateSegment) { + _format((TemplateSegment) clazz, document); + return; + } else if (clazz instanceof IntersectionTypeExpression) { + _format((IntersectionTypeExpression) clazz, document); + return; + } else if (clazz instanceof ParameterizedTypeRef) { + _format((ParameterizedTypeRef) clazz, document); + return; + } else if (clazz instanceof ThisTypeRef) { + _format((ThisTypeRef) clazz, document); + return; + } else if (clazz instanceof UnionTypeExpression) { + _format((UnionTypeExpression) clazz, document); + return; + } else if (clazz instanceof TStructMember) { + _format((TStructMember) clazz, document); + return; + } else if (clazz instanceof ArrayLiteral) { + _format((ArrayLiteral) clazz, document); + return; + } else if (clazz instanceof ForStatement) { + _format((ForStatement) clazz, document); + return; + } else if (clazz instanceof FunctionExpression) { + _format((FunctionExpression) clazz, document); + return; + } else if (clazz instanceof IndexedAccessExpression) { + _format((IndexedAccessExpression) clazz, document); + return; + } else if (clazz instanceof N4FieldDeclaration) { + _format((N4FieldDeclaration) clazz, document); + return; + } else if (clazz instanceof ObjectLiteral) { + _format((ObjectLiteral) clazz, document); + return; + } else if (clazz instanceof ParameterizedCallExpression) { + _format((ParameterizedCallExpression) clazz, document); + return; + } else if (clazz instanceof ParameterizedPropertyAccessExpression) { + _format((ParameterizedPropertyAccessExpression) clazz, document); + return; + } else if (clazz instanceof ParenExpression) { + _format((ParenExpression) clazz, document); + return; + } else if (clazz instanceof TaggedTemplateString) { + _format((TaggedTemplateString) clazz, document); + return; + } else if (clazz instanceof TemplateLiteral) { + _format((TemplateLiteral) clazz, document); + return; + } else if (clazz instanceof VariableDeclaration) { + _format((VariableDeclaration) clazz, document); + return; + } else if (clazz instanceof VariableStatement) { + _format((VariableStatement) clazz, document); + return; + } else if (clazz instanceof AdditiveExpression) { + _format((AdditiveExpression) clazz, document); + return; + } else if (clazz instanceof AssignmentExpression) { + _format((AssignmentExpression) clazz, document); + return; + } else if (clazz instanceof AwaitExpression) { + _format((AwaitExpression) clazz, document); + return; + } else if (clazz instanceof BinaryBitwiseExpression) { + _format((BinaryBitwiseExpression) clazz, document); + return; + } else if (clazz instanceof BinaryLogicalExpression) { + _format((BinaryLogicalExpression) clazz, document); + return; + } else if (clazz instanceof Block) { + _format((Block) clazz, document); + return; + } else if (clazz instanceof CastExpression) { + _format((CastExpression) clazz, document); + return; + } else if (clazz instanceof CommaExpression) { + _format((CommaExpression) clazz, document); + return; + } else if (clazz instanceof ConditionalExpression) { + _format((ConditionalExpression) clazz, document); + return; + } else if (clazz instanceof EqualityExpression) { + _format((EqualityExpression) clazz, document); + return; + } else if (clazz instanceof ExportDeclaration) { + _format((ExportDeclaration) clazz, document); + return; + } else if (clazz instanceof ExpressionStatement) { + _format((ExpressionStatement) clazz, document); + return; + } else if (clazz instanceof IfStatement) { + _format((IfStatement) clazz, document); + return; + } else if (clazz instanceof ImportDeclaration) { + _format((ImportDeclaration) clazz, document); + return; + } else if (clazz instanceof MultiplicativeExpression) { + _format((MultiplicativeExpression) clazz, document); + return; + } else if (clazz instanceof NamespaceImportSpecifier) { + _format((NamespaceImportSpecifier) clazz, document); + return; + } else if (clazz instanceof NewExpression) { + _format((NewExpression) clazz, document); + return; + } else if (clazz instanceof PostfixExpression) { + _format((PostfixExpression) clazz, document); + return; + } else if (clazz instanceof PromisifyExpression) { + _format((PromisifyExpression) clazz, document); + return; + } else if (clazz instanceof RelationalExpression) { + _format((RelationalExpression) clazz, document); + return; + } else if (clazz instanceof ReturnStatement) { + _format((ReturnStatement) clazz, document); + return; + } else if (clazz instanceof ShiftExpression) { + _format((ShiftExpression) clazz, document); + return; + } else if (clazz instanceof SwitchStatement) { + _format((SwitchStatement) clazz, document); + return; + } else if (clazz instanceof ThrowStatement) { + _format((ThrowStatement) clazz, document); + return; + } else if (clazz instanceof UnaryExpression) { + _format((UnaryExpression) clazz, document); + return; + } else if (clazz instanceof VariableBinding) { + _format((VariableBinding) clazz, document); + return; + } else if (clazz instanceof YieldExpression) { + _format((YieldExpression) clazz, document); + return; + } else if (clazz instanceof XtextResource) { + _format((XtextResource) clazz, document); + return; + } else if (clazz instanceof AbstractCaseClause) { + _format((AbstractCaseClause) clazz, document); + return; + } else if (clazz instanceof BindingPattern) { + _format((BindingPattern) clazz, document); + return; + } else if (clazz instanceof CatchBlock) { + _format((CatchBlock) clazz, document); + return; + } else if (clazz instanceof Expression) { + _format((Expression) clazz, document); + return; + } else if (clazz instanceof FinallyBlock) { + _format((FinallyBlock) clazz, document); + return; + } else if (clazz instanceof FunctionOrFieldAccessor) { + _format((FunctionOrFieldAccessor) clazz, document); + return; + } else if (clazz instanceof N4TypeVariable) { + _format((N4TypeVariable) clazz, document); + return; + } else if (clazz instanceof NamedImportSpecifier) { + _format((NamedImportSpecifier) clazz, document); + return; + } else if (clazz instanceof Script) { + _format((Script) clazz, document); + return; + } else if (clazz instanceof EObject) { + _format((EObject) clazz, document); + return; + } else if (clazz == null) { + _format((Void) null, document); + return; + } else { + _format(clazz, document); + return; + } + } + + private void configureAnnotations(final Object semEObject, final IFormattableDocument document) { + if (semEObject instanceof AnnotablePropertyAssignment) { + _configureAnnotations((AnnotablePropertyAssignment) semEObject, document); + return; + } else if (semEObject instanceof AnnotableExpression) { + _configureAnnotations((AnnotableExpression) semEObject, document); + return; + } else if (semEObject instanceof AnnotableN4MemberDeclaration) { + _configureAnnotations((AnnotableN4MemberDeclaration) semEObject, document); + return; + } else if (semEObject instanceof AnnotableScriptElement) { + _configureAnnotations((AnnotableScriptElement) semEObject, document); + return; + } else if (semEObject instanceof AbstractAnnotationList) { + _configureAnnotations((AbstractAnnotationList) semEObject, document); + return; + } else if (semEObject == null) { + _configureAnnotations((Void) null, document); + return; + } else { + _configureAnnotations(semEObject, document); + return; + } + } + + private Integer maxConsecutiveNewLines() { + // let's stick to 2 + return getPreference(FORMAT_MAX_CONSECUTIVE_NEWLINES); + } + + void _format(Script script, IFormattableDocument document) { + N4JSGenericFormatter generic = new N4JSGenericFormatter(grammarAccess, textRegionExtensions); + if (getPreference(FORMAT_PARENTHESIS)) { + // script.formatParenthesisBracketsAndBraces(document) + } + + // TODO the following line requires more conflict handling with semicolons: + // script.interior[noIndentation;]; + + generic.formatSemicolons(script, document); + generic.formatColon(script, document); + + formatScriptAnnotations(script, document); + + for (ScriptElement element : script.getScriptElements()) { + // element.append[setNewLines(1, 1, maxConsecutiveNewLines);hrf.noSpace(); autowrap].prepend, + // hrf->hrf.noSpace(); + document.append(element, hrf -> { + hrf.setNewLines(1, 1, maxConsecutiveNewLines()); + hrf.autowrap(); + }); + + document.format(element); + } + + // format last import, overrides default newLines: + document.append(last(filter(script.getScriptElements(), ImportDeclaration.class)), hfr -> { + hfr.setNewLines(2, 2, 3); + hfr.highPriority(); + }); + } + + /** put modifiers into a single line separated by one space, last modifier has one space to following element. */ + void configureModifiers(EObject semObject, IFormattableDocument document) { + for (ISemanticRegion sr : textRegionExtensions.regionFor(semObject) + .ruleCallsTo(grammarAccess.getN4ModifierRule())) { + + document.append(sr, hrf -> hrf.oneSpace()); + } + } + + void configureTypingStrategy(EObject semObject, IFormattableDocument document) { + for (ISemanticRegion sr : textRegionExtensions.regionFor(semObject) + .ruleCallsTo(grammarAccess.getTypingStrategyDefSiteOperatorRule(), + grammarAccess.getTypingStrategyUseSiteOperatorRule())) { + + document.append(sr, hrf -> hrf.noSpace()); + } + } + + void formatTypeVariables(GenericDeclaration semObject, IFormattableDocument document) { + if (semObject.getTypeVars().isEmpty()) { + return; + } + // to "<": + ISemanticRegion sr = document.prepend(textRegionExtensions.regionFor(semObject).keyword("<"), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + }); + document.append(sr, hrf -> hrf.noSpace()); + + document.prepend(textRegionExtensions.regionFor(semObject).keyword(">"), hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }); + + for (N4TypeVariable typeVar : semObject.getTypeVars()) { + N4TypeVariable sr2 = document.append(typeVar, hrf -> hrf.noSpace()); + document.append(textRegionExtensions.immediatelyFollowing(sr2).keyword(","), hrf -> hrf.oneSpace()); + format(typeVar, document); + } + } + + void _format(N4ClassDeclaration clazz, IFormattableDocument document) { + + configureAnnotations(clazz, document); + insertSpaceInFrontOfCurlyBlockOpener(clazz, document); + indentExcludingAnnotations(clazz, document); + + configureTypingStrategy(clazz, document); + configureModifiers(clazz, document); + + formatTypeVariables(clazz, document); + + // val semRegModifier = textRegionExtensions.regionFor(clazz).feature( + // N4JSPackage.Literals.MODIFIABLE_ELEMENT__DECLARED_MODIFIERS); + // if( semRegModifier != null ) { // only if exists. + // val beginModifierHR = semRegModifier.previousHiddenRegion; + // val endModifierHR = semRegModifier.nextHiddenRegion; + // // go over all semantic regions in the modifier location. + // var currHR = beginModifierHR.nextHiddenRegion; + // while( currHR != endModifierHR ){ + // currHR.set, hrf->hrf.oneSpace(); + // currHR = currHR.nextHiddenRegion; + // } + // endModifierHR.set, hrf->hrf.oneSpace(); + // } // end modifier formatting TODO extract into method. + + // TODO revise the following pattern of call-back implementations. + // Define lambda for callback & normal use: + Function twolinesBeforeFirstMember = (prio) -> { + return document.prepend(clazz.getOwnedMembersRaw().get(0), hrf -> { + hrf.setNewLines(2); + hrf.setPriority(prio); + }); + }; + + // Defines CallBack for autoWrap: + IAutowrapFormatter callBackOnAutoWrap = new IAutowrapFormatter() { // callback for auto-wrapping with implements + boolean didReconfigure = false; // track to only execute once. + + @SuppressWarnings("hiding") + @Override + public void format(ITextSegment region, IHiddenRegionFormatting wrapped, IFormattableDocument document) { + if (!didReconfigure) { + twolinesBeforeFirstMember.apply(IHiddenRegionFormatter.HIGH_PRIORITY); // reformat with higher + // priority + didReconfigure = true; // keep state. + } + } + }; + + // 2nd version of implementing the callback: + StateTrack state2 = new StateTrack(); + IAutowrapFormatter callBackOnAutoWrap2 = (region, hrFormatting, document2) -> { + if (state2.shouldDoThenDone()) + twolinesBeforeFirstMember.apply(IHiddenRegionFormatter.HIGH_PRIORITY); + }; + + suppressUnusedWarnings(callBackOnAutoWrap2); + + // Allow for lineBreaks in front of keywords: + document.append(document.prepend(textRegionExtensions.regionFor(clazz).keyword("extends"), hrf -> { + hrf.setNewLines(0, 0, 1); // allow line break in front. + hrf.autowrap(); + }), hrf -> { + hrf.oneSpace(); + hrf.autowrap(); + }); + + document.append(document.prepend(textRegionExtensions.regionFor(clazz).keyword("implements"), hrf -> { + hrf.setNewLines(0, 0, 1); + hrf.autowrap(); + hrf.setPriority(IHiddenRegionFormatter.LOW_PRIORITY); + hrf.setOnAutowrap(callBackOnAutoWrap); + }), hrf -> { + hrf.oneSpace(); + hrf.autowrap(); + }); + + for (TypeReferenceNode trn : tail(clazz.getImplementedInterfaceRefs())) { + document.prepend(trn, hrf -> { + hrf.autowrap(); + hrf.setPriority(IHiddenRegionFormatter.LOW_PRIORITY); + hrf.setOnAutowrap(callBackOnAutoWrap); + }); + } + + // special case if the header of the class spans multiple lines, then insert extra line break. + + ISemanticRegion kwClass = textRegionExtensions.regionFor(clazz).keyword("class"); + ISemanticRegion kwBrace = textRegionExtensions.regionFor(clazz).keyword("{"); // autowrap-listener ? + if (!kwClass.getLineRegions().get(0).contains(kwBrace)) { + twolinesBeforeFirstMember.apply(IHiddenRegionFormatter.NORMAL_PRIORITY); + } else { + document.prepend(clazz.getOwnedMembersRaw().get(0), hrf -> { + hrf.setNewLines(1, 1, maxConsecutiveNewLines()); + hrf.autowrap(); + }); + } + + document.append(kwClass, hrf -> hrf.oneSpace()); + + for (N4MemberDeclaration member : clazz.getOwnedMembersRaw()) { + document.append(member, hrf -> hrf.setNewLines(1, 1, maxConsecutiveNewLines())); + document.format(member); + } + + // Collapse empty block: + if (clazz.getOwnedMembersRaw().isEmpty()) { + // Empty body: + document.append(kwBrace, hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }); + } + } + + void _format(N4InterfaceDeclaration interf, IFormattableDocument document) { + configureAnnotations(interf, document); + configureModifiers(interf, document); + insertSpaceInFrontOfCurlyBlockOpener(interf, document); + indentExcludingAnnotations(interf, document);// .interiorBUGFIX(, hrf->hrf.indent(),document); + // //interf.interior, + // hrf->hrf.indent(); + + document.prepend(interf.getOwnedMembersRaw().get(0), hrf -> hrf.setNewLines(1, 1, maxConsecutiveNewLines())); + for (N4MemberDeclaration member : interf.getOwnedMembersRaw()) { + document.append(member, hrf -> hrf.setNewLines(1, 1, maxConsecutiveNewLines())); + document.format(member); + } + } + + // void _format(N4MemberDeclaration member, IFormattableDocument document) { + // textRegionExtensions.regionFor(member).keyword("(").prepend[hrf.noSpace(); hrf.setNewLines(1);].append, + // hrf->hrf.noSpace() + // + // member.insertSpaceInfrontOfPropertyNames(document); + // for (c : member.eContents) { + // document.format(// c); + // } + // } + + void _format(N4FieldDeclaration field, IFormattableDocument document) { + configureAnnotations(field, document); + configureModifiers(field, document); + + indentExcludingAnnotations(field, document); + + configureOptionality(field, document); + document.append(document.prepend(textRegionExtensions.regionFor(field).keyword("="), hrf -> hrf.oneSpace()), + hrf -> hrf.oneSpace()); + document.format(field.getExpression()); + document.format(field.getDeclaredTypeRefInAST()); + } + + // format(N4MethodDeclaration method, IFormattableDocument document) { + // configureAnnotations(method, document); + // method.insertSpaceInfrontOfPropertyNames(document); + // + // textRegionExtensions.regionFor(method).keyword("(").prepend[hrf.noSpace(); hrf.setNewLines(1);] + // + // method.textRegionExtensions.regionFor(body).keyword("{").prepend[hrf.oneSpace(); newLines = 0] + // for (child : method.eContents) { + // document.format(// child); + // } + // } + // + void _format(FunctionExpression funE, IFormattableDocument document) { + configureAnnotations(funE, document); + configureModifiers(funE, document); + + if (funE.isArrowFunction()) { + throw new IllegalStateException("Arrow functions should be formated differently."); + } + + configureFormalParameters(funE.getFpars(), document, + (ITextSegment $0, IHiddenRegionFormatting $1, IFormattableDocument $2) -> { + /* n.t.d. */}); + + Pair parenPair = textRegionExtensions.regionFor(funE).keywordPairs("(", ")") + .get(0); + + document.append(parenPair.getKey(), hrf -> hrf.noSpace()); + document.prepend(parenPair.getValue(), hrf -> hrf.noSpace()); + document.format(funE.getBody()); + } + + void _format(FunctionOrFieldAccessor fDecl, IFormattableDocument document) { + configureAnnotations(fDecl, document); + configureModifiers(fDecl, document); + + // State-keeper to avoid clashing reconfigurations if multiple auto-wraps get triggered. + final StateTrack state = new StateTrack(); // use state to only trigger one change, even if called multiple + // times. + + // Callback to introduce an additional line in body-block. + IAutowrapFormatter cbInsertEmptyLineInBody = ( + ITextSegment ts, IHiddenRegionFormatting hrf, IFormattableDocument fd) -> { + + if (state.shouldDoThenDone() && fDecl.getBody() != null && fDecl.getBody().getStatements() != null + && !fDecl.getBody().getStatements().isEmpty()) { + document.prepend(fDecl.getBody().getStatements().get(0), hrf2 -> { + hrf2.setNewLines(2, 2, maxConsecutiveNewLines()); + hrf2.highPriority(); + }); + } + }; + + // Formal parameters + if (fDecl instanceof FunctionDefinition) { + configureFormalParameters(((FunctionDefinition) fDecl).getFpars(), document, cbInsertEmptyLineInBody); + } else if (fDecl instanceof N4SetterDeclaration) { + /* no autowrap for setters: cbInsertEmptyLineInBody */ + document.append(document.prepend(((N4SetterDeclaration) fDecl).getFpar(), hrf -> hrf.noSpace()), + hrf -> hrf.noSpace()); + } + + // Type Variables + if (fDecl instanceof FunctionDeclaration) { + formatTypeVariables((FunctionDeclaration) fDecl, document); + } + + // special case for accessors: get / set keywords + if (fDecl instanceof FieldAccessor) { + configureGetSetKeyword((FieldAccessor) fDecl, document); + configureOptionality((FieldAccessor) fDecl, document); + } + + Pair parenPair = textRegionExtensions.regionFor(fDecl).keywordPairs("(", + ")").get(0); + + document.append(document.prepend(parenPair.getKey(), hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }), hrf -> hrf.noSpace()); + + document.interior(parenPair, hrf -> hrf.indent()); + + if (isMultiLine(parenPair) && !(fDecl instanceof FieldAccessor)) { + // it is already a multiline, insert the newLine immediately. + // cbInsertEmptyLineInBody.apply(null,null,null); // TODO re-think, if all will be collapsed this assumption + // does not hold an + } else { + // single line parameter block + } + document.prepend(parenPair.getValue(), hrf -> hrf.noSpace()); + + for (EObject child : fDecl.eContents()) { + document.format(child); + } + } + + /** to be used by FunctionDefintiions and SetterDeclarations */ + void configureFormalParameters(EList list, IFormattableDocument document, IAutowrapFormatter x) { + if (list == null || list.isEmpty()) { + return; + } + for (int idx = 0; idx < list.size(); idx++) { + FormalParameter it = list.get(idx); + if (idx != 0) { + document.prepend(it, hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0, 0, 1); + hrf.setOnAutowrap(x); + }); + } + document.append(it, hrf -> hrf.noSpace()); + configureAnnotationsInLine(it, document); // TODO maybe we need some in-line-annotation config here. + // textRegionExtensions.regionFor(it).ruleCallTo( bindingIdentifierAsFormalParameterRule ) // + // feature(N4JSPackage.Literals.FORMAL_PARAMETER__NAME) + // .prepend[hrf.oneSpace();hrf.setNewLines(1);].append[] + format(it.getDeclaredTypeRefInAST(), document); + if (it.isVariadic()) { + document.append(document.prepend(textRegionExtensions.regionFor(it).keyword("..."), + hrf -> hrf.setNewLines(0)/* hrf.oneSpace(); */), hrf -> { + hrf.setNewLines(0); + hrf.noSpace(); + }); + } + if (it.isHasInitializerAssignment()) { + document.append(document.prepend(textRegionExtensions.regionFor(it).keyword("="), hrf -> { + hrf.setNewLines(0); + hrf.noSpace(); + }), hrf -> { + hrf.setNewLines(0); + hrf.noSpace(); + }); + if (it.getInitializer() != null) { + format(it.getInitializer(), document); + } + } + } + } + + /** Check if key and value are in different lines. Defined for non-overlapping Regions, e.g. Keyword-pairs. */ + static boolean isMultiLine(Pair pair) { + return !last(pair.getKey().getLineRegions()).contains(pair.getValue()); + } + + // format(FunctionOrFieldAccessor fofAccessor, IFormattableDocument document) { + // val begin = fofAccessor.body.semanticRegions.head + // val end = fofAccessor.body.semanticRegions.last + // if (begin?.lineRegions?.head?.contains(end?.endOffset)) { + // // same line + // } else { + // // body spans multiple lines + // begin.append[newLine;]; + // end.prepend[newLine;]; + // // fofAccessor.body.interior, hrf->hrf.indent(); // already by parenthesis? + // } + // + // document.format(// fofAccessor.body?); + // + // } + + void _format(N4EnumDeclaration enumDecl, IFormattableDocument document) { + configureAnnotations(enumDecl, document); + configureModifiers(enumDecl, document); + insertSpaceInFrontOfCurlyBlockOpener(enumDecl, document); + indentExcludingAnnotations(enumDecl, document);// .interiorBUGFIX(, hrf->hrf.indent(),document); + // //enumDecl.interior, hrf->hrf.indent(); + configureCommas(enumDecl, document); + + Pair braces = textRegionExtensions.regionFor(enumDecl).keywordPairs("{", "}") + .get(0); + + boolean multiLine = textRegionExtensions.isMultiline(enumDecl); + + for (N4EnumLiteral it : enumDecl.getLiterals()) { + format(it, document); + if (multiLine) { + if (textRegionExtensions.regionForEObject(it).getPreviousHiddenRegion().containsComment()) { + // comment above + document.prepend(it, hrf -> hrf.setNewLines(2)); + } else { // no comment above + document.prepend(it, hrf -> hrf.newLine()); + } + } + } + if (multiLine) { + document.prepend(braces.getValue(), hrf -> hrf.newLine()); + } + } + + void _format(ParameterizedPropertyAccessExpression exp, IFormattableDocument document) { + ISemanticRegion dotKW = textRegionExtensions.regionFor(exp).keyword("."); + document.append(document.prepend(dotKW, hrf -> { + hrf.noSpace(); + hrf.autowrap(); + hrf.setNewLines(0, 0, 1); + }), hrf -> hrf.noSpace()); + if (exp.eContainer() instanceof ExpressionStatement) { + // top-level PPA, indent one level. + interiorBUGFIX(exp, hrf -> hrf.indent(), document); // exp.interior, hrf->hrf.indent(); + } + document.format(exp.getTarget()); + } + + void _format(ParameterizedCallExpression exp, IFormattableDocument document) { + // FIXME process typeArgs !!! + ISemanticRegion dotKW = textRegionExtensions.regionFor(exp).keyword("."); + document.append(document.prepend(dotKW, hrf -> { + hrf.noSpace(); + hrf.autowrap(); + }), hrf -> hrf.noSpace()); + document.append(document.prepend(textRegionExtensions.regionFor(exp).keyword("("), hrf -> hrf.noSpace()), + hrf -> hrf.noSpace()); + document.prepend(textRegionExtensions.regionFor(exp).keyword(")"), hrf -> hrf.noSpace()); + configureCommas(exp, document); + + for (Argument arg : tail(exp.getArguments())) { + document.prepend(arg, hrf -> { + hrf.oneSpace(); + hrf.autowrap(); + }); + } + + for (Argument arg : exp.getArguments()) { + format(arg, document); + } + + if (exp.eContainer() instanceof ExpressionStatement) { + // top-level PPA, indent one level. + interiorBUGFIX(exp, hrf -> hrf.indent(), document); // exp.interior, hrf->hrf.indent(); + } + document.format(exp.getTarget()); + } + + void _format(ImportDeclaration decl, IFormattableDocument document) { + // read configuration: + boolean extraSpace = getPreference(FORMAT_SURROUND_IMPORT_LIST_WITH_SPACE); + + document.append(document.prepend(textRegionExtensions.regionFor(decl).keyword("{"), hrf -> hrf.noSpace()), + hrf -> { + if (extraSpace) + hrf.oneSpace(); + else + hrf.noSpace(); + }); + document.append(document.prepend(textRegionExtensions.regionFor(decl).keyword("}"), hrf -> { + if (extraSpace) + hrf.oneSpace(); + else + hrf.noSpace(); + }), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + }); + document.surround(textRegionExtensions.regionFor(decl).keyword("from"), hrf -> hrf.oneSpace()); + configureCommas(decl, document); + for (EObject eobj : decl.eContents()) { + format(eobj, document); + } + } + + void _format(NamedImportSpecifier namedImp, IFormattableDocument document) { + document.append(document.prepend(textRegionExtensions.regionFor(namedImp).keyword("as"), hrf -> hrf.oneSpace()), + hrf -> hrf.oneSpace()); + // "+"-KW after alias-name + document.append(document.prepend( + textRegionExtensions.regionFor(namedImp) + .feature(N4JSPackage.Literals.IMPORT_SPECIFIER__DECLARED_DYNAMIC), + hrf -> hrf.noSpace()), + hrf -> hrf.oneSpace()); + } + + void _format(NamespaceImportSpecifier nsImp, IFormattableDocument document) { + document.append(textRegionExtensions.regionFor(nsImp).keyword("*"), hrf -> hrf.oneSpace()); + document.append(textRegionExtensions.regionFor(nsImp).keyword("as"), hrf -> hrf.oneSpace()); + // "+"-KW after alias-name + document.append(document.prepend(textRegionExtensions.regionFor(nsImp) + .feature(N4JSPackage.Literals.IMPORT_SPECIFIER__DECLARED_DYNAMIC), + hrf -> hrf.noSpace()), + hrf -> hrf.oneSpace()); + } + + void _format(ExportDeclaration export, IFormattableDocument document) { + document.append(textRegionExtensions.regionFor(export).keyword("export"), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(1); + // Apply prioritization to catch cases of 'trapped' annotations e.g. "export @Final public class" which + // could also be reordered to "@Final export public class.." + hrf.setPriority(PRIO_13); // Priority higher then highPriority used in AnnotationList. + }); + + for (EObject eo : export.eContents()) { + format(eo, document); + } + + // Fix Trapped annotations: + ExportableElement exported = export.getExportedElement(); + if (exported instanceof AnnotableScriptElement) { + AnnotationList annoList = ((AnnotableScriptElement) exported).getAnnotationList(); + if (annoList != null && !annoList.getAnnotations().isEmpty()) { + document.append(last(annoList.getAnnotations()), hrf -> { + hrf.setNewLines(0); + hrf.oneSpace(); + hrf.setPriority(PRIO_13); + }); + } + } + } + + void _format(IfStatement stmt, IFormattableDocument document) { + Pair parenPair = textRegionExtensions.regionFor(stmt).keywordPairs("(", ")") + .get(0); + document.interior(parenPair, hrf -> { + hrf.noSpace(); + hrf.indent(); + }); + document.prepend(parenPair.getKey(), hrf -> hrf.oneSpace()); + document.append(parenPair.getValue(), hrf -> hrf.oneSpace()); + + document.append(document.prepend(textRegionExtensions.regionFor(stmt).keyword("else"), hrf -> { + hrf.autowrap(); + hrf.oneSpace(); + }), hrf -> hrf.oneSpace()); + + document.prepend(stmt.getElseStmt(), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + }); + + document.format(stmt.getExpression()); + document.format(stmt.getIfStmt()); + document.format(stmt.getElseStmt()); + + } + + void _format(SwitchStatement swStmt, IFormattableDocument document) { + insertSpaceInFrontOfCurlyBlockOpener(swStmt, document); + interiorBUGFIX(swStmt, hrf -> hrf.indent(), document); // swStmt.interior, hrf->hrf.indent(); + document.format(swStmt.getExpression()); + document.prepend(swStmt.getCases().get(0), hrf -> hrf.newLine()); + + for (EObject eo : swStmt.getCases()) { + format(eo, document); + } + } + + /** Formats DefaultCaseClause + CaseClause */ + void _format(AbstractCaseClause caseClause, IFormattableDocument document) { + interiorBUGFIX(caseClause, hrf -> hrf.indent(), document); // caseClause.interior, hrf->hrf.indent(); + + EList stmts = caseClause.getStatements(); + + if (stmts.size() == 1) { + if (stmts.get(0) instanceof Block) { + document.prepend(stmts.get(0), hrf -> hrf.setNewLines(0, 0, 0)); + } else { + document.prepend(stmts.get(0), hrf -> hrf.setNewLines(0, 1, 1)); + } + } else { + document.prepend(stmts.get(0), hrf -> hrf.setNewLines(1, 1, 1)); + } + + // textRegionExtensions.regionFor(caseClause).keyword(":").prepend, hrf->hrf.oneSpace(); // In case one space + // before the colon is desired + for (EObject eo : stmts) { + format(eo, document); + } + for (EObject eo : stmts) { + document.append(eo, hrf -> hrf.setNewLines(1, 1, maxConsecutiveNewLines())); + } + + document.append(caseClause, hrf -> hrf.setNewLines(1, 1, maxConsecutiveNewLines())); + } + + void _format(CastExpression expr, IFormattableDocument document) { + document.append(document.prepend(textRegionExtensions.regionFor(expr).keyword("as"), hrf -> { + hrf.setNewLines(0); + hrf.oneSpace(); + }), hrf -> { + hrf.setNewLines(0); + hrf.oneSpace(); + }); + document.format(expr.getExpression()); + document.format(expr.getTargetTypeRefNode()); + } + + void _format(Block block, IFormattableDocument document) { + if (debug) { + LOGGER.debug("Formatting block " + containmentStructure(block)); + } + + // Beware there are blocks in the grammar, that are not surrounded by curly braces. (e.g. FunctionExpression) + + // Block not nested in other blocks usually are bodies. We want them separated by a space: + if (!(block.eContainer() instanceof Block || block.eContainer() instanceof Script)) { + // TODO maybe invert the control here, since the block is formatting the outside. + document.prepend(textRegionExtensions.regionFor(block).keyword("{"), hrf -> hrf.oneSpace()); + } + + interiorBUGFIX(block, hrf -> hrf.indent(), document); // block.interior, hrf->hrf.indent(); + + document.prepend(block.getStatements().get(0), hrf -> hrf.setNewLines(1, 1, maxConsecutiveNewLines())); + + for (Statement s : block.getStatements()) { + document.append(s, hrf -> hrf.setNewLines(1, 1, maxConsecutiveNewLines())); + } + + for (Statement s : block.getStatements()) { + document.format(s); + } + + // Format empty curly blocks, necessary for comments inside: + Pair braces = textRegionExtensions.regionFor(block).keywordPairs("{", "}") + .get(0); + if (braces != null && braces.getKey().getNextSemanticRegion() == braces.getValue()) { + // empty block: + if (braces.getKey().getNextHiddenRegion().containsComment()) { + document.append(braces.getKey(), hrf -> hrf.setNewLines(1, 1, maxConsecutiveNewLines())); + } else { + document.append(braces.getKey(), hrf -> { + hrf.setNewLines(1); + hrf.noSpace(); + }); + } + } + } + + void _format(ReturnStatement ret, IFormattableDocument document) { + interiorBUGFIX(ret, hrf -> hrf.indent(), document); // ret.interior[indent;] + document.prepend(ret.getExpression(), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + }); + document.format(ret.getExpression()); + } + + void _format(AdditiveExpression add, IFormattableDocument document) { + document.append(document.surround( + textRegionExtensions.regionFor(add).feature(N4JSPackage.Literals.ADDITIVE_EXPRESSION__OP), + hrf -> hrf.oneSpace()), hrf -> hrf.autowrap()); + document.format(add.getLhs()); + document.format(add.getRhs()); + } + + void _format(MultiplicativeExpression mul, IFormattableDocument document) { + document.append(document.surround( + textRegionExtensions.regionFor(mul).feature(N4JSPackage.Literals.MULTIPLICATIVE_EXPRESSION__OP), + hrf -> hrf.oneSpace()), hrf -> hrf.autowrap()); + document.format(mul.getLhs()); + document.format(mul.getRhs()); + } + + void _format(BinaryBitwiseExpression binbit, IFormattableDocument document) { + document.surround(textRegionExtensions.regionFor(binbit) + .feature(N4JSPackage.Literals.BINARY_BITWISE_EXPRESSION__OP), hrf -> hrf.oneSpace()); + document.format(binbit.getLhs()); + document.format(binbit.getRhs()); + } + + void _format(BinaryLogicalExpression binLog, IFormattableDocument document) { + ISemanticRegion opReg = textRegionExtensions.regionFor(binLog) + .feature(N4JSPackage.Literals.BINARY_LOGICAL_EXPRESSION__OP); + document.surround(opReg, hrf -> hrf.oneSpace()); + document.format(binLog.getLhs()); + document.format(binLog.getRhs()); + // auto-wrap: + boolean autoWrapInFront = getPreference(FORMAT_AUTO_WRAP_IN_FRONT_OF_LOGICAL_OPERATOR); + if (autoWrapInFront) { + document.prepend(opReg, hrf -> { + hrf.autowrap(); + hrf.lowPriority(); + hrf.setNewLines(0, 0, 1); + }); + } else { + document.append(opReg, hrf -> { + hrf.autowrap(); + hrf.lowPriority(); + hrf.setNewLines(0, 0, 1); + }); + } + } + + void _format(EqualityExpression eqExpr, IFormattableDocument document) { + document.append(document.surround( + textRegionExtensions.regionFor(eqExpr).feature(N4JSPackage.Literals.EQUALITY_EXPRESSION__OP), + hrf -> hrf.oneSpace()), hrf -> hrf.autowrap()); + document.format(eqExpr.getLhs()); + document.format(eqExpr.getRhs()); + } + + void _format(RelationalExpression relExpr, IFormattableDocument document) { + document.append(document.surround( + textRegionExtensions.regionFor(relExpr).feature(N4JSPackage.Literals.RELATIONAL_EXPRESSION__OP), + hrf -> hrf.oneSpace()), hrf -> hrf.autowrap()); + document.format(relExpr.getLhs()); + document.format(relExpr.getRhs()); + } + + void _format(ShiftExpression shiftExpr, IFormattableDocument document) { + document.append(document.surround( + textRegionExtensions.regionFor(shiftExpr).feature(N4JSPackage.Literals.SHIFT_EXPRESSION__OP), + hrf -> hrf.oneSpace()), hrf -> hrf.autowrap()); + document.format(shiftExpr.getLhs()); + document.format(shiftExpr.getRhs()); + } + + void _format(CommaExpression comma, IFormattableDocument document) { + configureCommas(comma, document); + for (EObject eo : comma.eContents()) { + document.format(eo); + } + } + + void _format(ConditionalExpression cond, IFormattableDocument document) { + document.append(document.surround(textRegionExtensions.regionFor(cond).keyword("?"), hrf -> hrf.oneSpace()), + hrf -> { + hrf.autowrap(); + hrf.lowPriority(); + hrf.setNewLines(0, 0, 1); + }); + document.append(document.surround(textRegionExtensions.regionFor(cond).keyword(":"), hrf -> hrf.oneSpace()), + hrf -> { + hrf.autowrap(); + hrf.lowPriority(); + hrf.setNewLines(0, 0, 1); + }); + document.format(cond.getExpression()); + document.format(cond.getTrueExpression()); + document.format(cond.getFalseExpression()); + } + + void _format(AwaitExpression await, IFormattableDocument document) { + document.append(document.prepend(textRegionExtensions.regionFor(await).keyword("await"), hrf -> hrf.oneSpace()), + hrf -> { + hrf.oneSpace(); + hrf.setNewLines(1); + }); + document.format(await.getExpression()); + } + + void _format(PromisifyExpression promify, IFormattableDocument document) { + noSpaceAfterAT(promify, document); + document.append(textRegionExtensions.regionFor(promify).keyword("Promisify"), hrf -> hrf.oneSpace()); + document.format(promify.getExpression()); + } + + void _format(IndexedAccessExpression idxAcc, IFormattableDocument document) { + IEObjectRegion indexRegion = textRegionExtensions.regionForEObject(idxAcc.getIndex()); + document.append(document.prepend(indexRegion.getPreviousSemanticRegion(), hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + }), hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + }); + document.prepend(indexRegion.getNextSemanticRegion(), hrf -> hrf.noSpace()); + + document.format(idxAcc.getIndex()); + document.format(idxAcc.getTarget()); + } + + void _format(NewExpression newExp, IFormattableDocument document) { + document.append(document.prepend(textRegionExtensions.regionFor(newExp).keyword("new"), hrf -> hrf.oneSpace()), + hrf -> { + hrf.oneSpace(); + hrf.setNewLines(1); + }); + document.format(newExp.getCallee()); + // Watch out, commas are used in Type-args and in argument list ! If necessary distinguish by offset. + ISemanticRegion commas = textRegionExtensions.regionFor(newExp).keyword(","); + document.append(document.prepend(commas, hrf -> hrf.noSpace()), hrf -> hrf.oneSpace()); + + // TODO maybe factor out TypeArgs formatting. + Pair typeArgsAngle = textRegionExtensions.regionFor(newExp) + .keywordPairs("<", ">").get(0); + + if (typeArgsAngle != null) { + document.append(document.prepend(typeArgsAngle.getKey(), hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + }), hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + }); + document.prepend(typeArgsAngle.getValue(), hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + }); + } + for (TypeReferenceNode trn : newExp.getTypeArgs()) { + document.format(trn); + } + + if (newExp.isWithArgs()) { + Pair argParen = textRegionExtensions.regionFor(newExp) + .keywordPairs("(", ")").get(0); + document.append(document.prepend(argParen.getKey(), hrf -> { + hrf.setNewLines(1); + hrf.noSpace(); + }), hrf -> hrf.noSpace()); + document.prepend(argParen.getValue(), hrf -> hrf.noSpace()); + for (Argument arg : newExp.getArguments()) { + document.format(arg); + } + } + } + + void _format(PostfixExpression postFix, IFormattableDocument document) { + // no line break allowed between Expression and operator ! + document.append(document.prepend( + textRegionExtensions.regionFor(postFix).feature(N4JSPackage.Literals.POSTFIX_EXPRESSION__OP), hrf -> { + hrf.setNewLines(1); + hrf.noSpace(); + }), hrf -> { + hrf.oneSpace(); + hrf.lowPriority(); + }); + // giving low priority for situations of closing parenthesis: "(a++)" + document.format(postFix.getExpression()); + } + + void _format(TaggedTemplateString taggedTemplate, IFormattableDocument document) { + document.append(textRegionExtensions.regionFor(taggedTemplate) + .feature(N4JSPackage.Literals.EXPRESSION_WITH_TARGET__TARGET), hrf -> { + hrf.setNewLines(1); + hrf.oneSpace(); + }); + document.format(taggedTemplate.getTarget()); + document.format(taggedTemplate.getTemplate()); + } + + void _format(UnaryExpression unaryExpr, IFormattableDocument document) { + // The operators 'void' 'delete' and 'typeof' must be separated from operand. + boolean requireSpace = (unaryExpr.getOp().ordinal() <= UnaryOperator.TYPEOF_VALUE); + document.append(textRegionExtensions.regionFor(unaryExpr).feature(N4JSPackage.Literals.UNARY_EXPRESSION__OP), + hrf -> { + if (requireSpace) + hrf.oneSpace(); + else + hrf.noSpace(); + hrf.setNewLines(1); + }); + + document.format(unaryExpr.getExpression()); + } + + void _format(YieldExpression yieldExpr, IFormattableDocument document) { + // " yield " or " yield* " + document.append(document.prepend(textRegionExtensions.regionFor(yieldExpr).keyword("yield"), + hrf -> hrf.oneSpace()), + hrf -> { + if (yieldExpr.isMany()) { + hrf.noSpace(); + } else { + hrf.oneSpace(); + } + }); + + if (yieldExpr.isMany()) { + document.append(document.prepend(textRegionExtensions.regionFor(yieldExpr).keyword("*"), + hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + }), + hrf -> hrf.oneSpace()); + } + document.format(yieldExpr.getExpression()); + } + + void _format(ParenExpression parenE, IFormattableDocument document) { + document.append(head(textRegionExtensions.semanticRegions(parenE)), hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + hrf.autowrap(); + }); + document.prepend(last(textRegionExtensions.semanticRegions(parenE)), hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + hrf.autowrap(); + }); + interiorBUGFIX(parenE, hrf -> hrf.indent(), document); // parenE.interior, hrf->hrf.indent(); + document.format(parenE.getExpression()); + } + + void _format(ArrowFunction arrowF, IFormattableDocument document) { + configureCommas(arrowF, document); + document.surround(textRegionExtensions.regionFor(arrowF).ruleCallTo(grammarAccess.getArrowRule()), + hrf -> hrf.oneSpace()); + document.interior(head(textRegionExtensions.regionFor(arrowF).keywordPairs("(", ")")), hrf -> hrf.noSpace()); + // too lax: arrowF.fpars.configureFormalParameters(document,[/*NTD*/]); + + if (arrowF.isHasBracesAroundBody()) { + + // format body as block. NOTE: this block differs from other blocks, since the curly braces are defined in + // the ArrowExpression. special handling of indentation in inside the braces. + Pair bracesPair = textRegionExtensions.regionFor(arrowF).keywordPairs("{", + "}").get(0); + document.interior(bracesPair, hrf -> hrf.indent()); + + if (last(bracesPair.getKey().getLineRegions()).contains(bracesPair.getValue()) + // one line '{ do; stuff; }' + || last(bracesPair.getKey().getLineRegions()).contains(bracesPair.getKey().getNextSemanticRegion()) + // no line-break after braces e.g. '{ do; \n stuff; }' + ) { + // one line + if (arrowF.getBody() != null) { + for (int idx = 0; idx < arrowF.getBody().getStatements().size(); idx++) { + Statement it = arrowF.getBody().getStatements().get(idx); + document.format(it); + if (idx != 0) { + document.prepend(it, hrf -> { + hrf.oneSpace(); + hrf.autowrap(); + hrf.setNewLines(1); + }); + } + } + } + + // do not autowrap after "{" to keep wrap-semantic + document.append(bracesPair.getKey(), hrf -> hrf.oneSpace()); + document.prepend(bracesPair.getValue(), hrf -> hrf.oneSpace()); + } + + else { + // multi-line + if (arrowF.getBody() != null && !arrowF.getBody().getStatements().isEmpty()) { + document.prepend(arrowF.getBody().getStatements().get(0), hrf -> hrf.setNewLines(1)); + for (Statement it : arrowF.getBody().getStatements()) { + document.format(it); + document.append(it, hrf -> hrf.setNewLines(1)); + } + + } else { + // empty block, squash interior. + document.append(bracesPair.getKey(), hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + }); + document.prepend(bracesPair.getValue(), hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + }); + } + } + + } else if (arrowF.getBody() != null) { + // no braces Around the implicit return statement. + document.format(arrowF.getBody().getStatements().get(0)); + } + } + + void _format(ArrayLiteral al, IFormattableDocument document) { + Pair bracketPair = textRegionExtensions.regionFor(al).keywordPairs("[", "]") + .get(0); + document.interior(bracketPair, hrf -> hrf.indent()); + boolean sameLine = bracketPair.getKey().getLineRegions().get(0).contains(bracketPair.getValue()); + // auto wrap in front of AL-Elements, to preserve comma at end. + if (!sameLine) { + document.append(last(al.getElements()), hrf -> hrf.autowrap()); + for (int num = 0; num < al.getElements().size(); num++) { + ArrayElement it = al.getElements().get(num); + final int numF = num; + document.append(document.prepend(it, hrf -> { + hrf.autowrap(); + hrf.setNewLines(0, 0, 1); + if (numF != 0) { + hrf.oneSpace(); + } + }), hrf -> hrf.noSpace()); + } + // format last bracket if in single.line. + if (!last(bracketPair.getValue().getPreviousSemanticRegion().getLineRegions()) + .contains(bracketPair.getValue())) { + document.prepend(bracketPair.getValue(), hrf -> hrf.newLine()); + } + } else { + for (int num = 0; num < al.getElements().size(); num++) { + ArrayElement it = al.getElements().get(num); + final int numF = num; + document.prepend(it, hrf -> { + hrf.autowrap(); + if (numF != 0) { + hrf.oneSpace(); + } + }); + } + } + } + + void _format(ObjectLiteral ol, IFormattableDocument document) { + configureCommas(ol, document); + + Pair bracePair = textRegionExtensions.regionFor(ol).keywordPairs("{", + "}").get(0); + document.interior(bracePair, hrf -> hrf.indent()); + + // Decide on multiline or not. + // Rule: if opening brace is preceded by a line break, then go multiline. + boolean sameLine = bracePair.getKey().getLineRegions().get(0) + .contains(bracePair.getKey().getNextSemanticRegion().getLineRegions().get(0)); + // OLD: val sameLine = bracePair.key.lineRegions.head.contains( bracePair.value ); + + if (!sameLine) { + // format WS in front of closing brace + document.prepend(bracePair.getValue(), hrf -> hrf.newLine()); + for (PropertyAssignment it : ol.getPropertyAssignments()) { + document.prepend(it, hrf -> hrf.newLine()); + } + + if ((bracePair.getKey().getNextSemanticRegion()) == bracePair.getValue()) { + // empty multiline, trigger formatting: + document.append(bracePair.getKey(), hrf -> hrf.newLine()); + } + + } else { // in one line + document.append(bracePair.getKey(), hrf -> hrf.setNewLines(1)); + for (int num = 0; num < ol.getPropertyAssignments().size(); num++) { + PropertyAssignment it = ol.getPropertyAssignments().get(num); + + final int numF = num; + document.prepend(it, hrf -> { + hrf.setNewLines(1); + if (numF != 0) { + hrf.autowrap(); + hrf.oneSpace(); + } else { + hrf.noSpace(); + } + }); + } + // low priority to avoid conflict with dangling commas + document.prepend(bracePair.getValue(), hrf -> { + hrf.setNewLines(1); + hrf.noSpace(); + hrf.lowPriority(); + }); + } + + for (EObject eo : ol.eContents()) { + format(eo, document); + } + } + + void _format(ForStatement fst, IFormattableDocument document) { + + document.append(textRegionExtensions.regionFor(fst).keyword("for"), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(1); + hrf.autowrap(); + }); + + Pair parenPair = textRegionExtensions.regionFor(fst).keywordPairs("(", + ")").get(0); + document.append(parenPair.getKey(), hrf -> { + hrf.noSpace(); + hrf.autowrap(); + hrf.setNewLines(1); + }); + document.append(document.prepend(parenPair.getValue(), hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + }), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(1); + hrf.autowrap(); + }); + + for (ISemanticRegion it : textRegionExtensions.regionFor(fst).keywords("in", "of")) { + document.surround(it, hrf -> { + hrf.oneSpace(); + hrf.setNewLines(1); + hrf.autowrap(); + }); + } + + for (ISemanticRegion it : textRegionExtensions.regionFor(fst).keywords(";")) { + document.append(document.prepend(it, hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + }), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(1); + hrf.autowrap(); + }); + } + + for (EObject eo : fst.eContents()) { + format(eo, document); + } + } + + void _format(TemplateLiteral tl, IFormattableDocument document) { + interiorBUGFIX(tl, hrf -> hrf.indent(), document); // tl.interior[indent;]; + for (Expression it : tl.getSegments()) { + if (it instanceof TemplateSegment) { + noOp(); + } else { + document.surround(it, hrf -> { + hrf.oneSpace(); + hrf.autowrap(); + }); + } + document.format(it); + } + } + + private void noOp() { + // empty + } + + @SuppressWarnings("unused") + void _format(TemplateSegment tl, IFormattableDocument document) { + // just leave as is. + } + + void _format(N4TypeVariable tv, IFormattableDocument document) { + // "out" + if (tv.isDeclaredCovariant()) { + document.append(textRegionExtensions.regionFor(tv) + .feature(N4JSPackage.Literals.N4_TYPE_VARIABLE__DECLARED_COVARIANT), hrf -> hrf.oneSpace()); + } + // "in" + if (tv.isDeclaredContravariant()) { + document.append(textRegionExtensions.regionFor(tv) + .feature(N4JSPackage.Literals.N4_TYPE_VARIABLE__DECLARED_CONTRAVARIANT), hrf -> hrf.oneSpace()); + } + + TypeReferenceNode upperBoundNode = tv.getDeclaredUpperBoundNode(); + + if (upperBoundNode != null) { + // "extends" + document.surround(textRegionExtensions.regionFor(tv).keyword("extends"), hrf -> hrf.oneSpace()); + document.surround(textRegionExtensions.immediatelyFollowing(upperBoundNode).keyword("&"), + hrf -> hrf.oneSpace()); + format(upperBoundNode, document); + } + + } + + @SuppressWarnings("unused") + void _format(Expression exp, IFormattableDocument document) { + // Things not to format: + if (exp instanceof BooleanLiteral + || exp instanceof IdentifierRef + || exp instanceof IntLiteral + || exp instanceof NullLiteral + || exp instanceof NumberLiteral + || exp instanceof RegularExpressionLiteral + || exp instanceof StringLiteral + || exp instanceof ThisLiteral + || exp instanceof SuperLiteral + || exp instanceof JSXElement) { + return; + } + + throw new UnsupportedOperationException( + "expression " + exp.getClass().getSimpleName() + " not yet implemented."); + } + + /** simply formats all content */ + void genericFormat(Expression exp, IFormattableDocument document) { + for (EObject eo : exp.eContents()) { + format(eo, document); + } + } + + void _format(AssignmentExpression ass, IFormattableDocument document) { + document.append(ass.getLhs(), hrf -> hrf.oneSpace()); + document.prepend(ass.getRhs(), hrf -> hrf.oneSpace()); + document.format(ass.getLhs()); + document.format(ass.getRhs()); + } + + void _format(ExpressionStatement eStmt, IFormattableDocument document) { + format(eStmt.getExpression(), document); + } + + /** var,let,const */ + void _format(VariableStatement vStmt, IFormattableDocument document) { + + configureModifiers(vStmt, document); + + // "let", "var" or "const" + document.append(textRegionExtensions.regionFor(vStmt) + .feature(N4JSPackage.Literals.VARIABLE_DECLARATION_CONTAINER__VAR_STMT_KEYWORD), hrf -> hrf.oneSpace()); + + configureCommas(vStmt, document); + + interiorBUGFIX(vStmt, hrf -> hrf.indent(), document); // vStmt.interior, hrf->hrf.indent(); + int lastIdx = vStmt.getVarDeclsOrBindings().size() - 1; + + for (int i = 0; i < vStmt.getVarDeclsOrBindings().size(); i++) { + VariableDeclarationOrBinding e = vStmt.getVarDeclsOrBindings().get(i); + document.format(e); + + if (i > 0) { // assignments start in separate lines. + if (e instanceof VariableDeclaration) { + if (e.getExpression() != null) { + document.prepend(e, hrf -> hrf.newLine()); + } else { + document.prepend(e, hrf -> { + hrf.setNewLines(0, 1, 1); + hrf.lowPriority(); + }); + } + } else if (e instanceof VariableBinding) { + if (e.getExpression() != null) { + document.prepend(e, hrf -> hrf.newLine()); + } else { + document.prepend(e, hrf -> { + hrf.setNewLines(0, 1, 1); + hrf.lowPriority(); + }); + } + } + } + + if (i < lastIdx) { + // assignments start let following continue in separate lines. + if (e instanceof VariableDeclaration) { + if (e.getExpression() != null) { + document.append(textRegionExtensions.immediatelyFollowing(e).keyword(","), + hrf -> hrf.newLine()); + } else { + document.prepend(e, hrf -> { + hrf.setNewLines(0, 1, 1); + hrf.lowPriority(); + }); + } + + } else if (e instanceof VariableBinding) { + if (e.getExpression() != null) { + document.append(textRegionExtensions.immediatelyFollowing(e).keyword(","), + hrf -> hrf.newLine()); + } else { + document.prepend(e, hrf -> { + hrf.setNewLines(0, 1, 1); + hrf.lowPriority(); + }); + } + } + } + } + } + + void _format(VariableDeclaration vDecl, IFormattableDocument document) { + document.set(textRegionExtensions.previousHiddenRegion(vDecl), hrf -> hrf.oneSpace()); + document.surround(textRegionExtensions.regionFor(vDecl).keyword("="), hrf -> hrf.oneSpace()); + document.format(vDecl.getExpression()); + document.format(vDecl.getDeclaredTypeRefInAST()); + } + + void _format(VariableBinding vBind, IFormattableDocument document) { + document.set(textRegionExtensions.previousHiddenRegion(vBind), hrf -> hrf.oneSpace()); + document.surround(textRegionExtensions.regionFor(vBind).keyword("="), hrf -> hrf.oneSpace()); + document.format(vBind.getPattern()); + document.format(vBind.getExpression()); + document.format(vBind.getPattern()); + } + + void _format(BindingPattern bp, IFormattableDocument document) { + // ObjectBindingPattern + // ArrayBindingPattern + + // '{' or '[' + document.append(head(textRegionExtensions.semanticRegions(bp)), hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + hrf.autowrap(); + }); + document.prepend(last(textRegionExtensions.semanticRegions(bp)), hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + hrf.autowrap(); + }); + configureCommas(bp, document); // doesn't handle elision. + + for (EObject eo : bp.eContents()) { + format(eo, document); + } + } + + void _format(ThrowStatement thrStmt, IFormattableDocument document) { + // No autowrap, otherwise ASI + document.prepend(thrStmt.getExpression(), hrf -> { + hrf.setNewLines(0, 0, 0); + hrf.oneSpace(); + }); + document.format(thrStmt.getExpression()); + + } + + void _format(CatchBlock ctch, IFormattableDocument document) { + document.prepend(ctch, hrf -> { + hrf.setNewLines(0, 0, 0); + hrf.oneSpace(); + }); + document.format(ctch.getCatchVariable()); + document.format(ctch.getBlock()); + + } + + void _format(FinallyBlock finlly, IFormattableDocument document) { + document.set(textRegionExtensions.previousHiddenRegion(finlly), hrf -> { + hrf.setNewLines(1); + hrf.oneSpace(); + }); + document.format(finlly.getBlock()); + } + + /** + * Insert one space in front of first '{' in the direct content of the element. semEObject is a semanticObject, e.g. + * N4EnumDecl, N4Classifier ... + */ + private void insertSpaceInFrontOfCurlyBlockOpener(EObject semEObject, IFormattableDocument document) { + document.prepend(textRegionExtensions.regionFor(semEObject).keyword("{"), hrf -> hrf.oneSpace()); + } + + /** force: " @" and no newLine after '@' */ + private void noSpaceAfterAT(EObject semEObject, IFormattableDocument document) { + document.prepend(document.append(textRegionExtensions.regionFor(semEObject).keyword("@"), hrf -> { + hrf.noSpace(); + hrf.setNewLines(1); + }), hrf -> hrf.oneSpace()); + } + + /** On the direct level of an semantic Object enforce commas to ", " with autoWrap option. */ + private void configureCommas(EObject semEObject, IFormattableDocument document) { + for (ISemanticRegion sr : textRegionExtensions.regionFor(semEObject).keywords(",")) { + document.prepend(sr, hrf -> hrf.noSpace()); + document.append(sr, hrf -> { + hrf.oneSpace(); + hrf.autowrap(); + }); + } + } + + void indentExcludingAnnotations(EObject semObject, IFormattableDocument document) { + // Exclude Annotations from indentation field.interior, hrf->hrf.indent(); + ISemanticRegion begin = findFirst(textRegionExtensions.semanticRegions(semObject), + sr -> !(sr instanceof Annotation)); + ISemanticRegion end = last(textRegionExtensions.semanticRegions(semObject)); + + if (begin != end) { // guard to prevent wrong indentation + document.interior(begin, end, hrf -> hrf.indent()); + } + } + + private void _configureAnnotations(AnnotableN4MemberDeclaration semEObject, IFormattableDocument document) { + configureAnnotations(semEObject.getAnnotationList(), document); + } + + @SuppressWarnings("unused") + private void _configureAnnotations(AnnotablePropertyAssignment semEObject, IFormattableDocument document) { + configureAnnotations(semEObject.getAnnotationList(), document); + } + + private void _configureAnnotations(AnnotableScriptElement semEObject, IFormattableDocument document) { + configureAnnotations(semEObject.getAnnotationList(), document); + } + + private void _configureAnnotations(AnnotableExpression semEObject, IFormattableDocument document) { + configureAnnotations(semEObject.getAnnotationList(), document); + } + + private void _configureAnnotations(AbstractAnnotationList aList, IFormattableDocument document) { + if (aList == null || aList.getAnnotations().isEmpty()) { + return; + } + + // TODO in case of trapped in Annotation like 'export @Final public class A{}' - a reorder would be necessary + // (see format for export) + document.prepend(aList, hrf -> { + hrf.setNewLines(2, 2, 2); + hrf.highPriority(); + }); + + // TODO special annotations like @Internal ? --> together with public, reorder to be in same line? + document.append(aList, hrf -> hrf.newLine()); + + for (int idx = 0; idx < aList.getAnnotations().size(); idx++) { + Annotation it = aList.getAnnotations().get(idx); + configureAnnotation(it, document, true, idx == 0); + } + } + + /** + * + * @param withLineWraps + * true do line-wrapping + * @param isFirstAnnotation + * if this is the first annotation in a sequence ( used with line-wrapping in front of '@') + */ + private void configureAnnotation(Annotation ann, IFormattableDocument document, boolean withLineWraps, + boolean isFirstAnnotation) { + // configure arguments + Pair parens = textRegionExtensions.regionFor(ann).keywordPairs("(", ")") + .get(0); + if (parens != null) { + document.append(document.prepend(parens.getKey(), hrf -> hrf.noSpace()), hrf -> hrf.noSpace()); + document.append(document.prepend(parens.getValue(), hrf -> hrf.noSpace()), hrf -> { + if (withLineWraps) { + hrf.noSpace(); + hrf.setNewLines(1); + } else { + hrf.oneSpace(); + hrf.setNewLines(0); + } + }); + document.interior(parens, hrf -> hrf.indent()); + // line break before "@": + if (withLineWraps && !isFirstAnnotation) { + document.prepend(parens.getKey().getPreviousSemanticRegion().getPreviousSemanticRegion(), + hrf -> hrf.setNewLines(1)); + } + + configureCommas(ann, document); + } + + // Configure @-Syntax + // Special case here: for "@XY" we can either get "@" or "XY" as the first semantic element + ISemanticRegion sr = head(textRegionExtensions.semanticRegions(ann)); + if (sr.getGrammarElement() instanceof Keyword) { + // assume '@' + document.append(sr, hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }); + } else { + // for "@Final" "Final" will be the first semantic region in case of exported classes, + document.prepend(sr, hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }); + } + } + + @SuppressWarnings("unused") + private void _configureAnnotations(Object semEObject, IFormattableDocument document) { + // no annotations to be configured. + } + + @SuppressWarnings("unused") + private void _configureAnnotations(Void x, IFormattableDocument document) { + // no annotations to be configured. + } + + private void configureAnnotationsInLine(FormalParameter fpar, IFormattableDocument document) { + if (fpar.getAnnotations().isEmpty()) { + return; + } + // (@x @y("") bogus a:typ) + Annotation fann = fpar.getAnnotations().get(0); + + configureAnnotation(fann, document, false, true); + document.prepend(fann, hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + hrf.autowrap(); + }); + + for (Annotation ann : tail(fpar.getAnnotations())) { + configureAnnotation(ann, document, false, false); + document.prepend(ann, hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + hrf.autowrap(); + }); + } + + document.append(last(fpar.getAnnotations()), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + hrf.autowrap(); + }); + } + + /** only script-level annotations '@@' */ + private void formatScriptAnnotations(Script script, IFormattableDocument document) { + if (script.getAnnotations().isEmpty()) { + return; + } + + if (textRegionExtensions.previousHiddenRegion(script.getAnnotations().get(0)).containsComment()) { + document.prepend(script.getAnnotations().get(0), hrf -> hrf.noSpace()); + } else { + document.prepend(script.getAnnotations().get(0), hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }); + } + document.append(last(script.getAnnotations()), hrf -> hrf.setNewLines(2, 2, 2)); + + for (int idx = 0; idx < script.getAnnotations().size(); idx++) { + Annotation it = script.getAnnotations().get(idx); + if (idx != 0) { + document.prepend(it, hrf -> { + hrf.setNewLines(1); + hrf.noSpace(); + }); + } + // its an '@@' + ISemanticRegion sr = head(textRegionExtensions.semanticRegions(it)); + document.append(sr, hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }); + } + } + + @Override + public ITextReplacer createCommentReplacer(IComment comment) { + // Overridden to distinguish between JSDOC-style, standard ML, formatter-off ML-comment. + EObject grammarElement = comment.getGrammarElement(); + if (grammarElement instanceof AbstractRule) { + String ruleName = ((AbstractRule) grammarElement).getName(); + if (ruleName.startsWith("ML")) { + String cText = comment.getText(); + if (cText.startsWith("/**") && !cText.startsWith("/***")) { // JSDOC + return new N4MultilineCommentReplacer(comment, '*'); + } else if (cText.startsWith("/*-")) { // Turn-off formatting. + return new OffMultilineCommentReplacer(comment, !isNotFirstInLine(comment)); + } else { // All other + return new FixedMultilineCommentReplacer(comment); + } + } + if (ruleName.startsWith("SL")) { + if (isNotFirstInLine(comment)) { + return new SinglelineDocCommentReplacer(comment, "//"); + } else { + return new SinglelineCodeCommentReplacer(comment, "//"); + } + } + } + + // fall back to super-impl. + return super.createCommentReplacer(comment); + } + + private static boolean isNotFirstInLine(IComment comment) { + ILineRegion lineRegion = comment.getLineRegions().get(0); + + return !comment.contains(lineRegion.getOffset()); + } + + @Override + public IndentHandlingTextReplaceMerger createTextReplacerMerger() { + return new IndentHandlingTextReplaceMerger(this); + } + + /** DEBUG-helper */ + private static String containmentStructure(EObject eo) { + String name = eo.getClass().getSimpleName(); + if (eo.eContainer() != null) { + return containmentStructure(eo.eContainer()) + "." + eo.eContainingFeature().getName() + "->" + name; + } + return name; + } + + /** HELPER to avoid Warnings in code, since @SuppressWarnings("unused") is not active in xtend code. */ + @SuppressWarnings("unused") + int suppressUnusedWarnings(Object... e) { + return PRIO_4; + } + + /** + * Simple tracker that only gives exactly one time the value {@code true} when calling + * {@link StateTrack#shouldDoThenDone()} + */ + private final static class StateTrack { + private boolean done = false; + + /** + * This method returns {@code true} exactly on it's first invocation. Proceeding calls always return + * {@code false}. + * + * @return Returns {@code true} if not done, immediately switches {@link #done} to {@code true}; returns + * {@code false} if already done. + */ + boolean shouldDoThenDone() { + boolean ret = !done; + done = true; + return ret; + } + } + + /**************************************************************************************************************** + * + * Type Expression + * + ***************************************************************************************************************/ + void _format(UnionTypeExpression ute, IFormattableDocument document) { + for (ISemanticRegion sr : textRegionExtensions.regionFor(ute).keywords("|")) { + document.prepend(document.surround(sr, hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + }), hrf -> { + hrf.autowrap(); + hrf.highPriority(); + }); + } + + for (TypeRef tr : ute.getTypeRefs()) { + format(tr, document); + } + + // OLD syntax: + ISemanticRegion kwUnion = textRegionExtensions.regionFor(ute).keyword("union"); + if (kwUnion != null) { + ISequentialRegion sr = document.append(document.prepend(kwUnion, hrf -> hrf.oneSpace()), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + }); + + /* '{' */ + document.append(sr.getNextSemanticRegion(), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + }); + /* '}' */ + document.prepend(last(textRegionExtensions.semanticRegions(ute)), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + }); + } + } + + void _format(IntersectionTypeExpression ite, IFormattableDocument document) { + for (ISemanticRegion sr : textRegionExtensions.regionFor(ite).keywords("&")) { + document.prepend(document.surround(sr, hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + }), hrf -> { + hrf.autowrap(); + hrf.highPriority(); + }); + } + + for (TypeRef tr : ite.getTypeRefs()) { + format(tr, document); + } + // OLD syntax + ISemanticRegion kwInersection = textRegionExtensions.regionFor(ite).keyword("intersection"); + if (kwInersection != null) { + ISequentialRegion sr = document.append(document.prepend(kwInersection, hrf -> hrf.oneSpace()), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + }); + /* '{' */ + document.append(sr.getNextSemanticRegion(), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + }); + /* '}' */ + document.prepend(last(textRegionExtensions.semanticRegions(ite)), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + }); + } + } + + void _format(TStructMember tsm, IFormattableDocument document) { + if (tsm instanceof TField) { + configureOptionality((TField) tsm, document); + } else if (tsm instanceof org.eclipse.n4js.ts.types.FieldAccessor) { + configureGetSetKeyword((org.eclipse.n4js.ts.types.FieldAccessor) tsm, document); + configureOptionality((org.eclipse.n4js.ts.types.FieldAccessor) tsm, document); + + Pair parenPair = textRegionExtensions.regionFor(tsm) + .keywordPairs("(", ")").get(0); + document.append(document.prepend(parenPair.getKey(), hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }), hrf -> hrf.noSpace()); + } + // get, set, method, field + + for (EObject eo : tsm.eContents()) { + format(eo, document); + } + // TODO format TStruct* more thoroughly + // (note: added some TStructMember formatting while working on IDE-2405, but it is still incomplete!) + } + + private void configureUndefModifier(StaticBaseTypeRef sbtr, IFormattableDocument document) { + // UndefModifier "?" + document.prepend(textRegionExtensions.regionFor(sbtr) + .feature(TypeRefsPackage.Literals.TYPE_REF__FOLLOWED_BY_QUESTION_MARK), hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }); + } + + void _format(ThisTypeRef ttr, IFormattableDocument document) { + configureUndefModifier(ttr, document); + if (ttr instanceof ThisTypeRefStructural) { + interiorBUGFIX(ttr, hrf -> hrf.indent(), document); + configureStructuralAdditions(ttr, document); + for (EObject eo : ttr.eContents()) { + format(eo, document); + } + } + } + + void _format(ParameterizedTypeRef ptr, IFormattableDocument document) { + interiorBUGFIX(ptr, hrf -> hrf.indent(), document); // ptr.interior, hrf->hrf.indent(); + configureUndefModifier(ptr, document); + + // Union / Intersection + for (ISemanticRegion sr : textRegionExtensions.regionFor(ptr).keywords("&", "|")) { + document.append(document.surround(sr, hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + }), hrf -> { + hrf.autowrap(); + hrf.highPriority(); + }); + } + // Short-Hand Syntax for Arrays + if (ptr.isArrayTypeExpression()) { + document.append(textRegionExtensions.regionFor(ptr).keyword("["), hrf -> hrf.noSpace()); + document.append(textRegionExtensions.regionFor(ptr).keyword("]"), hrf -> hrf.noSpace()); + } + // Short-Hand Syntax for IterableN + if (ptr.isArrayNTypeExpression()) { + document.append(textRegionExtensions.regionFor(ptr).keyword("["), hrf -> hrf.noSpace()); + document.append(textRegionExtensions.regionFor(ptr).keyword("]"), hrf -> hrf.noSpace()); + } + formatTypeArguments(ptr, document); + + // ParameterizedTypeRefStructural : + configureStructuralAdditions(ptr, document); + + // generically format content: + for (EObject eo : ptr.eContents()) { + format(eo, document); + } + } + + /** used for "~X with {}" except for the 'X' part. */ + void configureStructuralAdditions(TypeRef ptr, IFormattableDocument document) { + ISemanticRegion semRegTypingStrategy = textRegionExtensions.regionFor(ptr) + .ruleCallTo(grammarAccess.getTypingStrategyUseSiteOperatorRule()); + if (semRegTypingStrategy != null) { + document.append(document.prepend(semRegTypingStrategy, hrf -> hrf.oneSpace()), hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }); + + // declaredType + document.append(semRegTypingStrategy.getNextSemanticRegion(), null); + ISemanticRegion kwWith = textRegionExtensions.regionFor(ptr).keyword("with"); + + if (kwWith != null) { + document.surround(kwWith, hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + hrf.autowrap(); + }); + + Pair bracesPair = textRegionExtensions.regionFor(ptr) + .keywordPairs("{", "}").get(0); + + document.append(bracesPair.getKey(), hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + hrf.autowrap(); + }); + + document.prepend(bracesPair.getValue(), hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + hrf.autowrap(); + }); + + // textRegionExtensions.regionFor(ptr).keywords(",",";").forEach[ + // prepend[hrf.noSpace();hrf.setNewLines(1);].append[hrf.oneSpace();hrf.setNewLines(1); hrf.autowrap(); + // } ] + for (ISemanticRegion sr : textRegionExtensions.regionFor(ptr).keywords(";")) { + document.append(document.prepend(sr, hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + hrf.autowrap(); + hrf.lowPriority(); + }); + } + + for (TStructMember sm : tail((((StructuralTypeRef) ptr).getAstStructuralMembers()))) { + document.set(textRegionExtensions.regionForEObject(sm).getPreviousHiddenRegion(), hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + hrf.autowrap(); + }); + } + } + } + } + + /** formats type argument section including outside border. */ + void formatTypeArguments(ParameterizedTypeRef semObject, IFormattableDocument document) { + if (semObject.getDeclaredTypeArgs().isEmpty()) { + return; + } + // to "<": + document.prepend(document.append(textRegionExtensions.regionFor(semObject).keyword("<"), + hrf -> hrf.noSpace()), + hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + hrf.lowPriority(); + }); + document.append(document.prepend(textRegionExtensions.regionFor(semObject).keyword(">"), + hrf -> hrf.noSpace()), + hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + hrf.lowPriority(); + }); + for (TypeArgument typeArg : semObject.getDeclaredTypeArgs()) { + document.append(textRegionExtensions.immediatelyFollowing(document.append(typeArg, hrf -> hrf.noSpace())) + .keyword(","), hrf -> hrf.oneSpace()); + format(typeArg, document); + } + + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Configure Methods + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + private void configureGetSetKeyword(FieldAccessor fieldAccessor, IFormattableDocument document) { + String kw = (fieldAccessor instanceof GetterDeclaration) ? "get" : "set"; + + document.append(document.prepend(textRegionExtensions.regionFor(fieldAccessor).keyword(kw), + hrf -> hrf.oneSpace()), + hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + hrf.autowrap(); + }); + } + + private void configureGetSetKeyword(org.eclipse.n4js.ts.types.FieldAccessor tFieldAccessor, + IFormattableDocument document) { + + String kw = (tFieldAccessor instanceof TGetter) ? "get" : "set"; + document.append(document.prepend(textRegionExtensions.regionFor(tFieldAccessor).keyword(kw), + hrf -> hrf.oneSpace()), + hrf -> { + hrf.oneSpace(); + hrf.setNewLines(0); + hrf.autowrap(); + }); + } + + private void configureOptionality(N4FieldDeclaration fieldDecl, IFormattableDocument document) { + document.prepend( + textRegionExtensions.regionFor(fieldDecl) + .feature(N4JSPackage.Literals.N4_FIELD_DECLARATION__DECLARED_OPTIONAL), + hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }); + } + + private void configureOptionality(FieldAccessor fieldAccessor, IFormattableDocument document) { + document.prepend( + textRegionExtensions.regionFor(fieldAccessor) + .feature(N4JSPackage.Literals.FIELD_ACCESSOR__DECLARED_OPTIONAL), + hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }); + } + + private void configureOptionality(TField tField, IFormattableDocument document) { + document.prepend( + textRegionExtensions.regionFor(tField).feature(TypesPackage.Literals.TFIELD__OPTIONAL), + hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }); + } + + private void configureOptionality(org.eclipse.n4js.ts.types.FieldAccessor tFieldAccessor, + IFormattableDocument document) { + document.prepend( + textRegionExtensions.regionFor(tFieldAccessor).feature(TypesPackage.Literals.FIELD_ACCESSOR__OPTIONAL), + hrf -> { + hrf.noSpace(); + hrf.setNewLines(0); + }); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Bug-workarounds + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Temporarily used method to replace document.interior(EObject, Procedure1) to prevent wrong indentations. + * + * Main pattern replace document-extension method call: + * + *
+	 * object.interior, hrf->hrf.indent()
+	 * 
+ * + * by + * + *
+	 * object.interiorBUGFIX(, hrf->hrf.indent(),document);
+	 *
+	 * 
+	 *
+	 */
+	void interiorBUGFIX(EObject object, Procedure1 init,
+			IFormattableDocument document) {
+
+		IEObjectRegion objRegion = getTextRegionAccess().regionForEObject(object);
+		if (objRegion != null) {
+			IHiddenRegion previous = objRegion.getPreviousHiddenRegion();
+			IHiddenRegion next = objRegion.getNextHiddenRegion();
+			if (previous != null && next != null && previous != next) {
+				ISemanticRegion nsr = previous.getNextSemanticRegion();
+				ISemanticRegion psr = next.getPreviousSemanticRegion();
+				if (nsr != psr) { // standard
+									// case
+					document.interior(nsr, psr, init);
+				} else {
+					// former error-case:
+					// there is no interior --> don't do anything!
+					//
+					// applying to the next HiddenRegion is a bad idea,
+					// since it could wrongly indent a multiline-comment (c.f. GHOLD-260)
+				}
+			}
+		}
+	}
+
+	/**
+	 * Dummy method to prevent accidentally calling interior - extension method form document. You should call
+	 * interiorBUGFIX instead !
+	 */
+	@SuppressWarnings("unused")
+	Procedure1 interior(EObject eo, Procedure1 init) {
+		throw new IllegalStateException("Method should not be called.");
+	}
+
+}
diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatter.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatter.xtend
deleted file mode 100644
index 9ca9a39a56..0000000000
--- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatter.xtend
+++ /dev/null
@@ -1,1441 +0,0 @@
-/**
- * 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.formatting2;
-
-import com.google.inject.Inject
-import org.eclipse.emf.common.util.EList
-import org.eclipse.emf.ecore.EObject
-import org.eclipse.n4js.n4JS.AbstractAnnotationList
-import org.eclipse.n4js.n4JS.AbstractCaseClause
-import org.eclipse.n4js.n4JS.AdditiveExpression
-import org.eclipse.n4js.n4JS.AnnotableExpression
-import org.eclipse.n4js.n4JS.AnnotableN4MemberDeclaration
-import org.eclipse.n4js.n4JS.AnnotablePropertyAssignment
-import org.eclipse.n4js.n4JS.AnnotableScriptElement
-import org.eclipse.n4js.n4JS.Annotation
-import org.eclipse.n4js.n4JS.ArrayLiteral
-import org.eclipse.n4js.n4JS.ArrowFunction
-import org.eclipse.n4js.n4JS.AssignmentExpression
-import org.eclipse.n4js.n4JS.AwaitExpression
-import org.eclipse.n4js.n4JS.BinaryBitwiseExpression
-import org.eclipse.n4js.n4JS.BinaryLogicalExpression
-import org.eclipse.n4js.n4JS.BindingPattern
-import org.eclipse.n4js.n4JS.Block
-import org.eclipse.n4js.n4JS.BooleanLiteral
-import org.eclipse.n4js.n4JS.CastExpression
-import org.eclipse.n4js.n4JS.CatchBlock
-import org.eclipse.n4js.n4JS.CommaExpression
-import org.eclipse.n4js.n4JS.ConditionalExpression
-import org.eclipse.n4js.n4JS.EqualityExpression
-import org.eclipse.n4js.n4JS.ExportDeclaration
-import org.eclipse.n4js.n4JS.Expression
-import org.eclipse.n4js.n4JS.ExpressionStatement
-import org.eclipse.n4js.n4JS.FieldAccessor
-import org.eclipse.n4js.n4JS.FinallyBlock
-import org.eclipse.n4js.n4JS.ForStatement
-import org.eclipse.n4js.n4JS.FormalParameter
-import org.eclipse.n4js.n4JS.FunctionDeclaration
-import org.eclipse.n4js.n4JS.FunctionDefinition
-import org.eclipse.n4js.n4JS.FunctionExpression
-import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor
-import org.eclipse.n4js.n4JS.GenericDeclaration
-import org.eclipse.n4js.n4JS.GetterDeclaration
-import org.eclipse.n4js.n4JS.IdentifierRef
-import org.eclipse.n4js.n4JS.IfStatement
-import org.eclipse.n4js.n4JS.ImportDeclaration
-import org.eclipse.n4js.n4JS.IndexedAccessExpression
-import org.eclipse.n4js.n4JS.IntLiteral
-import org.eclipse.n4js.n4JS.JSXElement
-import org.eclipse.n4js.n4JS.MultiplicativeExpression
-import org.eclipse.n4js.n4JS.N4ClassDeclaration
-import org.eclipse.n4js.n4JS.N4EnumDeclaration
-import org.eclipse.n4js.n4JS.N4FieldDeclaration
-import org.eclipse.n4js.n4JS.N4InterfaceDeclaration
-import org.eclipse.n4js.n4JS.N4JSPackage
-import org.eclipse.n4js.n4JS.N4SetterDeclaration
-import org.eclipse.n4js.n4JS.N4TypeVariable
-import org.eclipse.n4js.n4JS.NamedImportSpecifier
-import org.eclipse.n4js.n4JS.NamespaceImportSpecifier
-import org.eclipse.n4js.n4JS.NewExpression
-import org.eclipse.n4js.n4JS.NullLiteral
-import org.eclipse.n4js.n4JS.ObjectLiteral
-import org.eclipse.n4js.n4JS.ParameterizedCallExpression
-import org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression
-import org.eclipse.n4js.n4JS.ParenExpression
-import org.eclipse.n4js.n4JS.PostfixExpression
-import org.eclipse.n4js.n4JS.PromisifyExpression
-import org.eclipse.n4js.n4JS.RegularExpressionLiteral
-import org.eclipse.n4js.n4JS.RelationalExpression
-import org.eclipse.n4js.n4JS.ReturnStatement
-import org.eclipse.n4js.n4JS.Script
-import org.eclipse.n4js.n4JS.ShiftExpression
-import org.eclipse.n4js.n4JS.StringLiteral
-import org.eclipse.n4js.n4JS.SuperLiteral
-import org.eclipse.n4js.n4JS.SwitchStatement
-import org.eclipse.n4js.n4JS.TaggedTemplateString
-import org.eclipse.n4js.n4JS.TemplateLiteral
-import org.eclipse.n4js.n4JS.TemplateSegment
-import org.eclipse.n4js.n4JS.ThisLiteral
-import org.eclipse.n4js.n4JS.ThrowStatement
-import org.eclipse.n4js.n4JS.UnaryExpression
-import org.eclipse.n4js.n4JS.UnaryOperator
-import org.eclipse.n4js.n4JS.VariableBinding
-import org.eclipse.n4js.n4JS.VariableDeclaration
-import org.eclipse.n4js.n4JS.VariableStatement
-import org.eclipse.n4js.n4JS.YieldExpression
-import org.eclipse.n4js.services.N4JSGrammarAccess
-import org.eclipse.n4js.ts.typeRefs.IntersectionTypeExpression
-import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef
-import org.eclipse.n4js.ts.typeRefs.StaticBaseTypeRef
-import org.eclipse.n4js.ts.typeRefs.StructuralTypeRef
-import org.eclipse.n4js.ts.typeRefs.ThisTypeRef
-import org.eclipse.n4js.ts.typeRefs.ThisTypeRefStructural
-import org.eclipse.n4js.ts.typeRefs.TypeRef
-import org.eclipse.n4js.ts.typeRefs.TypeRefsPackage
-import org.eclipse.n4js.ts.typeRefs.UnionTypeExpression
-import org.eclipse.n4js.ts.types.TField
-import org.eclipse.n4js.ts.types.TGetter
-import org.eclipse.n4js.ts.types.TStructMember
-import org.eclipse.n4js.ts.types.TypesPackage
-import org.eclipse.xtext.AbstractRule
-import org.eclipse.xtext.Keyword
-import org.eclipse.xtext.formatting2.IAutowrapFormatter
-import org.eclipse.xtext.formatting2.IFormattableDocument
-import org.eclipse.xtext.formatting2.IHiddenRegionFormatter
-import org.eclipse.xtext.formatting2.IHiddenRegionFormatting
-import org.eclipse.xtext.formatting2.ITextReplacer
-import org.eclipse.xtext.formatting2.internal.SinglelineCodeCommentReplacer
-import org.eclipse.xtext.formatting2.internal.SinglelineDocCommentReplacer
-import org.eclipse.xtext.formatting2.regionaccess.IComment
-import org.eclipse.xtext.formatting2.regionaccess.IEObjectRegion
-import org.eclipse.xtext.formatting2.regionaccess.IHiddenRegion
-import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion
-import org.eclipse.xtext.formatting2.regionaccess.ITextSegment
-import org.eclipse.xtext.xbase.lib.Procedures.Procedure1
-import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.simpleExpressions.NumberLiteral
-
-import static org.eclipse.n4js.formatting2.N4JSFormatterPreferenceKeys.*
-import static org.eclipse.n4js.formatting2.N4JSGenericFormatter.*
-
-class N4JSFormatter extends TypeExpressionsFormatter {
-
-	/** Debug switch */
-	private static var debug = false;
-
-	@Inject extension N4JSGrammarAccess
-
-	/** PRIO_4 = -7 - still very low.
-	 * Standard priorities in the formatter are:
-	 * 
    - *
  • lowPriority = -1; == PRIO_10 - *
  • normal priority = 0; == PRIO_11 - *
  • high priority = +1; == PRIO_12 - *
- */ - static val PRIO_4 = PRIO_3 + 1; - static val PRIO_13 = IHiddenRegionFormatter.HIGH_PRIORITY + 1; - - - private def maxConsecutiveNewLines() { - // let's stick to 2 - getPreference(FORMAT_MAX_CONSECUTIVE_NEWLINES); - } - - - def dispatch void format(Script script, extension IFormattableDocument document) { - - val extension generic = new N4JSGenericFormatter(_n4JSGrammarAccess, textRegionExtensions) - if (getPreference(FORMAT_PARENTHESIS)) { -// script.formatParenthesisBracketsAndBraces(document) - } - - // TODO the following line requires more conflict handling with semicolons: - // script.interior[noIndentation;]; - - script.formatSemicolons(document); - script.formatColon(document); - - formatScriptAnnotations(script,document); - - for (element : script.scriptElements) { - // element.append[setNewLines(1, 1, maxConsecutiveNewLines);noSpace; autowrap].prepend[noSpace]; - element.append[setNewLines(1, 1, maxConsecutiveNewLines); autowrap]; - element.format; - } - - // format last import, overrides default newLines: - script.scriptElements.filter(ImportDeclaration).last?.append[setNewLines(2, 2, 3); highPriority]; - - } - - /** put modifiers into a single line separated by one space, last modifier has one space to following element. */ - def void configureModifiers(EObject semObject, extension IFormattableDocument document){ - semObject.regionFor.ruleCallsTo( n4ModifierRule ).forEach[ - append[oneSpace]; - ]; - } - - def void configureTypingStrategy(EObject semObject, extension IFormattableDocument document) { - semObject.regionFor.ruleCallsTo( typingStrategyDefSiteOperatorRule, typingStrategyUseSiteOperatorRule).forEach[ - append[noSpace]; - ] - } - - def void formatTypeVariables(GenericDeclaration semObject, extension IFormattableDocument document) { - if( semObject.typeVars.isEmpty ) return; - // to "<": - semObject.regionFor.keyword("<").prepend[oneSpace;newLines=0].append[noSpace]; - semObject.regionFor.keyword(">").prepend[noSpace;newLines=0]; - for( typeVar: semObject.typeVars ){ - typeVar.append[noSpace].immediatelyFollowing.keyword(",").append[oneSpace]; - typeVar.format(document); - } - - } - - def dispatch format(N4ClassDeclaration clazz, extension IFormattableDocument document) { - - clazz.configureAnnotations(document); - clazz.insertSpaceInFrontOfCurlyBlockOpener(document); - clazz.indentExcludingAnnotations(document); - - - clazz.configureTypingStrategy(document); - clazz.configureModifiers(document); - - clazz.formatTypeVariables(document); - -// val semRegModifier = clazz.regionFor.feature( N4JSPackage.Literals.MODIFIABLE_ELEMENT__DECLARED_MODIFIERS); -// if( semRegModifier !== null ) { // only if exists. -// val beginModifierHR = semRegModifier.previousHiddenRegion; -// val endModifierHR = semRegModifier.nextHiddenRegion; -// // go over all semantic regions in the modifier location. -// var currHR = beginModifierHR.nextHiddenRegion; -// while( currHR != endModifierHR ){ -// currHR.set[oneSpace]; -// currHR = currHR.nextHiddenRegion; -// } -// endModifierHR.set[oneSpace]; -// } // end modifier formatting TODO extract into method. - - // TODO revise the following pattern of call-back implementations. - // Define lambda for callback & normal use: - val twolinesBeforeFirstMember = [int prio | clazz.ownedMembersRaw.head.prepend[newLines=2;priority = prio]]; - - // Defines CallBack for autoWrap: - val callBackOnAutoWrap = new IAutowrapFormatter{ // callback for auto-wrapping with implements - var didReconfigure = false; // track to only execute once. - override format(ITextSegment region, IHiddenRegionFormatting wrapped, IFormattableDocument document) { - if( !didReconfigure ) { - twolinesBeforeFirstMember.apply(IHiddenRegionFormatter.HIGH_PRIORITY); // reformat with higher priority - didReconfigure=true; // keep state. - } - } - }; - - // 2nd version of implementing the callback: - val StateTrack state2 = new StateTrack; - val IAutowrapFormatter callBackOnAutoWrap2 = [region, hrFormatting, document2 | - if( state2.shouldDoThenDone ) twolinesBeforeFirstMember.apply(IHiddenRegionFormatter.HIGH_PRIORITY); - ]; - suppressUnusedWarnings( callBackOnAutoWrap2 ); - - // Allow for lineBreaks in front of keywords: - clazz.regionFor.keyword("extends").prepend[ - setNewLines(0,0,1); // allow line break in front. - autowrap; - ].append[oneSpace; autowrap;]; - - clazz.regionFor.keyword("implements").prepend[ - setNewLines(0,0,1); - autowrap; - priority = IHiddenRegionFormatter.LOW_PRIORITY; - onAutowrap=callBackOnAutoWrap; - ].append[oneSpace; autowrap;]; - - clazz.implementedInterfaceRefs.tail.forEach[prepend[ - autowrap; - priority = IHiddenRegionFormatter.LOW_PRIORITY; - onAutowrap=callBackOnAutoWrap; - ]]; - - // special case if the header of the class spans multiple lines, then insert extra line break. - val kwClass = clazz.regionFor.keyword("class"); - val kwBrace = clazz.regionFor.keyword("{"); // autowrap-listener ? - if( ! kwClass.lineRegions.head.contains( kwBrace ) ) { - twolinesBeforeFirstMember.apply(IHiddenRegionFormatter.NORMAL_PRIORITY); - } else { - clazz.ownedMembersRaw.head.prepend[setNewLines(1,1,maxConsecutiveNewLines);autowrap;]; - } - - kwClass.append[oneSpace]; - - for (member : clazz.ownedMembersRaw) { - member.append[setNewLines(1, 1, maxConsecutiveNewLines)] - member.format - } - - // Collapse empty block: - if( clazz.ownedMembersRaw.isEmpty) { - // Empty body: - kwBrace.append[noSpace;newLines=0]; - } - } - - def dispatch format(N4InterfaceDeclaration interf, extension IFormattableDocument document) { - interf.configureAnnotations(document); - interf.configureModifiers(document); - interf.insertSpaceInFrontOfCurlyBlockOpener(document); - interf.indentExcludingAnnotations(document);// .interiorBUGFIX([indent],document); //interf.interior[indent]; - - interf.ownedMembersRaw.head.prepend[setNewLines(1, 1, maxConsecutiveNewLines)] - for (member : interf.ownedMembersRaw) { - member.append[setNewLines(1, 1, maxConsecutiveNewLines)] - member.format - } - } - -// def dispatch void format(N4MemberDeclaration member, extension IFormattableDocument document) { -// member.regionFor.keyword("(").prepend[noSpace; newLines=0].append[noSpace] -// -// member.insertSpaceInfrontOfPropertyNames(document); -// for (c : member.eContents) { -// c.format; -// } -// } - - def dispatch void format(N4FieldDeclaration field, extension IFormattableDocument document) { - field.configureAnnotations(document); - field.configureModifiers(document); - - field.indentExcludingAnnotations(document); - - field.configureOptionality(document); - field.regionFor.keyword("=").prepend[oneSpace].append[oneSpace]; - field.expression.format; - field.declaredTypeRefInAST.format; - } - - - - -// def dispatch format(N4MethodDeclaration method, extension IFormattableDocument document) { -// method.configureAnnotations(document); -// method.insertSpaceInfrontOfPropertyNames(document); -// -// method.regionFor.keyword("(").prepend[noSpace; newLines=0] -// -// method.body.regionFor.keyword("{").prepend[oneSpace; newLines = 0] -// for (child : method.eContents) { -// child.format; -// } -// } -// - def dispatch void format(FunctionExpression funE, extension IFormattableDocument document) { - funE.configureAnnotations(document); - funE.configureModifiers(document); - if (funE.isArrowFunction) { - throw new IllegalStateException("Arrow functions should be formated differently.") - } - funE.fpars.configureFormalParameters(document,[/*n.t.d.*/]); - val parenPair = funE.regionFor.keywordPairs("(",")").head; - parenPair.key.append[noSpace]; - parenPair.value.prepend[noSpace]; - funE.body.format; - } - - - - def dispatch format(FunctionOrFieldAccessor fDecl, extension IFormattableDocument document) { - fDecl.configureAnnotations(document); - fDecl.configureModifiers(document); - - // State-keeper to avoid clashing reconfigurations if multiple auto-wraps get triggered. - val state = new StateTrack; // use state to only trigger one change, even if called multiple times. - - // Callback to introduce an additional line in body-block. - val (ITextSegment , IHiddenRegionFormatting , IFormattableDocument )=>void cbInsertEmptyLineInBody = [ - if(state.shouldDoThenDone){ - fDecl.body?.statements?.head.prepend[ setNewLines(2,2,maxConsecutiveNewLines); highPriority]; - } - ]; - - // Formal parameters - switch( fDecl) { - FunctionDefinition : - fDecl.fpars.configureFormalParameters(document, cbInsertEmptyLineInBody ) - N4SetterDeclaration: - fDecl.fpar.prepend[noSpace].append[noSpace] /* no autowrap for setters: cbInsertEmptyLineInBody */ - } - - // Type Variables - switch( fDecl) { - FunctionDeclaration : - fDecl.formatTypeVariables(document) - } - - // special case for accessors: get / set keywords - if(fDecl instanceof FieldAccessor){ - fDecl.configureGetSetKeyword(document); - fDecl.configureOptionality(document); - } - - - - val parenPair = fDecl.regionFor.keywordPairs("(",")").head; - parenPair.key.prepend[noSpace; newLines = 0].append[noSpace]; - parenPair.interior[indent]; - if( parenPair.isMultiLine && ! (fDecl instanceof FieldAccessor)) { - // it is already a multiline, insert the newLine immediately. - // cbInsertEmptyLineInBody.apply(null,null,null); // TODO re-think, if all will be collapsed this assumption does not hold an - } else { - // single line parameter block - } - parenPair.value.prepend[noSpace] - - for (child : fDecl.eContents) { - child.format; - } - } - - /** to be used by FunctionDefintiions and SetterDeclarations */ - def void configureFormalParameters(EList list, extension IFormattableDocument document, (ITextSegment , IHiddenRegionFormatting , IFormattableDocument )=>void x){ - if( list === null || list.isEmpty ) return; - list.forEach[it,idx| - if(idx !== 0) it.prepend[oneSpace;setNewLines(0,0,1);onAutowrap=x]; - it.append[noSpace]; - it.configureAnnotationsInLine(document); // TODO maybe we need some in-line-annotation config here. -// it.regionFor.ruleCallTo( bindingIdentifierAsFormalParameterRule ) // feature(N4JSPackage.Literals.FORMAL_PARAMETER__NAME) -// .prepend[oneSpace;newLines=0].append[] - it.declaredTypeRefInAST.format(document); - if( it.isVariadic ) - it.regionFor.keyword("...").prepend[newLines=0;/*oneSpace;*/].append[newLines=0;noSpace]; - if( it.hasInitializerAssignment ) { - it.regionFor.keyword("=").prepend[newLines=0;noSpace;].append[newLines=0;noSpace]; - if (it.initializer !== null) { - it.initializer.format(document); - } - } - ]; - } - - /** Check if key and value are in different lines. Defined for non-overlapping Regions, e.g. Keyword-pairs.*/ - def static boolean isMultiLine(Pair pair) { - ! pair.key.lineRegions.last.contains( pair.value ) - } - -// def dispatch format(FunctionOrFieldAccessor fofAccessor, extension IFormattableDocument document) { -// val begin = fofAccessor.body.semanticRegions.head -// val end = fofAccessor.body.semanticRegions.last -// if (begin?.lineRegions?.head?.contains(end?.endOffset)) { -// // same line -// } else { -// // body spans multiple lines -// begin.append[newLine;]; -// end.prepend[newLine;]; -// // fofAccessor.body.interior[indent]; // already by parenthesis? -// } -// -// fofAccessor.body?.format; -// -// } - - def dispatch void format(N4EnumDeclaration enumDecl, extension IFormattableDocument document) { - enumDecl.configureAnnotations(document); - enumDecl.configureModifiers(document); - enumDecl.insertSpaceInFrontOfCurlyBlockOpener(document); - enumDecl.indentExcludingAnnotations(document);//.interiorBUGFIX([indent],document); //enumDecl.interior[indent]; - enumDecl.configureCommas(document); - - val braces = enumDecl.regionFor.keywordPairs("{","}").head; - - val multiLine = enumDecl.isMultiline; - - enumDecl.literals.forEach[ - format; - if( multiLine ) { - if( it.regionForEObject.previousHiddenRegion.containsComment ) - { // comment above - it.prepend[newLines=2]; - } else { // no comment above - it.prepend[newLine]; - } - } - ]; - if( multiLine ) { - braces.value.prepend[newLine]; - } - } - - def dispatch void format(ParameterizedPropertyAccessExpression exp, extension IFormattableDocument document) { - val dotKW = exp.regionFor.keyword("."); - dotKW.prepend[noSpace; autowrap; setNewLines(0,0,1)].append[noSpace;]; - if( exp.eContainer instanceof ExpressionStatement) { - // top-level PPA, indent one level. - exp.interiorBUGFIX([indent],document); //exp.interior[indent]; - } - exp.target.format; - } - - def dispatch void format(ParameterizedCallExpression exp, extension IFormattableDocument document) { - // FIXME process typeArgs !!! - val dotKW = exp.regionFor.keyword("."); - dotKW.prepend[noSpace; autowrap;].append[noSpace;] - exp.regionFor.keyword("(").prepend[noSpace].append[noSpace]; - exp.regionFor.keyword(")").prepend[noSpace]; - exp.configureCommas(document); - - exp.arguments.tail.forEach[prepend[oneSpace;autowrap]]; - exp.arguments.forEach[format]; - - if( exp.eContainer instanceof ExpressionStatement) { - // top-level PPA, indent one level. - exp.interiorBUGFIX([indent],document); //exp.interior[indent]; - } - exp.target.format; - } - - - - def dispatch void format(ImportDeclaration decl, extension IFormattableDocument document) { - - // read configuration: - val extraSpace = getPreference(FORMAT_SURROUND_IMPORT_LIST_WITH_SPACE) - - decl.regionFor.keyword("{").prepend[oneSpace].append[if(extraSpace) oneSpace else noSpace]; - decl.regionFor.keyword("}").prepend[if(extraSpace) oneSpace else noSpace].append[oneSpace; newLines = 0]; - decl.regionFor.keyword("from").surround[oneSpace]; - decl.configureCommas(document); - decl.eContents.forEach[format]; - } - - def dispatch void format(NamedImportSpecifier namedImp, extension IFormattableDocument document){ - namedImp.regionFor.keyword("as").prepend[oneSpace].append[oneSpace]; - namedImp.regionFor.feature(N4JSPackage.Literals.IMPORT_SPECIFIER__DECLARED_DYNAMIC).prepend[noSpace].append[oneSpace]; // "+"-KW after alias-name - } - - def dispatch void format(NamespaceImportSpecifier nsImp, extension IFormattableDocument document){ - nsImp.regionFor.keyword("*").append[oneSpace]; - nsImp.regionFor.keyword("as").append[oneSpace]; - nsImp.regionFor.feature(N4JSPackage.Literals.IMPORT_SPECIFIER__DECLARED_DYNAMIC).prepend[noSpace].append[oneSpace]; // "+"-KW after alias-name - } - - def dispatch void format(ExportDeclaration export, extension IFormattableDocument document){ - export.regionFor.keyword("export").append[ - oneSpace; - newLines=0; - // Apply prioritization to catch cases of 'trapped' annotations e.g. "export @Final public class" which - // could also be reordered to "@Final export public class.." - priority=PRIO_13; // Priority higher then highPriority used in AnnotationList. - ]; - - export.eContents.forEach[format]; - - // Fix Trapped annotations: - val exported = export.exportedElement; - if( exported instanceof AnnotableScriptElement ){ - val annoList = exported.annotationList; - if( annoList !== null && !annoList.annotations.isEmpty) { - annoList.annotations.last.append[ - newLines = 0; oneSpace; priority = PRIO_13; - ] - } - } - } - - def dispatch void format(IfStatement stmt, extension IFormattableDocument document) { - val parenPair = stmt.regionFor.keywordPairs("(",")").head; - parenPair.interior[noSpace;indent]; - parenPair.key.prepend[oneSpace]; - parenPair.value.append[oneSpace]; - - stmt.regionFor.keyword("else").prepend[autowrap;oneSpace].append[oneSpace]; - - stmt.elseStmt.prepend[oneSpace; newLines = 0]; - - stmt.expression.format; - stmt.ifStmt.format; - stmt.elseStmt.format; - } - - def dispatch void format(SwitchStatement swStmt, extension IFormattableDocument document) { - swStmt.insertSpaceInFrontOfCurlyBlockOpener(document); - swStmt.interiorBUGFIX([indent],document); //swStmt.interior[indent]; - swStmt.expression.format; - swStmt.cases.head.prepend[newLine]; - swStmt.cases.forEach[format]; - } - - /** Formats DefaultCaseClause + CaseClause */ - def dispatch void format(AbstractCaseClause caseClause, extension IFormattableDocument document) { - caseClause.interiorBUGFIX([indent],document); //caseClause.interior[indent]; - - if (caseClause.statements.size == 1) { - if (caseClause.statements.head instanceof Block) { - caseClause.statements.head.prepend[setNewLines(0,0,0)]; - } else { - caseClause.statements.head.prepend[setNewLines(0,1,1)]; - } - } else { - caseClause.statements.head.prepend[setNewLines(1,1,1)]; - } - - // caseClause.regionFor.keyword(":").prepend[oneSpace]; // In case one space before the colon is desired - caseClause.statements.forEach[format]; - caseClause.statements.forEach[append[setNewLines(1,1,maxConsecutiveNewLines)]]; - caseClause.append[setNewLines(1, 1, maxConsecutiveNewLines)]; - } - - def dispatch void format(CastExpression expr, extension IFormattableDocument document) { - expr.regionFor.keyword("as").prepend[newLines = 0; oneSpace].append[newLines = 0; oneSpace]; - expr.expression.format; - expr.targetTypeRefNode.format; - } - - def dispatch void format(Block block, extension IFormattableDocument document) { - if( debug ) println("Formatting block "+containmentStructure(block)); - - // Beware there are blocks in the grammar, that are not surrounded by curly braces. (e.g. FunctionExpression) - - // Block not nested in other blocks usually are bodies. We want them separated by a space: - if (! (block.eContainer instanceof Block || block.eContainer instanceof Script)) { // TODO maybe invert the control here, since the block is formatting the outside. - block.regionFor.keyword("{").prepend[oneSpace]; - } - - block.interiorBUGFIX([indent],document); //block.interior[indent]; - - block.statements.head.prepend[setNewLines(1,1,maxConsecutiveNewLines)]; - block.statements.forEach[append[setNewLines(1,1,maxConsecutiveNewLines)]]; - - block.statements.forEach[format]; - - // Format empty curly blocks, necessary for comments inside: - val braces = block.regionFor.keywordPairs("{","}").head - if( braces !== null - && braces.key.nextSemanticRegion == braces.value - ) { - // empty block: - if( braces.key.nextHiddenRegion.containsComment ) { - braces.key.append[setNewLines(1,1,maxConsecutiveNewLines)]; - } else { - braces.key.append[newLines=0;noSpace]; - } - } - } - - - def dispatch void format(ReturnStatement ret, extension IFormattableDocument document) { - ret.interiorBUGFIX([indent],document); //ret.interior[indent;] - ret.expression.prepend[oneSpace; newLines = 0]; - ret.expression.format; - } - - def dispatch void format(AdditiveExpression add, extension IFormattableDocument document) { - add.regionFor.feature(N4JSPackage.Literals.ADDITIVE_EXPRESSION__OP).surround[oneSpace].append[autowrap]; - add.lhs.format - add.rhs.format - } - - def dispatch void format(MultiplicativeExpression mul, extension IFormattableDocument document) { - mul.regionFor.feature(N4JSPackage.Literals.MULTIPLICATIVE_EXPRESSION__OP).surround[oneSpace].append[autowrap]; - mul.lhs.format - mul.rhs.format - } - - def dispatch void format(BinaryBitwiseExpression binbit, extension IFormattableDocument document) { - binbit.regionFor.feature(N4JSPackage.Literals.BINARY_BITWISE_EXPRESSION__OP).surround[oneSpace]; - binbit.lhs.format - binbit.rhs.format - } - - def dispatch void format(BinaryLogicalExpression binLog, extension IFormattableDocument document) { - val opReg = binLog.regionFor.feature(N4JSPackage.Literals.BINARY_LOGICAL_EXPRESSION__OP); - opReg.surround[oneSpace]; - binLog.lhs.format - binLog.rhs.format - // auto-wrap: - val autoWrapInFront = getPreference(FORMAT_AUTO_WRAP_IN_FRONT_OF_LOGICAL_OPERATOR); - if( autoWrapInFront ) { - opReg.prepend[autowrap; lowPriority; setNewLines(0,0,1);] - } else { - opReg.append[autowrap; lowPriority; setNewLines(0,0,1);] - }; - } - - def dispatch void format(EqualityExpression eqExpr, extension IFormattableDocument document) { - eqExpr.regionFor.feature(N4JSPackage.Literals.EQUALITY_EXPRESSION__OP).surround[oneSpace].append[autowrap]; - eqExpr.lhs.format - eqExpr.rhs.format - } - - def dispatch void format(RelationalExpression relExpr, extension IFormattableDocument document) { - relExpr.regionFor.feature(N4JSPackage.Literals.RELATIONAL_EXPRESSION__OP).surround[oneSpace].append[autowrap]; - relExpr.lhs.format - relExpr.rhs.format - } - - def dispatch void format(ShiftExpression shiftExpr, extension IFormattableDocument document) { - shiftExpr.regionFor.feature(N4JSPackage.Literals.SHIFT_EXPRESSION__OP).surround[oneSpace].append[autowrap]; - shiftExpr.lhs.format - shiftExpr.rhs.format - } - - def dispatch void format(CommaExpression comma, extension IFormattableDocument document) { - comma.configureCommas(document); - comma.eContents.forEach[format]; - } - - def dispatch void format(ConditionalExpression cond, extension IFormattableDocument document) { - cond.regionFor.keyword("?").surround[oneSpace].append[autowrap; lowPriority; setNewLines(0,0,1);]; - cond.regionFor.keyword(":").surround[oneSpace].append[autowrap; lowPriority; setNewLines(0,0,1);]; - cond.expression.format; - cond.trueExpression.format; - cond.falseExpression.format; - } - - def dispatch void format(AwaitExpression await, extension IFormattableDocument document) { - await.regionFor.keyword("await").prepend[oneSpace].append[oneSpace; newLines = 0]; - await.expression.format - } - - def dispatch void format(PromisifyExpression promify, extension IFormattableDocument document) { - promify.noSpaceAfterAT(document); - promify.regionFor.keyword("Promisify").append[oneSpace]; - promify.expression.format - } - - def dispatch void format(IndexedAccessExpression idxAcc, extension IFormattableDocument document) { - val indexRegion = idxAcc.index.regionForEObject(); - indexRegion.previousSemanticRegion.prepend[noSpace;newLines=0].append[noSpace;newLines = 0]; - indexRegion.nextSemanticRegion.prepend[noSpace]; - - idxAcc.index.format; - idxAcc.target.format; - } - - def dispatch void format(NewExpression newExp, extension IFormattableDocument document) { - newExp.regionFor.keyword("new").prepend[oneSpace].append[oneSpace;newLines=0]; - newExp.callee.format; - // Watch out, commas are used in Type-args and in argument list ! If necessary distinguish by offset. - val commas = newExp.regionFor.keyword(","); - commas.prepend[noSpace].append[oneSpace]; - - // TODO maybe factor out TypeArgs formatting. - val typeArgsAngle = newExp.regionFor.keywordPairs("<",">").head; - if( typeArgsAngle !== null ) { - typeArgsAngle.key.append[noSpace;newLines=0].prepend[noSpace;newLines=0]; - typeArgsAngle.value.prepend[noSpace;newLines=0]; - } - newExp.typeArgs.forEach[format]; - - - if( newExp.isWithArgs ) { - val argParen = newExp.regionFor.keywordPairs("(",")").head; - argParen.key.prepend[newLines=0;noSpace].append[noSpace]; - argParen.value.prepend[noSpace]; - newExp.arguments.forEach[format]; - } - } - - def dispatch void format(PostfixExpression postFix, extension IFormattableDocument document) { - // no line break allowed between Expression and operator ! - postFix.regionFor.feature(N4JSPackage.Literals.POSTFIX_EXPRESSION__OP) - .prepend[newLines=0;noSpace;].append[oneSpace;lowPriority]; // giving low priority for situations of closing parenthesis: "(a++)" - postFix.expression.format; - } - - def dispatch void format(TaggedTemplateString taggedTemplate, extension IFormattableDocument document) { - taggedTemplate.regionFor.feature(N4JSPackage.Literals.EXPRESSION_WITH_TARGET__TARGET).append[ newLines = 0; oneSpace ]; - taggedTemplate.target.format; - taggedTemplate.template.format; - } - - def dispatch void format(UnaryExpression unaryExpr, extension IFormattableDocument document) { - // The operators 'void' 'delete' and 'typeof' must be separated from operand. - val boolean requireSpace=(unaryExpr.op.ordinal <= UnaryOperator.TYPEOF_VALUE); - unaryExpr.regionFor.feature(N4JSPackage.Literals.UNARY_EXPRESSION__OP) - .append[if(requireSpace) oneSpace else noSpace; newLines = 0;]; - unaryExpr.expression.format; - } - - def dispatch void format(YieldExpression yieldExpr, extension IFormattableDocument document) { - // " yield " or " yield* " - yieldExpr.regionFor.keyword("yield") - .prepend[oneSpace;] - .append[if( yieldExpr.isMany ) noSpace else oneSpace]; - if( yieldExpr.isMany ){ - yieldExpr.regionFor.keyword("*").prepend[noSpace;newLines=0].append[oneSpace] - } - yieldExpr.expression.format; - } - - def dispatch void format(ParenExpression parenE, extension IFormattableDocument document) { - parenE.semanticRegions.head.append[noSpace;newLines=0;autowrap]; - parenE.semanticRegions.last.prepend[noSpace;newLines=0;autowrap]; - parenE.interiorBUGFIX([indent],document); //parenE.interior[indent]; - parenE.expression.format; - } - - def dispatch void format(ArrowFunction arrowF, extension IFormattableDocument document) { - arrowF.configureCommas(document); - arrowF.regionFor.ruleCallTo(arrowRule).surround[oneSpace]; - arrowF.regionFor.keywordPairs("(",")").head?.interior[noSpace]; - // too lax: arrowF.fpars.configureFormalParameters(document,[/*NTD*/]); - - if( arrowF.isHasBracesAroundBody ) { - // format body as block. NOTE: this block differs from other blocks, since the curly braces are defined in the ArrowExpression. - // special handling of indentation in inside the braces. - val bracesPair = arrowF.regionFor.keywordPairs("{","}").head; - bracesPair.interior[indent]; - if( bracesPair.key.lineRegions.last.contains( bracesPair.value) // one line '{ do; stuff; }' - || bracesPair.key.lineRegions.last.contains( bracesPair.key.nextSemanticRegion ) // no line-break after braces e.g. '{ do; \n stuff; }' - ) { - // one line - arrowF.body?.statements.forEach[ it,idx| - format; if( idx !==0 ) {it.prepend[oneSpace; autowrap; newLines=0;]} - ]; - bracesPair.key.append[oneSpace]; // do not autowrap after "{" to keep wrap-semantic - bracesPair.value.prepend[oneSpace]; - } else { - // multi-line - if( arrowF.body !== null && !arrowF.body.statements.empty ) { - arrowF.body?.statements.head.prepend[newLines=1;]; - arrowF.body?.statements.forEach[format;append[newLines=1]]; - } else { - // empty block, squash interior. - bracesPair.key.append[noSpace;newLines=1;]; - bracesPair.value.prepend[noSpace;newLines=1]; - } - } - } else { - // no braces Around the implicit return statement. - arrowF.body?.statements.head.format; - } - } - - - def dispatch void format(ArrayLiteral al, extension IFormattableDocument document) { - val bracketPair = al.regionFor.keywordPairs("[","]").head; - bracketPair.interior[indent]; - val sameLine = bracketPair.key.lineRegions.head.contains( bracketPair.value ); - // auto wrap in front of AL-Elements, to preserve comma at end. - if( ! sameLine) { - al.elements.last.append[autowrap]; - al.elements.forEach[it,num|prepend[autowrap;setNewLines(0,0,1);if(num!==0)oneSpace;].append[noSpace]]; - // format last bracket if in single.line. - if( ! bracketPair.value.previousSemanticRegion.lineRegions.last.contains( bracketPair.value ) ) { - bracketPair.value.prepend[newLine]; - } - } else { - al.elements.forEach[it,num|prepend[autowrap;if(num!==0)oneSpace;]]; - } - } - - def dispatch void format(ObjectLiteral ol, extension IFormattableDocument document) { - ol.configureCommas(document); - - val bracePair = ol.regionFor.keywordPairs("{","}").head; - bracePair.interior[indent]; - - - // Decide on multiline or not. - // Rule: if opening brace is preceded by a line break, then go multiline. - val sameLine = bracePair.key.lineRegions.head.contains( bracePair.key.nextSemanticRegion.lineRegions.head ); - // OLD: val sameLine = bracePair.key.lineRegions.head.contains( bracePair.value ); - if( ! sameLine) { - bracePair.value.prepend[newLine]; // format WS in front of closing brace - ol.propertyAssignments.forEach[it,num|prepend[newLine]]; - if( bracePair.key.nextSemanticRegion == bracePair.value ) { - // empty multiline, trigger formatting: - bracePair.key.append[newLine]; - } - } else { // in one line - bracePair.key.append[newLines=0]; - ol.propertyAssignments.forEach[it,num|prepend[newLines=0;if(num!==0) { autowrap; oneSpace; } else {noSpace;}]]; - bracePair.value.prepend[newLines=0; noSpace; lowPriority]; // low priority to avoid conflict with dangling commas - } - - ol.eContents.forEach[format]; - } - - def dispatch void format( ForStatement fst, extension IFormattableDocument document){ - - fst.regionFor.keyword("for").append[oneSpace;newLines=0; autowrap]; - - val parenPair = fst.regionFor.keywordPairs("(",")").head; - parenPair.key.append[noSpace;autowrap;newLines=0]; - parenPair.value.prepend[noSpace;newLines=0].append[oneSpace;newLines=0;autowrap;]; - - fst.regionFor.keywords("in","of").forEach[ it.surround[oneSpace; newLines=0; autowrap] ]; - fst.regionFor.keywords(";").forEach[it.prepend[noSpace;newLines=0;].append[oneSpace;newLines=0;autowrap]]; - - fst.eContents.forEach[format]; - } - - def dispatch void format(TemplateLiteral tl, extension IFormattableDocument document) { - tl.interiorBUGFIX([indent],document); //tl.interior[indent;]; - tl.segments.forEach[ - switch(it) { - TemplateSegment: noOp - default: it.surround[oneSpace; autowrap;] - }; - it.format; - ]; - } - private def noOp (){} - - def dispatch void format(TemplateSegment tl, extension IFormattableDocument document) { - // just leave as is. - } - - def dispatch void format(N4TypeVariable tv, extension IFormattableDocument document) { - // "out" - if( tv.declaredCovariant ) { tv.regionFor.feature(N4JSPackage.Literals.N4_TYPE_VARIABLE__DECLARED_COVARIANT).append[oneSpace]; } - // "in" - if( tv.declaredContravariant ) {tv.regionFor.feature(N4JSPackage.Literals.N4_TYPE_VARIABLE__DECLARED_CONTRAVARIANT).append[oneSpace];} - - val upperBoundNode = tv.declaredUpperBoundNode; - if( upperBoundNode!==null ) { - // "extends" - tv.regionFor.keyword("extends").surround[oneSpace]; - upperBoundNode.immediatelyFollowing.keyword("&").surround[oneSpace]; - upperBoundNode.format(document); - } - - } - - - - def dispatch void format(Expression exp, extension IFormattableDocument document) { - switch(exp) { - // Things not to format: - BooleanLiteral, - IdentifierRef, - IntLiteral, - NullLiteral, - NumberLiteral, - RegularExpressionLiteral, - StringLiteral, - ThisLiteral, - SuperLiteral, - JSXElement - : return - } - throw new UnsupportedOperationException("expression "+exp.class.simpleName+" not yet implemented."); - } - - /** simply formats all content */ - def void genericFormat(Expression exp, extension IFormattableDocument document) { - exp.eContents.forEach[format]; - } - - - def dispatch void format(AssignmentExpression ass, extension IFormattableDocument document) { - ass.lhs.append[oneSpace] - ass.rhs.prepend[oneSpace] - ass.lhs.format; - ass.rhs.format; - } - - def dispatch void format( ExpressionStatement eStmt, extension IFormattableDocument docuemt){ - eStmt.expression.format; - } - - /** var,let,const */ - def dispatch void format(VariableStatement vStmt, extension IFormattableDocument document) { - - vStmt.configureModifiers(document); - - vStmt.regionFor.feature( - N4JSPackage.Literals.VARIABLE_DECLARATION_CONTAINER__VAR_STMT_KEYWORD).append [ - oneSpace; - ]; // "let", "var" or "const" - - vStmt.configureCommas(document); - - vStmt.interiorBUGFIX([indent],document); //vStmt.interior[indent]; - val lastIdx = vStmt.varDeclsOrBindings.size - 1; - - vStmt.varDeclsOrBindings.forEach [ e, int i | - e.format; - if (i > 0) { // assignments start in separate lines. - if (e instanceof VariableDeclaration) { - if (e.expression !== null) e.prepend[newLine] - else e.prepend[setNewLines(0,1,1); lowPriority]; - } else if (e instanceof VariableBinding) { - if (e.expression !== null) e.prepend[newLine] - else e.prepend[setNewLines(0,1,1); lowPriority]; - } - } - if (i < lastIdx) { // assignments start let following continue in separate lines. - if (e instanceof VariableDeclaration) { - if (e.expression !== null) e.immediatelyFollowing.keyword(",").append[newLine] - else e.prepend[setNewLines(0,1,1); lowPriority]; - } else if (e instanceof VariableBinding) { - if (e.expression !== null) e.immediatelyFollowing.keyword(",").append[newLine] - else e.prepend[setNewLines(0,1,1); lowPriority]; - } - - } - ]; - } - - def dispatch void format(VariableDeclaration vDecl, extension IFormattableDocument document) { - vDecl.previousHiddenRegion.set[oneSpace]; - vDecl.regionFor.keyword("=").surround[oneSpace]; - vDecl.expression.format; - vDecl.declaredTypeRefInAST.format; - } - - def dispatch void format(VariableBinding vBind, extension IFormattableDocument document) { - vBind.previousHiddenRegion.set[oneSpace]; - vBind.regionFor.keyword("=").surround[oneSpace]; - vBind.pattern.format; - vBind.expression.format; - vBind.pattern.format; - } - - def dispatch void format( BindingPattern bp, extension IFormattableDocument document) { - // ObjectBindingPattern - // ArrayBindingPattern - - // '{' or '[' - bp.semanticRegions.head.append[noSpace;newLines=0;autowrap]; - bp.semanticRegions.last.prepend[noSpace;newLines=0;autowrap]; - bp.configureCommas(document); // doesn't handle elision. - - bp.eContents.forEach[format]; - } - - - def dispatch void format(ThrowStatement thrStmt, extension IFormattableDocument document) { - thrStmt.expression.prepend[setNewLines(0, 0, 0); oneSpace]; // No autowrap, otherwise ASI - thrStmt.expression.format; - } - - - def dispatch void format(CatchBlock ctch, extension IFormattableDocument document) { - ctch.prepend[setNewLines(0, 0, 0); oneSpace]; - ctch.catchVariable.format; - ctch.block.format; - } - - def dispatch void format(FinallyBlock finlly, extension IFormattableDocument document) { - finlly.previousHiddenRegion.set[newLines = 0; oneSpace]; - finlly.block.format; - } - - /** Insert one space in front of first '{' in the direct content of the element. - * semEObject is a semanticObject, e.g. N4EnumDecl, N4Classifier ...*/ - private def void insertSpaceInFrontOfCurlyBlockOpener(EObject semEObject, extension IFormattableDocument document) { - semEObject.regionFor.keyword("{").prepend[oneSpace]; - } - - /** force: " @" and no newLine after '@' */ - private def void noSpaceAfterAT(EObject semEObject, extension IFormattableDocument document) { - semEObject.regionFor.keyword("@").append[noSpace;newLines=0].prepend[oneSpace]; - } - - /** On the direct level of an semantic Object enforce commas to ", " with autoWrap option. */ - private def void configureCommas(EObject semEObject, extension IFormattableDocument document) { - semEObject.regionFor.keywords(",").forEach [ - prepend[noSpace]; - append[oneSpace; autowrap]; - ]; - } - - def void indentExcludingAnnotations(EObject semObject, extension IFormattableDocument document) { - //Exclude Annotations from indentation field.interior[indent]; - val begin = semObject.semanticRegions.findFirst[!(semanticElement instanceof Annotation)]; - val end = semObject.semanticRegions.last; - if( begin !== end ) { // guard to prevent wrong indentation - interior(begin,end,[indent]); - } - } - - - private def dispatch void configureAnnotations(AnnotableN4MemberDeclaration semEObject, extension IFormattableDocument document) { - configureAnnotations( semEObject.annotationList, document ); - } - - private def dispatch void configureAnnotations(AnnotablePropertyAssignment semEObject, extension IFormattableDocument document) { - configureAnnotations( semEObject.annotationList, document ); - } - - private def dispatch void configureAnnotations(AnnotableScriptElement semEObject, extension IFormattableDocument document) { - configureAnnotations( semEObject.annotationList, document ); - } - - private def dispatch void configureAnnotations(AnnotableExpression semEObject, extension IFormattableDocument document) { - configureAnnotations( semEObject.annotationList, document ); - } - - private def dispatch void configureAnnotations(AbstractAnnotationList aList, extension IFormattableDocument document) { - if( aList === null || aList.annotations.isEmpty ) return; - - aList.prepend[setNewLines(2,2,2);highPriority]; // TODO in case of trapped in Annotation like 'export @Final public class A{}' - a reorder would be necessary (see format for export) - aList.append[newLine]; // TODO special annotations like @Internal ? --> together with public, reorder to be in same line? - aList.annotations.forEach[it, idx | - it.configureAnnotation(document,true,idx ===0); - ]; - } - - /** - * - * @param withLineWraps true do line-wrapping - * @param isFirstenAnnotation if this is the first annotation in a sequence ( used with line-wrapping in front of '@') - */ - private def configureAnnotation(Annotation it, extension IFormattableDocument document, boolean withLineWraps, boolean isFirstAnnotation ){ - // configure arguments - val parens = it.regionFor.keywordPairs("(",")").head; - if( parens !== null ) { - parens=>[ - it.key.prepend[noSpace].append[noSpace]; - it.value.prepend[noSpace].append[if( withLineWraps ) {noSpace; newLines=1;} else {oneSpace; newLines=0;}]; - it.interior[indent]; - // line break before "@": - if( withLineWraps && !isFirstAnnotation ) { - it.key.previousSemanticRegion.previousSemanticRegion.prepend[newLines = 1]; - } - ]; - it.configureCommas(document); - } - - // Configure @-Syntax - // Special case here: for "@XY" we can either get "@" or "XY" as the first semantic element - it.semanticRegions.head =>[ - if( it.grammarElement instanceof Keyword) { - // assume '@' - it.append[ noSpace; newLines=0 ]; - } else { - it.prepend[ // for "@Final" "Final" will be the first semantic region in case of exported classes, - noSpace; newLines=0 - ]; - } - ]; - } - - private def dispatch void configureAnnotations(Object semEObject, extension IFormattableDocument document) { - // no annotations to be configured. - } - - private def dispatch void configureAnnotations(Void x, extension IFormattableDocument document) { - // no annotations to be configured. - } - - private def void configureAnnotationsInLine(FormalParameter fpar, extension IFormattableDocument document) { - if( fpar.annotations.isEmpty ) return; - // (@x @y("") bogus a:typ) - fpar.annotations.head=>[ - it.configureAnnotation(document,false,true); - prepend[noSpace;newLines=0;autowrap;]; - ] - fpar.annotations.tail.forEach[ - configureAnnotation(document,false,false); - prepend[oneSpace;newLines=0;autowrap;]; - ] - fpar.annotations.last.append[oneSpace;newLines=0;autowrap;]; - } - - - /** only script-level annotations '@@' */ - private def void formatScriptAnnotations(Script script, extension IFormattableDocument document) { - if( script.annotations.isEmpty ) return; - - if (script.annotations.head.previousHiddenRegion.containsComment) { - script.annotations.head.prepend[noSpace;]; - } else { - script.annotations.head.prepend[noSpace;newLines=0;]; - } - script.annotations.last.append[setNewLines(2,2,2)]; - - script.annotations.forEach[it,idx| - if( idx !==0 ) it.prepend[newLines=1;noSpace]; - it.semanticRegions.head=>[ // its an '@@' - append[noSpace;newLines=0] - ] - ] - - } - - - - - public override ITextReplacer createCommentReplacer(IComment comment) { - // Overridden to distinguish between JSDOC-style, standard ML, formatter-off ML-comment. - val EObject grammarElement = comment.getGrammarElement(); - if (grammarElement instanceof AbstractRule) { - val String ruleName = (/*(AbstractRule)*/ grammarElement).getName(); - if (ruleName.startsWith("ML")) { - val cText = comment.text; - if (cText.startsWith("/**") && !cText.startsWith("/***")) { // JSDOC - return new N4MultilineCommentReplacer(comment, '*'); - } else if (cText.startsWith("/*-")) { // Turn-off formatting. - return new OffMultilineCommentReplacer(comment, !comment.isNotFirstInLine); - } else { // All other - return new FixedMultilineCommentReplacer(comment); - } - } - if (ruleName.startsWith("SL")) { - if (comment.isNotFirstInLine) { - return new SinglelineDocCommentReplacer(comment, "//"); - } else { - return new SinglelineCodeCommentReplacer(comment, "//"); - } - } - } - - // fall back to super-impl. - super.createCommentReplacer(comment); - } - - private static def boolean isNotFirstInLine(IComment comment) { - val lineRegion = comment.getLineRegions().get(0); - - return !comment.contains( lineRegion.offset ); - } - - - public override createTextReplacerMerger(){ - return new IndentHandlingTextReplaceMerger(this); - } - - /** DEBUG-helper */ - private def static String containmentStructure(EObject eo) { - val name = eo.class.simpleName; - if( eo.eContainer !== null ) - return '''«eo.eContainer.containmentStructure».«eo.eContainingFeature.name»-> «name»''' - return name - } - - /** HELPER to avoid Warnings in code, since @SuppressWarnings("unused") is not active in xtend code.*/ - def suppressUnusedWarnings(Object ... e) - { - PRIO_4; - } - - /** - * Simple tracker that only gives exactly one time the value {@code true} - * when calling {@link StateTrack#shouldDoThenDone()} - */ - private final static class StateTrack { - private boolean done=false; - - /** - * This method returns {@code true} exactly on it's first invocation. Proceeding calls always return {@code false}. - * - * @return Returns {@code true} if not done, immediately switches {@link #done} to {@code true}; - * returns {@code false} if already done. - */ - def boolean shouldDoThenDone(){ - val ret = !done; - done = true; - return ret; - } - } - - - /**************************************************************************************************************** - * - * Type Expression - * - ***************************************************************************************************************/ - def dispatch void format(UnionTypeExpression ute, extension IFormattableDocument document) { - ute.regionFor.keywords("|").forEach[ surround[oneSpace;newLines=0].prepend[autowrap;highPriority] ]; - ute.typeRefs.forEach[format]; - // OLD syntax: - val kwUnion = ute.regionFor.keyword("union"); - if( kwUnion !== null ) { - kwUnion.prepend[oneSpace].append[oneSpace;newLines=0].nextSemanticRegion/*'{'*/.append[oneSpace;newLines=0]; - ute.semanticRegions.last/*'}'*/.prepend[oneSpace;newLines=0]; - } - } - - def dispatch void format(IntersectionTypeExpression ite, extension IFormattableDocument document) { - ite.regionFor.keywords("&").forEach[surround[oneSpace;newLines=0].prepend[autowrap;highPriority]]; - ite.typeRefs.forEach[format]; - // OLD syntax - val kwInersection = ite.regionFor.keyword("intersection"); - if( kwInersection !== null ) { - kwInersection.prepend[oneSpace].append[oneSpace;newLines=0].nextSemanticRegion/*'{'*/.append[oneSpace;newLines=0]; - ite.semanticRegions.last/*'}'*/.prepend[oneSpace;newLines=0]; - } - } - - def dispatch void format( TStructMember tsm, extension IFormattableDocument document) { - if(tsm instanceof TField) { - tsm.configureOptionality(document); - } else if(tsm instanceof org.eclipse.n4js.ts.types.FieldAccessor) { - tsm.configureGetSetKeyword(document); - tsm.configureOptionality(document); - - val parenPair = tsm.regionFor.keywordPairs("(",")").head; - parenPair.key.prepend[noSpace; newLines = 0].append[noSpace]; - } - // get, set, method, field - tsm.eContents.forEach[format;]; - // TODO format TStruct* more thoroughly - // (note: added some TStructMember formatting while working on IDE-2405, but it is still incomplete!) - } - - - - def private void configureUndefModifier( StaticBaseTypeRef sbtr, extension IFormattableDocument document){ - // UndefModifier "?" - sbtr.regionFor.feature(TypeRefsPackage.Literals.TYPE_REF__FOLLOWED_BY_QUESTION_MARK).prepend[noSpace;newLines=0;]; - } - - def dispatch void format( ThisTypeRef ttr, extension IFormattableDocument document) { - ttr.configureUndefModifier(document); - if( ttr instanceof ThisTypeRefStructural) { - ttr.interiorBUGFIX([indent],document) - configureStructuralAdditions(ttr,document); - ttr.eContents.forEach[ - format; - ] - } - } - - def dispatch void format( ParameterizedTypeRef ptr, extension IFormattableDocument document) { - ptr.interiorBUGFIX([indent],document); //ptr.interior[indent]; - ptr.configureUndefModifier(document); - - // Union / Intersection - ptr.regionFor.keywords("&","|").forEach[ surround[oneSpace;newLines=0].append[autowrap;highPriority]]; - // Short-Hand Syntax for Arrays - if( ptr.isArrayTypeExpression ) { - ptr.regionFor.keyword("[").append[noSpace]; - ptr.regionFor.keyword("]").append[noSpace]; - } - // Short-Hand Syntax for IterableN - if( ptr.isArrayNTypeExpression ) { - ptr.regionFor.keyword("[").append[noSpace]; - ptr.regionFor.keyword("]").append[noSpace]; - } - ptr.formatTypeArguments(document); - - // ParameterizedTypeRefStructural : - configureStructuralAdditions(ptr,document); - - // generically format content: - ptr.eContents.forEach[format] - } - - /** used for "~X with {}" except for the 'X' part. */ - def void configureStructuralAdditions( TypeRef ptr, extension IFormattableDocument document) { - val semRegTypingStrategy = ptr.regionFor.ruleCallTo(typingStrategyUseSiteOperatorRule); - if( semRegTypingStrategy!== null) { - semRegTypingStrategy.prepend[oneSpace].append[noSpace;newLines=0;]; - - // declaredType - semRegTypingStrategy.nextSemanticRegion.append[]; - - val kwWith = ptr.regionFor.keyword("with"); - if( kwWith !== null ) { - kwWith.surround[oneSpace;newLines=0;autowrap]; - val bracesPair = ptr.regionFor.keywordPairs("{","}").head; - bracesPair.key.append[noSpace;newLines=0;autowrap]; - bracesPair.value.prepend[noSpace;newLines=0;autowrap]; - //ptr.regionFor.keywords(",",";").forEach[ prepend[noSpace;newLines=0].append[oneSpace;newLines=0;autowrap] ] - ptr.regionFor.keywords(";").forEach[ prepend[noSpace;newLines=0].append[oneSpace;newLines=0;autowrap;lowPriority] ] - ((ptr as StructuralTypeRef).astStructuralMembers.tail - .forEach[ regionForEObject.previousHiddenRegion.set[oneSpace;newLines=0;autowrap]] - ); - } - } - } - - /** formats type argument section including outside border. */ - def void formatTypeArguments(ParameterizedTypeRef semObject, extension IFormattableDocument document) { - if( semObject.declaredTypeArgs.isEmpty ) return; - // to "<": - semObject.regionFor.keyword("<").append[noSpace].prepend[noSpace; newLines=0; lowPriority]; - semObject.regionFor.keyword(">").prepend[noSpace].append[noSpace; newLines=0; lowPriority]; - for( typeArg: semObject.declaredTypeArgs ){ - typeArg.append[noSpace].immediatelyFollowing.keyword(",").append[oneSpace]; - typeArg.format(document); - } - - } - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Configure Methods - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - def private void configureGetSetKeyword(FieldAccessor fieldAccessor, extension IFormattableDocument document) { - val kw = if(fieldAccessor instanceof GetterDeclaration) "get" else "set"; - fieldAccessor.regionFor.keyword(kw).prepend[oneSpace].append[oneSpace; newLines=0; autowrap]; - } - def private void configureGetSetKeyword(org.eclipse.n4js.ts.types.FieldAccessor tFieldAccessor, extension IFormattableDocument document) { - val kw = if(tFieldAccessor instanceof TGetter) "get" else "set"; - tFieldAccessor.regionFor.keyword(kw).prepend[oneSpace].append[oneSpace; newLines=0; autowrap]; - } - - def private void configureOptionality(N4FieldDeclaration fieldDecl, extension IFormattableDocument document) { - fieldDecl.regionFor.feature(N4JSPackage.Literals.N4_FIELD_DECLARATION__DECLARED_OPTIONAL).prepend[noSpace;newLines=0;]; - } - def private void configureOptionality(FieldAccessor fieldAccessor, extension IFormattableDocument document) { - fieldAccessor.regionFor.feature(N4JSPackage.Literals.FIELD_ACCESSOR__DECLARED_OPTIONAL).prepend[noSpace;newLines=0;]; - } - def private void configureOptionality(TField tField, extension IFormattableDocument document) { - tField.regionFor.feature(TypesPackage.Literals.TFIELD__OPTIONAL).prepend[noSpace;newLines=0;]; - } - def private void configureOptionality(org.eclipse.n4js.ts.types.FieldAccessor tFieldAccessor, extension IFormattableDocument document) { - tFieldAccessor.regionFor.feature(TypesPackage.Literals.FIELD_ACCESSOR__OPTIONAL).prepend[noSpace;newLines=0;]; - } - - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Bug-workarounds - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /** Temporarily used method to replace document.interior(EObject, Procedure1) to prevent wrong indentations. - * - * Main pattern replace document-extension method call: - *
-	 * object.interior[indent]
-	 * 
- * by - *
-	 * object.interiorBUGFIX([indent],document);
-	 * 
-	 *
-	 */
-	def void interiorBUGFIX(EObject object, Procedure1 init,IFormattableDocument document ){
-		val IEObjectRegion objRegion = getTextRegionAccess().regionForEObject(object);
-		if (objRegion !== null) {
-			val IHiddenRegion previous = objRegion.getPreviousHiddenRegion();
-			val IHiddenRegion next = objRegion.getNextHiddenRegion();
-			if (previous !== null && next !== null && previous != next) {
-				val nsr = previous.getNextSemanticRegion();
-				val psr = next.getPreviousSemanticRegion();
-				if( nsr != psr )
-				{ // standard case
-					document.interior(nsr, psr , init);
-				} else {
-					// former error-case:
-					// there is no interior --> don't do anything!
-					//
-					// applying to the next HiddenRegion is a bad idea,
-					// since it could wrongly indent a multiline-comment (c.f. GHOLD-260)
-				}
-			}
-		}
-	}
-
-
-	/** Dummy method to prevent accidentally calling interior - extension method form document. You should call interiorBUGFIX instead ! */
-	def Procedure1 interior( EObject eo, Procedure1 init ){
-		throw new IllegalStateException("Method should not be called.")
-	}
-
-}
diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatterPreferenceKeys.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatterPreferenceKeys.java
new file mode 100644
index 0000000000..ac9d39dff7
--- /dev/null
+++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatterPreferenceKeys.java
@@ -0,0 +1,42 @@
+/**
+ * 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.formatting2;
+
+import org.eclipse.xtext.formatting2.FormatterPreferenceKeys;
+import org.eclipse.xtext.preferences.BooleanKey;
+import org.eclipse.xtext.preferences.IntegerKey;
+
+/**
+ *
+ */
+public class N4JSFormatterPreferenceKeys extends FormatterPreferenceKeys {
+	/***/
+	public static BooleanKey FORMAT_PARENTHESIS = new BooleanKey("format.parenthesis", false);
+	/***/
+	public static BooleanKey FORMAT_SURROUND_PAREN_CONTENT_WITH_SPACE = new BooleanKey(
+			"format.surround_paren_content_with_space", false);
+	/***/
+	public static IntegerKey FORMAT_MAX_CONSECUTIVE_NEWLINES = new IntegerKey("format.max_consecutive_newlines", 2);
+	/***/
+	public static BooleanKey FORMAT_SWITCH_CASES_HAVE_SPACE_IN_FRONT_OF_COLON = new BooleanKey(
+			"format.switch_cases_have_space_in_front_of_colon", false);
+	/***/
+	public static BooleanKey FORMAT_AUTO_WRAP_IN_FRONT_OF_LOGICAL_OPERATOR = new BooleanKey(
+			"format.auto_wrap_in_front_of_logical_operator", true);
+	/**
+	 * Considering the code import a, {b,c,d} from "xy"; a value of true will render an
+	 * additional space after "{" and one before the closing bracket "}" Default value is false and the
+	 * line will be rendered as above.
+	 */
+	public static BooleanKey FORMAT_SURROUND_IMPORT_LIST_WITH_SPACE = new BooleanKey(
+			"format.surround_import_list_with_space", false);
+
+}
diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatterPreferenceKeys.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatterPreferenceKeys.xtend
deleted file mode 100644
index c14a9a65f7..0000000000
--- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSFormatterPreferenceKeys.xtend
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * 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.formatting2
-
-import org.eclipse.xtext.formatting2.FormatterPreferenceKeys
-import org.eclipse.xtext.preferences.BooleanKey
-import org.eclipse.xtext.preferences.IntegerKey
-
-/**
- *
- */
-class N4JSFormatterPreferenceKeys extends FormatterPreferenceKeys {
-	public static val BooleanKey FORMAT_PARENTHESIS = new BooleanKey("format.parenthesis", false);
-	public static val BooleanKey FORMAT_SURROUND_PAREN_CONTENT_WITH_SPACE = new BooleanKey("format.surround_paren_content_with_space", false);
-	public static val IntegerKey FORMAT_MAX_CONSECUTIVE_NEWLINES = new IntegerKey("format.max_consecutive_newlines",2);
-	public static val BooleanKey FORMAT_SWITCH_CASES_HAVE_SPACE_IN_FRONT_OF_COLON = new BooleanKey("format.switch_cases_have_space_in_front_of_colon", false);
-	public static val BooleanKey FORMAT_AUTO_WRAP_IN_FRONT_OF_LOGICAL_OPERATOR= new BooleanKey("format.auto_wrap_in_front_of_logical_operator", true);
-	/** Considering the code import a, {b,c,d} from "xy"; a value of true will render an additional space after "{" and one before the closing bracket "}"
-	 * Default value is false and the line will be rendered as above.*/
-	public static val BooleanKey FORMAT_SURROUND_IMPORT_LIST_WITH_SPACE = new BooleanKey("format.surround_import_list_with_space", false);
-
-
-}
diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSGenericFormatter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSGenericFormatter.java
new file mode 100644
index 0000000000..17560c88f9
--- /dev/null
+++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSGenericFormatter.java
@@ -0,0 +1,368 @@
+/**
+ * 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.formatting2;
+
+import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter;
+import static org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst;
+import static org.eclipse.xtext.xbase.lib.IterableExtensions.groupBy;
+import static org.eclipse.xtext.xbase.lib.IterableExtensions.last;
+import static org.eclipse.xtext.xbase.lib.IterableExtensions.map;
+import static org.eclipse.xtext.xbase.lib.IterableExtensions.sortBy;
+import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.log4j.Logger;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.n4js.services.N4JSGrammarAccess;
+import org.eclipse.xtend.lib.annotations.Accessors;
+import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor;
+import org.eclipse.xtext.RuleCall;
+import org.eclipse.xtext.formatting2.AbstractFormatter2;
+import org.eclipse.xtext.formatting2.IFormattableDocument;
+import org.eclipse.xtext.formatting2.IHiddenRegionFormatting;
+import org.eclipse.xtext.formatting2.ITextReplacer;
+import org.eclipse.xtext.formatting2.ITextReplacerContext;
+import org.eclipse.xtext.formatting2.internal.HiddenRegionReplacer;
+import org.eclipse.xtext.formatting2.internal.TextReplacerMerger;
+import org.eclipse.xtext.formatting2.regionaccess.IHiddenRegion;
+import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion;
+import org.eclipse.xtext.formatting2.regionaccess.ITextRegionExtensions;
+import org.eclipse.xtext.formatting2.regionaccess.ITextSegment;
+import org.eclipse.xtext.xbase.lib.Pair;
+
+/**
+ *
+ */
+@SuppressWarnings("restriction")
+@FinalFieldsConstructor
+class N4JSGenericFormatter {
+
+	N4JSGrammarAccess grammarAccess;
+	ITextRegionExtensions trExtensions;
+
+	public static int PRIO_1 = -10;
+	public static int PRIO_2 = -9;
+	public static int PRIO_3 = -8;
+
+	public N4JSGenericFormatter(N4JSGrammarAccess grammarAccess, ITextRegionExtensions trExtensions) {
+		this.grammarAccess = grammarAccess;
+		this.trExtensions = trExtensions;
+	}
+
+	public void formatColon(EObject semanticElement, IFormattableDocument document) {
+		for (ISemanticRegion colon : trExtensions.allRegionsFor(semanticElement).keywords(":")) {
+			ISemanticRegion sr = document.prepend(colon, hrf -> {
+				hrf.noSpace();
+				hrf.setNewLines(0);
+				hrf.setPriority(PRIO_3);
+			});
+			document.append(sr, hrf -> {
+				hrf.oneSpace();
+				hrf.setPriority(PRIO_2);
+			});
+		}
+	}
+
+	/**
+	 * Formats whitespace around already present semicolons (;) and inserts new semicolons where the parser expects
+	 * them.
+	 */
+	public void formatSemicolons(EObject script, IFormattableDocument document) {
+		for (ISemanticRegion region : trExtensions.allRegionsFor(script).ruleCallsTo(grammarAccess.getSemiRule())) {
+			String text = region.getText();
+			IHiddenRegion previous = region.getPreviousHiddenRegion();
+			if (text == ";") {
+
+				// there is already a ";" so let's format it
+				document.prepend(region, hrf -> {
+					hrf.noSpace();
+					hrf.setNewLines(0);
+					hrf.highPriority();
+				});
+			} else if (region.getNextSemanticRegion() != null && "}".equals(region.getNextSemanticRegion().getText())
+					&& !region.isMultiline()) {
+				// do nothing
+			} else if (previous.containsComment()) {
+
+				// we're behind a comment - insert semicolon before the comment
+				ITextSegment insertAt = region.getTextRegionAccess().regionForOffset(previous.getOffset(), 0);
+				document.addReplacer(new InsertSemi(insertAt, ";"));
+			} else if (text.trim().isEmpty()) {
+				// Don't eat up white space here.
+				// Look for first line break and replace with ";\n":
+				int lbIdx = text.indexOf("\n");
+				if (lbIdx >= 0) {
+					ITextSegment replaceRegion = region.getTextRegionAccess().regionForOffset(region.getOffset(),
+							lbIdx + 1);
+					document.addReplacer(new InsertSemi(replaceRegion, ";\n"));
+				} else {
+					// the text region only contains whitespace, e.g. so let's insert a ; and a "\n"
+					document.addReplacer(new InsertSemi(region, ";"));
+				}
+			} else {
+
+				// we probably are the comment, so let's prefix it with ;
+				ITextSegment insertAt = region.getTextRegionAccess().regionForOffset(region.getOffset(), 0);
+				document.addReplacer(new InsertSemi(insertAt, ";"));
+			}
+		}
+	}
+
+	/**
+	 * Format whitespace around (), [], and {}
+	 *
+	 * When multiple pairs of (), [], or {} open in the same line, indentation is only applied for the innermost pair.
+	 */
+	public void formatParenthesisBracketsAndBraces(EObject script, IFormattableDocument document) {
+		List> all = new ArrayList<>();
+		all.addAll(trExtensions.allRegionsFor(script).keywordPairs("(", ")"));
+		all.addAll(trExtensions.allRegionsFor(script).keywordPairs("{", "}"));
+		all.addAll(trExtensions.allRegionsFor(script).keywordPairs("[", "]"));
+
+		Map>> byLine = groupBy(all,
+				p -> p.getKey().getLineRegions().get(0).getOffset());
+
+		for (Entry>> e : byLine.entrySet()) {
+			List> bracePairsInSameLine = sortBy(e.getValue(),
+					p -> p.getKey().getOffset());
+			Pair outermost = bracePairsInSameLine.get(0);
+			Pair innermost = last(bracePairsInSameLine);
+
+			// keep track of lastOpen/lastClose to avoid formatting the HiddenRegion twice if that hidden region
+			// is located directly between two brackets. Then, first.append[] would collide with second.prepend[].
+			IHiddenRegion lastOpen = null;
+			IHiddenRegion lastClose = null;
+			for (Pair pair : bracePairsInSameLine) {
+				ISemanticRegion open = pair.getKey();
+				ISemanticRegion close = pair.getValue();
+				if (open.getPreviousHiddenRegion() != lastOpen && lastOpen != null) {
+					// something between last opening and this one; null-check for first opening-> don't force noSpace
+					// here
+					document.prepend(open, hrf -> {
+						hrf.noSpace();
+						hrf.setPriority(PRIO_1);
+					});
+				}
+				if (pair != innermost) {
+					document.append(open, hrf -> {
+						hrf.noSpace();
+						hrf.setPriority(PRIO_1);
+					});
+					document.prepend(close, hrf -> {
+						hrf.noSpace();
+						hrf.setPriority(PRIO_1);
+					});
+				}
+				if (close.getNextHiddenRegion() != lastClose) {
+					if (pair == outermost) {
+						// close.appendNewLine(document)
+					} else {
+						document.append(close, hrf -> {
+							hrf.noSpace();
+							hrf.setPriority(PRIO_1);
+						});
+					}
+				}
+				lastOpen = open.getNextHiddenRegion();
+				lastClose = close.getPreviousHiddenRegion();
+			}
+
+			ISemanticRegion open = innermost.getKey();
+			ISemanticRegion close = innermost.getValue();
+			if (open.getNextSemanticRegion() == close && !open.getNextHiddenRegion().isMultiline()) { // empty
+																										// brace-pair
+				document.append(open, hrf -> {
+					hrf.noSpace();
+					hrf.setPriority(PRIO_1);
+				});
+			} // otherwise, if there is a newline before the innermost closing bracket, we want to format the surrounded
+				// tokens multiline style.
+			else if (close.getPreviousHiddenRegion().isMultiline()) {
+				appendNewLine(document.prepend(close, hrf -> {
+					hrf.newLine();
+					hrf.setPriority(PRIO_1);
+				}), document);
+				document.append(open, hrf -> {
+					hrf.newLine();
+					hrf.setPriority(PRIO_1);
+				});
+				document.interior(innermost, hrf -> hrf.indent());
+				for (ISemanticRegion comma : trExtensions.regionFor(open.getSemanticElement()).keywords(",")) {
+					// FIXME: bug in toString: println(comma.toString);
+					ISemanticRegion sr = document.prepend(comma, hrf -> {
+						hrf.noSpace();
+						hrf.setPriority(PRIO_1);
+					});
+					document.append(sr, hfr -> {
+						// If dangling comma, then a conflict arises with new line of close.
+						// Avoid here by using Prio_2
+						hfr.setNewLines(1, 1, 2);
+						hfr.setPriority(PRIO_2);
+					});
+				}
+			} // otherwise, format the tokens into a single line.
+			else {
+				if (document.getRequest().getPreferences()
+						.getPreference(N4JSFormatterPreferenceKeys.FORMAT_SURROUND_PAREN_CONTENT_WITH_SPACE)) {
+					// configured way to have single space in parenthesised expression.
+					document.prepend(close, hrf -> {
+						hrf.oneSpace();
+						hrf.setPriority(PRIO_1);
+					});
+					document.append(open, hrf -> {
+						hrf.oneSpace();
+						hrf.setPriority(PRIO_1);
+					});
+				}
+				for (ISemanticRegion comma : trExtensions.regionFor(open.getSemanticElement()).keywords(",")) {
+					ISemanticRegion sr = document.prepend(comma, hrf -> {
+						hrf.noSpace();
+						hrf.setPriority(PRIO_1);
+					});
+					document.append(sr, hrf -> {
+						hrf.oneSpace();
+						hrf.setPriority(PRIO_1);
+					});
+				}
+			}
+		}
+	}
+
+	public ISemanticRegion appendNewLine(ISemanticRegion appendAfter, IFormattableDocument doc) {
+		EObject semi = appendAfter.getNextSemanticRegion() == null ? null
+				: appendAfter.getNextSemanticRegion().getGrammarElement();
+		if (semi instanceof RuleCall && ((RuleCall) semi).getRule() == grammarAccess.getSemiRule()) {
+			// noop, handled by org.eclipse.n4js.formatting2.N4JSGenericFormatter.formatSemicolons(EObject,
+			// IFormattableDocument)
+		} else {
+			doc.append(appendAfter, hrf -> {
+				hrf.newLine();
+				hrf.setPriority(PRIO_1);
+			});
+		}
+		return appendAfter;
+	}
+
+	static interface InsertSemiBase extends ITextReplacer {
+		// marker interface
+	}
+
+	@Accessors
+	static class InsertSemi implements InsertSemiBase {
+		ITextSegment region;
+		String text;
+
+		public InsertSemi(ITextSegment region, String text) {
+			this.region = region;
+			this.text = text;
+		}
+
+		@Override
+		public ITextReplacerContext createReplacements(ITextReplacerContext context) {
+			context.addReplacement(region.replaceWith(text));
+			return context;
+		}
+
+		@Override
+		public ITextSegment getRegion() {
+			return this.region;
+		}
+
+		public String getText() {
+			return this.text;
+		}
+	}
+
+	static class InsertSemiFollowedByTextReplacer implements InsertSemiBase {
+		InsertSemiBase insertSemi;
+		ITextReplacer textReplacer;
+		ITextSegment region;
+
+		InsertSemiFollowedByTextReplacer(InsertSemiBase insertSemi, ITextReplacer textReplacer) {
+			this.insertSemi = insertSemi;
+			this.textReplacer = textReplacer;
+			this.region = insertSemi.getRegion().merge(textReplacer.getRegion());
+		}
+
+		@Override
+		public ITextReplacerContext createReplacements(ITextReplacerContext context) {
+			// First insert semicolon
+			ITextReplacerContext replContext = insertSemi.createReplacements(context).withReplacer(textReplacer);
+			// Then apply the text replacer
+			return textReplacer.createReplacements(replContext);
+		}
+
+		@Override
+		public ITextSegment getRegion() {
+			return this.region;
+		}
+	}
+
+	static class IndentHandlingTextReplaceMerger extends TextReplacerMerger {
+		private final static Logger LOGGER = Logger.getLogger(IndentHandlingTextReplaceMerger.class);
+
+		AbstractFormatter2 fmt;
+
+		IndentHandlingTextReplaceMerger(AbstractFormatter2 formatter) {
+			super(formatter);
+			fmt = formatter;
+		}
+
+		/**
+		 * Overridden for special case of {@link InsertSemi} & {@link HiddenRegionReplacer} merging. Calls super
+		 * implementation if no InsertSemi object is involved
+		 */
+		@Override
+		public ITextReplacer merge(List conflicting) {
+			if (findFirst(conflicting, tr -> tr instanceof InsertSemiBase) == null) {
+				// standard case, but not handled as we want by super because due to ASI there can be
+				// HiddenRegionReplacer that have equal offsets and length but are not identical.
+				List hrf = toList(filter(conflicting, HiddenRegionReplacer.class));
+				if (hrf.size() == conflicting.size()) {
+					IHiddenRegionFormatting merged = fmt.createHiddenRegionFormattingMerger()
+							.merge(toList(map(hrf, hrr -> hrr.getFormatting())));
+					if (merged != null) {
+						return fmt.createHiddenRegionReplacer(hrf.get(0).getRegion(), merged);
+					}
+				}
+				return super.merge(conflicting);
+			}
+
+			// there is an insertSemi.
+			List semiReplacements = toList(
+					filter(conflicting, tr -> tr instanceof InsertSemiBase));
+			List otherReplacements = toList(
+					filter(conflicting, tr -> !(tr instanceof InsertSemiBase)));
+
+			if (semiReplacements.size() != 1 || otherReplacements.size() != 1) {
+				LOGGER.warn("""
+						Unhandled merge-case: "
+							"Semis replacer («semiReplacements.size») :«semiReplacements»
+							"Non-Semi replacer ( «otherReplacements.size»  «otherReplacements»
+						""");
+				return null; // null creates merge Exception
+			}
+			// exactly one:
+			InsertSemiBase semiRepl = (InsertSemiBase) semiReplacements.get(0);
+			ITextReplacer otherRepl = otherReplacements.get(0);
+
+			if (otherRepl instanceof HiddenRegionReplacer) {
+				return new InsertSemiFollowedByTextReplacer(semiRepl, otherRepl);
+			}
+
+			return null;
+		}
+	}
+}
diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSGenericFormatter.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSGenericFormatter.xtend
deleted file mode 100644
index 886173e018..0000000000
--- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/N4JSGenericFormatter.xtend
+++ /dev/null
@@ -1,257 +0,0 @@
-/**
- * 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.formatting2
-
-import org.eclipse.n4js.services.N4JSGrammarAccess
-import org.eclipse.emf.ecore.EObject
-import org.eclipse.xtend.lib.annotations.Accessors
-import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
-import org.eclipse.xtext.RuleCall
-import org.eclipse.xtext.formatting2.IFormattableDocument
-import org.eclipse.xtext.formatting2.ITextReplacer
-import org.eclipse.xtext.formatting2.ITextReplacerContext
-import org.eclipse.xtext.formatting2.regionaccess.IHiddenRegion
-import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion
-import org.eclipse.xtext.formatting2.regionaccess.ITextRegionExtensions
-import org.eclipse.xtext.formatting2.regionaccess.ITextSegment
-import org.eclipse.xtext.formatting2.internal.TextReplacerMerger
-import org.eclipse.xtext.formatting2.AbstractFormatter2
-import java.util.List
-import org.eclipse.n4js.utils.Log
-import org.eclipse.xtext.formatting2.internal.HiddenRegionReplacer
-
-/**
- *
- */
-@FinalFieldsConstructor class N4JSGenericFormatter {
-
-	val extension N4JSGrammarAccess
-	val extension ITextRegionExtensions
-
-	public static val PRIO_1 = -10
-	public static val PRIO_2 = -9
-	public static val PRIO_3 = -8
-
-	def void formatColon(EObject semanticElement, extension IFormattableDocument document) {
-		for (colon : semanticElement.allRegionsFor.keywords(":")) {
-			colon.prepend[noSpace; newLines = 0; priority = PRIO_3]
-				 .append[oneSpace; priority = PRIO_2];
-		}
-	}
-
-	/**
-	 * Formats whitespace around already present semicolons (;) and inserts new semicolons where the parser expects them.
-	 */
-	def void formatSemicolons(EObject script, extension IFormattableDocument document) {
-		for (region : script.allRegionsFor.ruleCallsTo(semiRule)) {
-			val text = region.text;
-			val previous = region.previousHiddenRegion;
-			if (text == ";") {
-
-				// there is already a ";" so let's format it
-				region.prepend[noSpace; newLines = 0; highPriority];
-			} else if(region.nextSemanticRegion?.text == "}" && !region.isMultiline){
-				// do nothing
-			}
-			else if (previous.containsComment) {
-
-				// we're behind a comment - insert semicolon before the comment
-				val insertAt = region.textRegionAccess.regionForOffset(previous.offset, 0)
-				document.addReplacer(new InsertSemi(insertAt, ";"));
-			} else if (text.trim.isEmpty) {
-				// Don't eat up white space here.
-				// Look for first line break and replace with ";\n":
-				val lbIdx = text.indexOf("\n");
-				if( lbIdx >= 0 ) {
-					val replaceRegion = region.textRegionAccess.regionForOffset(region.offset, lbIdx+1 );
-					document.addReplacer(new InsertSemi(replaceRegion, ";\n"));
-				} else {
-					// the text region only contains whitespace, e.g. so let's insert a ; and a "\n"
-					document.addReplacer(new InsertSemi(region, ";"));
-				}
-			} else {
-
-				// we probably are the comment, so let's prefix it with ;
-				val insertAt = region.textRegionAccess.regionForOffset(region.offset, 0);
-				document.addReplacer(new InsertSemi(insertAt, ";"));
-			}
-		}
-	}
-
-	/**
-	 * Format whitespace around (), [], and {}
-	 *
-	 * When multiple pairs of (), [], or {} open in the same line, indentation is only applied for the innermost pair.
-	 */
-	def void formatParenthesisBracketsAndBraces(EObject script, extension IFormattableDocument document) {
-		val all = newArrayList()
-		all += script.allRegionsFor.keywordPairs("(", ")")
-		all += script.allRegionsFor.keywordPairs("{", "}")
-		all += script.allRegionsFor.keywordPairs("[", "]")
-
-		val byLine = all.groupBy[key.lineRegions.head.offset]
-
-		for (e : byLine.entrySet) {
-			val bracePairsInSameLine = e.value.sortBy[key.offset]
-			val outermost = bracePairsInSameLine.head
-			val innermost = bracePairsInSameLine.last
-
-			// keep track of lastOpen/lastClose to avoid formatting the HiddenRegion twice if that hidden region
-			// is located directly between two brackets. Then, first.append[] would collide with second.prepend[].
-			var IHiddenRegion lastOpen = null
-			var IHiddenRegion lastClose = null
-			for (pair : bracePairsInSameLine) {
-				val open = pair.key
-				val close = pair.value
-				if (open.previousHiddenRegion != lastOpen && lastOpen !== null) { // something between last opening and this one; null-check for first opening-> don't force noSpace here
-					open.prepend[noSpace; priority = PRIO_1]
-				}
-				if (pair !== innermost) {
-					open.append[noSpace; priority = PRIO_1]
-					close.prepend[noSpace; priority = PRIO_1]
-				}
-				if (close.nextHiddenRegion != lastClose) {
-					if (pair === outermost) {
-//						close.appendNewLine(document)
-					} else {
-						close.append[noSpace; priority = PRIO_1]
-					}
-				}
-				lastOpen = open.nextHiddenRegion
-				lastClose = close.previousHiddenRegion
-			}
-
-			val ISemanticRegion open = innermost.key;
-			val ISemanticRegion close = innermost.value;
-			if (open.nextSemanticRegion == close && !open.nextHiddenRegion.isMultiline) { // empty brace-pair
-				open.append[noSpace; priority = PRIO_1];
-			} // otherwise, if there is a newline before the innermost closing bracket, we want to format the surrounded tokens multiline style.
-			else if (close.previousHiddenRegion.isMultiline) {
-				close.prepend[newLine; priority = PRIO_1].appendNewLine(document);
-				open.append[newLine; priority = PRIO_1];
-				innermost.interior[indent];
-				for (comma : open.semanticElement.regionFor.keywords(",")) {
-					// FIXME: bug in toString: println(comma.toString);
-					comma.prepend[noSpace; priority = PRIO_1]
-					.append[
-						// If dangling comma, then a conflict arises with new line of close.
-						// Avoid here by using Prio_2
-						setNewLines(1,1,2);
-						priority = PRIO_2
-					];
-				}
-			} // otherwise, format the tokens into a single line.
-			else {
-				if( document.request.preferences.getPreference( N4JSFormatterPreferenceKeys.FORMAT_SURROUND_PAREN_CONTENT_WITH_SPACE ) ) { // configured way to have single space in parenthesised expression.
-					close.prepend[oneSpace; priority = PRIO_1]
-					open.append[oneSpace; priority = PRIO_1]
-				}
-				for (comma : open.semanticElement.regionFor.keywords(",")) {
-					comma.prepend[noSpace; priority = PRIO_1].append[oneSpace; priority = PRIO_1]
-				}
-			}
-		}
-	}
-
-	def ISemanticRegion appendNewLine(ISemanticRegion appendAfter, extension IFormattableDocument doc) {
-		val semi = appendAfter.nextSemanticRegion?.grammarElement
-		if (semi instanceof RuleCall && (semi as RuleCall)?.rule == semiRule) {
-			// noop, handled by org.eclipse.n4js.formatting2.N4JSGenericFormatter.formatSemicolons(EObject, IFormattableDocument)
-		} else {
-			appendAfter.append[newLine; priority = PRIO_1]
-		}
-		return appendAfter
-	}
-}
-
-interface InsertSemiBase extends ITextReplacer {}
-
-@Accessors class InsertSemi implements InsertSemiBase {
-	val ITextSegment region
-	val String text
-
-	override createReplacements(ITextReplacerContext context) {
-		context.addReplacement(region.replaceWith(text))
-		return context;
-	}
-}
-
-class InsertSemiFollowedByTextReplacer implements InsertSemiBase {
-	val InsertSemiBase insertSemi;
-	val ITextReplacer textReplacer;
-	val ITextSegment region;
-	
-	new(InsertSemiBase insertSemi, ITextReplacer textReplacer) {
-		this.insertSemi = insertSemi;
-		this.textReplacer = textReplacer;
-		this.region = insertSemi.region.merge(textReplacer.region)
-	}
-
-	override createReplacements(ITextReplacerContext context) {
-		// First insert semicolon
-		var replContext = insertSemi.createReplacements(context).withReplacer(textReplacer);
-		// Then apply the text replacer
-		return textReplacer.createReplacements(replContext);
-	}
-	
-	override getRegion() {
-		return this.region;
-	}
-}
-
-@Log
-class IndentHandlingTextReplaceMerger extends TextReplacerMerger {
-	val AbstractFormatter2 fmt
-
-	new(AbstractFormatter2 formatter) {
-		super(formatter)
-		fmt = formatter
-	}
-
-	/** Overridden for special case of {@link InsertSemi} & {@link HiddenRegionReplacer} merging.
-	 * Calls super implementation if no InsertSemi object is involved */
-	override merge(List conflicting) {
-		if(conflicting.findFirst[it instanceof InsertSemiBase] === null ) {
- 			// standard case, but not handled as we want by super because due to ASI there can be
- 			// HiddenRegionReplacer that have equal offsets and length but are not identical.
- 			val hrf = conflicting.filter(HiddenRegionReplacer).toList
- 			if(hrf.size === conflicting.size) {
- 				val merged = fmt.createHiddenRegionFormattingMerger.merge(hrf.map[formatting])
- 				if(merged !== null) {
- 					return fmt.createHiddenRegionReplacer(hrf.head.region, merged)
- 				}
- 			}
-			return super.merge(conflicting);
-		}
-
-		// there is an insertSemi.
-		val semiReplacements = conflicting.filter[it instanceof InsertSemiBase].toList;
-		val otherReplacements = conflicting.filter[!(it instanceof InsertSemiBase)].toList;
-
-		if( semiReplacements.size !== 1  || otherReplacements.size !== 1  ) {
-			logger.warn( '''
-			Unhandled merge-case: "
-				"Semis replacer («semiReplacements.size») :«semiReplacements»
-				"Non-Semi replacer ( «otherReplacements.size»  «otherReplacements»
-			 ''');
-			return null; // null creates merge Exception
-		}
-		// exactly one:
-		val semiRepl = semiReplacements.get(0) as InsertSemiBase;
-		val otherRepl = otherReplacements.get(0);
-		
-		if( otherRepl instanceof HiddenRegionReplacer ) {
-			return new InsertSemiFollowedByTextReplacer(semiRepl, otherRepl);
-		}
-
-		return null;
-	}
-}
diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/TypeExpressionsFormatter.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/TypeExpressionFormatterNoOp.java
similarity index 61%
rename from plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/TypeExpressionsFormatter.xtend
rename to plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/TypeExpressionFormatterNoOp.java
index 5f3645ec9a..896e4444e5 100644
--- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/TypeExpressionsFormatter.xtend
+++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/TypeExpressionFormatterNoOp.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2016 NumberFour AG.
+ * Copyright (c) 2024 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
@@ -10,16 +10,15 @@
  */
 package org.eclipse.n4js.formatting2;
 
-import org.eclipse.xtext.formatting2.AbstractFormatter2
-import org.eclipse.xtext.formatting2.IFormattableDocument
-
-abstract class TypeExpressionsFormatter extends AbstractFormatter2 {
-}
+import org.eclipse.xtext.formatting2.IFormattableDocument;
 
+/**
+ *
+ */
 public class TypeExpressionFormatterNoOp extends TypeExpressionsFormatter {
 
-	override format(Object obj, IFormattableDocument document) {
-		throw new UnsupportedOperationException("TypeExpressionFormatter should not be used directly.")
+	@Override
+	public void format(Object obj, IFormattableDocument document) {
+		throw new UnsupportedOperationException("TypeExpressionFormatter should not be used directly.");
 	}
-
 }
diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDescriptionUtils.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/TypeExpressionsFormatter.java
similarity index 55%
rename from plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDescriptionUtils.xtend
rename to plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/TypeExpressionsFormatter.java
index 7509a2c621..9ff8ad432f 100644
--- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDescriptionUtils.xtend
+++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/formatting2/TypeExpressionsFormatter.java
@@ -8,16 +8,10 @@
  * Contributors:
  *   NumberFour AG - Initial API and implementation
  */
-package org.eclipse.n4js.resource
+package org.eclipse.n4js.formatting2;
 
-import org.eclipse.xtext.resource.DescriptionUtils
-import org.eclipse.xtext.resource.IResourceDescription
+import org.eclipse.xtext.formatting2.AbstractFormatter2;
 
-/**
- */
-class N4JSDescriptionUtils extends DescriptionUtils {
-
-	override collectOutgoingReferences(IResourceDescription description) {
-		newHashSet
-	}
+abstract class TypeExpressionsFormatter extends AbstractFormatter2 {
+	// empty
 }
diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/AbstractSubGenerator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/AbstractSubGenerator.java
new file mode 100644
index 0000000000..c09948e05e
--- /dev/null
+++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/AbstractSubGenerator.java
@@ -0,0 +1,539 @@
+/**
+ * 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.generator;
+
+import static org.eclipse.xtext.diagnostics.Severity.ERROR;
+import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter;
+import static org.eclipse.xtext.xbase.lib.IterableExtensions.head;
+import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList;
+
+import java.io.StringWriter;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.eclipse.emf.common.EMFPlugin;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.n4js.N4JSGlobals;
+import org.eclipse.n4js.N4JSLanguageConstants;
+import org.eclipse.n4js.generator.IGeneratorMarkerSupport.Severity;
+import org.eclipse.n4js.n4JS.Script;
+import org.eclipse.n4js.packagejson.projectDescription.ProjectType;
+import org.eclipse.n4js.resource.N4JSCache;
+import org.eclipse.n4js.resource.N4JSResource;
+import org.eclipse.n4js.ts.types.TModule;
+import org.eclipse.n4js.utils.FolderContainmentHelper;
+import org.eclipse.n4js.utils.ResourceNameComputer;
+import org.eclipse.n4js.utils.ResourceType;
+import org.eclipse.n4js.utils.StaticPolyfillHelper;
+import org.eclipse.n4js.utils.URIUtils;
+import org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot;
+import org.eclipse.n4js.workspace.N4JSSourceFolderSnapshot;
+import org.eclipse.n4js.workspace.N4JSWorkspaceConfigSnapshot;
+import org.eclipse.n4js.workspace.WorkspaceAccess;
+import org.eclipse.xtext.generator.AbstractFileSystemAccess;
+import org.eclipse.xtext.generator.IFileSystemAccess;
+import org.eclipse.xtext.generator.IFileSystemAccess2;
+import org.eclipse.xtext.generator.IGenerator2;
+import org.eclipse.xtext.generator.IGeneratorContext;
+import org.eclipse.xtext.generator.OutputConfiguration;
+import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
+import org.eclipse.xtext.service.OperationCanceledManager;
+import org.eclipse.xtext.util.CancelIndicator;
+import org.eclipse.xtext.util.UriExtensions;
+import org.eclipse.xtext.validation.CheckMode;
+import org.eclipse.xtext.validation.IResourceValidator;
+import org.eclipse.xtext.validation.Issue;
+
+import com.google.inject.Inject;
+
+/**
+ * All sub generators should extend this class. It provides basic blocks of the logic, and shared implementations.
+ */
+abstract public class AbstractSubGenerator implements ISubGenerator, IGenerator2 {
+	private final static Logger LOGGER = Logger.getLogger(AbstractSubGenerator.class);
+
+	private CompilerDescriptor compilerDescriptor = null;
+
+	/***/
+	@Inject
+	protected StaticPolyfillHelper staticPolyfillHelper;
+
+	/***/
+	@Inject
+	protected WorkspaceAccess workspaceAccess;
+
+	/***/
+	@Inject
+	protected ResourceNameComputer resourceNameComputer;
+
+	/***/
+	@Inject
+	protected IResourceValidator resVal;
+
+	/***/
+	@Inject
+	protected N4JSCache cache;
+
+	/***/
+	@Inject
+	protected IGeneratorMarkerSupport genMarkerSupport;
+
+	/***/
+	@Inject
+	protected OperationCanceledManager operationCanceledManager;
+
+	/***/
+	@Inject
+	protected GeneratorExceptionHandler exceptionHandler;
+
+	/***/
+	@Inject
+	protected N4JSPreferenceAccess preferenceAccess;
+
+	@Inject
+	private FolderContainmentHelper containmentHelper;
+
+	@Inject
+	private UriExtensions uriExtensions;
+
+	@Override
+	public CompilerDescriptor getCompilerDescriptor() {
+		if (compilerDescriptor == null) {
+			compilerDescriptor = getDefaultDescriptor();
+		}
+		return compilerDescriptor;
+	}
+
+	@Override
+	public void setCompilerDescriptor(CompilerDescriptor compilerDescriptor) {
+		this.compilerDescriptor = compilerDescriptor;
+	}
+
+	@Override
+	public void doGenerate(Resource input, IFileSystemAccess2 fsa, IGeneratorContext context) {
+		doGenerate(input, fsa);
+	}
+
+	@Override
+	public void beforeGenerate(Resource input, IFileSystemAccess2 fsa, IGeneratorContext context) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	public void afterGenerate(Resource input, IFileSystemAccess2 fsa, IGeneratorContext context) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/**
+	 * This override declares an {@link IFileSystemAccess} parameter. At runtime, its actual type depends on whether IDE
+	 * or headless, which in turn determines whether the actual argument has a progress monitor or not:
+	 * 
    + *
  • IDE scenario: Actual type is {@code EclipseResourceFileSystemAccess2}. A progress monitor can be obtained via + * {@code getMonitor()}. It is checked automatically behind the scenes, for example in {@code generateFile()}. Upon + * detecting a pending cancellation request, an {@code OperationCanceledException} is raised.
  • + *
  • Headless scenario: Actual type is {@code JavaIoFileSystemAccess}. No progress monitor is available.
  • + *
+ */ + @Override + public void doGenerate(Resource input, IFileSystemAccess fsa) { + if (justCopy(input)) { + copyWithoutTranspilation(input, fsa); + return; + } + + N4JSWorkspaceConfigSnapshot ws = workspaceAccess.getWorkspaceConfig(input); + + try { + // remove error-marker + genMarkerSupport.deleteMarker(input); + + updateOutputPath(ws, fsa, getCompilerID(), input); + internalDoGenerate(ws, input, GeneratorOption.DEFAULT_OPTIONS, fsa); + + } catch (UnresolvedProxyInSubGeneratorException e) { + genMarkerSupport.createMarker(input, e.getMessage(), Severity.ERROR); + + } catch (Exception e) { + // cancellation is not an error case, so simply propagate as usual + operationCanceledManager.propagateIfCancelException(e); + + // issue error marker + String target = input.getURI() == null ? "unknown" : input.getURI().toString(); + if (input instanceof N4JSResource && ((N4JSResource) input).getModule() != null) { + target = ((N4JSResource) input).getModule().getModuleSpecifier(); + } + String msgMarker = "Severe error occurred while transpiling module " + target + + ". Check error log for details about the failure."; + genMarkerSupport.createMarker(input, msgMarker, Severity.ERROR); + + // re-throw as GeneratorException to have the frameworks notify the error. + if (e instanceof GeneratorException) { + throw e; + } + String msg = (e.getMessage() == null) ? "type=" + e.getClass().getName() : "message=" + e.getMessage(); + exceptionHandler.handleError("Severe error occurred in transpiler=" + getCompilerID() + " " + msg + ".", e); + } + } + + @Override + public boolean shouldBeCompiled(Resource input, CancelIndicator monitor) { + N4JSWorkspaceConfigSnapshot ws = workspaceAccess.getWorkspaceConfig(input); + + boolean autobuildEnabled = isActive(input); + boolean isXPECTMode = N4JSGlobals.XT_FILE_EXTENSION + .equals(URIUtils.fileExtension(input.getURI()).toLowerCase()); + URI inputUri = input.getURI(); + + boolean result = (autobuildEnabled + && isGenerateProjectType(ws, inputUri) + && hasOutput(ws, inputUri) + && isOutputNotInSourceContainer(ws, inputUri) + && isOutsideOfOutputFolder(ws, inputUri) + && isSource(ws, inputUri) + && (isNoValidate(ws, inputUri) + || isExternal(ws, inputUri) + // if platform is running (but not in XPECT mode) the generator is called from the builder, + // hence cannot have any validation errors + // (note: XPECT swallows errors hence we cannot rely on Eclipse in case of .xt files) + || ((EMFPlugin.IS_ECLIPSE_RUNNING && !isXPECTMode) || hasNoErrors(input, monitor)))) + && (!isStaticPolyfillingModule(input)) // compile driven by filled type + && hasNoPolyfillErrors(input, monitor); + return result; + } + + private boolean hasOutput(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI) { + return getOutputPath(ws, n4jsSourceURI) != null; + } + + private boolean isSource(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI) { + return ws.findSourceFolderContaining(n4jsSourceURI) != null; + } + + private boolean isNoValidate(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI) { + return ws.isNoValidate(n4jsSourceURI); + } + + private boolean isExternal(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI) { + N4JSSourceFolderSnapshot sourceContainerOpt = ws.findSourceFolderContaining(n4jsSourceURI); + if (sourceContainerOpt != null) { + N4JSSourceFolderSnapshot sourceContainer = sourceContainerOpt; + return sourceContainer.isExternal(); + } + return false; + } + + /** + * If the resource has a static polyfill, then ensure it is error-free. Calls + * {@link #hasNoErrors(Resource, CancelIndicator)} on the static polyfill resource. + */ + private boolean hasNoPolyfillErrors(Resource input, CancelIndicator monitor) { + N4JSResource resSPoly = staticPolyfillHelper.getStaticPolyfillResource(input); + if (resSPoly == null) { + return true; + } + // re-validation is necessary since the changes of the current resource (i.e. filled resource) + // can affect the filling resource in a way that validation errors will be removed or created. + cache.recreateIssues(resVal, resSPoly, CheckMode.ALL, monitor); + return hasNoErrors(resSPoly, monitor); + } + + /** + * Does validation report no errors for the given resource? If errors exists, log them as a side-effect. If + * validation was canceled before finishing, don't assume absence of errors. + */ + private boolean hasNoErrors(Resource input, CancelIndicator monitor) { + List issues = cache.getOrUpdateIssues(resVal, input, CheckMode.ALL, monitor); + if (issues == null || input instanceof N4JSResource && !((N4JSResource) input).isFullyProcessed()) { + // Cancellation occurred likely before all validations completed, thus can't assume absence of errors. + // Cancellation may result in exit via normal control-flow (this case) or via exceptional control-flow (see + // exception handler below) + warnDueToCancelation(input, null); + return false; + } + + List errors = toList(filter(issues, i -> i.getSeverity() == ERROR)); + if (errors.isEmpty()) { + return true; + } + if (LOGGER.isDebugEnabled()) { + for (Issue it : errors) { + LOGGER.debug(input.getURI() + " " + it.getMessage() + " " + it.getSeverity() + " @L_" + + it.getLineNumber() + " "); + } + } + return false; + } + + private void warnDueToCancelation(Resource input, Throwable exc) { + String msg = "User canceled the validation of " + input.getURI() + ". Will not compile."; + if (null == exc) { + LOGGER.warn(msg); + } else { + LOGGER.warn(msg, exc); + } + } + + /** @return true iff the current project has a project type that is supposed to generate code. */ + private boolean isGenerateProjectType(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI) { + N4JSProjectConfigSnapshot project = ws.findProjectContaining(n4jsSourceURI); + if (project != null) { + ProjectType projectType = project.getType(); + if (N4JSGlobals.PROJECT_TYPES_WITHOUT_GENERATION.contains(projectType)) { + return false; + } + } + + return true; + } + + /** @return true iff the given resource does not lie within the output folder. */ + private boolean isOutsideOfOutputFolder(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI) { + return !containmentHelper.isContainedInOutputFolder(ws, n4jsSourceURI); + } + + /** @return true iff the output folder of the given n4js resource is not contained by a source container. */ + private boolean isOutputNotInSourceContainer(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI) { + N4JSProjectConfigSnapshot project = ws.findProjectContaining(n4jsSourceURI); + if (project != null) { + return !containmentHelper.isOutputContainedInSourceContainer(ws, project); + } else { + return false; + } + } + + /** + * Actual generation to be overridden by subclasses. + */ + abstract protected void internalDoGenerate(N4JSWorkspaceConfigSnapshot ws, Resource resource, + GeneratorOption[] options, IFileSystemAccess access); + + /** + * Returns the name of the target file (without path) to which the source is to be compiled to. Default + * implementation returns a configured project Name with version + file name + extension. E.g., "proj-0.0.1/p/A.js" + * for a file A in proj. + * + * Convenience method, to provide all necessary API for the sub-classes. Delegates to + * {@link ResourceNameComputer#generateFileDescriptor(Resource, String)}. + */ + protected String getTargetFileName(Resource n4jsSourceFile, String compiledFileExtension) { + return resourceNameComputer.generateFileDescriptor(n4jsSourceFile, compiledFileExtension); + } + + /** + * Convenient access to the Script-Element + */ + protected Script rootElement(Resource resource) { + return head(filter(resource.getContents(), Script.class)); + } + + /** The file-extension of the compiled result */ + protected String getCompiledFileExtension(Resource input) { + return preferenceAccess.getPreference(input, getCompilerID(), CompilerProperties.COMPILED_FILE_EXTENSION, + getDefaultDescriptor()); + } + + /** The file-extension of the source-map to the compiled result */ + protected String getCompiledFileSourceMapExtension(Resource input) { + return preferenceAccess.getPreference(input, getCompilerID(), + CompilerProperties.COMPILED_FILE_SOURCEMAP_EXTENSION, + getDefaultDescriptor()); + } + + /** Adjust output-path of the generator to match the N4JS projects-settings. */ + private void updateOutputPath(N4JSWorkspaceConfigSnapshot ws, IFileSystemAccess fsa, String compilerID, + Resource input) { + String outputPath = getOutputPath(ws, input.getURI()); + if (outputPath == null) { + outputPath = N4JSLanguageConstants.DEFAULT_PROJECT_OUTPUT; + } + if (fsa instanceof AbstractFileSystemAccess) { + OutputConfiguration conf = ((AbstractFileSystemAccess) fsa).getOutputConfigurations().get(compilerID); + if (conf != null) { + conf.setOutputDirectory(outputPath); + } + } + } + + private static String getOutputPath(N4JSWorkspaceConfigSnapshot ws, URI nestedLocation) { + if (ws.findProjectContaining(nestedLocation) == null) { + return null; + } + if (ws.findProjectContaining(nestedLocation).getProjectDescription() == null) { + return null; + } + return ws.findProjectContaining(nestedLocation).getProjectDescription().getOutputPath(); + } + + /** Navigation from the generated output-location to the location of the input-resource */ + @SuppressWarnings("unused") + protected Path calculateNavigationFromOutputToSourcePath(N4JSWorkspaceConfigSnapshot ws, IFileSystemAccess fsa, + String compilerID, N4JSResource input) { + // --- Project locations --- + N4JSProjectConfigSnapshot project = ws.findProjectContaining(input.getURI()); + + // /home/user/workspace/Project/ + Path projectPath = project.getPathAsFileURI().toFileSystemPath(); + // platform:/resource/Project/ + URI projectLocURI = project.getPathAsFileURI().withTrailingPathDelimiter().toURI(); + + // --- output locations --- + // src-gen + String outputPath = project.getOutputPath(); + // Project/a/b/c + Path outputRelativeLocation = getOutputRelativeLocation(input); + + // --- source locations --- + // src/a/b/c + URI inputURI = uriExtensions.withEmptyAuthority(input.getURI()); + URI completetSourceURI = inputURI.trimSegments(1).deresolve(projectLocURI); + String completetSource = URIUtils.toFile(completetSourceURI).toString(); + + // Handling case when source container is the project root itself. (Sources { source { '.' } }) + if (null == completetSource && project.getPathAsFileURI().toURI() == input.getURI().trimSegments(1)) { + completetSource = projectPath.toFile().getAbsolutePath(); + } + + // /home/user/workspace/Project/src-gen/a/b/c + Path fullOutpath = projectPath.resolve(outputPath).normalize().resolve(outputRelativeLocation).normalize(); + // /home/user/workspace/Project/src/a/b/c + Path fullSourcePath = projectPath.resolve(completetSource).normalize(); + + // ../../../../../../src/a/b/c + Path rel = fullOutpath.relativize(fullSourcePath); + + return rel; + } + + /** + * Calculates local output path for a given resource. Depending on the configuration this path can be in various + * forms, {@code Project-1.0.0/a/b/c/}, {@code Project/a/b/c/} or just {@code a/b/c/} + * + */ + private Path getOutputRelativeLocation(N4JSResource input) { + URI uri = uriExtensions.withEmptyAuthority(input.getURI()); + // Project/a/b/c/Input.XX + Path localOutputFilePath = Paths.get(resourceNameComputer.generateFileDescriptor(input, uri, ".XX")); + + // if calculated path has just one element, e.g. "Input.XX" + // then local path segment is empty + if (localOutputFilePath.getNameCount() < 2) { + return Paths.get(""); + } + + // otherwise strip resource to get local path, i.e. Project/a/b/c/Input.XX => Project/a/b/c/ + return localOutputFilePath.subpath(0, localOutputFilePath.getNameCount() - 1); + } + + /** + * TODO IDE-1487 currently there is no notion of default compiler. We fake call to the ES5 sub generator. + */ + final static String calculateProjectBasedOutputDirectory(N4JSProjectConfigSnapshot project, + boolean includeProjectName) { + return (includeProjectName) ? project.getPackageName() + "/" + project.getOutputPath() + : project.getOutputPath(); + } + + /** Access to compiler ID */ + abstract public String getCompilerID(); + + /** Access to compiler descriptor */ + abstract public CompilerDescriptor getDefaultDescriptor(); + + /** Answers: Is this compiler activated for the input at hand? */ + public boolean isActive(Resource input) { + return Boolean.valueOf(preferenceAccess.getPreference(input, getCompilerID(), CompilerProperties.IS_ACTIVE, + getDefaultDescriptor())); + } + + /** + * Checking the availability of a static polyfill, which will override the compilation of this module. + **/ + public boolean isNotStaticallyPolyfilled(Resource resource) { + // val TModule tmodule = (N4JSResource::getModule(resource) ); // for some reason xtend cannot see static + // getModule ?! + if (resource instanceof N4JSResource) { + TModule tmodule = N4JSResource.getModule(resource); + // 1. resource must be StaticPolyfillAware and + // 2. there must exist a polyfilling instance (second instance with same fqn) + if (tmodule.isStaticPolyfillAware()) { + // search for second instance. + if (staticPolyfillHelper.hasStaticPolyfill(resource)) { + return false; + } + } + } + return true; + } + + /** + * Checking if this resource represents a static polyfill, which will contribute to a filled resource. + **/ + private boolean isStaticPolyfillingModule(Resource resource) { + TModule tmodule = (N4JSResource.getModule(resource)); + if (null != tmodule) { + return tmodule.isStaticPolyfillModule(); + } + return false; + } + + /** + * + * @return true if the composite generator is applicable to the given resource and false otherwise. + */ + @Override + public boolean isApplicableTo(Resource input) { + return shouldBeCompiled(input, null); + } + + /** + * Depending on the file-extension, determines if the given resource requires actual transpilation as opposed to + * simply copying the source file to the output folder. + * + * @param eResource + * N4JS resource to check. + * @return true if the code requires transpilation. + */ + protected boolean justCopy(Resource eResource) { + ResourceType resourceType = ResourceType.getResourceType(eResource); + return !(resourceType.equals(ResourceType.N4JS) || resourceType.equals(ResourceType.N4JSX) + || resourceType.equals(ResourceType.N4JSD)); + } + + /** + * Take the content of resource and copy it over to the output folder without any transformation. + * + * @param resource + * JS-code snippet which will be treated as text. + * @param fsa + * file system access + */ + protected void copyWithoutTranspilation(Resource resource, IFileSystemAccess fsa) { + StringWriter outCode = new StringWriter(); + // get script + EObject script = resource.getContents().get(0); + + // obtain text + String scriptAsText = NodeModelUtils.getNode(script).getRootNode().getText(); + + // write + String decorated = scriptAsText.toString(); + outCode.write(decorated); + String filename = resourceNameComputer.generateFileDescriptor(resource, + URIUtils.fileExtension(resource.getURI())); + fsa.generateFile(filename, getCompilerID(), outCode.toString()); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/AbstractSubGenerator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/AbstractSubGenerator.xtend deleted file mode 100644 index 56c17a092f..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/AbstractSubGenerator.xtend +++ /dev/null @@ -1,482 +0,0 @@ -/** - * 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.generator - -import com.google.inject.Inject -import java.io.StringWriter -import java.nio.file.Path -import java.nio.file.Paths -import java.util.List -import org.eclipse.emf.common.EMFPlugin -import org.eclipse.emf.common.util.URI -import org.eclipse.emf.ecore.resource.Resource -import org.eclipse.n4js.N4JSGlobals -import org.eclipse.n4js.N4JSLanguageConstants -import org.eclipse.n4js.generator.IGeneratorMarkerSupport.Severity -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.resource.N4JSCache -import org.eclipse.n4js.resource.N4JSResource -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.utils.FolderContainmentHelper -import org.eclipse.n4js.utils.Log -import org.eclipse.n4js.utils.ResourceNameComputer -import org.eclipse.n4js.utils.ResourceType -import org.eclipse.n4js.utils.StaticPolyfillHelper -import org.eclipse.n4js.utils.URIUtils -import org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot -import org.eclipse.n4js.workspace.N4JSWorkspaceConfigSnapshot -import org.eclipse.n4js.workspace.WorkspaceAccess -import org.eclipse.xtend.lib.annotations.Accessors -import org.eclipse.xtext.generator.AbstractFileSystemAccess -import org.eclipse.xtext.generator.IFileSystemAccess -import org.eclipse.xtext.generator.IFileSystemAccess2 -import org.eclipse.xtext.generator.IGenerator2 -import org.eclipse.xtext.generator.IGeneratorContext -import org.eclipse.xtext.nodemodel.util.NodeModelUtils -import org.eclipse.xtext.service.OperationCanceledManager -import org.eclipse.xtext.util.CancelIndicator -import org.eclipse.xtext.util.UriExtensions -import org.eclipse.xtext.validation.CheckMode -import org.eclipse.xtext.validation.IResourceValidator -import org.eclipse.xtext.validation.Issue - -import static org.eclipse.xtext.diagnostics.Severity.* - -/** - * All sub generators should extend this class. It provides basic blocks of the logic, and - * shared implementations. - */ -@Log -abstract class AbstractSubGenerator implements ISubGenerator, IGenerator2 { - - @Accessors - private CompilerDescriptor compilerDescriptor = null - - @Inject protected StaticPolyfillHelper staticPolyfillHelper - - @Inject protected WorkspaceAccess workspaceAccess - - @Inject protected ResourceNameComputer resourceNameComputer - - @Inject protected IResourceValidator resVal - - @Inject protected N4JSCache cache - - @Inject protected IGeneratorMarkerSupport genMarkerSupport - - @Inject protected OperationCanceledManager operationCanceledManager - - @Inject protected GeneratorExceptionHandler exceptionHandler - - @Inject protected N4JSPreferenceAccess preferenceAccess - - @Inject private FolderContainmentHelper containmentHelper; - - @Inject private UriExtensions uriExtensions; - - - override getCompilerDescriptor() { - if (compilerDescriptor === null) { - compilerDescriptor = getDefaultDescriptor - } - return compilerDescriptor - } - - - override doGenerate(Resource input, IFileSystemAccess2 fsa, IGeneratorContext context) { - doGenerate(input, fsa); - } - - override beforeGenerate(Resource input, IFileSystemAccess2 fsa, IGeneratorContext context) { - // TODO Auto-generated method stub - - } - - override afterGenerate(Resource input, IFileSystemAccess2 fsa, IGeneratorContext context) { - // TODO Auto-generated method stub - - } - - /** - * This override declares an {@link IFileSystemAccess} parameter. At runtime, its actual type depends on whether IDE or headless, - * which in turn determines whether the actual argument has a progress monitor or not: - *
    - *
  • - * IDE scenario: Actual type is {@code EclipseResourceFileSystemAccess2}. A progress monitor can be obtained via {@code getMonitor()}. - * It is checked automatically behind the scenes, for example in {@code generateFile()}. - * Upon detecting a pending cancellation request, an {@code OperationCanceledException} is raised. - *
  • - *
  • - * Headless scenario: Actual type is {@code JavaIoFileSystemAccess}. No progress monitor is available. - *
  • - *
- */ - override doGenerate(Resource input, IFileSystemAccess fsa) { - if (justCopy(input)) { - copyWithoutTranspilation(input, fsa); - return; - } - - val ws = workspaceAccess.getWorkspaceConfig(input); - - try { - // remove error-marker - genMarkerSupport.deleteMarker(input) - - updateOutputPath(ws, fsa, getCompilerID, input); - internalDoGenerate(ws, input, GeneratorOption.DEFAULT_OPTIONS, fsa); - - } catch (UnresolvedProxyInSubGeneratorException e) { - genMarkerSupport.createMarker(input, e.message, Severity.ERROR); - - } catch (Exception e) { - // cancellation is not an error case, so simply propagate as usual - operationCanceledManager.propagateIfCancelException(e); - - // issue error marker - val target = (if (input instanceof N4JSResource) input.module?.moduleSpecifier) ?: input.URI?.toString; - val msgMarker = "Severe error occurred while transpiling module " + target - + ". Check error log for details about the failure."; - genMarkerSupport.createMarker(input, msgMarker, Severity.ERROR); - - // re-throw as GeneratorException to have the frameworks notify the error. - if (e instanceof GeneratorException) { - throw e; - } - var msg = if (e.message === null) "type=" + e.class.name else "message=" + e.message; - exceptionHandler.handleError('''Severe error occurred in transpiler=«compilerID» «msg».''', e); - } - } - - override shouldBeCompiled(Resource input, CancelIndicator monitor) { - val ws = workspaceAccess.getWorkspaceConfig(input); - - val autobuildEnabled = isActive(input) - val isXPECTMode = N4JSGlobals.XT_FILE_EXTENSION.equals(URIUtils.fileExtension(input.URI).toLowerCase); - val inputUri = input.URI - - val boolean result = (autobuildEnabled - && isGenerateProjectType(ws, inputUri) - && hasOutput(ws, inputUri) - && isOutputNotInSourceContainer(ws, inputUri) - && isOutsideOfOutputFolder(ws, inputUri) - && isSource(ws, inputUri) - && (isNoValidate(ws, inputUri) - || isExternal(ws, inputUri) - // if platform is running (but not in XPECT mode) the generator is called from the builder, hence cannot have any validation errors - // (note: XPECT swallows errors hence we cannot rely on Eclipse in case of .xt files) - || ((EMFPlugin.IS_ECLIPSE_RUNNING && !isXPECTMode) || hasNoErrors(input, monitor)) - )) - && (!input.isStaticPolyfillingModule) // compile driven by filled type - && hasNoPolyfillErrors(input,monitor) - return result - } - - private def hasOutput(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI){ - return getOutputPath(ws, n4jsSourceURI) !== null; - } - private def isSource(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI) { - return ws.findSourceFolderContaining(n4jsSourceURI) !== null; - } - - private def isNoValidate(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI) { - return ws.isNoValidate(n4jsSourceURI); - } - - private def isExternal(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI) { - val sourceContainerOpt = ws.findSourceFolderContaining(n4jsSourceURI); - if (sourceContainerOpt !== null) { - val sourceContainer = sourceContainerOpt; - return sourceContainer.external; - } - return false; - } - - /** If the resource has a static polyfill, then ensure it is error-free. - * Calls {@link #hasNoErrors()} on the static polyfill resource. - */ - private def boolean hasNoPolyfillErrors(Resource input, CancelIndicator monitor) { - val resSPoly = staticPolyfillHelper.getStaticPolyfillResource(input) - if (resSPoly === null) { - return true; - } - // re-validation is necessary since the changes of the current resource (i.e. filled resource) - // can affect the filling resource in a way that validation errors will be removed or created. - cache.recreateIssues(resVal, resSPoly, CheckMode.ALL, monitor); - return hasNoErrors(resSPoly, monitor) - } - - /** - * Does validation report no errors for the given resource? - * If errors exists, log them as a side-effect. - * If validation was canceled before finishing, don't assume absence of errors. - */ - private def boolean hasNoErrors(Resource input, CancelIndicator monitor) { - val List issues = cache.getOrUpdateIssues(resVal, input, CheckMode.ALL, monitor); - if (issues === null || input instanceof N4JSResource && !(input as N4JSResource).isFullyProcessed) { - // Cancellation occurred likely before all validations completed, thus can't assume absence of errors. - // Cancellation may result in exit via normal control-flow (this case) or via exceptional control-flow (see exception handler below) - warnDueToCancelation(input, null); - return false; - } - - val Iterable errors = issues.filter[severity == ERROR]; - if (errors.isEmpty()) { - return true - } - if (logger.isDebugEnabled) { - errors.forEach[logger.debug(input.URI + " " + it.message + " " + it.severity + " @L_" + it.lineNumber + " ")] - } - return false - } - - private def void warnDueToCancelation(Resource input, Throwable exc) { - val msg = "User canceled the validation of " + input.URI + ". Will not compile."; - if (null === exc) { - logger.warn(msg) - } else { - logger.warn(msg,exc) - } - } - - /** @return true iff the current project has a project type that is supposed to generate code. */ - private def boolean isGenerateProjectType(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI) { - val project = ws.findProjectContaining(n4jsSourceURI); - if (project !== null) { - val projectType = project.getType(); - if (N4JSGlobals.PROJECT_TYPES_WITHOUT_GENERATION.contains(projectType)) { - return false; - } - } - - return true; - } - - /** @return true iff the given resource does not lie within the output folder. */ - private def boolean isOutsideOfOutputFolder(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI) { - return !containmentHelper.isContainedInOutputFolder(ws, n4jsSourceURI); - } - - /** @return true iff the output folder of the given n4js resource is not contained by a source container. */ - private def boolean isOutputNotInSourceContainer(N4JSWorkspaceConfigSnapshot ws, URI n4jsSourceURI) { - val project = ws.findProjectContaining(n4jsSourceURI); - if (project !== null) { - return !containmentHelper.isOutputContainedInSourceContainer(ws, project) - } else { - return false; - } - } - - /** - * Actual generation to be overridden by subclasses. - */ - protected def void internalDoGenerate(N4JSWorkspaceConfigSnapshot ws, Resource resource, GeneratorOption[] options, IFileSystemAccess access) - - /** - * Returns the name of the target file (without path) to which the source is to be compiled to. - * Default implementation returns a configured project Name with version + file name + extension. - * E.g., "proj-0.0.1/p/A.js" for a file A in proj. - * - * Convenience method, to provide all necessary API for the sub-classes. - * Delegates to {@link ResourceNameComputer#getTargetFileName}. - */ - protected def String getTargetFileName(Resource n4jsSourceFile, String compiledFileExtension) { - return resourceNameComputer.generateFileDescriptor(n4jsSourceFile, compiledFileExtension) - } - - /** - * Convenient access to the Script-Element - */ - protected def rootElement(Resource resource) { - resource.contents.filter(Script).head - } - - /** The file-extension of the compiled result */ - protected def String getCompiledFileExtension(Resource input) { - preferenceAccess.getPreference(input, getCompilerID(), CompilerProperties.COMPILED_FILE_EXTENSION, - getDefaultDescriptor()) - } - - /** The file-extension of the source-map to the compiled result */ - protected def String getCompiledFileSourceMapExtension(Resource input) { - preferenceAccess.getPreference(input, getCompilerID(), CompilerProperties.COMPILED_FILE_SOURCEMAP_EXTENSION, - getDefaultDescriptor()) - } - - /** Adjust output-path of the generator to match the N4JS projects-settings. */ - private def void updateOutputPath(N4JSWorkspaceConfigSnapshot ws, IFileSystemAccess fsa, String compilerID, Resource input) { - val outputPath = getOutputPath(ws, input.URI) ?: N4JSLanguageConstants.DEFAULT_PROJECT_OUTPUT; - if (fsa instanceof AbstractFileSystemAccess) { - val conf = fsa.outputConfigurations.get(compilerID) - if (conf !== null) { - conf.setOutputDirectory(outputPath) - } - } - } - - private static def String getOutputPath(N4JSWorkspaceConfigSnapshot ws, URI nestedLocation) { - return ws.findProjectContaining(nestedLocation)?.getProjectDescription()?.getOutputPath(); - } - - /** Navigation from the generated output-location to the location of the input-resource */ - protected def Path calculateNavigationFromOutputToSourcePath(N4JSWorkspaceConfigSnapshot ws, IFileSystemAccess fsa, String compilerID, N4JSResource input) { - // --- Project locations --- - val project = ws.findProjectContaining(input.URI); - - // /home/user/workspace/Project/ - val projectPath = project.pathAsFileURI.toFileSystemPath - // platform:/resource/Project/ - val projectLocURI = project.pathAsFileURI.withTrailingPathDelimiter.toURI - - // --- output locations --- - // src-gen - val outputPath = project.outputPath - // Project/a/b/c - val outputRelativeLocation = getOutputRelativeLocation(input) - - // --- source locations --- - // src/a/b/c - val inputURI = uriExtensions.withEmptyAuthority(input.URI); - val completetSourceURI = inputURI.trimSegments(1).deresolve(projectLocURI) - var completetSource = URIUtils.toFile(completetSourceURI).toString(); - - // Handling case when source container is the project root itself. (Sources { source { '.' } }) - if (null === completetSource && project.pathAsFileURI.toURI === input.URI.trimSegments(1)) { - completetSource = projectPath.toFile.absolutePath; - } - - // /home/user/workspace/Project/src-gen/a/b/c - val fullOutpath = projectPath.resolve(outputPath).normalize.resolve(outputRelativeLocation).normalize - // /home/user/workspace/Project/src/a/b/c - val fullSourcePath = projectPath.resolve(completetSource).normalize - - // ../../../../../../src/a/b/c - val rel = fullOutpath.relativize(fullSourcePath) - - return rel - } - - /** - * Calculates local output path for a given resource. - * Depending on the configuration this path can be in various forms, {@code Project-1.0.0/a/b/c/}, - * {@code Project/a/b/c/} or just {@code a/b/c/} - * - */ - private def Path getOutputRelativeLocation(N4JSResource input){ - val uri = uriExtensions.withEmptyAuthority(input.URI); - // Project/a/b/c/Input.XX - val localOutputFilePath = Paths.get(resourceNameComputer.generateFileDescriptor(input, uri, ".XX")) - - // if calculated path has just one element, e.g. "Input.XX" - // then local path segment is empty - if(localOutputFilePath.nameCount<2){ - return Paths.get("") - } - - //otherwise strip resource to get local path, i.e. Project/a/b/c/Input.XX => Project/a/b/c/ - return localOutputFilePath.subpath(0,localOutputFilePath.nameCount - 1) - } - - /** - * Convenience for {@link AbstractSubGenerator#calculateOutputDirectory(String, String)}, - * uses default compiler ID. - * - * TODO IDE-1487 currently there is no notion of default compiler. We fake call to the ES5 sub generator. - */ - def final static String calculateProjectBasedOutputDirectory(N4JSProjectConfigSnapshot project, boolean includeProjectName) { - return if (includeProjectName) project.packageName + "/" + project.outputPath else project.outputPath; - } - - /** Access to compiler ID */ - def abstract String getCompilerID() - - /** Access to compiler descriptor */ - def abstract CompilerDescriptor getDefaultDescriptor() - - /** Answers: Is this compiler activated for the input at hand? */ - def boolean isActive(Resource input) { - return Boolean.valueOf(preferenceAccess.getPreference(input, getCompilerID(), CompilerProperties.IS_ACTIVE, getDefaultDescriptor())) - } - - /** Checking the availability of a static polyfill, which will override the compilation of this module. - **/ - def boolean isNotStaticallyPolyfilled(Resource resource) { - // val TModule tmodule = (N4JSResource::getModule(resource) ); // for some reason xtend cannot see static getModule ?! - if (resource instanceof N4JSResource) { - val TModule tmodule = N4JSResource.getModule(resource) - // 1. resource must be StaticPolyfillAware and - // 2. there must exist a polyfilling instance (second instance with same fqn) - if (tmodule.isStaticPolyfillAware) { - // search for second instance. - if (staticPolyfillHelper.hasStaticPolyfill(resource)) { - return false; - } - } - } - return true; - } - - /** - * Checking if this resource represents a static polyfill, which will contribute to a filled resource. - **/ - private def boolean isStaticPolyfillingModule(Resource resource) { - val TModule tmodule = (N4JSResource.getModule(resource)); - if (null !== tmodule) { - return tmodule.isStaticPolyfillModule; - } - return false; - } - - /** - * - * @return true if the composite generator is applicable to the given resource and false otherwise. - */ - override boolean isApplicableTo(Resource input) { - return shouldBeCompiled(input, null); - } - - /** - * Depending on the file-extension, determines if the given resource requires actual transpilation as opposed to - * simply copying the source file to the output folder. - * - * @param eResource - * N4JS resource to check. - * @return true if the code requires transpilation. - */ - def protected boolean justCopy(Resource eResource) { - val resourceType = ResourceType.getResourceType(eResource); - return !(resourceType.equals(ResourceType.N4JS) || resourceType.equals(ResourceType.N4JSX) - || resourceType.equals(ResourceType.N4JSD)); - } - - /** - * Take the content of resource and copy it over to the output folder without any transformation. - * - * @param resource - * JS-code snippet which will be treated as text. - * @param fsa - * file system access - */ - def protected void copyWithoutTranspilation(Resource resource, IFileSystemAccess fsa) { - val outCode = new StringWriter(); - // get script - val script = resource.getContents().get(0); - - // obtain text - val scriptAsText = NodeModelUtils.getNode(script).getRootNode().getText(); - - // write - val decorated = scriptAsText.toString(); - outCode.write(decorated); - val filename = resourceNameComputer.generateFileDescriptor(resource, URIUtils.fileExtension(resource.getURI())); - fsa.generateFile(filename, compilerID, outCode.toString()); - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/GeneratorExceptionHandler.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/GeneratorExceptionHandler.java similarity index 58% rename from plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/GeneratorExceptionHandler.xtend rename to plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/GeneratorExceptionHandler.java index 2d21c7328c..2a58482697 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/GeneratorExceptionHandler.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/generator/GeneratorExceptionHandler.java @@ -8,20 +8,20 @@ * Contributors: * NumberFour AG - Initial API and implementation */ -package org.eclipse.n4js.generator +package org.eclipse.n4js.generator; /** * Code generator exception handler. */ -class GeneratorExceptionHandler { +public class GeneratorExceptionHandler { /** - * Prints provided message to the out stream, and the stack trace of the provided cause. - * Afterwards throws new {@link GeneratorException} wrapping provided cause. + * Prints provided message to the out stream, and the stack trace of the provided cause. Afterwards throws new + * {@link GeneratorException} wrapping provided cause. */ - def handleError(String message, Throwable cause) { - println(message) - cause.printStackTrace - throw new GeneratorException( message, cause); + public void handleError(String message, Throwable cause) { + System.out.println(message); + cause.printStackTrace(); + throw new GeneratorException(message, cause); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonBuilder.java new file mode 100644 index 0000000000..c91ec98e79 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonBuilder.java @@ -0,0 +1,380 @@ +/** + * 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.packagejson; + +import static com.google.common.base.Optional.fromNullable; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.eclipse.n4js.json.JSON.JSONDocument; +import org.eclipse.n4js.json.model.utils.JSONModelUtils; +import org.eclipse.n4js.packagejson.projectDescription.ProjectType; +import org.eclipse.n4js.packagejson.projectDescription.SourceContainerType; +import org.eclipse.n4js.utils.ProjectDescriptionLoader; +import org.eclipse.n4js.workspace.utils.N4JSPackageName; + +/** + * Convenient builder for creating the N4JS package.json compliant {@link JSONDocument} model instances or file + * content.# + * + * Provides support for most supported N4JS-specific package.json properties. See {@link ProjectDescriptionLoader} for + * details on all supported properties. + */ +@SuppressWarnings("hiding") +public class PackageJsonBuilder { + + /** + * Creates a new builder instance with a default project type of {@link ProjectType#VALIDATION}. + */ + public static PackageJsonBuilder newBuilder() { + return new PackageJsonBuilder(ProjectType.VALIDATION); // use project type 'validation' + } + + /** + * Creates a new builder instance without a default project type. Use this for creating a plain package.json without + * an "n4js" section. + */ + public static PackageJsonBuilder newPlainBuilder() { + return new PackageJsonBuilder(null); + } + + private String projectName; + private ProjectType type; + private String version; + private Boolean _private; + + private final SortedMap dependencies; + private final SortedMap devDependencies; + + private String vendorId; + private String vendorName; + + private String output; + + private final Collection providedRLs; + private final Collection requiredRLs; + private final Collection testedProjects; + private String extendedRE; + private final Collection implementedProjects; + private String implementationId; + + private final Map sourceContainers; + + private final Collection workspaces; + + private PackageJsonBuilder(ProjectType defaultProjectType) { + type = defaultProjectType; + providedRLs = new ArrayList<>(); + requiredRLs = new ArrayList<>(); + dependencies = new TreeMap<>(); + devDependencies = new TreeMap<>(); + implementedProjects = new ArrayList<>(); + testedProjects = new ArrayList<>(); + sourceContainers = new HashMap<>(); + workspaces = new ArrayList<>(); + } + + /** + * Builds the N4JS package.json file contents for a project with the given name. + * + * @return the N4JS package.json file contents as a string. + */ + public String build() { + JSONDocument document = this.buildModel(); + return JSONModelUtils.serializeJSON(document); + } + + /** + * Builds the N4JS package.json {@code JSONDocument} model representation. + * + * @return the N4JS package.json {@code JSONDocument} representation. + */ + public JSONDocument buildModel() { + return PackageJsonContentProvider.getModel( + fromNullable(projectName), + fromNullable(version), + fromNullable(_private), + workspaces, + fromNullable(type), + fromNullable(vendorId), + fromNullable(vendorName), + fromNullable(output), + fromNullable(extendedRE), + dependencies, + devDependencies, + providedRLs, + requiredRLs, + fromNullable(implementationId), + implementedProjects, + testedProjects, + sourceContainers); + } + + /** + * Sets the project name and returns with the builder. + * + * @param name + * The N4JS project name. + * @return the builder. + */ + public PackageJsonBuilder withName(String name) { + this.projectName = checkNotNull(name); + return this; + } + + /** + * Sets the project version and returns with the builder. + * + * @param version + * The project version. + * @return the builder. + */ + public PackageJsonBuilder withVersion(String version) { + this.version = checkNotNull(version); + return this; + } + + /** + * Adds top-level property "private" to the package.json, with the given value. + */ + public PackageJsonBuilder withPrivate(boolean _private) { + this._private = _private; + return this; + } + + /** + * Sets the project type and returns with the builder. + * + * @param type + * the N4JS project type. + * @return the builder. + */ + public PackageJsonBuilder withType(ProjectType type) { + this.type = checkNotNull(type); + return this; + } + + /** + * Sets the vendorId and returns with the builder. + * + * @param vendorId + * The project's vendor ID. + * @return the builder. + */ + public PackageJsonBuilder withVendorId(String vendorId) { + this.vendorId = vendorId; + return this; + } + + /** + * Sets the vendor name and returns with the builder. + * + * @param vendorName + * The project's vendor name. + * @return the builder. + */ + public PackageJsonBuilder withVendorName(String vendorName) { + this.vendorName = vendorName; + return this; + } + + /** + * Sets the output folder and returns with the builder. + * + * @param output + * The project's vendor name. + * @return the builder. + */ + public PackageJsonBuilder withOutput(String output) { + this.output = output; + return this; + } + + /** + * Adds a source container with the given folder specifier and type. + * + * @param type + * The source container type. + * @param path + * The source container path. + */ + public PackageJsonBuilder withSourceContainer(SourceContainerType type, String path) { + this.sourceContainers.put(checkNotNull(type), checkNotNull(path)); + return this; + } + + /** + * Sets the extended runtime environment on the builder. + * + * @param extendedRE + * the extended runtime environment. Optional. Can be {@code null}. + * @return the builder. + */ + public PackageJsonBuilder withExtendedRE(String extendedRE) { + this.extendedRE = extendedRE; + return this; + } + + /** + * Adds a new provided runtime library to the current builder. + * + * @param providedRL + * the provided runtime library to add to the current builder. Cannot be {@code null}. + * @return the builder. + */ + public PackageJsonBuilder withProvidedRL(String providedRL) { + providedRLs.add(checkNotNull(providedRL)); + return this; + } + + /** + * Adds a new required runtime library to the current builder. + * + * This method will add the required runtime library both to the "requiredRuntimeLibraries" section, as well as the + * "dependencies" section. + * + * @param requiredRL + * the required runtime library to add to the current builder. Cannot be {@code null}. + * @return the builder. + */ + public PackageJsonBuilder withRequiredRL(String requiredRL) { + requiredRLs.add(checkNotNull(requiredRL)); + // also add to dependencies + dependencies.put(requiredRL, "*"); + return this; + } + + /** + * Adds a new required runtime library with the given version constraint. + * + * This method will add the required runtime library both to the "requiredRuntimeLibraries" section, as well as the + * "dependencies" section. + * + * @param requiredRL + * The project id of the required runtime library. + * @param versionConstraint + * The version constraint to be used in the dependency section. + */ + public PackageJsonBuilder withRequiredRL(String requiredRL, String versionConstraint) { + requiredRLs.add(checkNotNull(requiredRL)); + // also add to dependencies + dependencies.put(requiredRL, versionConstraint); + return this; + } + + /** + * Adds a new project dependency to the current builder. + * + * @param projectDependency + * the project dependency to add to the current builder. Cannot be {@code null}. + * @return the builder. + */ + public PackageJsonBuilder withDependency(N4JSPackageName projectDependency) { + dependencies.put(checkNotNull(projectDependency).getRawName(), "*"); + return this; + } + + /** + * Adds a new project dependency to the current builder. + * + * @param projectDependency + * The project dependency to add to the current builder. Cannot be {@code null}. + * @param versionConstraint + * The version constraint of the added project dependency. + * + * @return the builder. + */ + public PackageJsonBuilder withDependency(N4JSPackageName projectDependency, String versionConstraint) { + dependencies.put(checkNotNull(projectDependency).getRawName(), checkNotNull(versionConstraint)); + return this; + } + + /** + * Adds a new project devDependency to the current builder. + * + * @param projectDevDependency + * the project devDependency to add to the current builder. Cannot be {@code null}. + * @return the builder. + */ + public PackageJsonBuilder withDevDependency(N4JSPackageName projectDevDependency) { + devDependencies.put(checkNotNull(projectDevDependency).getRawName(), "*"); + return this; + } + + /** + * Adds a new project devDependency to the current builder. + * + * @param projectDevDependency + * The project devDependency to add to the current builder. Cannot be {@code null}. + * @param versionConstraint + * The version constraint of the added project devDependency. + * + * @return the builder. + */ + public PackageJsonBuilder withDevDependency(String projectDevDependency, String versionConstraint) { + devDependencies.put(checkNotNull(projectDevDependency), checkNotNull(versionConstraint)); + return this; + } + + /** + * Adds the given project id to the list of tested projects. + * + * This method also adds the given tested project as project dependency. + */ + public PackageJsonBuilder withTestedProject(String testedProject) { + dependencies.put(checkNotNull(testedProject), "*"); + testedProjects.add(checkNotNull(testedProject)); + return this; + } + + /** + * Sets the implementation id to the current builder. + * + * @param implementationId + * id for the implementations to choose from. + * @return the builder. + */ + public PackageJsonBuilder withImplementationId(String implementationId) { + this.implementationId = checkNotNull(implementationId); + return this; + } + + /** + * Adds a project to the list of implemented Projects. + * + * @param implementationAPI + * id of the implemented API + * @return the builder. + */ + public PackageJsonBuilder withImplementedProject(String implementationAPI) { + implementedProjects.add(checkNotNull(implementationAPI)); + return this; + } + + /** Adds top-level property "workspaces" to the package.json, using an array with the given strings as value. */ + public PackageJsonBuilder withWorkspaces(String... workspaces) { + this.workspaces.addAll(Arrays.asList(workspaces)); + return this; + } + + @Override + public String toString() { + return "!!! This is just a preview of the N4JS package.json file !!!\n" + this.build(); + } + +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonBuilder.xtend deleted file mode 100644 index b85a94da8c..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonBuilder.xtend +++ /dev/null @@ -1,358 +0,0 @@ -/** - * 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.packagejson - -import java.util.Collection -import java.util.Map -import java.util.SortedMap -import java.util.TreeMap -import org.eclipse.n4js.json.JSON.JSONDocument -import org.eclipse.n4js.json.model.utils.JSONModelUtils -import org.eclipse.n4js.packagejson.projectDescription.ProjectType -import org.eclipse.n4js.packagejson.projectDescription.SourceContainerType -import org.eclipse.n4js.utils.ProjectDescriptionLoader - -import static com.google.common.base.Optional.fromNullable -import static com.google.common.base.Preconditions.checkNotNull -import org.eclipse.n4js.workspace.utils.N4JSPackageName - -/** - * Convenient builder for creating the N4JS package.json compliant {@link JSONDocument} model - * instances or file content.# - * - * Provides support for most supported N4JS-specific package.json properties. - * See {@link ProjectDescriptionLoader} for details on all supported properties. - */ -public class PackageJsonBuilder { - - /** - * Creates a new builder instance with a default project type of {@link ProjectType#VALIDATION}. - */ - public static def PackageJsonBuilder newBuilder() { - return new PackageJsonBuilder(ProjectType.VALIDATION); // use project type 'validation' - } - - /** - * Creates a new builder instance without a default project type. Use this for creating a - * plain package.json without an "n4js" section. - */ - public static def PackageJsonBuilder newPlainBuilder() { - return new PackageJsonBuilder(null); - } - - private String projectName; - private ProjectType type; - private String version; - private Boolean _private; - - private SortedMap dependencies; - private SortedMap devDependencies; - - private String vendorId; - private String vendorName; - - private String output; - - private Collection providedRLs; - private Collection requiredRLs; - private Collection testedProjects; - private String extendedRE; - private Collection implementedProjects; - private String implementationId; - - private Map sourceContainers; - - private Collection workspaces; - - private new(ProjectType defaultProjectType) { - type = defaultProjectType; - providedRLs = newArrayList - requiredRLs = newArrayList - dependencies = new TreeMap(); - devDependencies = new TreeMap(); - implementedProjects = newArrayList - testedProjects = newArrayList; - sourceContainers = newHashMap; - workspaces = newArrayList; - } - - /** - * Builds the N4JS package.json file contents for a project with the given name. - * - * @return the N4JS package.json file contents as a string. - */ - def String build() { - val document = this.buildModel(); - return JSONModelUtils.serializeJSON(document); - } - - /** - * Builds the N4JS package.json {@code JSONDocument} model representation. - * - * @return the N4JS package.json {@code JSONDocument} representation. - */ - def JSONDocument buildModel() { - return PackageJsonContentProvider.getModel( - fromNullable(projectName), - fromNullable(version), - fromNullable(_private), - workspaces, - fromNullable(type), - fromNullable(vendorId), - fromNullable(vendorName), - fromNullable(output), - fromNullable(extendedRE), - dependencies, - devDependencies, - providedRLs, - requiredRLs, - fromNullable(implementationId), - implementedProjects, - testedProjects, - sourceContainers); - } - - /** - * Sets the project name and returns with the builder. - * - * @param type The N4JS project name. - * @return the builder. - */ - def PackageJsonBuilder withName(String name) { - this.projectName = checkNotNull(name) - return this; - } - - /** - * Sets the project version and returns with the builder. - * - * @param version The project version. - * @return the builder. - */ - def PackageJsonBuilder withVersion(String version) { - this.version = checkNotNull(version) - return this; - } - - /** - * Adds top-level property "private" to the package.json, with the given value. - */ - def PackageJsonBuilder withPrivate(boolean _private) { - this._private = _private; - return this; - } - - /** - * Sets the project type and returns with the builder. - * - * @param type the N4JS project type. - * @return the builder. - */ - def PackageJsonBuilder withType(ProjectType type) { - this.type = checkNotNull(type) - return this; - } - - /** - * Sets the vendorId and returns with the builder. - * - * @param type The project's vendor ID. - * @return the builder. - */ - def PackageJsonBuilder withVendorId(String vendorId) { - this.vendorId = vendorId; - return this; - } - - /** - * Sets the vendor name and returns with the builder. - * - * @param type The project's vendor name. - * @return the builder. - */ - def PackageJsonBuilder withVendorName(String vendorName) { - this.vendorName = vendorName; - return this; - } - - /** - * Sets the output folder and returns with the builder. - * - * @param type The project's vendor name. - * @return the builder. - */ - def PackageJsonBuilder withOutput(String output) { - this.output = output; - return this; - } - - /** - * Adds a source container with the given folder specifier and type. - * - * @param type The source container type. - * @param path The source container path. - */ - def PackageJsonBuilder withSourceContainer(SourceContainerType type, String path) { - this.sourceContainers.put(checkNotNull(type), checkNotNull(path)); - return this; - } - - /** - * Sets the extended runtime environment on the builder. - * @param extendedRE the extended runtime environment. Optional. Can be {@code null}. - * @return the builder. - */ - def PackageJsonBuilder withExtendedRE(String extendedRE) { - this.extendedRE = extendedRE - return this; - } - - /** - * Adds a new provided runtime library to the current builder. - * @param providedRL the provided runtime library to add to the current builder. Cannot be {@code null}. - * @return the builder. - */ - def PackageJsonBuilder withProvidedRL(String providedRL) { - providedRLs.add(checkNotNull(providedRL)) - return this; - } - - /** - * Adds a new required runtime library to the current builder. - * - * This method will add the required runtime library both to the "requiredRuntimeLibraries" section, - * as well as the "dependencies" section. - * - * @param requiredRL the required runtime library to add to the current builder. Cannot be {@code null}. - * @return the builder. - */ - def PackageJsonBuilder withRequiredRL(String requiredRL) { - requiredRLs.add(checkNotNull(requiredRL)) - // also add to dependencies - dependencies.put(requiredRL, "*") - return this; - } - - /** - * Adds a new required runtime library with the given version constraint. - * - * This method will add the required runtime library both to the "requiredRuntimeLibraries" section, - * as well as the "dependencies" section. - * - * @param requiredRL The project id of the required runtime library. - * @param versionConstraint The version constraint to be used in the dependency section. - */ - def PackageJsonBuilder withRequiredRL(String requiredRL, String versionConstraint) { - requiredRLs.add(checkNotNull(requiredRL)) - // also add to dependencies - dependencies.put(requiredRL, versionConstraint) - return this; - } - - /** - * Adds a new project dependency to the current builder. - * @param projectDependency the project dependency to add to the current builder. Cannot be {@code null}. - * @return the builder. - */ - def PackageJsonBuilder withDependency(N4JSPackageName projectDependency) { - dependencies.put(checkNotNull(projectDependency).rawName, "*") - return this; - } - - /** - * Adds a new project dependency to the current builder. - * - * @param projectDependency The project dependency to add to the current builder. Cannot be {@code null}. - * @param versionConstraint The version constraint of the added project dependency. - * - * @return the builder. - */ - def PackageJsonBuilder withDependency(N4JSPackageName projectDependency, String versionConstraint) { - dependencies.put(checkNotNull(projectDependency).rawName, checkNotNull(versionConstraint)) - return this; - } - - /** - * Adds a new project devDependency to the current builder. - * @param projectDevDependency the project devDependency to add to the current builder. Cannot be {@code null}. - * @return the builder. - */ - def PackageJsonBuilder withDevDependency(N4JSPackageName projectDevDependency) { - devDependencies.put(checkNotNull(projectDevDependency).rawName, "*") - return this; - } - - /** - * Adds a new project devDependency to the current builder. - * - * @param projectDevDependency The project devDependency to add to the current builder. Cannot be {@code null}. - * @param versionConstraint The version constraint of the added project devDependency. - * - * @return the builder. - */ - def PackageJsonBuilder withDevDependency(String projectDevDependency, String versionConstraint) { - devDependencies.put(checkNotNull(projectDevDependency), checkNotNull(versionConstraint)) - return this; - } - - /** - * Adds the given project id to the list of tested projects. - * - * This method also adds the given tested project as project dependency. - */ - def PackageJsonBuilder withTestedProject(String testedProject) { - dependencies.put(checkNotNull(testedProject), "*"); - testedProjects.add(checkNotNull(testedProject)); - return this; - } - - /** - * Adds the given project id to the list of tested projects and to the list - * of dependencies with the given version constraint. - * - * This method also adds the given tested project as project dependency. - */ - def PackageJsonBuilder withTestedProject(String testedProject, String version) { - dependencies.put(checkNotNull(testedProject), "*"); - testedProjects.add(checkNotNull(testedProject)); - return this; - } - - /** Sets the implementation id to the current builder. - * @param implementationId id for the implementations to choose from. - * @return the builder. - */ - def PackageJsonBuilder withImplementationId(String implementationId) { - this.implementationId = checkNotNull(implementationId) - return this; - } - - /** Adds a project to the list of implemented Projects. - * NOTE: also call {@link withImplementationId()} - * @param project id of the implemented API - * @return the builder. - */ - def PackageJsonBuilder withImplementedProject(String implementationAPI) { - implementedProjects.add(checkNotNull(implementationAPI)) - return this; - } - - /** Adds top-level property "workspaces" to the package.json, using an array with the given strings as value. */ - def PackageJsonBuilder withWorkspaces(String... workspaces) { - this.workspaces.addAll(workspaces); - return this; - } - - override toString() { - return '!!! This is just a preview of the N4JS package.json file !!!\n' + this.build(); - } - -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonContentProvider.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonContentProvider.java new file mode 100644 index 0000000000..50206fa4ca --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonContentProvider.java @@ -0,0 +1,241 @@ +/** + * 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.packagejson; + +import static org.eclipse.n4js.packagejson.PackageJsonProperties.DEPENDENCIES; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.DEV_DEPENDENCIES; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.EXTENDED_RUNTIME_ENVIRONMENT; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.IMPLEMENTATION_ID; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.IMPLEMENTED_PROJECTS; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.N4JS; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.NAME; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.OUTPUT; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.PRIVATE; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.PROJECT_TYPE; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.PROVIDED_RUNTIME_LIBRARIES; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.REQUIRED_RUNTIME_LIBRARIES; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.SOURCES; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.TESTED_PROJECTS; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.VENDOR_ID; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.VENDOR_NAME; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.VERSION; +import static org.eclipse.n4js.packagejson.PackageJsonProperties.WORKSPACES_ARRAY; +import static org.eclipse.n4js.packagejson.PackageJsonUtils.getSourceContainerTypeStringRepresentation; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.groupBy; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.SortedMap; + +import org.eclipse.n4js.json.JSON.JSONArray; +import org.eclipse.n4js.json.JSON.JSONDocument; +import org.eclipse.n4js.json.JSON.JSONFactory; +import org.eclipse.n4js.json.JSON.JSONObject; +import org.eclipse.n4js.json.JSON.JSONStringLiteral; +import org.eclipse.n4js.json.JSON.NameValuePair; +import org.eclipse.n4js.json.model.utils.JSONModelUtils; +import org.eclipse.n4js.packagejson.projectDescription.ProjectType; +import org.eclipse.n4js.packagejson.projectDescription.SourceContainerType; + +import com.google.common.base.Optional; + +/** + * Class for providing the content of N4JS-specific package.json files. + * + * Use {@link PackageJsonBuilder} for creating package.json model instances and file content. + */ +class PackageJsonContentProvider { + + /** + * Creates and returns with the N4JS package.json {@link JSONDocument} representation based on the given arguments. + * + * @param projectName + * the N4JS project name of the project (cf. name). + * @param version + * The declared version of the project. + * @param type + * The type of the N4JS project. + * @param vendorId + * The vendorId to use. + * @param vendorName + * The name of the vendor as string. + * @param output + * The relative output folder location. + * @param extendedRE + * The optional extended runtime environment. + * @param dependencies + * A map of dependencies of the project (maps dependencies to their version constraints). + * @param providedRL + * An iterable of provided runtime libraries. + * @param requiredRL + * An iterable of required runtime libraries. + * @param implementationId + * The implementationId of the project. + * @param testedProjects + * A list of all projects that are being tested. + * @param sourceContainers + * A map of all source containers of the project. + * + * @return the N4JS package.json content as a string. + */ + static JSONDocument getModel( + Optional projectName, + Optional version, + Optional _private, + Iterable workspaces, + Optional type, + Optional vendorId, + Optional vendorName, + Optional output, + Optional extendedRE, + SortedMap dependencies, + SortedMap devDependencies, + Iterable providedRL, + Iterable requiredRL, + Optional implementationId, + Iterable implementedProjects, + Iterable testedProjects, + Map sourceContainers) { + JSONObject root = JSONFactory.eINSTANCE.createJSONObject(); + + if (projectName.isPresent()) + JSONModelUtils.addProperty(root, NAME.name, projectName.get()); + + if (version.isPresent()) + JSONModelUtils.addProperty(root, VERSION.name, version.get()); + + if (_private.isPresent()) { + JSONModelUtils.addProperty(root, PRIVATE.name, + JSONModelUtils.createBooleanLiteral(_private.get())); + } + + if (workspaces.iterator().hasNext()) { + JSONModelUtils.addProperty(root, WORKSPACES_ARRAY.name, + JSONModelUtils.createStringArray(workspaces)); + } + + // add "dependencies" section + if (!dependencies.isEmpty()) { + JSONObject dependenciesValue = createDependenciesValue(dependencies); + JSONModelUtils.addProperty(root, DEPENDENCIES.name, dependenciesValue); + } + + // add "devDependencies" section + if (!devDependencies.isEmpty()) { + JSONObject devDependenciesValue = createDependenciesValue(devDependencies); + JSONModelUtils.addProperty(root, DEV_DEPENDENCIES.name, devDependenciesValue); + } + + // create "n4js" section (will be added below iff it will be non-empty) + JSONObject n4jsRoot = JSONFactory.eINSTANCE.createJSONObject(); + + // project type + if (type.isPresent()) { + String projectTypeStr = PackageJsonUtils.getProjectTypeStringRepresentation(type.get()); + JSONModelUtils.addProperty(n4jsRoot, PROJECT_TYPE.name, projectTypeStr); + } + + // add vendor related properties + if (vendorId.isPresent()) + JSONModelUtils.addProperty(n4jsRoot, VENDOR_ID.name, vendorId.get()); + if (vendorName.isPresent()) + JSONModelUtils.addProperty(n4jsRoot, VENDOR_NAME.name, vendorName.get()); + + // add sources section + if (!sourceContainers.isEmpty()) { + JSONObject sourcesSection = JSONFactory.eINSTANCE.createJSONObject(); + JSONModelUtils.addProperty(n4jsRoot, SOURCES.name, sourcesSection); + + // add sources sub-sections + List> srcConts = new ArrayList<>(sourceContainers.entrySet()); + // sort by container type + Collections.sort(srcConts, + Comparator.comparing(e -> getSourceContainerTypeStringRepresentation(e.getKey()))); + // group by source container type + Map>> srcContsByPath = groupBy(srcConts, + e -> e.getKey()); + + // add source container sub-section for each specified source container type + for (SourceContainerType sct : srcContsByPath.keySet()) { + List> paths = srcContsByPath.get(sct); + JSONArray typeSectionArray = JSONFactory.eINSTANCE.createJSONArray(); + JSONModelUtils.addProperty(sourcesSection, + PackageJsonUtils.getSourceContainerTypeStringRepresentation(sct), typeSectionArray); + List pathLiterals = toList( + map(paths, pathEntry -> JSONModelUtils.createStringLiteral(pathEntry.getValue()))); + typeSectionArray.getElements().addAll(pathLiterals); + } + } + + // add output folder + if (output.isPresent()) + JSONModelUtils.addProperty(n4jsRoot, OUTPUT.name, output.get()); + + // add provided and required runtime libraries if given + if (providedRL.iterator().hasNext()) { + JSONModelUtils.addProperty(n4jsRoot, PROVIDED_RUNTIME_LIBRARIES.name, + JSONModelUtils.createStringArray(providedRL)); + } + if (requiredRL.iterator().hasNext()) { + JSONModelUtils.addProperty(n4jsRoot, REQUIRED_RUNTIME_LIBRARIES.name, + JSONModelUtils.createStringArray(requiredRL)); + } + + if (extendedRE.isPresent()) { + JSONModelUtils.addProperty(n4jsRoot, EXTENDED_RUNTIME_ENVIRONMENT.name, + extendedRE.get()); + } + if (implementationId.isPresent()) { + JSONModelUtils.addProperty(n4jsRoot, IMPLEMENTATION_ID.name, + implementationId.get()); + } + + if (implementedProjects.iterator().hasNext()) { + JSONModelUtils.addProperty(n4jsRoot, IMPLEMENTED_PROJECTS.name, + JSONModelUtils.createStringArray(implementedProjects)); + } + + if (testedProjects.iterator().hasNext()) { + JSONModelUtils.addProperty(n4jsRoot, TESTED_PROJECTS.name, + JSONModelUtils.createStringArray(testedProjects)); + } + + // add "n4js" section (if non-empty) + if (!n4jsRoot.getNameValuePairs().isEmpty()) { + JSONModelUtils.addProperty(root, N4JS.name, n4jsRoot); + } + + // finally serialize as JSONDocument + JSONDocument document = JSONFactory.eINSTANCE.createJSONDocument(); + document.setContent(root); + + return document; + } + + private static JSONObject createDependenciesValue(Map dependencies) { + JSONObject dependenciesValue = JSONFactory.eINSTANCE.createJSONObject(); + + List map = toList(map(dependencies.entrySet(), e -> { + NameValuePair pair = JSONFactory.eINSTANCE.createNameValuePair(); + pair.setName(e.getKey()); + pair.setValue(JSONModelUtils.createStringLiteral(e.getValue())); + return pair; + })); + dependenciesValue.getNameValuePairs().addAll(map); + return dependenciesValue; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonContentProvider.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonContentProvider.xtend deleted file mode 100644 index 1b36e0aa57..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/packagejson/PackageJsonContentProvider.xtend +++ /dev/null @@ -1,210 +0,0 @@ -/** - * 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.packagejson - -import com.google.common.base.Optional -import java.util.Map -import java.util.SortedMap -import org.eclipse.n4js.json.JSON.JSONArray -import org.eclipse.n4js.json.JSON.JSONDocument -import org.eclipse.n4js.json.JSON.JSONFactory -import org.eclipse.n4js.json.JSON.JSONObject -import org.eclipse.n4js.json.model.utils.JSONModelUtils -import org.eclipse.n4js.packagejson.projectDescription.ProjectType -import org.eclipse.n4js.packagejson.projectDescription.SourceContainerType - -import static org.eclipse.n4js.packagejson.PackageJsonProperties.DEPENDENCIES -import static org.eclipse.n4js.packagejson.PackageJsonProperties.DEV_DEPENDENCIES -import static org.eclipse.n4js.packagejson.PackageJsonProperties.EXTENDED_RUNTIME_ENVIRONMENT -import static org.eclipse.n4js.packagejson.PackageJsonProperties.IMPLEMENTATION_ID -import static org.eclipse.n4js.packagejson.PackageJsonProperties.IMPLEMENTED_PROJECTS -import static org.eclipse.n4js.packagejson.PackageJsonProperties.N4JS -import static org.eclipse.n4js.packagejson.PackageJsonProperties.NAME -import static org.eclipse.n4js.packagejson.PackageJsonProperties.OUTPUT -import static org.eclipse.n4js.packagejson.PackageJsonProperties.PRIVATE -import static org.eclipse.n4js.packagejson.PackageJsonProperties.PROJECT_TYPE -import static org.eclipse.n4js.packagejson.PackageJsonProperties.PROVIDED_RUNTIME_LIBRARIES -import static org.eclipse.n4js.packagejson.PackageJsonProperties.REQUIRED_RUNTIME_LIBRARIES -import static org.eclipse.n4js.packagejson.PackageJsonProperties.SOURCES -import static org.eclipse.n4js.packagejson.PackageJsonProperties.TESTED_PROJECTS -import static org.eclipse.n4js.packagejson.PackageJsonProperties.VENDOR_ID -import static org.eclipse.n4js.packagejson.PackageJsonProperties.VENDOR_NAME -import static org.eclipse.n4js.packagejson.PackageJsonProperties.VERSION -import static org.eclipse.n4js.packagejson.PackageJsonProperties.WORKSPACES_ARRAY - -/** - * Class for providing the content of N4JS-specific package.json files. - * - * Use {@link PackageJsonBuilder} for creating package.json model instances and file content. - */ -package class PackageJsonContentProvider { - - /** - * Creates and returns with the N4JS package.json {@link JSONDocument} representation - * based on the given arguments. - * - * @param projectName the N4JS project name of the project (cf. name). - * @param version The declared version of the project. - * @param type The type of the N4JS project. - * @param vendorId The vendorId to use. - * @param vendorName The name of the vendor as string. - * @param output The relative output folder location. - * @param extendedRE The optional extended runtime environment. - * @param dependencies A map of dependencies of the project (maps dependencies to their version constraints). - * @param providedRL An iterable of provided runtime libraries. - * @param requiredRL An iterable of required runtime libraries. - * @param implementationId The implementationId of the project. - * @param testedProject A list of all projects that are being tested. - * @param sourceContainers A map of all source containers of the project. - * - * @return the N4JS package.json content as a string. - */ - package static def JSONDocument getModel( - Optional projectName, - Optional version, - Optional _private, - Iterable workspaces, - Optional type, - Optional vendorId, - Optional vendorName, - Optional output, - Optional extendedRE, - SortedMap dependencies, - SortedMap devDependencies, - Iterable providedRL, - Iterable requiredRL, - Optional implementationId, - Iterable implementedProjects, - Iterable testedProjects, - Map sourceContainers - ) { - val JSONObject root = JSONFactory.eINSTANCE.createJSONObject(); - - if (projectName.present) - JSONModelUtils.addProperty(root, NAME.name, projectName.get()); - - if (version.present) - JSONModelUtils.addProperty(root, VERSION.name, version.get()); - - if (_private.present) { - JSONModelUtils.addProperty(root, PRIVATE.name, - JSONModelUtils.createBooleanLiteral(_private.get())); - } - - if (!workspaces.empty) { - JSONModelUtils.addProperty(root, WORKSPACES_ARRAY.name, - JSONModelUtils.createStringArray(workspaces)); - } - - // add "dependencies" section - if (!dependencies.empty) { - val dependenciesValue = createDependenciesValue(dependencies); - JSONModelUtils.addProperty(root, DEPENDENCIES.name, dependenciesValue); - } - - // add "devDependencies" section - if (!devDependencies.empty) { - val devDependenciesValue = createDependenciesValue(devDependencies); - JSONModelUtils.addProperty(root, DEV_DEPENDENCIES.name, devDependenciesValue); - } - - // create "n4js" section (will be added below iff it will be non-empty) - val JSONObject n4jsRoot = JSONFactory.eINSTANCE.createJSONObject(); - - // project type - if (type.present) { - val projectTypeStr = PackageJsonUtils.getProjectTypeStringRepresentation(type.get()); - JSONModelUtils.addProperty(n4jsRoot, PROJECT_TYPE.name, projectTypeStr); - } - - // add vendor related properties - if (vendorId.present) - JSONModelUtils.addProperty(n4jsRoot, VENDOR_ID.name, vendorId.get()); - if (vendorName.present) - JSONModelUtils.addProperty(n4jsRoot, VENDOR_NAME.name, vendorName.get()); - - // add sources section - if (!sourceContainers.empty) { - val JSONObject sourcesSection = JSONFactory.eINSTANCE.createJSONObject(); - JSONModelUtils.addProperty(n4jsRoot, SOURCES.name, sourcesSection); - - // add sources sub-sections - sourceContainers.entrySet - // sort by container type - .sortBy[ e | PackageJsonUtils.getSourceContainerTypeStringRepresentation(e.key) ] - // group by source container type - .groupBy[ e | e.key ] - // add source container sub-section for each specified source container type - .forEach[containerType, paths| - val JSONArray typeSectionArray = JSONFactory.eINSTANCE.createJSONArray(); - JSONModelUtils.addProperty(sourcesSection, - PackageJsonUtils.getSourceContainerTypeStringRepresentation(containerType), typeSectionArray); - val pathLiterals = paths.map[pathEntry | JSONModelUtils.createStringLiteral(pathEntry.value) ]; - typeSectionArray.getElements().addAll(pathLiterals); - ]; - } - - // add output folder - if (output.present) - JSONModelUtils.addProperty(n4jsRoot, OUTPUT.name, output.get()); - - // add provided and required runtime libraries if given - if (!providedRL.empty) { - JSONModelUtils.addProperty(n4jsRoot, PROVIDED_RUNTIME_LIBRARIES.name, - JSONModelUtils.createStringArray(providedRL)); - } - if (!requiredRL.empty) { - JSONModelUtils.addProperty(n4jsRoot, REQUIRED_RUNTIME_LIBRARIES.name, - JSONModelUtils.createStringArray(requiredRL)); - } - - if (extendedRE.isPresent) { - JSONModelUtils.addProperty(n4jsRoot, EXTENDED_RUNTIME_ENVIRONMENT.name, - extendedRE.get()); - } - if (implementationId.isPresent) { - JSONModelUtils.addProperty(n4jsRoot, IMPLEMENTATION_ID.name, - implementationId.get()); - } - - if (!implementedProjects.empty) { - JSONModelUtils.addProperty(n4jsRoot, IMPLEMENTED_PROJECTS.name, - JSONModelUtils.createStringArray(implementedProjects)); - } - - if (!testedProjects.empty) { - JSONModelUtils.addProperty(n4jsRoot, TESTED_PROJECTS.name, - JSONModelUtils.createStringArray(testedProjects)); - } - - // add "n4js" section (if non-empty) - if (!n4jsRoot.nameValuePairs.empty) { - JSONModelUtils.addProperty(root, N4JS.name, n4jsRoot); - } - - // finally serialize as JSONDocument - val JSONDocument document = JSONFactory.eINSTANCE.createJSONDocument(); - document.setContent(root); - - return document; - } - - private def static JSONObject createDependenciesValue(Map dependencies) { - val JSONObject dependenciesValue = JSONFactory.eINSTANCE.createJSONObject(); - dependenciesValue.nameValuePairs.addAll(dependencies.entrySet.map [ e | - val pair = JSONFactory.eINSTANCE.createNameValuePair(); - pair.name = e.key; - pair.value = JSONModelUtils.createStringLiteral(e.value); - return pair; - ]); - return dependenciesValue; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ASTProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ASTProcessor.java new file mode 100644 index 0000000000..20c34f159c --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ASTProcessor.java @@ -0,0 +1,563 @@ +/** + * 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.postprocessing; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.addCancelIndicator; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.getCancelIndicator; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.isCanceled; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.newRuleEnvironment; +import static org.eclipse.n4js.utils.N4JSLanguageUtils.isASTNode; +import static org.eclipse.n4js.utils.N4JSLanguageUtils.isIdentifiableSubtree; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filterNull; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.toIterable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.n4JS.Annotation; +import org.eclipse.n4js.n4JS.CatchBlock; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ForStatement; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName; +import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4JSASTUtils; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.PropertyGetterDeclaration; +import org.eclipse.n4js.n4JS.PropertyMethodDeclaration; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.n4JS.PropertySetterDeclaration; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.n4JS.SetterDeclaration; +import org.eclipse.n4js.n4JS.ThisLiteral; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.YieldExpression; +import org.eclipse.n4js.resource.N4JSResource; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.SyntaxRelatedTElement; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.TVariable; +import org.eclipse.n4js.ts.types.TypableElement; +import org.eclipse.n4js.ts.types.TypesPackage; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.utils.EcoreUtilN4; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.StaticPolyfillHelper; +import org.eclipse.xtext.resource.XtextResource; +import org.eclipse.xtext.util.CancelIndicator; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +/** + * Main processor used during {@link N4JSPostProcessor post-processing} of N4JS resources. It controls the overall work + * flow of processing the AST, but does not do any actual work; instead, it delegates to the other processors: + *
    + *
  • {@link TypeProcessor}, which delegates further to + *
      + *
    • {@link PolyProcessor}, which delegates further to + *
        + *
      • {@link PolyProcessor_ArrayLiteral} + *
      • {@link PolyProcessor_ObjectLiteral} + *
      • {@link PolyProcessor_FunctionExpression} + *
      • {@link PolyProcessor_CallExpression} + *
      + *
    • {@link DestructureProcessor} + *
    + *
  • {@code TypeExpectedProcessor} (coming soon!) + *
  • {@link TypeDeferredProcessor} + *
+ */ +@Singleton +public class ASTProcessor extends AbstractProcessor { + + @Inject + private ComputedNameProcessor computedNameProcessor; + @Inject + private TypeProcessor typeProcessor; + @Inject + private TypeRefProcessor typeRefProcessor; + @Inject + private TypeDeferredProcessor typeDeferredProcessor; + @Inject + private CompileTimeExpressionProcessor compileTimeExpressionProcessor; + @Inject + private RuntimeDependencyProcessor runtimeDependencyProcessor; + @Inject + private StaticPolyfillHelper staticPolyfillHelper; + + /** + * Entry point for processing of the entire AST of the given resource. Will throw IllegalStateException if called + * more than once per N4JSResource. + *

+ * This method performs some preparatory tasks (e.g., creating an instance of {@link ASTMetaInfoCache}) and ensures + * consistency by tracking the 'isProcessing' state with try/finally; for actual processing, this method delegates + * to method {@link #processAST(RuleEnvironment, Script, ASTMetaInfoCache)}. + * + * @param resource + * may not be null. + * @param cancelIndicator + * may be null. + */ + public void processAST(N4JSResource resource, CancelIndicator cancelIndicator) { + if (resource == null) + throw new IllegalArgumentException("resource may not be null"); + + // the following is required, because typing may have been initiated by resolution of a proxy + // -> when traversing the AST, we will sooner or later try to resolve this same proxy, which would be + // interpreted as a cyclic proxy resolution by method LazyLinkingResource#getEObject(String,Triple) + resource.clearResolving(); + + log(0, "### processing resource: " + resource.getURI()); + + Script script = resource.getScript(); + // we're during post-processing, so cache should be available now + ASTMetaInfoCache cache = resource.getASTMetaInfoCacheVerifyContext(); + RuleEnvironment G = newRuleEnvironment(resource); + addCancelIndicator(G, cancelIndicator); + try { + processAST(G, script, cache); + } finally { + if (isCanceled(G)) { + log(0, "CANCELED by cancelIndicator"); + } + + if (isDEBUG_LOG_RESULT()) { + log(0, "### result for " + resource.getURI()); + log(4, resource.getScript(), cache); + } + log(0, "### done: " + resource.getURI()); + } + } + + /** + * First method to actually perform processing of the AST. This method defines the various processing phases. + *

+ * There exists a single "main phase" where 95% of processing happens (entry point for this main phase is method + * {@link #processSubtree(RuleEnvironment, EObject, ASTMetaInfoCache, int)}), plus a number of smaller phases before + * and after that where some special handling is performed. + */ + private void processAST(RuleEnvironment G, Script script, ASTMetaInfoCache cache) { + // phase 0: process compile-time expressions & computed property names (order is important) + for (Expression node : toIterable(filter(script.eAllContents(), Expression.class))) { + compileTimeExpressionProcessor.evaluateCompileTimeExpression(G, node, cache); + } + for (LiteralOrComputedPropertyName node : toIterable( + filter(script.eAllContents(), LiteralOrComputedPropertyName.class))) { + computedNameProcessor.processComputedPropertyName(node, cache); + } + + // phase 1: main processing + processSubtree(G, script, cache, 0); + // phase 2: processing of postponed subtrees + EObject eObj; + while ((eObj = cache.postponedSubTrees.poll()) != null) { + // note: we need to allow adding more postponed subtrees inside this loop! + processSubtree(G, eObj, cache, 0); + } + // phase 3: store runtime and load-time dependencies in TModule + runtimeDependencyProcessor.storeDirectRuntimeDependenciesInTModule(script, cache); + } + + /** + * Process given node and all of its direct and indirect children. + * + * @param node + * the root of the subtree to process; must be an AST node. + */ + void processSubtree(RuleEnvironment G, EObject node, ASTMetaInfoCache cache, int indentLevel) { + assertTrueIfRigid(cache, "argument 'node' must be an AST node", isASTNode(node)); + + log(indentLevel, "processing: " + getObjectInfo(node)); + + checkCanceled(G); + + // already done as part of a forward processing? + if (cache.forwardProcessedSubTrees.contains(node)) { + if (isDEBUG_LOG()) { + log(indentLevel, "(subtree already processed as a forward reference)"); + if (node instanceof TypableElement) { + log(indentLevel, cache.getTypeFailSafe((TypableElement) node)); + } + } + return; + } + if (cache.postponedSubTrees.contains(node)) { + // in case this happens, you can either: + // * not postpone this node, or + // * handle the postponed node later (not as part of a forward reference) + throw new IllegalStateException("eager processing of postponed subtree"); + } + + if (!cache.astNodesCurrentlyBeingTyped.add(node)) { + // this subtree is currently being processed + // (can happen, for example, if we are processing a member (e.g. field) and during that processing we + // encounter a reference to the containing class (e.g. in the initializer expression)) + if (isDEBUG_LOG()) { + log(indentLevel, "(subtree currently in progress - skipping)"); + } + return; + } + + try { + // process node itself - part 1 (before child processing) + processNode_preChildren(G, node, cache); + + // process the children + List children = childrenToBeProcessed(node); + for (EObject child : children) { + if (isPostponedNode(child)) { + // postpone + cache.postponedSubTrees.add(child); + } else { + // process now + processSubtree(G, child, cache, indentLevel + 1); + checkCanceled(G); + } + } + + // process node itself - part 2 (after child processing) + processNode_postChildren(G, node, cache, indentLevel); + + // we're done with this node, but make sure that all proxies have actually been resolved + // (this is important mainly for two reasons: (1) post-processing is often triggered by a call to + // N4JSResource#resolveLazyCrossReferences(CancelIndicator), so we have to guarantee that all lazy + // cross-references are actually resolved; (2) the type system may not resolve all proxies and some + // nodes are not typed at all (i.e. isTypableNode() returns false), so we have to enforce this here. + + // We also perform all processing, related to outgoing references from the current node at this point. + resolveAndProcessReferencesInNode(node, cache); + + } finally { + cache.astNodesCurrentlyBeingTyped.remove(node); + } + } + + private boolean isPostponedNode(EObject node) { + return isPostponedInitializer(node) + || N4JSASTUtils.isBodyOfFunctionOrFieldAccessor(node); + } + + /** + * Initializers are postponed iff: + *

    + *
  • Node is an initializer of a FormalParameter p,
  • + *
  • and p is part of a Poly FunctionExpression f,
  • + *
  • and p contains references to other FormalParameters of f, or f itself.
  • + *
+ */ + private boolean isPostponedInitializer(EObject node) { + boolean isPostponedInitializer = false; + EObject fp = node.eContainer(); + if (fp instanceof FormalParameter) { + FormalParameter fpar = (FormalParameter) fp; + if (node instanceof Expression) { + if (fpar.isHasInitializerAssignment()) { + EObject funDefObj = fpar.eContainer(); + // IdentifierRef in Initializers can cause cyclic dependencies + if (funDefObj instanceof FunctionExpression) { + FunctionExpression funDef = (FunctionExpression) funDefObj; + // Check if the initializer refers to other fpars + EList allFPars = funDef.getFpars(); + List allRefs = EcoreUtilN4.getAllContentsOfTypeStopAt(fpar, IdentifierRef.class, + N4JSPackage.Literals.FUNCTION_OR_FIELD_ACCESSOR__BODY); + + for (IdentifierRef ir : allRefs) { + Object id = ir.getId(); + if (id instanceof SyntaxRelatedTElement) { + id = ((SyntaxRelatedTElement) id) + .eGet(TypesPackage.eINSTANCE.getSyntaxRelatedTElement_AstElement(), false); + } + boolean idRefCausesCyclDep = allFPars.contains(id) // f(p, q=p) {} + || id instanceof VariableDeclaration + && ((VariableDeclaration) id).getExpression() == funDef; // f(p, q=f(1)) {} + if (idRefCausesCyclDep) { + isPostponedInitializer = true; + } + } + } + // In ObjectLiterals, the ThisLiteral in Initializers can cause cyclic dependencies + // TODO GH-1337 add support for spread operator + boolean thisLiteralCausesCyclDep = + // let o = { a:1, f(p=this.a) {} } + funDefObj instanceof PropertyMethodDeclaration + || + // let o = {a:2, f: function(p=this.a) {}} + funDefObj instanceof FunctionExpression + && funDefObj.eContainer() instanceof PropertyNameValuePair; + + if (thisLiteralCausesCyclDep) { + boolean containsThisLiteral = EcoreUtilN4.containsContentsOfTypeStopAt(fpar, ThisLiteral.class, + N4JSPackage.Literals.FUNCTION_OR_FIELD_ACCESSOR__BODY); + if (containsThisLiteral) { + isPostponedInitializer = true; + } + } + // If this check is not sufficient, we have to add more checks here. Note: Setters never have + // initializers. + } + } + } + return isPostponedInitializer; + } + + /** + * Forward-process given node and all of its direct and indirect children. + *

+ * Via this method, other processors can request a forward processing of some subtree. Does nothing if the given + * node was processed already, either as part of a forward reference or during normal processing. + * + * @return true iff the forward processing is legal, false otherwise. + */ + boolean processSubtree_forwardReference(RuleEnvironment G, TypableElement node, ASTMetaInfoCache cache) { + assertTrueIfRigid(cache, "argument 'node' must be an AST node", isASTNode(node)); + + // is node a valid target for a forward reference (i.e. an identifiable subtree)? + boolean valid = isIdentifiableSubtree(node) || isExceptionCaseOfForwardReferencableSubtree(node); + if (!valid) { + XtextResource resource = (XtextResource) node.eResource(); + if (resource != null) { + assertTrueIfRigid(cache, + "forward reference only allowed to identifiable subtrees; but was: " + node + " in\n" + + resource.getParseResult().getRootNode().getText(), + valid); + } else { + assertTrueIfRigid(cache, "forward reference only allowed to identifiable subtrees; but was: " + node, + valid); + } + } + + TypeRef fromCache = cache.getTypeFailSafe(node); + if (fromCache != null) { + // already processed, nothing else to do + // note: this is not an error, we may have many forward references to the same identifiable subtree + return true; + } + + if (cache.astNodesCurrentlyBeingTyped.contains(node)) { + // cyclic forward reference + // legal cases of a cyclic reference + // TODO GH-1337 add support for spread operator + boolean isCyclicForwardReference = cache.astNodesCurrentlyBeingTyped.contains(node); + if (isCyclicForwardReference && (node instanceof VariableDeclaration + || node instanceof N4ClassifierDeclaration + || node instanceof N4FieldDeclaration + || (node instanceof PropertyNameValuePair + && ((PropertyNameValuePair) node).getExpression() instanceof FunctionExpression) + || node instanceof PropertyGetterDeclaration || node instanceof PropertySetterDeclaration + || (node instanceof Expression && node.eContainer() instanceof YieldExpression))) { + return true; + } + + // illegal cyclic node inference + String msg = "*#*#*#*#*#* illegal cyclic forward reference to " + getObjectInfo(node) + + " (resource: " + (node.eResource() == null ? "null" : node.eResource().getURI()) + ")"; + logErr(msg); + return false; + } else if (isSemiCyclicForwardReferenceInForLoop(node, cache)) { + // semi-cyclic forward reference + // (this is deemed legal for the same reason why 'var x = 1+x;' is treated as a legal forward reference) + return true; + } + + if (cache.forwardProcessedSubTrees.contains(node)) { + // we saw above that the cache does not contain anything for node, so this is an error + throw new IllegalStateException(); + } + + // actually perform the forward processing + log(0, "==START of identifiable sub-tree below " + getObjectInfo(node)); + RuleEnvironment G_fresh = newRuleEnvironment(G); // use a new, empty environment here (but retain + // cancelIndicator!) + processSubtree(G_fresh, node, cache, 0); // note how we reset the indent level + cache.forwardProcessedSubTrees.add(node); + log(0, "==END of identifiable sub-tree below " + getObjectInfo(node)); + + return true; + } + + // --------------------------------------------------------------------------------------------------------------- + + /** + * Top-down processing of AST nodes happens here, i.e. this method will see all AST nodes in a top-down order. + */ + private void processNode_preChildren(RuleEnvironment G, EObject node, ASTMetaInfoCache cache) { + typeRefProcessor.handleTypeRefs(G, node, cache); + + if (node instanceof FunctionDefinition) { + handleAsyncOrGeneratorFunctionDefinition(G, (FunctionDefinition) node); + } + + typeDeferredProcessor.handleDeferredTypeRefs_preChildren(G, node, cache); + } + + /** + * Bottom-up processing of AST nodes happens here, i.e. this method will see all AST nodes in a bottom-up order. + */ + private void processNode_postChildren(RuleEnvironment G, EObject node, ASTMetaInfoCache cache, int indentLevel) { + + typeDeferredProcessor.handleDeferredTypeRefs_postChildren(G, node, cache); + + typeProcessor.typeNode(G, node, cache, indentLevel); + /* + * references to other files via import statements NOTE: for all imports except bare imports, the following is + * unnecessary, because post-processing of the target resource would be triggered automatically as soon as type + * inference is performed on an element imported from the target resource. However, by doing this eagerly up + * front, the overall flow of post-processing across multiple resources is a bit easier to understand/predict. + * This does not lead to any additional processing being done (it's just done a bit earlier), except in case of + * unused imports. + */ + if (node instanceof ImportDeclaration) { + TModule targetModule = ((ImportDeclaration) node).getModule(); + if (targetModule != null && !targetModule.eIsProxy()) { + Resource targetResource = targetModule.eResource(); + if (targetResource instanceof N4JSResource) { + // trigger post-processing of target resource + ((N4JSResource) targetResource).performPostProcessing(getCancelIndicator(G)); + } + } + } + + if (node instanceof Annotation) { + if (Objects.equals(((Annotation) node).getName(), AnnotationDefinition.STATIC_POLYFILL_AWARE.name)) { + N4JSResource resSPoly = staticPolyfillHelper.getStaticPolyfillResource(node.eResource()); + if (resSPoly != null) { + // trigger post-processing of poly filler + resSPoly.performPostProcessing(getCancelIndicator(G)); + } + } + } + + runtimeDependencyProcessor.recordRuntimeReferencesInCache(node, cache); + } + + // --------------------------------------------------------------------------------------------------------------- + + /** + * This method returns the direct children of 'obj' that are to be processed, in the order in which they are to + * be processed. By default, all direct children must be processed and the order is insignificant, so in the + * default case this method simply returns {@link EObject#eContents()}. However, this method implements special + * handling for some exception cases where the processing order is significant. + */ + private List childrenToBeProcessed(EObject obj) { + if (obj instanceof SetterDeclaration) { + // process formal parameter before body + return bringToFront(obj.eContents(), ((SetterDeclaration) obj).getFpar()); + } + if (obj instanceof FunctionDefinition) { + // process formal parameters before body + return bringToFront(obj.eContents(), ((FunctionDefinition) obj).getFpars().toArray(new EObject[0])); + } + if (obj instanceof CatchBlock) { + // process catch variable before block + return bringToFront(obj.eContents(), ((CatchBlock) obj).getCatchVariable()); + } + if (obj instanceof ForStatement) { + // process expression before varDeclOrBindings + return bringToFront(obj.eContents(), ((ForStatement) obj).getExpression()); + } + // standard case: order is insignificant (so we simply use the order provided by EMF) + return obj.eContents(); + } + + // --------------------------------------------------------------------------------------------------------------- + + /** + * Normally, forward references are allowed only to {@link N4JSLanguageUtils#isIdentifiableSubtree(EObject) + * identifiable subtrees}. However, there are exception cases that are also allowed and this method returns + * true for those cases. + */ + private static boolean isExceptionCaseOfForwardReferencableSubtree(EObject astNode) { + return isExpressionInForOf(astNode); + } + + private static boolean isExpressionInForOf(EObject astNode) { + return astNode instanceof Expression && astNode.eContainer() instanceof ForStatement + && ((ForStatement) astNode.eContainer()).isForOf() + && astNode.eContainingFeature() == N4JSPackage.eINSTANCE.getIterationStatement_Expression(); + } + + /** + * Returns true if we have a semi-cyclic reference to a variable declaration in a for in/of loop. For example: + * + *

+	 * for(var x of foo(x)) {}
+	 * 
+ */ + boolean isSemiCyclicForwardReferenceInForLoop(EObject node, ASTMetaInfoCache cache) { + if (node instanceof VariableDeclaration) { + EObject parent = node.eContainer(); + if (parent instanceof ForStatement) { + ForStatement fs = (ForStatement) parent; + return (fs.isForIn() || fs.isForOf()) && cache.astNodesCurrentlyBeingTyped.contains(fs.getExpression()); + } + } + return false; + } + + private void resolveAndProcessReferencesInNode(EObject astNode, ASTMetaInfoCache cache) { + for (EReference eRef : astNode.eClass().getEAllReferences()) { + if (!eRef.isContainment() && !eRef.isContainer()) { // only cross-references have proxies (in our case) + Object node = astNode.eGet(eRef, true); + + if (node instanceof EObject) { + recordReferencesToLocalVariables(eRef, astNode, (EObject) node, cache); + } + } + } + } + + private void recordReferencesToLocalVariables(EReference reference, EObject sourceNode, EObject target, + ASTMetaInfoCache cache) { + // skip reference Variable#definedVariable (it does not constitute a usage of the variable) + if (reference == N4JSPackage.Literals.ABSTRACT_VARIABLE__DEFINED_VARIABLE) { + return; + } + // If target is still a proxy its resolution failed, therefore it should be skipped. + if (target.eIsProxy()) { + return; + } + // skip non-local references + if (sourceNode.eResource() != target.eResource()) { + return; + } + if (target instanceof TVariable) { + // don't record references to directly exported variables + if (((TVariable) target).isDirectlyExported()) { + return; + } + + cache.storeLocalVariableReference((TVariable) target, sourceNode); + } + } + + private List bringToFront(List l, EObject... elements) { + List result = new ArrayList<>(l); + List elemSanitized = toList(filterNull(Arrays.asList(elements))); + result.removeAll(elemSanitized); + result.addAll(0, elemSanitized); + return result; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ASTProcessor.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ASTProcessor.xtend deleted file mode 100644 index e214de2616..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ASTProcessor.xtend +++ /dev/null @@ -1,540 +0,0 @@ -/** - * 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.postprocessing - -import com.google.inject.Inject -import com.google.inject.Singleton -import java.util.ArrayList -import java.util.List -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.EReference -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.Annotation -import org.eclipse.n4js.n4JS.CatchBlock -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.ForStatement -import org.eclipse.n4js.n4JS.FormalParameter -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.FunctionExpression -import org.eclipse.n4js.n4JS.IdentifierRef -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.N4JSASTUtils -import org.eclipse.n4js.n4JS.N4JSPackage -import org.eclipse.n4js.n4JS.PropertyGetterDeclaration -import org.eclipse.n4js.n4JS.PropertyMethodDeclaration -import org.eclipse.n4js.n4JS.PropertyNameValuePair -import org.eclipse.n4js.n4JS.PropertySetterDeclaration -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.n4JS.SetterDeclaration -import org.eclipse.n4js.n4JS.ThisLiteral -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.n4JS.YieldExpression -import org.eclipse.n4js.resource.N4JSResource -import org.eclipse.n4js.ts.types.SyntaxRelatedTElement -import org.eclipse.n4js.ts.types.TVariable -import org.eclipse.n4js.ts.types.TypableElement -import org.eclipse.n4js.ts.types.TypesPackage -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.utils.EcoreUtilN4 -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.StaticPolyfillHelper -import org.eclipse.xtext.resource.XtextResource -import org.eclipse.xtext.util.CancelIndicator - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* -import static extension org.eclipse.n4js.utils.N4JSLanguageUtils.* - -/** - * Main processor used during {@link N4JSPostProcessor post-processing} of N4JS resources. It controls the overall - * work flow of processing the AST, but does not do any actual work; instead, it delegates to the other processors: - *
    - *
  • {@link TypeProcessor}, which delegates further to - *
      - *
    • {@link PolyProcessor}, which delegates further to - *
        - *
      • {@link PolyProcessor_ArrayLiteral} - *
      • {@link PolyProcessor_ObjectLiteral} - *
      • {@link PolyProcessor_FunctionExpression} - *
      • {@link PolyProcessor_CallExpression} - *
      - *
    • {@link DestructureProcessor} - *
    - *
  • {@code TypeExpectedProcessor} (coming soon!) - *
  • {@link TypeDeferredProcessor} - *
- */ -@Singleton -public class ASTProcessor extends AbstractProcessor { - - @Inject - private ComputedNameProcessor computedNameProcessor; - @Inject - private TypeProcessor typeProcessor; - @Inject - private TypeRefProcessor typeRefProcessor; - @Inject - private TypeDeferredProcessor typeDeferredProcessor; - @Inject - private CompileTimeExpressionProcessor compileTimeExpressionProcessor; - @Inject - private RuntimeDependencyProcessor runtimeDependencyProcessor; - @Inject - private StaticPolyfillHelper staticPolyfillHelper - - /** - * Entry point for processing of the entire AST of the given resource. - * Will throw IllegalStateException if called more than once per N4JSResource. - *

- * This method performs some preparatory tasks (e.g., creating an instance of {@link ASTMetaInfoCache}) and ensures - * consistency by tracking the 'isProcessing' state with try/finally; for actual processing, this method delegates - * to method {@link #processAST(RuleEnvironment, Script, ASTMetaInfoCache)}. - * - * @param resource may not be null. - * @param cancelIndicator may be null. - */ - def public void processAST(N4JSResource resource, CancelIndicator cancelIndicator) { - if (resource === null) - throw new IllegalArgumentException("resource may not be null"); - - // the following is required, because typing may have been initiated by resolution of a proxy - // -> when traversing the AST, we will sooner or later try to resolve this same proxy, which would be - // interpreted as a cyclic proxy resolution by method LazyLinkingResource#getEObject(String,Triple) - resource.clearResolving(); - - log(0, "### processing resource: " + resource.URI); - - val script = resource.script; - val cache = resource.getASTMetaInfoCacheVerifyContext(); // we're during post-processing, so cache should be available now - val G = resource.newRuleEnvironment; - G.addCancelIndicator(cancelIndicator); - try { - processAST(G, script, cache); - } finally { - if (G.canceled) { - log(0, "CANCELED by cancelIndicator"); - } - - if (isDEBUG_LOG_RESULT) { - log(0, "### result for " + resource.URI); - log(4, resource.script, cache); - } - log(0, "### done: " + resource.URI); - } - } - - /** - * First method to actually perform processing of the AST. This method defines the various processing phases. - *

- * There exists a single "main phase" where 95% of processing happens (entry point for this main phase is method - * {@link #processSubtree(RuleEnvironment, EObject, ASTMetaInfoCache, int)}), plus a number of smaller phases before - * and after that where some special handling is performed. - * - * @param resource may not be null. - * @param cancelIndicator may be null. - */ - def private void processAST(RuleEnvironment G, Script script, ASTMetaInfoCache cache) { - // phase 0: process compile-time expressions & computed property names (order is important) - for(node : script.eAllContents.filter(Expression).toIterable) { - compileTimeExpressionProcessor.evaluateCompileTimeExpression(G, node, cache, 0); - } - for(node : script.eAllContents.filter(LiteralOrComputedPropertyName).toIterable) { - computedNameProcessor.processComputedPropertyName(G, node, cache, 0); - } - - // phase 1: main processing - processSubtree(G, script, cache, 0); - // phase 2: processing of postponed subtrees - var EObject eObj; - while ((eObj = cache.postponedSubTrees.poll) !== null) { - // note: we need to allow adding more postponed subtrees inside this loop! - processSubtree(G, eObj, cache, 0); - } - // phase 3: store runtime and load-time dependencies in TModule - runtimeDependencyProcessor.storeDirectRuntimeDependenciesInTModule(script, cache); - } - - /** - * Process given node and all of its direct and indirect children. - * - * @param node the root of the subtree to process; must be an AST node. - */ - def package void processSubtree(RuleEnvironment G, EObject node, ASTMetaInfoCache cache, int indentLevel) { - assertTrueIfRigid(cache, "argument 'node' must be an AST node", node.isASTNode); - - log(indentLevel, "processing: " + node.objectInfo); - - checkCanceled(G); - - // already done as part of a forward processing? - if (cache.forwardProcessedSubTrees.contains(node)) { - if (isDEBUG_LOG) { - log(indentLevel, "(subtree already processed as a forward reference)"); - if(node instanceof TypableElement) { - log(indentLevel, cache.getTypeFailSafe(node)); - } - } - return; - } - if (cache.postponedSubTrees.contains(node)) { - // in case this happens, you can either: - // * not postpone this node, or - // * handle the postponed node later (not as part of a forward reference) - throw new IllegalStateException("eager processing of postponed subtree"); - } - - if (!cache.astNodesCurrentlyBeingTyped.add(node)) { - // this subtree is currently being processed - // (can happen, for example, if we are processing a member (e.g. field) and during that processing we - // encounter a reference to the containing class (e.g. in the initializer expression)) - if (isDEBUG_LOG) { - log(indentLevel, "(subtree currently in progress - skipping)"); - } - return; - } - - try { - // process node itself - part 1 (before child processing) - processNode_preChildren(G, node, cache, indentLevel); - - // process the children - val children = childrenToBeProcessed(G, node); - for (child : children) { - if (isPostponedNode(child)) { - // postpone - cache.postponedSubTrees.add(child); - } else { - // process now - processSubtree(G, child, cache, indentLevel + 1); - checkCanceled(G); - } - } - - // process node itself - part 2 (after child processing) - processNode_postChildren(G, node, cache, indentLevel); - - // we're done with this node, but make sure that all proxies have actually been resolved - // (this is important mainly for two reasons: (1) post-processing is often triggered by a call to - // N4JSResource#resolveLazyCrossReferences(CancelIndicator), so we have to guarantee that all lazy - // cross-references are actually resolved; (2) the type system may not resolve all proxies and some - // nodes are not typed at all (i.e. isTypableNode() returns false), so we have to enforce this here. - - // We also perform all processing, related to outgoing references from the current node at this point. - resolveAndProcessReferencesInNode(node, cache); - - } finally { - cache.astNodesCurrentlyBeingTyped.remove(node); - } - } - - def private boolean isPostponedNode(EObject node) { - return isPostponedInitializer(node) - || N4JSASTUtils.isBodyOfFunctionOrFieldAccessor(node); - } - - /** - * Initializers are postponed iff: - *

    - *
  • Node is an initializer of a FormalParameter p,
  • - *
  • and p is part of a Poly FunctionExpression f,
  • - *
  • and p contains references to other FormalParameters of f, or f itself.
  • - *
- */ - def private boolean isPostponedInitializer(EObject node) { - var boolean isPostponedInitializer = false; - val fpar = node.eContainer; - if (fpar instanceof FormalParameter) { - if (node instanceof Expression) { - if (fpar.hasInitializerAssignment) { - val funDef = fpar.eContainer; - // IdentifierRef in Initializers can cause cyclic dependencies - if (funDef instanceof FunctionExpression) { - // Check if the initializer refers to other fpars - val allFPars = funDef.fpars; - val allRefs = EcoreUtilN4.getAllContentsOfTypeStopAt(fpar, IdentifierRef, N4JSPackage.Literals.FUNCTION_OR_FIELD_ACCESSOR__BODY); - - for (IdentifierRef ir : allRefs) { - var Object id = ir.getId(); - if (id instanceof SyntaxRelatedTElement) { - id = id.eGet(TypesPackage.eINSTANCE.syntaxRelatedTElement_AstElement, false); - } - val idRefCausesCyclDep = - allFPars.contains(id) // f(p, q=p) {} - || id instanceof VariableDeclaration && (id as VariableDeclaration).expression === funDef; // f(p, q=f(1)) {} - if (idRefCausesCyclDep) { - isPostponedInitializer = true; - } - } - } - // In ObjectLiterals, the ThisLiteral in Initializers can cause cyclic dependencies - // TODO GH-1337 add support for spread operator - val thisLiteralCausesCyclDep = - funDef instanceof PropertyMethodDeclaration // let o = { a:1, f(p=this.a) {} } - || funDef instanceof FunctionExpression && funDef.eContainer instanceof PropertyNameValuePair; // let o = {a:2, f: function(p=this.a) {}} - if (thisLiteralCausesCyclDep) { - val containsThisLiteral = EcoreUtilN4.containsContentsOfTypeStopAt(fpar, ThisLiteral, N4JSPackage.Literals.FUNCTION_OR_FIELD_ACCESSOR__BODY); - if (containsThisLiteral) { - isPostponedInitializer = true; - } - } - // If this check is not sufficient, we have to add more checks here. Note: Setters never have initializers. - } - } - } - return isPostponedInitializer; - } - - /** - * Forward-process given node and all of its direct and indirect children. - *

- * Via this method, other processors can request a forward processing of some subtree. Does nothing if the given - * node was processed already, either as part of a forward reference or during normal processing. - * - * @return true iff the forward processing is legal, false otherwise. - */ - def package boolean processSubtree_forwardReference(RuleEnvironment G, TypableElement node, ASTMetaInfoCache cache) { - assertTrueIfRigid(cache, "argument 'node' must be an AST node", node.isASTNode); - - // is node a valid target for a forward reference (i.e. an identifiable subtree)? - val valid = node.isIdentifiableSubtree || node.isExceptionCaseOfForwardReferencableSubtree; - if (!valid) { - val resource = node.eResource as XtextResource - if (resource !== null) { - assertTrueIfRigid(cache, - "forward reference only allowed to identifiable subtrees; but was: " + node + " in\n" + - resource.parseResult.rootNode.text, valid) - } else { - assertTrueIfRigid(cache, "forward reference only allowed to identifiable subtrees; but was: " + node, valid); - } - } - - val fromCache = cache.getTypeFailSafe(node); - if (fromCache !== null) { - // already processed, nothing else to do - // note: this is not an error, we may have many forward references to the same identifiable subtree - return true; - } - - if (cache.astNodesCurrentlyBeingTyped.contains(node)) { - // cyclic forward reference - // legal cases of a cyclic reference - // TODO GH-1337 add support for spread operator - val isCyclicForwardReference = cache.astNodesCurrentlyBeingTyped.contains(node); - if (isCyclicForwardReference && ( - node instanceof VariableDeclaration - || node instanceof N4ClassifierDeclaration - || node instanceof N4FieldDeclaration - || (node instanceof PropertyNameValuePair && (node as PropertyNameValuePair).expression instanceof FunctionExpression) - || node instanceof PropertyGetterDeclaration || node instanceof PropertySetterDeclaration - || (node instanceof Expression && node.eContainer instanceof YieldExpression) - )) { - return true; - } - - // illegal cyclic node inference - val msg = "*#*#*#*#*#* illegal cyclic forward reference to " + node.objectInfo + " (resource: " - + node.eResource?.URI + ")"; - logErr(msg); - return false; - } else if (isSemiCyclicForwardReferenceInForLoop(node, cache)) { - // semi-cyclic forward reference - // (this is deemed legal for the same reason why 'var x = 1+x;' is treated as a legal forward reference) - return true; - } - - if (cache.forwardProcessedSubTrees.contains(node)) { - // we saw above that the cache does not contain anything for node, so this is an error - throw new IllegalStateException - } - - // actually perform the forward processing - log(0, "===START of identifiable sub-tree below " + node.objectInfo); - val G_fresh = G.newRuleEnvironment; // use a new, empty environment here (but retain cancelIndicator!) - processSubtree(G_fresh, node, cache, 0); // note how we reset the indent level - cache.forwardProcessedSubTrees.add(node); - log(0, "===END of identifiable sub-tree below " + node.objectInfo); - - return true; - } - - - // --------------------------------------------------------------------------------------------------------------- - - - /** - * Top-down processing of AST nodes happens here, i.e. this method will see all AST nodes in a top-down order. - */ - def private void processNode_preChildren(RuleEnvironment G, EObject node, ASTMetaInfoCache cache, int indentLevel) { - - typeRefProcessor.handleTypeRefs(G, node, cache); - - if (node instanceof FunctionDefinition) { - handleAsyncOrGeneratorFunctionDefinition(G, node, cache); - } - - typeDeferredProcessor.handleDeferredTypeRefs_preChildren(G, node, cache); - } - - /** - * Bottom-up processing of AST nodes happens here, i.e. this method will see all AST nodes in a bottom-up order. - */ - def private void processNode_postChildren(RuleEnvironment G, EObject node, ASTMetaInfoCache cache, int indentLevel) { - - typeDeferredProcessor.handleDeferredTypeRefs_postChildren(G, node, cache); - - typeProcessor.typeNode(G, node, cache, indentLevel); - - // references to other files via import statements - // NOTE: for all imports except bare imports, the following is unnecessary, because post-processing of the target - // resource would be triggered automatically as soon as type inference is performed on an element imported from the - // target resource. However, by doing this eagerly up front, the overall flow of post-processing across multiple - // resources is a bit easier to understand/predict. This does not lead to any additional processing being done (it's - // just done a bit earlier), except in case of unused imports. - if (node instanceof ImportDeclaration) { - val targetModule = node.module; - if (targetModule !== null && !targetModule.eIsProxy) { - val targetResource = targetModule.eResource; - if (targetResource instanceof N4JSResource) { - // trigger post-processing of target resource - targetResource.performPostProcessing(G.cancelIndicator); - } - } - } - - if (node instanceof Annotation) { - if (node.name == AnnotationDefinition.STATIC_POLYFILL_AWARE.name) { - val resSPoly = staticPolyfillHelper.getStaticPolyfillResource(node.eResource); - if (resSPoly !== null) { - // trigger post-processing of poly filler - resSPoly.performPostProcessing(G.cancelIndicator); - } - } - } - - runtimeDependencyProcessor.recordRuntimeReferencesInCache(node, cache); - } - - - // --------------------------------------------------------------------------------------------------------------- - - - /** - * This method returns the direct children of 'obj' that are to be processed, in the order in which they are to - * be processed. By default, all direct children must be processed and the order is insignificant, so in the - * default case this method simply returns {@link EObject#eContents()}. However, this method implements special - * handling for some exception cases where the processing order is significant. - */ - def private List childrenToBeProcessed(RuleEnvironment G, EObject obj) { - return switch (obj) { - SetterDeclaration: { - // process formal parameter before body - obj.eContents.bringToFront(obj.fpar) - } - FunctionDefinition: { - // process formal parameters before body - obj.eContents.bringToFront(obj.fpars) - } - CatchBlock: { - // process catch variable before block - obj.eContents.bringToFront(obj.catchVariable) - } - ForStatement: { - // process expression before varDeclOrBindings - obj.eContents.bringToFront(obj.expression) - } - default: { - // standard case: order is insignificant (so we simply use the order provided by EMF) - obj.eContents - } - }; - } - - - // --------------------------------------------------------------------------------------------------------------- - - - /** - * Normally, forward references are allowed only to {@link N4JSLanguageUtils#isIdentifiableSubtree(EObject) - * identifiable subtrees}. However, there are exception cases that are also allowed and this method returns - * true for those cases. - */ - def private static boolean isExceptionCaseOfForwardReferencableSubtree(EObject astNode) { - isExpressionInForOf(astNode) - } - def private static boolean isExpressionInForOf(EObject astNode) { - astNode instanceof Expression && astNode.eContainer instanceof ForStatement - && (astNode.eContainer as ForStatement).isForOf - && astNode.eContainingFeature===N4JSPackage.eINSTANCE.iterationStatement_Expression; - } - - /** - * Returns true if we have a semi-cyclic reference to a variable declaration in a for in/of loop. - * For example: - *

-	 * for(var x of foo(x)) {}
-	 * 
- */ - def package boolean isSemiCyclicForwardReferenceInForLoop(EObject node, ASTMetaInfoCache cache) { - if (node instanceof VariableDeclaration) { - val parent = node.eContainer; - if (parent instanceof ForStatement) { - return (parent.forIn || parent.forOf) && cache.astNodesCurrentlyBeingTyped.contains(parent.expression); - } - } - return false; - } - - def private void resolveAndProcessReferencesInNode(EObject astNode, ASTMetaInfoCache cache) { - for(eRef : astNode.eClass.EAllReferences) { - if(!eRef.isContainment && !eRef.isContainer) { // only cross-references have proxies (in our case) - val node = astNode.eGet(eRef, true); - - if (node instanceof EObject) { - recordReferencesToLocalVariables(eRef, astNode, node, cache); - } - } - } - } - - def private recordReferencesToLocalVariables(EReference reference, EObject sourceNode, EObject target, ASTMetaInfoCache cache) { - - // skip reference Variable#definedVariable (it does not constitute a usage of the variable) - if (reference === N4JSPackage.Literals.ABSTRACT_VARIABLE__DEFINED_VARIABLE) { - return; - } - // If target is still a proxy its resolution failed, therefore it should be skipped. - if (target.eIsProxy) { - return; - } - // skip non-local references - if (sourceNode.eResource !== target.eResource) { - return; - } - if (target instanceof TVariable) { - // don't record references to directly exported variables - if (target.directlyExported) { - return; - } - - cache.storeLocalVariableReference(target, sourceNode); - } - } - - def private List bringToFront(List l, T... elements) { - val result = new ArrayList(l); - val elemSanitized = elements.filterNull.toList; - result.removeAll(elemSanitized); - result.addAll(0, elemSanitized); - return result; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractPolyProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractPolyProcessor.java new file mode 100644 index 0000000000..92a9142382 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractPolyProcessor.java @@ -0,0 +1,336 @@ +/** + * 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.postprocessing; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.newRuleEnvironment; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.wrap; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toSet; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.exists; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.Argument; +import org.eclipse.n4js.n4JS.ArrayElement; +import org.eclipse.n4js.n4JS.ArrayLiteral; +import org.eclipse.n4js.n4JS.ArrowFunction; +import org.eclipse.n4js.n4JS.ConditionalExpression; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.n4JS.PropertyAssignment; +import org.eclipse.n4js.n4JS.PropertyAssignmentAnnotationList; +import org.eclipse.n4js.n4JS.PropertyGetterDeclaration; +import org.eclipse.n4js.n4JS.PropertyMethodDeclaration; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.n4JS.PropertySetterDeclaration; +import org.eclipse.n4js.n4JS.PropertySpread; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.InferenceVariable; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.TSetter; +import org.eclipse.n4js.ts.types.TypeVariable; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.constraints.InferenceContext; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper.Callable; +import org.eclipse.n4js.utils.N4JSLanguageUtils; + +import com.google.inject.Inject; + +/** + * Base for all poly processors. Contains some utility and convenience methods. + */ +abstract class AbstractPolyProcessor extends AbstractProcessor { + + @Inject + private N4JSTypeSystem ts; + @Inject + private TypeSystemHelper tsh; + + /** + * Convenience method for {@link #isPoly(Expression)} and {@link #isPoly(PropertyAssignment)}, accepting any type of + * EObject. + */ + boolean isPoly(EObject obj) { + if (obj instanceof Expression) { + return isPoly((Expression) obj); + } + if (obj instanceof PropertyAssignment) { + return isPoly((PropertyAssignment) obj); + } + return false; + } + + /** + * Tells whether the given expression is a poly expression, i.e. requires constraint-based type inference. + */ + boolean isPoly(Expression obj) { + if (obj instanceof ParameterizedCallExpression) { + ParameterizedCallExpression pce = (ParameterizedCallExpression) obj; + // NOTE: in next line, we do not propagate the cancel indicator; however, this is not required, because + // all we do with the newly created rule environment is to type a backward(!) reference, so we can be + // sure that no significant processing will be triggered by the type judgment invocation below + RuleEnvironment G = newRuleEnvironment(pce); + TypeRef targetTypeRef = ts.type(G, pce.getTarget()); // this is a backward reference (because we type obj's + // child) + Callable callable = tsh.getCallableTypeRef(G, targetTypeRef); + if (callable != null && callable.getSignatureTypeRef().isPresent()) { + FunctionTypeExprOrRef signatureTypeRef = callable.getSignatureTypeRef().get(); + return N4JSLanguageUtils.isPoly(signatureTypeRef, pce); + } else { + return false; + } + } + if (obj instanceof FunctionExpression) { + FunctionExpression fe = (FunctionExpression) obj; + return exists(fe.getFpars(), fpar -> fpar.getDeclaredTypeRefInAST() == null) + // type of 1 or more fpars is undeclared + || fe.getDeclaredReturnTypeRefInAST() == null; // return type is undeclared + // note: if the FunctionExpression is generic, this does *not* make it poly! + } + if (obj instanceof ArrayLiteral) { + return true; + } + if (obj instanceof ObjectLiteral) { + return exists(((ObjectLiteral) obj).getPropertyAssignments(), pa -> isPoly(pa)); + } + if (obj instanceof ConditionalExpression) { + ConditionalExpression ce = (ConditionalExpression) obj; + boolean trueIsPoly = isPoly(ce.getTrueExpression()); + boolean trueAllowsPoly = allowsPoly(ce.getTrueExpression()); + boolean falseAllowsPoly = allowsPoly(ce.getFalseExpression()); + boolean falseIsPoly = isPoly(ce.getFalseExpression()); + + return (trueIsPoly && falseAllowsPoly) || (falseIsPoly && trueAllowsPoly); + } + + return false; + + } + + boolean allowsPoly(Expression obj) { + if (obj == null) { + return false; + } + RuleEnvironment G = RuleEnvironmentExtensions.newRuleEnvironment(obj); + return N4JSLanguageUtils.isUndefinedLiteral(G, obj) || N4JSLanguageUtils.isNullLiteral(G, obj); + } + + /** + * True iff the given PropertyAssignment is a poly "expression", i.e. requires constraint-based type inference. + */ + private boolean isPoly(PropertyAssignment pa) { + if (pa instanceof PropertyNameValuePair) { + PropertyNameValuePair pnvp = (PropertyNameValuePair) pa; + // FIXME requiring pa.expression!=null is inconsistent! + return pnvp.getExpression() != null && pnvp.getDeclaredTypeRefInAST() == null; + } + if (pa instanceof PropertyGetterDeclaration) { + PropertyGetterDeclaration pgd = (PropertyGetterDeclaration) pa; + return pgd.getDeclaredTypeRefInAST() == null; + } + if (pa instanceof PropertySetterDeclaration) { + PropertySetterDeclaration psd = (PropertySetterDeclaration) pa; + return psd.getDeclaredTypeRefInAST() == null; + } + if (pa instanceof PropertyMethodDeclaration) { + return false; + } + if (pa instanceof PropertySpread) { + return false; // TODO GH-1337 add support for spread operator + } + if (pa instanceof PropertyAssignmentAnnotationList) { + return false; + } + + throw new IllegalArgumentException("unsupported subclass of PropertyAssignment: " + pa.eClass().getName()); + } + + /** + * Convenience method for {@link #isRootPoly(Expression)}, accepting any type of EObject. + */ + boolean isRootPoly(EObject obj) { + return (obj instanceof Expression) ? isRootPoly((Expression) obj) : false; + } + + /** + * Tells whether the given expression is a root poly expression, i.e. it + *
    + *
  1. is a {@link #isPoly(Expression) poly expression}, and + *
  2. represents the root of a tree of nested poly expressions which have to be inferred together within a single + * constraint system (this tree may have depth 0, i.e. consist only of the given expression). + *
+ */ + boolean isRootPoly(Expression obj) { + if (isPoly(obj)) { + EObject p = getParentPolyCandidate(obj); + return p == null || !isPoly(p); + } + return false; + } + + /** + * Given a poly expression, returns the parent expression that might be the parent poly expression. If the + * given expression is not poly, the return value is undefined. + */ + private EObject getParentPolyCandidate(Expression poly) { + EObject directParent = poly == null ? null : poly.eContainer(); + EObject grandParent = directParent == null ? null : directParent.eContainer(); + + if (directParent instanceof Argument) { + if (grandParent instanceof ParameterizedCallExpression && toSet(map( + ((ParameterizedCallExpression) grandParent).getArguments(), a -> a.getExpression())) + .contains(poly)) { + // TODO what about the target expression? i.e.: || directParent.target==poly) { + return grandParent; + } + } else if (directParent instanceof FunctionExpression) { + return null; // function expressions never have nested poly expressions (expression in the body are + // detached) + } else if (directParent instanceof ArrayElement) { + if (((ArrayElement) directParent).getExpression() == poly) { + return directParent.eContainer();// return the ArrayLiteral as parent (not the ArrayElement) + } + } else if (directParent instanceof PropertyNameValuePair) { + if (((PropertyNameValuePair) directParent).getExpression() == poly) { + return directParent;// return the PropertyNameValuePair as parent (not the ObjectLiteral) + } + } else if (directParent instanceof ConditionalExpression) { + return directParent; + } else if (directParent instanceof PropertyGetterDeclaration) { + return null;// getters never have nested poly expressions + } else if (directParent instanceof PropertySetterDeclaration) { + return null; // setters never have nested poly expressions + } else if (directParent instanceof PropertySpread) { + return null;// TODO GH-1337 add support for spread operator + } + + return null; + } + + // ------------------------------------------------------------------------------------------------------------------------------ + + /** + * Returns the type of a nested poly expression. The final type is returned, i.e. not the one created when preparing + * the constraint system that may contain inference variables. + *

+ * Because final types are created and stored in the typing cache in the onSuccess/onFailure lambdas and those + * lambdas of nested poly expressions are registered before those of outer expression, we can here simply read the + * nested poly expression's type from the cache. + */ + protected TypeRef getFinalResultTypeOfNestedPolyExpression(Expression nestedPolyExpression) { + return ASTMetaInfoUtils.getTypeFailSafe(nestedPolyExpression); + } + + protected TypeRef subst(TypeRef typeRef, RuleEnvironment G, + Map substitutions) { + + return subst(typeRef, G, substitutions, false); + } + + protected TypeRef subst(TypeRef typeRef, RuleEnvironment G, + Map substitutions, boolean reverse) { + + RuleEnvironment Gx = wrap(G); + for (Entry e : substitutions.entrySet()) { + if (reverse) { + Gx.put(e.getValue(), TypeUtils.createTypeRef(e.getKey())); + } else { + Gx.put(e.getKey(), TypeUtils.createTypeRef(e.getValue())); + } + } + + TypeRef typeRefSubst = ts.substTypeVariables(Gx, typeRef); + if (typeRefSubst == null) { + throw new IllegalArgumentException("substitution failed"); + } + return typeRefSubst; + } + + protected TypeRef applySolution(TypeRef typeRef, RuleEnvironment G, Map solution) { + if (typeRef == null || solution == null || solution.isEmpty()) { + return typeRef; // note: returning 'null' if typeRef==null (broken AST, etc.) + } + RuleEnvironment Gx = wrap(G); + for (Entry e : solution.entrySet()) { + Gx.put(e.getKey(), e.getValue()); + } + TypeRef typeRefSubst = ts.substTypeVariables(Gx, typeRef); + if (typeRefSubst == null) { + throw new IllegalArgumentException("substitution failed"); + } + return typeRefSubst; + } + + protected Map createPseudoSolution(InferenceContext infCtx, + TypeRef defaultTypeRef) { + + Map pseudoSolution = new HashMap<>(); + for (InferenceVariable iv : infCtx.getInferenceVariables()) { + pseudoSolution.put(iv, defaultTypeRef); // map all inference variables to the default + } + return pseudoSolution; + } + + // FIXME move to a better place + protected boolean isReturningValue(FunctionDefinition fun) { + return (fun.getBody() != null && exists(fun.getBody().getAllReturnStatements(), s -> s.getExpression() != null)) + || ((fun instanceof ArrowFunction) ? ((ArrowFunction) fun).isSingleExprImplicitReturn() : false); + // TODO except call to void function!! + } + + protected TypeRef getTypeOfMember(TMember m) { + if (m instanceof TField) { + return ((TField) m).getTypeRef(); + } else if (m instanceof TGetter) { + return ((TGetter) m).getTypeRef(); + } else if (m instanceof TSetter) { + return ((TSetter) m).getFpar().getTypeRef(); + } else if (m instanceof TMethod) { + throw new IllegalArgumentException("this method should not be used for TMethod"); + } else { + String clsName = m == null ? null : m.eClass() == null ? null : m.eClass().getName(); + throw new IllegalArgumentException("unknown subtype of TMember: " + clsName); + } + } + + protected void setTypeOfMember(TMember m, TypeRef type) { + if (m instanceof TField) { + ((TField) m).setTypeRef(type); + } else if (m instanceof TGetter) { + ((TGetter) m).setTypeRef(type); + } else if (m instanceof TSetter) { + TSetter tst = (TSetter) m; + if (tst.getFpar() != null) { + tst.getFpar().setTypeRef(type); + } + } else if (m instanceof TMethod) { + throw new IllegalArgumentException("this method should not be used for TMethod"); + } else { + String clsName = m == null ? null : m.eClass() == null ? null : m.eClass().getName(); + throw new IllegalArgumentException("unknown subtype of TMember: " + clsName); + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractPolyProcessor.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractPolyProcessor.xtend deleted file mode 100644 index 8d3b99d5f3..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractPolyProcessor.xtend +++ /dev/null @@ -1,289 +0,0 @@ -/** - * 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.postprocessing - -import com.google.inject.Inject -import java.util.Map -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.Argument -import org.eclipse.n4js.n4JS.ArrayElement -import org.eclipse.n4js.n4JS.ArrayLiteral -import org.eclipse.n4js.n4JS.ArrowFunction -import org.eclipse.n4js.n4JS.ConditionalExpression -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.FunctionExpression -import org.eclipse.n4js.n4JS.ObjectLiteral -import org.eclipse.n4js.n4JS.ParameterizedCallExpression -import org.eclipse.n4js.n4JS.PropertyAssignment -import org.eclipse.n4js.n4JS.PropertyAssignmentAnnotationList -import org.eclipse.n4js.n4JS.PropertyGetterDeclaration -import org.eclipse.n4js.n4JS.PropertyMethodDeclaration -import org.eclipse.n4js.n4JS.PropertyNameValuePair -import org.eclipse.n4js.n4JS.PropertySetterDeclaration -import org.eclipse.n4js.n4JS.PropertySpread -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.InferenceVariable -import org.eclipse.n4js.ts.types.TField -import org.eclipse.n4js.ts.types.TGetter -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.ts.types.TSetter -import org.eclipse.n4js.ts.types.TypeVariable -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.constraints.InferenceContext -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper -import org.eclipse.n4js.utils.N4JSLanguageUtils - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * Base for all poly processors. Contains some utility and convenience methods. - */ -package abstract class AbstractPolyProcessor extends AbstractProcessor { - - @Inject - private N4JSTypeSystem ts; - @Inject - private TypeSystemHelper tsh; - - /** - * Convenience method for {@link #isPoly(Expression)} and {@link #isPoly(PropertyAssignment)}, accepting any type of - * EObject. - */ - def boolean isPoly(EObject obj) { - return switch (obj) { - Expression: obj.isPoly - PropertyAssignment: obj.isPoly - default: false - } - } - - /** - * Tells whether the given expression is a poly expression, i.e. requires constraint-based type inference. - */ - def boolean isPoly(Expression obj) { - return switch (obj) { - ParameterizedCallExpression: { - // NOTE: in next line, we do not propagate the cancel indicator; however, this is not required, because - // all we do with the newly created rule environment is to type a backward(!) reference, so we can be - // sure that no significant processing will be triggered by the type judgment invocation below - val G = obj.newRuleEnvironment; - val TypeRef targetTypeRef = ts.type(G, obj.target); // this is a backward reference (because we type obj's child) - val callable = tsh.getCallableTypeRef(G, targetTypeRef); - if (callable !== null && callable.signatureTypeRef.present) { - val signatureTypeRef = callable.signatureTypeRef.get(); - N4JSLanguageUtils.isPoly(signatureTypeRef, obj) - } else { - false - } - } - FunctionExpression: - obj.fpars.exists[declaredTypeRefInAST === null] // type of 1 or more fpars is undeclared - || obj.declaredReturnTypeRefInAST === null // return type is undeclared - // note: if the FunctionExpression is generic, this does *not* make it poly! - ArrayLiteral: - true - ObjectLiteral: - obj.propertyAssignments.exists[isPoly] - ConditionalExpression: { - val boolean trueIsPoly = isPoly(obj.trueExpression); - val boolean trueAllowsPoly = allowsPoly(obj.trueExpression); - val boolean falseAllowsPoly = allowsPoly(obj.falseExpression); - val boolean falseIsPoly = isPoly(obj.falseExpression); - - (trueIsPoly && falseAllowsPoly) || (falseIsPoly && trueAllowsPoly) - } - default: - false - } - } - - def boolean allowsPoly(Expression obj) { - if (obj === null) { - return false; - } - val RuleEnvironment G = RuleEnvironmentExtensions.newRuleEnvironment(obj); - return N4JSLanguageUtils.isUndefinedLiteral(G, obj) || N4JSLanguageUtils.isNullLiteral(G, obj); - } - - /** - * Tells whether the given PropertyAssignment is a poly "expression", i.e. requires constraint-based type inference. - */ - def private boolean isPoly(PropertyAssignment pa) { - switch (pa) { - PropertyNameValuePair: - pa.expression !== null && pa.declaredTypeRefInAST === null // FIXME requiring pa.expression!==null is inconsistent! - PropertyGetterDeclaration: - pa.declaredTypeRefInAST === null - PropertySetterDeclaration: - pa.declaredTypeRefInAST === null - PropertyMethodDeclaration: - false - PropertySpread: - false // TODO GH-1337 add support for spread operator - PropertyAssignmentAnnotationList: - false - default: - throw new IllegalArgumentException("unsupported subclass of PropertyAssignment: " + pa.eClass.name) - } - } - - /** - * Convenience method for {@link #isRootPoly(Expression)}, accepting any type of EObject. - */ - def boolean isRootPoly(EObject obj) { - if (obj instanceof Expression) obj.isRootPoly else false - } - - /** - * Tells whether the given expression is a root poly expression, i.e. it - *

    - *
  1. is a {@link #isPoly(Expression) poly expression}, and - *
  2. represents the root of a tree of nested poly expressions which have to be inferred together within a single - * constraint system (this tree may have depth 0, i.e. consist only of the given expression). - *
- */ - def boolean isRootPoly(Expression obj) { - if (isPoly(obj)) { - val p = getParentPolyCandidate(obj); - return p === null || !isPoly(p); - } - return false; - } - - /** - * Given a poly expression, returns the parent expression that might be the parent poly expression. - * If the given expression is not poly, the return value is undefined. - */ - def private EObject getParentPolyCandidate(Expression poly) { - val directParent = poly?.eContainer; - val grandParent = directParent?.eContainer; - return switch (directParent) { - Argument case grandParent instanceof ParameterizedCallExpression && - (grandParent as ParameterizedCallExpression).arguments.map[expression].contains(poly): // TODO what about the target expression? i.e.: || directParent.target===poly - grandParent - FunctionExpression: - null // function expressions never have nested poly expressions (expression in the body are detached) - ArrayElement case directParent.expression === poly: - directParent.eContainer as ArrayLiteral // return the ArrayLiteral as parent (not the ArrayElement) - PropertyNameValuePair case directParent.expression === poly: - directParent // return the PropertyNameValuePair as parent (not the ObjectLiteral) - ConditionalExpression: - directParent - PropertyGetterDeclaration: - null // getters never have nested poly expressions - PropertySetterDeclaration: - null // setters never have nested poly expressions - PropertySpread: - null // TODO GH-1337 add support for spread operator - } - } - - - // ------------------------------------------------------------------------------------------------------------------------------ - - - /** - * Returns the type of a nested poly expression. The final type is returned, i.e. not the one created when preparing - * the constraint system that may contain inference variables. - *

- * Because final types are created and stored in the typing cache in the onSuccess/onFailure lambdas and those - * lambdas of nested poly expressions are registered before those of outer expression, we can here simply read the - * nested poly expression's type from the cache. - */ - def protected TypeRef getFinalResultTypeOfNestedPolyExpression(Expression nestedPolyExpression) { - return ASTMetaInfoUtils.getTypeFailSafe(nestedPolyExpression); - } - - def protected TypeRef subst(TypeRef typeRef, RuleEnvironment G, - Map substitutions) { - - subst(typeRef, G, substitutions, false) - } - - def protected TypeRef subst(TypeRef typeRef, RuleEnvironment G, - Map substitutions, boolean reverse) { - - val Gx = G.wrap; - substitutions.entrySet.forEach [ e | - if (reverse) - Gx.put(e.value, TypeUtils.createTypeRef(e.key)) - else - Gx.put(e.key, TypeUtils.createTypeRef(e.value)) - ]; - val typeRefSubst = ts.substTypeVariables(Gx, typeRef); - if (typeRefSubst === null) - throw new IllegalArgumentException("substitution failed"); - return typeRefSubst; - } - - def protected TypeRef applySolution(TypeRef typeRef, RuleEnvironment G, Map solution) { - if (typeRef === null || solution === null || solution.empty) { - return typeRef; // note: returning 'null' if typeRef==null (broken AST, etc.) - } - val Gx = G.wrap; - solution.entrySet.forEach[e|Gx.put(e.key, e.value)]; - val typeRefSubst = ts.substTypeVariables(Gx, typeRef); - if (typeRefSubst === null) - throw new IllegalArgumentException("substitution failed"); - return typeRefSubst; - } - - def protected Map createPseudoSolution(InferenceContext infCtx, - TypeRef defaultTypeRef) { - - val pseudoSolution = newHashMap; - for (iv : infCtx.getInferenceVariables) { - pseudoSolution.put(iv, defaultTypeRef); // map all inference variables to the default - } - return pseudoSolution; - } - - // FIXME move to a better place - def protected boolean isReturningValue(FunctionDefinition fun) { - return (fun.body !== null && fun.body.allReturnStatements.exists[expression !== null]) || - (if (fun instanceof ArrowFunction) fun.singleExprImplicitReturn else false); // TODO except call to void function!! - } - - def protected TypeRef getTypeOfMember(TMember m) { - switch (m) { - TField: - m.typeRef - TGetter: - m.typeRef - TSetter: - m?.fpar.typeRef - TMethod: - throw new IllegalArgumentException("this method should not be used for TMethod") - default: - throw new IllegalArgumentException("unknown subtype of TMember: " + m?.eClass?.name) - } - } - - def protected void setTypeOfMember(TMember m, TypeRef type) { - switch (m) { - TField: - m.typeRef = type - TGetter: - m.typeRef = type - TSetter: - if (m.fpar !== null) m.fpar.typeRef = type - TMethod: - throw new IllegalArgumentException("this method should not be used for TMethod") - default: - throw new IllegalArgumentException("unknown subtype of TMember: " + m?.eClass?.name) - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractProcessor.java new file mode 100644 index 0000000000..b1724b5eab --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractProcessor.java @@ -0,0 +1,270 @@ +/** + * 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.postprocessing; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.getBuiltInTypeScope; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.getCancelIndicator; +import static org.eclipse.n4js.utils.N4JSLanguageUtils.isASTNode; +import static org.eclipse.n4js.utils.N4JSLanguageUtils.isTypableNode; + +import java.util.function.BooleanSupplier; + +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.n4JS.NamedElement; +import org.eclipse.n4js.resource.N4JSResource; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.ts.typeRefs.DeferredTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeArgument; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TStructMember; +import org.eclipse.n4js.ts.types.TypableElement; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.n4js.utils.EcoreUtilN4; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.UtilN4; +import org.eclipse.xtext.nodemodel.ICompositeNode; +import org.eclipse.xtext.nodemodel.util.NodeModelUtils; +import org.eclipse.xtext.service.OperationCanceledManager; +import org.eclipse.xtext.util.CancelIndicator; + +import com.google.common.base.Throwables; +import com.google.inject.Inject; + +/** + * Provides some common base functionality used across all processors (e.g. logging). See {@link ASTProcessor} for more + * details on processors and post-processing of {@link N4JSResource}s. + */ +abstract class AbstractProcessor { + + private static Logger LOG = Logger.getLogger(AbstractProcessor.class); + + private static boolean DEBUG_LOG = false; + private static boolean DEBUG_LOG_RESULT = false; + private static boolean DEBUG_RIGID = false; // if true, more consistency checks are performed and exceptions thrown + // if wrong + + @Inject + private N4JSTypeSystem ts; + @Inject + private TypeSystemHelper tsh; + @Inject + private OperationCanceledManager operationCanceledManager; + + /** + * Convenience method. Same as {@link OperationCanceledManager#checkCanceled(CancelIndicator)}, using the cancel + * indicator of the given rule environment. + */ + protected void checkCanceled(RuleEnvironment G) { + operationCanceledManager.checkCanceled(getCancelIndicator(G)); + } + + /** + * Processors can call this method to directly invoke the 'type' judgment, i.e. invoke method + * {@code TypeJudgment#apply()} via facade method + * {@link N4JSTypeSystem#use_type_judgment_from_PostProcessors(RuleEnvironment, TypableElement) + * use_type_judgment_from_PostProcessors()}. Normally, this should only be required by {@link TypeProcessor}, so use + * this sparingly (however, sometimes it can be helpful to avoid duplication of logic). + */ + protected TypeRef invokeTypeJudgmentToInferType(RuleEnvironment G, TypableElement elem) { + if (elem.eIsProxy()) { + return TypeRefsFactory.eINSTANCE.createUnknownTypeRef(); + } + // special case: + // TStructMembers are special in that they may be types (in case of TStructMethod) and appear as AST nodes + // -> if we are dealing with an AST node, make sure to use the definedMember in the TModule + TStructMember definedMember = (elem instanceof TStructMember) + ? ((TStructMember) elem).getDefinedMember() + : null; + if (definedMember != null && isASTNode(elem)) { + return invokeTypeJudgmentToInferType(G, definedMember); + } + return ts.use_type_judgment_from_PostProcessors(G, elem); + } + + /** + * Some special handling for async and/or generator functions (including methods): we have to wrap their inner + * return type R into a {@code Promise}, {@code Generator}, or + * {@code AsyncGenerator} and use that as their actual, outer return type. This means for async and/or + * generator functions, the types builder will create a TFunction with the inner return type and during + * post-processing this method will change that return type to a + * Promise/Generator/AsyncGenerator (only the return type of the TFunction in + * the types model is changed; the declared return type in the AST remains unchanged). + *

+ * In addition, a return type of void will be replaced by undefined, i.e. will produce an + * outer return type of Promise<undefined,?>, Generator<undefined,undefined,TNext>, + * etc. This will be taken care of by utility methods + * {@link TypeUtils#createPromiseTypeRef(BuiltInTypeScope,TypeArgument,TypeArgument)} and + * {@link TypeUtils#createGeneratorTypeRef(BuiltInTypeScope,FunctionDefinition)}, respectively. + *

+ * NOTES: + *

    + *
  1. normally, this wrapping could easily be done in the types builder, but because we have to check if the inner + * return type is void we need to resolve proxies, which is not allowed in the types builder. + *
+ */ + protected void handleAsyncOrGeneratorFunctionDefinition(RuleEnvironment G, FunctionDefinition funDef) { + boolean isAsync = funDef.isAsync(); + boolean isGenerator = funDef.isGenerator(); + if (isAsync || isGenerator) { + Type tFunction = funDef.getDefinedType(); + if (tFunction instanceof TFunction) { + TFunction tFun = (TFunction) tFunction; + TypeRef innerReturnTypeRef = tFun.getReturnTypeRef(); + if (innerReturnTypeRef != null && !(innerReturnTypeRef instanceof DeferredTypeRef)) { + // we took 'innerReturnTypeRef' from the TModule (not the AST), so normally we would not have to + // invoke #resolveTypeAliases() here; however, since this code is running before TypeAliasProcessor, + // we still have to invoke #resolveTypeAliases(): + TypeRef innerReturnTypeRefResolved = tsh.resolveTypeAliases(G, innerReturnTypeRef); + TypeRef innerReturnTypeRefResolvedUB = ts.upperBoundWithReopenAndResolveTypeVars(G, + innerReturnTypeRefResolved); + BuiltInTypeScope scope = getBuiltInTypeScope(G); + boolean needsRewrite = !N4JSLanguageUtils.hasExpectedSpecialReturnType(innerReturnTypeRefResolvedUB, + funDef, scope); + if (needsRewrite) { + TypeRef outerReturnTypeRef = (!isGenerator) + ? TypeUtils.createPromiseTypeRef(scope, innerReturnTypeRef, null) + : + // note: this method handles the choice Generator vs. AsyncGenerator + TypeUtils.createGeneratorTypeRef(scope, funDef); + EcoreUtilN4.doWithDeliver(false, () -> tFun.setReturnTypeRef(outerReturnTypeRef), tFun); + } + } + } + } + } + + protected static String getObjectInfo(EObject obj) { + if (obj == null) { + return ""; + } else if (obj instanceof IdentifierRef) { + ICompositeNode node = NodeModelUtils.findActualNodeFor(obj); + if (node == null) { + return ""; + } else { + return "IdentifierRef \"" + NodeModelUtils.getTokenText(node) + "\""; + } + } else { + String name = getName(obj); + if (name != null) { + return obj.eClass().getName() + " \"" + name + "\""; + } else { + return obj.eClass().getName(); + } + } + } + + protected static String getName(EObject obj) { + if (obj instanceof NamedElement) { + return ((NamedElement) obj).getName(); + } + if (obj instanceof IdentifiableElement) { + return ((IdentifiableElement) obj).getName(); + } + return null; + } + + protected static void log(int indentLevel, TypeRef result) { + if (!isDEBUG_LOG()) { + return; + } + log(indentLevel, result.getTypeRefAsString()); + } + + protected static void log(int indentLevel, EObject astNode, ASTMetaInfoCache cache) { + if (!isDEBUG_LOG()) + return; + if (isTypableNode(astNode)) { + TypeRef result = cache.getTypeFailSafe((TypableElement) astNode); + String resultStr = (result != null) ? result.getTypeRefAsString() : "*** MISSING ***"; + log(indentLevel, getObjectInfo(astNode) + " " + resultStr); + } else { + log(indentLevel, getObjectInfo(astNode)); + } + for (EObject childNode : astNode.eContents()) { + log(indentLevel + 1, childNode, cache); + } + } + + protected static void log(int indentLevel, String msg) { + if (!isDEBUG_LOG()) { + return; + } + System.out.println(indent(indentLevel) + msg); + } + + protected static void logErr(String msg) { + // always log errors, even if !isDEBUG_LOG() + System.out.flush(); + System.err.println(msg); + System.err.flush(); + LOG.error(msg); + } + + protected static Throwable logException(String msg, Throwable th) { + // always log exceptions, even if !isDEBUG_LOG() + th.printStackTrace(); // enforce dumping all exceptions to stderr + // GH-2002: TEMPORARY DEBUG LOGGING + // Only passing the exception to Logger#error(String,Throwable) does not emit the stack trace of the caught + // exception in all logger configurations; we therefore include the stack trace in the main message: + LOG.error(msg + "\n" + Throwables.getStackTraceAsString(th), th); + return th; + } + + protected static void assertTrueIfRigid(ASTMetaInfoCache cache, String message, BooleanSupplier check) { + if (isDEBUG_RIGID()) { + assertTrueIfRigid(cache, message, check.getAsBoolean()); + } + } + + protected static void assertTrueIfRigid(ASTMetaInfoCache cache, String message, boolean actual) { + if (isDEBUG_RIGID() && !actual) { + Error e = new Error(message); + if (!cache.hasBrokenAST()) { + // make sure we see this exception on the console, even if it gets caught somewhere + UtilN4.reportError(e); + } + Throwables.throwIfUnchecked(e); + throw new RuntimeException(e); + } + } + + // using a method to read field DEBUG_LOG to get rid of Xtend's "Constant condition is always true|false." warnings + protected static boolean isDEBUG_LOG() { + return DEBUG_LOG; + } + + protected static boolean isDEBUG_LOG_RESULT() { + return DEBUG_LOG_RESULT; + } + + protected static boolean isDEBUG_RIGID() { + return DEBUG_RIGID; + } + + protected static String indent(int indentLevel) { + String res = ""; + for (int i = 0; i < indentLevel; i++) { + res += " "; + } + return res; + + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractProcessor.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractProcessor.xtend deleted file mode 100644 index 158e1d1d2a..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractProcessor.xtend +++ /dev/null @@ -1,247 +0,0 @@ -/** - * 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.postprocessing - -import com.google.common.base.Throwables -import com.google.inject.Inject -import java.util.function.BooleanSupplier -import org.apache.log4j.Logger -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.IdentifierRef -import org.eclipse.n4js.n4JS.NamedElement -import org.eclipse.n4js.resource.N4JSResource -import org.eclipse.n4js.ts.typeRefs.DeferredTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory -import org.eclipse.n4js.ts.types.IdentifiableElement -import org.eclipse.n4js.ts.types.TFunction -import org.eclipse.n4js.ts.types.TStructMember -import org.eclipse.n4js.ts.types.TypableElement -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper -import org.eclipse.n4js.utils.EcoreUtilN4 -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.UtilN4 -import org.eclipse.xtext.nodemodel.util.NodeModelUtils -import org.eclipse.xtext.service.OperationCanceledManager - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* -import static extension org.eclipse.n4js.utils.N4JSLanguageUtils.* - -/** - * Provides some common base functionality used across all processors (e.g. logging). See {@link ASTProcessor} for more - * details on processors and post-processing of {@link N4JSResource}s. - */ -package abstract class AbstractProcessor { - - val private static Logger LOG = Logger.getLogger(AbstractProcessor); - - val private static DEBUG_LOG = false; - val private static DEBUG_LOG_RESULT = false; - val private static DEBUG_RIGID = false; // if true, more consistency checks are performed and exceptions thrown if wrong - - @Inject - private N4JSTypeSystem ts; - @Inject - private TypeSystemHelper tsh; - @Inject - private OperationCanceledManager operationCanceledManager; - - - /** - * Convenience method. Same as {@link OperationCanceledManager#checkCanceled(CancelIndicator)}, using the cancel - * indicator of the given rule environment. - */ - def protected void checkCanceled(RuleEnvironment G) { - operationCanceledManager.checkCanceled(G.cancelIndicator); - } - - - /** - * Processors can call this method to directly invoke the 'type' judgment, i.e. invoke method {@code TypeJudgment#apply()} - * via facade method {@link N4JSTypeSystem#use_type_judgment_from_PostProcessors(RuleEnvironment, TypableElement) - * use_type_judgment_from_PostProcessors()}. Normally, this should only be required by {@link TypeProcessor}, so use - * this sparingly (however, sometimes it can be helpful to avoid duplication of logic). - */ - def protected TypeRef invokeTypeJudgmentToInferType(RuleEnvironment G, TypableElement elem) { - if (elem.eIsProxy) { - return TypeRefsFactory.eINSTANCE.createUnknownTypeRef; - } - // special case: - // TStructMembers are special in that they may be types (in case of TStructMethod) and appear as AST nodes - // -> if we are dealing with an AST node, make sure to use the definedMember in the TModule - val definedMember = if (elem instanceof TStructMember) elem.definedMember; - if (definedMember !== null && elem.isASTNode) { - return invokeTypeJudgmentToInferType(G, definedMember); - } - return ts.use_type_judgment_from_PostProcessors(G, elem); - } - - - /** - * Some special handling for async and/or generator functions (including methods): we have to wrap their inner return type - * R into a {@code Promise}, {@code Generator}, or {@code AsyncGenerator} and use - * that as their actual, outer return type. This means for async and/or generator functions, the types builder will create - * a TFunction with the inner return type and during post-processing this method will change that return type - * to a Promise/Generator/AsyncGenerator (only the return type of the TFunction in - * the types model is changed; the declared return type in the AST remains unchanged). - *

- * In addition, a return type of void will be replaced by undefined, i.e. will produce an outer - * return type of Promise<undefined,?>, Generator<undefined,undefined,TNext>, etc. This will - * be taken care of by utility methods {@link TypeUtils#createPromiseTypeRef(BuiltInTypeScope,TypeArgument,TypeArgument)} - * and {@link TypeUtils#createGeneratorTypeRef(BuiltInTypeScope,FunctionDefinition)}, respectively. - *

- * NOTES: - *

    - *
  1. normally, this wrapping could easily be done in the types builder, but because we have to check if the inner - * return type is void we need to resolve proxies, which is not allowed in the types builder. - *
- */ - def protected void handleAsyncOrGeneratorFunctionDefinition(RuleEnvironment G, FunctionDefinition funDef, ASTMetaInfoCache cache) { - val isAsync = funDef.isAsync; - val isGenerator = funDef.isGenerator; - if(isAsync || isGenerator) { - val tFunction = funDef.definedType; - if(tFunction instanceof TFunction) { - val innerReturnTypeRef = tFunction.returnTypeRef; - if (innerReturnTypeRef !== null && !(innerReturnTypeRef instanceof DeferredTypeRef)) { - // we took 'innerReturnTypeRef' from the TModule (not the AST), so normally we would not have to - // invoke #resolveTypeAliases() here; however, since this code is running before TypeAliasProcessor, - // we still have to invoke #resolveTypeAliases(): - val innerReturnTypeRefResolved = tsh.resolveTypeAliases(G, innerReturnTypeRef); - val innerReturnTypeRefResolvedUB = ts.upperBoundWithReopenAndResolveTypeVars(G, innerReturnTypeRefResolved); - val scope = G.builtInTypeScope; - val needsRewrite = !N4JSLanguageUtils.hasExpectedSpecialReturnType(innerReturnTypeRefResolvedUB, funDef, scope); - if (needsRewrite) { - val outerReturnTypeRef = if (!isGenerator) { - TypeUtils.createPromiseTypeRef(scope, innerReturnTypeRef, null); - } else { - TypeUtils.createGeneratorTypeRef(scope, funDef); // note: this method handles the choice Generator vs. AsyncGenerator - }; - EcoreUtilN4.doWithDeliver(false, [ - tFunction.returnTypeRef = outerReturnTypeRef; - ], tFunction); - } - } - } - } - } - - def protected static String getObjectInfo(EObject obj) { - if (obj === null) { - "" - } else if (obj instanceof IdentifierRef) { - val node = NodeModelUtils.findActualNodeFor(obj); - if (node === null) { - "" - } else { - "IdentifierRef \"" + NodeModelUtils.getTokenText(node) + "\"" - } - } else { - val name = obj.name; - if (name !== null) { - obj.eClass.name + " \"" + name + "\"" - } else { - obj.eClass.name - } - } - } - - def protected static String getName(EObject obj) { - switch (obj) { - NamedElement: obj.name - IdentifiableElement: obj.name - } - } - - def protected static void log(int indentLevel, TypeRef result) { - if (!isDEBUG_LOG) - return; - log(indentLevel, result.typeRefAsString); - } - - def protected static void log(int indentLevel, EObject astNode, ASTMetaInfoCache cache) { - if (!isDEBUG_LOG) - return; - if (astNode.isTypableNode) { - val result = cache.getTypeFailSafe(astNode as TypableElement); - val resultStr = if (result !== null) result.typeRefAsString else "*** MISSING ***"; - log(indentLevel, astNode.objectInfo + " " + resultStr); - } else { - log(indentLevel, astNode.objectInfo); - } - for (childNode : astNode.eContents) { - log(indentLevel + 1, childNode, cache); - } - } - - def protected static void log(int indentLevel, String msg) { - if (!isDEBUG_LOG) - return; - println(indent(indentLevel) + msg); - } - - def protected static void logErr(String msg) { - // always log errors, even if !isDEBUG_LOG() - System.out.flush(); - System.err.println(msg); - System.err.flush(); - LOG.error(msg); - } - - def protected static Throwable logException(String msg, Throwable th) { - // always log exceptions, even if !isDEBUG_LOG() - th.printStackTrace // enforce dumping all exceptions to stderr - // GH-2002: TEMPORARY DEBUG LOGGING - // Only passing the exception to Logger#error(String,Throwable) does not emit the stack trace of the caught - // exception in all logger configurations; we therefore include the stack trace in the main message: - LOG.error(msg + "\n" + Throwables.getStackTraceAsString(th), th); - return th; - } - - def protected static void assertTrueIfRigid(ASTMetaInfoCache cache, String message, BooleanSupplier check) { - if (isDEBUG_RIGID) { - assertTrueIfRigid(cache, message, check.asBoolean); - } - } - - def protected static void assertTrueIfRigid(ASTMetaInfoCache cache, String message, boolean actual) { - if (isDEBUG_RIGID && !actual) { - val e = new Error(message); - if(!cache.hasBrokenAST) { - // make sure we see this exception on the console, even if it gets caught somewhere - UtilN4.reportError(e); - } - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); - } - } - - // using a method to read field DEBUG_LOG to get rid of Xtend's "Constant condition is always true|false." warnings - def protected static boolean isDEBUG_LOG() { - return DEBUG_LOG; - } - - def protected static boolean isDEBUG_LOG_RESULT() { - return DEBUG_LOG_RESULT; - } - - def protected static boolean isDEBUG_RIGID() { - return DEBUG_RIGID; - } - - def protected static String indent(int indentLevel) { - (0 ..< indentLevel).map[" "].join - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/CompileTimeExpressionProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/CompileTimeExpressionProcessor.java new file mode 100644 index 0000000000..8aae96c70f --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/CompileTimeExpressionProcessor.java @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2017 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.postprocessing; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.compileTime.CompileTimeEvaluator; +import org.eclipse.n4js.compileTime.CompileTimeValue; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.ts.types.TConstableElement; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.utils.EcoreUtilN4; +import org.eclipse.n4js.utils.N4JSLanguageUtils; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +/** + * Processing of compile-time expressions. + *

+ * All expressions for which {@link N4JSLanguageUtils#isProcessedAsCompileTimeExpression(Expression)} returns + * true are evaluated and the resulting {@link CompileTimeValue} is stored in the cache. In some cases, the + * value is also stored in the TModule. + */ +@Singleton +public class CompileTimeExpressionProcessor { + + @Inject + private CompileTimeEvaluator compileTimeEvaluator; + + /** + * If the given AST node is an expression that is directly processed as a compile-time expression (cf. + * {@link N4JSLanguageUtils#isProcessedAsCompileTimeExpression(Expression)}, this method will evaluate the + * expression and store the evaluation result in the given cache; otherwise, this method will do nothing. + */ + public void evaluateCompileTimeExpression(RuleEnvironment G, Expression astNode, ASTMetaInfoCache cache) { + if (N4JSLanguageUtils.isProcessedAsCompileTimeExpression(astNode)) { + CompileTimeValue value = compileTimeEvaluator.evaluateCompileTimeExpression(G, astNode); + cache.storeCompileTimeValue(astNode, value); + + // in some cases, we have to store the compile-time value in the TModule: + EObject parent = astNode.eContainer(); + if (parent instanceof VariableDeclaration) { + VariableDeclaration vd = (VariableDeclaration) parent; + if (vd.isDirectlyExported()) { + storeValueInTModule(vd.getDefinedVariable(), value); + } + } else if (parent instanceof N4FieldDeclaration) { + N4FieldDeclaration fd = (N4FieldDeclaration) parent; + storeValueInTModule(fd.getDefinedField(), value); + } + } + } + + private void storeValueInTModule(TConstableElement elem, CompileTimeValue value) { + if (elem != null && elem.isConst()) { + String valueStr = CompileTimeValue.serialize(value); + EcoreUtilN4.doWithDeliver(false, () -> { + elem.setCompileTimeValue(valueStr); + }, elem); + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/CompileTimeExpressionProcessor.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/CompileTimeExpressionProcessor.xtend deleted file mode 100644 index 131327ad52..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/CompileTimeExpressionProcessor.xtend +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (c) 2017 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.postprocessing - -import com.google.inject.Inject -import com.google.inject.Singleton -import org.eclipse.n4js.compileTime.CompileTimeEvaluator -import org.eclipse.n4js.compileTime.CompileTimeValue -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.ts.types.TConstableElement -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.utils.EcoreUtilN4 -import org.eclipse.n4js.utils.N4JSLanguageUtils - -/** - * Processing of compile-time expressions. - *

- * All expressions for which {@link N4JSLanguageUtils#isProcessedAsCompileTimeExpression(Expression)} returns - * true are evaluated and the resulting {@link CompileTimeValue} is stored in the cache. In some cases, - * the value is also stored in the TModule. - */ -@Singleton -class CompileTimeExpressionProcessor { - - @Inject - private CompileTimeEvaluator compileTimeEvaluator; - - /** - * If the given AST node is an expression that is directly processed as a compile-time expression (cf. - * {@link N4JSLanguageUtils#isProcessedAsCompileTimeExpression(Expression)}, this method will evaluate the - * expression and store the evaluation result in the given cache; otherwise, this method will do nothing. - */ - def public void evaluateCompileTimeExpression(RuleEnvironment G, Expression astNode, ASTMetaInfoCache cache, - int indentLevel) { - - if (N4JSLanguageUtils.isProcessedAsCompileTimeExpression(astNode)) { - val value = compileTimeEvaluator.evaluateCompileTimeExpression(G, astNode); - cache.storeCompileTimeValue(astNode, value); - - // in some cases, we have to store the compile-time value in the TModule: - val parent = astNode.eContainer; - if (parent instanceof VariableDeclaration) { - if (parent.directlyExported) { - storeValueInTModule(G, parent.definedVariable, value); - } - } else if (parent instanceof N4FieldDeclaration) { - storeValueInTModule(G, parent.definedField, value); - } - } - } - - def private void storeValueInTModule(RuleEnvironment G, TConstableElement elem, CompileTimeValue value) { - if (elem !== null && elem.const) { - val valueStr = CompileTimeValue.serialize(value); - EcoreUtilN4.doWithDeliver(false, [ - elem.compileTimeValue = valueStr; - ], elem); - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ComputedNameProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ComputedNameProcessor.java new file mode 100644 index 0000000000..b8429a6d55 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ComputedNameProcessor.java @@ -0,0 +1,127 @@ +/** + * Copyright (c) 2017 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.postprocessing; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.n4js.compileTime.CompileTimeValue; +import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4GetterDeclaration; +import org.eclipse.n4js.n4JS.N4JSASTUtils; +import org.eclipse.n4js.n4JS.N4SetterDeclaration; +import org.eclipse.n4js.n4JS.PropertyGetterDeclaration; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.n4JS.PropertySetterDeclaration; +import org.eclipse.n4js.n4JS.PropertySpread; +import org.eclipse.n4js.n4JS.TypeDefiningElement; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.SyntaxRelatedTElement; +import org.eclipse.n4js.utils.EcoreUtilN4; +import org.eclipse.n4js.utils.N4JSLanguageUtils; + +import com.google.inject.Singleton; + +/** + * Processing of {@link LiteralOrComputedPropertyName}s that have a computed property name, mainly setting property + * {@link LiteralOrComputedPropertyName#getComputedName() 'computedName'}. + *

+ * For details, see + * {@link ComputedNameProcessor#processComputedPropertyName( LiteralOrComputedPropertyName, ASTMetaInfoCache )}. + */ +@Singleton +public class ComputedNameProcessor { + + /** + * If the given 'nameDecl' has a computed property name, this method will + *

    + *
  1. obtain its expression's compile-time value from the cache (the actual evaluation of the expression happened + * in {@link CompileTimeExpressionProcessor}), + *
  2. store this name in 'nameDecl' (for later use), and + *
  3. store this name in the corresponding TModule element (if such a TModule element exists). + *
+ *

+ * In case the compile-time value of the expression is invalid (i.e. the expression is not a valid compile-time + * expression) no actual name will be stored in 'nameDecl' and the corresponding TModule element will be removed + * from the TModule, entirely (if such a TModule element exists). + */ + public void processComputedPropertyName(LiteralOrComputedPropertyName nameDecl, ASTMetaInfoCache cache) { + if (nameDecl.hasComputedPropertyName()) { + // obtain compile-time value of expression + CompileTimeValue value = cache.getCompileTimeValue(nameDecl.getExpression()); + // derive a property name from the value + String name = N4JSLanguageUtils.derivePropertyNameFromCompileTimeValue(value); + if (name != null) { + // cache the computed name in the LiteralOrComputedPropertyName AST node + EcoreUtilN4.doWithDeliver(false, () -> { + nameDecl.setComputedName(name); + nameDecl.setComputedSymbol(value instanceof CompileTimeValue.ValueSymbol); + }, nameDecl); + // set the computed name in the types model element + EObject owner = nameDecl.eContainer(); + EObject typeElem = N4JSASTUtils.getCorrespondingTypeModelElement(owner); + if (typeElem instanceof IdentifiableElement) { + EcoreUtilN4.doWithDeliver(false, () -> { + ((IdentifiableElement) typeElem).setName(name); + }, typeElem); + } + } else { + // invalid name expression (i.e. not a constant expression) + // -> remove the types model element from the TModule + // (note: we have to do this for consistency with how the types builder handles elements that are + // unnamed (usually due to a broken AST): in those cases, the types builder does not create a TModule + // element) + EObject owner = nameDecl.eContainer(); + discardTypeModelElement(owner); + } + } + } + + /** + * Discards the types model element corresponding to the given AST node. Throws exception if given AST node does not + * have a corresponding types model element. + */ + private void discardTypeModelElement(EObject astNode) { + EObject elem = N4JSASTUtils.getCorrespondingTypeModelElement(astNode); + + EcoreUtilN4.doWithDeliver(false, () -> { + if (astNode instanceof TypeDefiningElement) { + ((TypeDefiningElement) astNode).setDefinedType(null); + } else if (astNode instanceof N4FieldDeclaration) { + ((N4FieldDeclaration) astNode).setDefinedField(null); + } else if (astNode instanceof N4GetterDeclaration) { + ((N4GetterDeclaration) astNode).setDefinedGetter(null); + } else if (astNode instanceof N4SetterDeclaration) { + ((N4SetterDeclaration) astNode).setDefinedSetter(null); + } else if (astNode instanceof PropertyNameValuePair) { + ((PropertyNameValuePair) astNode).setDefinedField(null); + } else if (astNode instanceof PropertyGetterDeclaration) { + ((PropertyGetterDeclaration) astNode).setDefinedGetter(null); + } else if (astNode instanceof PropertySetterDeclaration) { + ((PropertySetterDeclaration) astNode).setDefinedSetter(null); + // note: PropertyMethodDeclaration is a TypeDefiningElement (handled above) + } else if (astNode instanceof PropertySpread) { + // nothing to discard in this case + } else { + throw new UnsupportedOperationException("switch case missing for: " + astNode); + } + }, astNode); + + if (elem instanceof SyntaxRelatedTElement) { + ((SyntaxRelatedTElement) elem).setAstElement(null); + } + if (elem != null) { + EcoreUtilN4.doWithDeliver(false, () -> { + EcoreUtil.remove(elem); + }, elem.eContainer()); + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ComputedNameProcessor.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ComputedNameProcessor.xtend deleted file mode 100644 index 4bb8100700..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/ComputedNameProcessor.xtend +++ /dev/null @@ -1,131 +0,0 @@ -/** - * Copyright (c) 2017 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.postprocessing - -import com.google.inject.Singleton -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.compileTime.CompileTimeValue -import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.N4GetterDeclaration -import org.eclipse.n4js.n4JS.N4JSASTUtils -import org.eclipse.n4js.n4JS.N4SetterDeclaration -import org.eclipse.n4js.n4JS.PropertyGetterDeclaration -import org.eclipse.n4js.n4JS.PropertyNameValuePair -import org.eclipse.n4js.n4JS.PropertySetterDeclaration -import org.eclipse.n4js.n4JS.PropertySpread -import org.eclipse.n4js.n4JS.TypeDefiningElement -import org.eclipse.n4js.ts.types.IdentifiableElement -import org.eclipse.n4js.ts.types.SyntaxRelatedTElement -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.utils.EcoreUtilN4 -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.xtext.EcoreUtil2 - -/** - * Processing of {@link LiteralOrComputedPropertyName}s that have a computed property name, mainly setting property - * {@link LiteralOrComputedPropertyName#getComputedName() 'computedName'}. - *

- * For details, see {@link ComputedNameProcessor#processComputedPropertyName(RuleEnvironment, LiteralOrComputedPropertyName, ASTMetaInfoCache, int)}. - */ -@Singleton -class ComputedNameProcessor { - - /** - * If the given 'nameDecl' has a computed property name, this method will - *

    - *
  1. obtain its expression's compile-time value from the cache (the actual evaluation of the expression happened - * in {@link CompileTimeExpressionProcessor}), - *
  2. derive the actual property name from that value (cf. {@link #getPropertyNameFromExpression(RuleEnvironment, Expression, ASTMetaInfoCache)}), - *
  3. store this name in 'nameDecl' (for later use), and - *
  4. store this name in the corresponding TModule element (if such a TModule element exists). - *
- *

- * In case the compile-time value of the expression is invalid (i.e. the expression is not a valid compile-time - * expression) no actual name will be stored in 'nameDecl' and the corresponding TModule element will be removed - * from the TModule, entirely (if such a TModule element exists). - */ - def public void processComputedPropertyName(RuleEnvironment G, LiteralOrComputedPropertyName nameDecl, - ASTMetaInfoCache cache, int indentLevel) { - - if (nameDecl.hasComputedPropertyName) { - // obtain compile-time value of expression - val value = cache.getCompileTimeValue(nameDecl.expression); - // derive a property name from the value - val name = N4JSLanguageUtils.derivePropertyNameFromCompileTimeValue(value); - if (name !== null) { - // cache the computed name in the LiteralOrComputedPropertyName AST node - EcoreUtilN4.doWithDeliver(false, [ - nameDecl.computedName = name; - nameDecl.computedSymbol = value instanceof CompileTimeValue.ValueSymbol; - ], nameDecl); - // set the computed name in the types model element - val owner = nameDecl.eContainer; - val typeElem = N4JSASTUtils.getCorrespondingTypeModelElement(owner); - if (typeElem instanceof IdentifiableElement) { - EcoreUtilN4.doWithDeliver(false, [ - typeElem.name = name; - ], typeElem); - } - } else { - // invalid name expression (i.e. not a constant expression) - // -> remove the types model element from the TModule - // (note: we have to do this for consistency with how the types builder handles elements that are - // unnamed (usually due to a broken AST): in those cases, the types builder does not create a TModule - // element) - val owner = nameDecl.eContainer; - discardTypeModelElement(owner); - } - } - } - - /** - * Discards the types model element corresponding to the given AST node. Throws exception if given AST node does not - * have a corresponding types model element. - */ - def private void discardTypeModelElement(EObject astNode) { - val elem = N4JSASTUtils.getCorrespondingTypeModelElement(astNode); - - EcoreUtilN4.doWithDeliver(false, [ - switch (astNode) { - TypeDefiningElement: - astNode.definedType = null - N4FieldDeclaration: - astNode.definedField = null - N4GetterDeclaration: - astNode.definedGetter = null - N4SetterDeclaration: - astNode.definedSetter = null - PropertyNameValuePair: - astNode.definedField = null - PropertyGetterDeclaration: - astNode.definedGetter = null - PropertySetterDeclaration: - astNode.definedSetter = null - // note: PropertyMethodDeclaration is a TypeDefiningElement (handled above) - PropertySpread: { - // nothing to discard in this case - } - default: - throw new UnsupportedOperationException("switch case missing for: " + astNode) - }; - ], astNode); - - if (elem instanceof SyntaxRelatedTElement) { - elem.astElement = null; - } - if (elem !== null) { - EcoreUtilN4.doWithDeliver(false, [ - EcoreUtil2.remove(elem); - ], elem.eContainer); - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/DestructureProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/DestructureProcessor.java new file mode 100644 index 0000000000..dd88121cc0 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/DestructureProcessor.java @@ -0,0 +1,143 @@ +/** + * 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.postprocessing; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.anyTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.undefinedTypeRef; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.toIterable; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.n4js.n4JS.ArrayElement; +import org.eclipse.n4js.n4JS.ArrayLiteral; +import org.eclipse.n4js.n4JS.AssignmentExpression; +import org.eclipse.n4js.n4JS.BindingElement; +import org.eclipse.n4js.n4JS.DestructureUtils; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ForStatement; +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.PropertyAssignment; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.n4JS.VariableBinding; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.ts.typeRefs.DeferredTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.TypableElement; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; +import org.eclipse.n4js.utils.EcoreUtilN4; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +/** + * Deals with destructuring patterns during post processing of an N4JS resource (only the destructuring pattern; the + * value to be destructured is handled normally by the other processors). + *

+ * TODO clean up handling of destructuring patterns during AST traversal, IDE-1714 + */ +@Singleton +class DestructureProcessor extends AbstractProcessor { + + @Inject + private ASTProcessor astProcessor; + @Inject + private PolyProcessor polyProcessor; + + /** + * Temporary handling of destructuring patterns while typing the AST. + */ + void typeDestructuringPattern(RuleEnvironment G, EObject node, ASTMetaInfoCache cache) { + // ArrayLiteral or ObjectLiteral, but plays role of a destructuring pattern + // -> does not really have a type, but use UnknownTypeRef to avoid having + // to deal with this special case whenever asking for type of an expression + cache.storeType((TypableElement) node, undefinedTypeRef(G)); + // for object literals, some additional hacks are required ... + if (node instanceof ObjectLiteral) { + ObjectLiteral olit = (ObjectLiteral) node; + // poly expressions in property name/value pairs expect to be processed as part of the outer poly expression + // -> invoke poly processor for them + // TODO GH-1337 add support for spread operator + for (PropertyAssignment pa : olit.getPropertyAssignments()) { + if (pa instanceof PropertyNameValuePair) { + Expression expr = ((PropertyNameValuePair) pa).getExpression(); + if (expr != null && polyProcessor.isResponsibleFor(expr) && !polyProcessor.isEntryPoint(expr)) { + polyProcessor.inferType(G, expr, cache); + } + } + } + // the defined type of the object literal may still have some DeferredTypeRefs -> remove them + for (DeferredTypeRef dtr : toIterable(filter( + olit.getDefinedType().eAllContents(), DeferredTypeRef.class))) { + + EcoreUtilN4.doWithDeliver(false, () -> EcoreUtil.replace(dtr, undefinedTypeRef(G)), dtr.eContainer()); + } + // add types for property assignments + for (PropertyAssignment pa : olit.getPropertyAssignments()) { + cache.storeType(pa, undefinedTypeRef(G)); + } + } + // here we basically turn off the fail-fast approach within the destructuring pattern + for (EObject elem : toIterable(node.eAllContents())) { + if (elem instanceof ObjectLiteral || elem instanceof PropertyAssignment + || elem instanceof ArrayLiteral || elem instanceof ArrayElement) { + + if (cache.getTypeFailSafe((TypableElement) elem) == null) { + cache.storeType((TypableElement) elem, undefinedTypeRef(G)); + } + } + } + } + + /** + * Temporary handling of forward references within destructuring patterns. + */ + TypeRef handleForwardReferenceWhileTypingDestructuringPattern(RuleEnvironment G, TypableElement node, + ASTMetaInfoCache cache) { + + EObject parent = node.eContainer(); + boolean isCyclicForwardReference = cache.astNodesCurrentlyBeingTyped.contains(node); + if (isCyclicForwardReference) { + if (parent instanceof VariableBinding && ((VariableBinding) parent).getExpression() == node) { + // we get here when typing the second 'b' in 'var [a,b] = [0,b,2];' + return anyTypeRef(G); + } else if (parent instanceof ForStatement && ((ForStatement) parent).getExpression() == node) { + // we get here when typing the second 'a' in 'for(var [a] of [[a]]) {}' + return anyTypeRef(G); + } + } + + log(0, "===START of other identifiable sub-tree"); + RuleEnvironment G_fresh = RuleEnvironmentExtensions.wrap(G); // don't use a new, empty environment here + // (required for recursion guards) + astProcessor.processSubtree(G_fresh, node, cache, 0); // note how we reset the indent level + cache.forwardProcessedSubTrees.add(node); + log(0, "===END of other identifiable sub-tree"); + return cache.getType(G, node); + } + + boolean isForwardReferenceWhileTypingDestructuringPattern(EObject obj) { + if (obj instanceof Expression) { + EObject parent = obj.eContainer(); + if (parent instanceof ForStatement) { + return DestructureUtils.isTopOfDestructuringForStatement(parent); + } + if (parent instanceof AssignmentExpression) { + return DestructureUtils.isTopOfDestructuringAssignment(parent); + } + return parent instanceof VariableBinding + || parent instanceof BindingElement + || (parent instanceof VariableDeclaration && parent.eContainer() instanceof BindingElement); + } + return false; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/DestructureProcessor.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/DestructureProcessor.xtend deleted file mode 100644 index cbfde29496..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/DestructureProcessor.xtend +++ /dev/null @@ -1,137 +0,0 @@ -/** - * 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.postprocessing - -import com.google.inject.Inject -import com.google.inject.Singleton -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.util.EcoreUtil -import org.eclipse.n4js.n4JS.ArrayElement -import org.eclipse.n4js.n4JS.ArrayLiteral -import org.eclipse.n4js.n4JS.AssignmentExpression -import org.eclipse.n4js.n4JS.BindingElement -import org.eclipse.n4js.n4JS.DestructureUtils -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.ForStatement -import org.eclipse.n4js.n4JS.ObjectLiteral -import org.eclipse.n4js.n4JS.PropertyAssignment -import org.eclipse.n4js.n4JS.PropertyNameValuePair -import org.eclipse.n4js.n4JS.VariableBinding -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.ts.typeRefs.DeferredTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.TypableElement -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions -import org.eclipse.n4js.utils.EcoreUtilN4 - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * Deals with destructuring patterns during post processing of an N4JS resource (only the destructuring pattern; - * the value to be destructured is handled normally by the other processors). - *

- * TODO clean up handling of destructuring patterns during AST traversal, IDE-1714 - */ -@Singleton -package class DestructureProcessor extends AbstractProcessor { - - @Inject - private ASTProcessor astProcessor; - @Inject - private PolyProcessor polyProcessor; - - /** - * Temporary handling of destructuring patterns while typing the AST. - */ - def void typeDestructuringPattern(RuleEnvironment G, EObject node, ASTMetaInfoCache cache, int indentLevel) { - // ArrayLiteral or ObjectLiteral, but plays role of a destructuring pattern - // -> does not really have a type, but use UnknownTypeRef to avoid having - // to deal with this special case whenever asking for type of an expression - cache.storeType(node as TypableElement, G.undefinedTypeRef); - // for object literals, some additional hacks are required ... - if (node instanceof ObjectLiteral) { - // poly expressions in property name/value pairs expect to be processed as part of the outer poly expression - // -> invoke poly processor for them - // TODO GH-1337 add support for spread operator - node.propertyAssignments // - .filter(PropertyNameValuePair) // - .map[expression] // - .filterNull // - .filter[polyProcessor.isResponsibleFor(it) && !polyProcessor.isEntryPoint(it)] // - .forEach [ - polyProcessor.inferType(G, it, cache); - ]; - // the defined type of the object literal may still have some DeferredTypeRefs -> remove them - node.definedType.eAllContents.filter(DeferredTypeRef).forEach [ dtr | - EcoreUtilN4.doWithDeliver(false, [ - EcoreUtil.replace(dtr, G.undefinedTypeRef); - ], dtr.eContainer); - ] - // add types for property assignments - node.propertyAssignments.forEach [ - cache.storeType(it, G.undefinedTypeRef); - ] - } - // here we basically turn off the fail-fast approach within the destructuring pattern - node.eAllContents // - .filter[ - it instanceof ObjectLiteral || it instanceof PropertyAssignment - || it instanceof ArrayLiteral || it instanceof ArrayElement - ] // - .filter[cache.getTypeFailSafe(it as TypableElement)===null] // - .forEach[ - cache.storeType(it as TypableElement, G.undefinedTypeRef); - ]; - } - - /** - * Temporary handling of forward references within destructuring patterns. - */ - def TypeRef handleForwardReferenceWhileTypingDestructuringPattern(RuleEnvironment G, TypableElement node, - ASTMetaInfoCache cache) { - - val parent = node.eContainer(); - val isCyclicForwardReference = cache.astNodesCurrentlyBeingTyped.contains(node); - if(isCyclicForwardReference) { - if(parent instanceof VariableBinding && (parent as VariableBinding).expression===node) { - // we get here when typing the second 'b' in 'var [a,b] = [0,b,2];' - return G.anyTypeRef; - } else if(parent instanceof ForStatement && (parent as ForStatement).expression===node) { - // we get here when typing the second 'a' in 'for(var [a] of [[a]]) {}' - return G.anyTypeRef; - } - } - - log(0, "===START of other identifiable sub-tree"); - val G_fresh = RuleEnvironmentExtensions.wrap(G); // don't use a new, empty environment here (required for recursion guards) - astProcessor.processSubtree(G_fresh, node, cache, 0); // note how we reset the indent level - cache.forwardProcessedSubTrees.add(node); - log(0, "===END of other identifiable sub-tree"); - return cache.getType(G, node); - } - - def boolean isForwardReferenceWhileTypingDestructuringPattern(EObject obj) { - if (obj instanceof Expression) { - val parent = obj.eContainer; - if (parent instanceof ForStatement) { - return DestructureUtils.isTopOfDestructuringForStatement(parent); - } - if (parent instanceof AssignmentExpression) { - return DestructureUtils.isTopOfDestructuringAssignment(parent) - } - return parent instanceof VariableBinding - || parent instanceof BindingElement - || (parent instanceof VariableDeclaration && parent.eContainer instanceof BindingElement) - } - return false; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor.java new file mode 100644 index 0000000000..2d07c2ade6 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor.java @@ -0,0 +1,267 @@ +/** + * 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.postprocessing; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.getCancelIndicator; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.Argument; +import org.eclipse.n4js.n4JS.ArrayElement; +import org.eclipse.n4js.n4JS.ArrayLiteral; +import org.eclipse.n4js.n4JS.ConditionalExpression; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.n4JS.PropertyAssignment; +import org.eclipse.n4js.n4JS.PropertyMethodDeclaration; +import org.eclipse.n4js.n4JS.RelationalExpression; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.TypableElement; +import org.eclipse.n4js.ts.types.util.Variance; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.constraints.InferenceContext; +import org.eclipse.n4js.typesystem.constraints.TypeConstraint; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.n4js.utils.DeclMergingHelper; +import org.eclipse.n4js.utils.DestructureHelper; +import org.eclipse.n4js.validation.JavaScriptVariantHelper; +import org.eclipse.xtext.service.OperationCanceledManager; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +/** + * The main poly processor responsible for typing poly expressions using a constraint-based approach. + *

+ * It tells other processors which AST nodes it is responsible for (see + * {@link PolyProcessor#isResponsibleFor(TypableElement) isResponsibleFor()}) and which AST nodes are an entry point to + * constraint-based type inference (see {@link PolyProcessor#isEntryPoint(TypableElement) isEntryPoint()}). For those + * "entry points" method {@link PolyProcessor#inferType(RuleEnvironment,Expression,ASTMetaInfoCache) inferType()} should + * be invoked by the other processors (mainly the TypeProcessor). + */ +@Singleton +class PolyProcessor extends AbstractPolyProcessor { + + @Inject + private PolyProcessor_ArrayLiteral arrayLiteralProcessor; + @Inject + private PolyProcessor_ObjectLiteral objectLiteralProcessor; + @Inject + private PolyProcessor_FunctionExpression functionExpressionProcessor; + @Inject + private PolyProcessor_CallExpression callExpressionProcessor; + + @Inject + private N4JSTypeSystem ts; + @Inject + private TypeSystemHelper tsh; + @Inject + private DeclMergingHelper declMergingHelper; + + @Inject + private DestructureHelper destructureHelper; + + @Inject + private OperationCanceledManager operationCanceledManager; + + @Inject + private JavaScriptVariantHelper jsVariantHelper; + + // ################################################################################################################ + + /** + * Tells if the given AST node's type should be inferred through constraint-based type inference. In that case, no + * other processor is allowed to add a type for this node to the {@link ASTMetaInfoCache}! + */ + boolean isResponsibleFor(TypableElement astNode) { + EObject parent = astNode.eContainer(); + return isPoly(astNode) + || (astNode instanceof Argument && parent instanceof ParameterizedCallExpression && isPoly(parent)) + || (astNode instanceof FormalParameter && parent instanceof FunctionExpression && isPoly(parent)) + || (astNode instanceof FormalParameter && parent instanceof PropertyMethodDeclaration && isPoly(parent)) + || (astNode instanceof ArrayElement && parent instanceof ArrayLiteral && isPoly(parent)) + || (astNode instanceof PropertyAssignment && parent instanceof ObjectLiteral && isPoly(parent)); + // note in previous line: + // even if the PropertyAssignment itself is NOT poly, we claim responsibility for it if the containing + // ObjectLiteral is poly + } + + /** + * Tells if the given AST node is an entry point to constraint-based type inference. In that case, and only in that + * case, method {@link #inferType(RuleEnvironment,Expression,ASTMetaInfoCache) inferType()} must be invoked for this + * AST node. + */ + boolean isEntryPoint(TypableElement astNode) { + return isRootPoly(astNode); + } + + // ################################################################################################################ + + /** + * Main method for inferring the type of poly expressions, i.e. for constraint-based type inference. It should be + * invoked for all AST nodes for which method {@link #isEntryPoint(TypableElement) isEntryPoint()} returns + * true (and only for such nodes!). This will ensure that this method will be called for all roots of + * trees of nested poly expressions (including such trees that only consist of a root without children) but not for + * the nested children. + *

+ * This method, together with its delegates, is responsible for adding to the cache types for all the following AST + * nodes: + *

    + *
  1. the given root poly expression rootPoly, + *
  2. all nested child poly expressions, + *
  3. some nested elements that aren't expressions but closely belong to one of the above expressions, e.g. formal + * parameters contained in a function expression (see code of {@link #isResponsibleFor(TypableElement)} for which + * elements are included here). + *
+ *

+ * The overall process of constraint-based type inference is as follows: + *

    + *
  1. create a new, empty {@link InferenceContext} called IC. + *
  2. invoke method {@link #processExpr(RuleEnvironment,Expression,TypeRef,InferenceContext,ASTMetaInfoCache) + * #processExpr()} for the given root poly expression and all its direct and indirect child poly expressions. This + * will ... + *
      + *
    1. add to IC (i) inference variables for all types to be inferred and (ii) appropriate constraints + * derived from the poly expressions and their relations. + *
    2. register onSolved handlers to IC (see below what these handlers are doing). + *
    + *
  3. solve the entire constraint system, i.e. invoke {@link InferenceContext#solve()} on IC. + *
  4. once solution is done (no matter if successful or failed) IC will automatically trigger the + * onSolved handlers: + *
      + *
    • in the success case, the handlers will use the solution in IC to add types to the cache for the + * given root poly expression and all its nested child poly expressions (and also for contained, typable elements + * such as fpars of function expressions). + *
    • in the failure case, the handlers will add fall-back types to the cache. + *
    + *
+ */ + void inferType(RuleEnvironment G, Expression rootPoly, ASTMetaInfoCache cache) { + // create a new constraint system + InferenceContext infCtx = new InferenceContext(ts, tsh, declMergingHelper, operationCanceledManager, + getCancelIndicator(G), G); + + // in plain JS files, we want to avoid searching for a solution (to avoid performance problems in some JS files + // with extremely large array/object literals) but to avoid having to deal with this case with additional code, + // we still build a constraint system as usual (TEMPORARAY HACK) + // TODO find proper way to deal with extremely large array/object literals + if (jsVariantHelper.doomTypeInference(rootPoly)) { + infCtx.addConstraint(TypeConstraint.FALSE); + } + + TypeRef expectedTypeOfPoly = destructureHelper.calculateExpectedType(rootPoly, G, infCtx); + // we have to pass the expected type to the #getType() method, so retrieve it first + // (until the expectedType judgment is integrated into AST traversal, we have to invoke this judgment here; + // in case of not-well-behaving expectedType rules, we use 'null' as expected type, i.e. no expectation) + // TODO integrate expectedType judgment into AST traversal and remove #isProblematicCaseOfExpectedType() + TypeRef expectedTypeRef = null; + if (expectedTypeOfPoly != null) { + expectedTypeRef = expectedTypeOfPoly; + } else if (!isProblematicCaseOfExpectedType(rootPoly)) { + expectedTypeRef = ts.expectedType(G, rootPoly.eContainer(), rootPoly); + } + + // call #processExpr() (this will recursively call #processExpr() on nested expressions, even if non-poly) + TypeRef typeRef = processExpr(G, rootPoly, expectedTypeRef, infCtx, cache); + + // add constraint to ensure that type of 'rootPoly' is subtype of its expected type + if (!TypeUtils.isVoid(typeRef)) { + if (expectedTypeRef != null) { + infCtx.addConstraint(0, typeRef, expectedTypeRef, Variance.CO); + } + } + + // compute solution + // (note: we're not actually interested in the solution, here; we just want to make sure to trigger the + // onSolved handlers registered by the #process*() methods of the other poly processors; see responsibilities of + // #processExpr(RuleEnvironment, Expression, TypeRef, InferenceContext, ASTMetaInfoCache) + infCtx.solve(); + } + + /** + * Key method for handling poly expressions. + *

+ * It has the following responsibilities: + *

    + *
  • if given expression is non-poly: simply return its type
    + * (note: in this case this method won't process nested expressions in any way). + *
  • if given expression is poly: + *
      + *
    1. introduce a new inference variable to the given inference context for each type to be inferred for the given + * poly expression (usually only 1, but may be several, e.g. for a function expression we introduce an inference + * variable for the return type and each fpar), + *
    2. add appropriate constraints to the given inference context, + *
    3. recursively invoke this method for nested expressions (no matter if poly or non-poly). + *
    4. register to the given inference context an onSolved handler that will - after the inference + * context will have been solved - add all required final types for 'expr' and its non-expression children + * (e.g. fpars) to the typing cache. + *
    5. return temporary type of the given expression expr. + *
    + *
+ * IMPORTANT: the "temporary" type may contain inference variables; the "final" types must be proper, i.e. must not + * contain any inference variables! + */ + protected TypeRef processExpr(RuleEnvironment G, Expression expr, TypeRef expectedTypeRef, + InferenceContext infCtx, ASTMetaInfoCache cache) { + + if (isPoly(expr)) { + // poly -> delegate this to the appropriate, specific PolyProcessor + if (expr instanceof ArrayLiteral) { + return arrayLiteralProcessor.processArrayLiteral(G, (ArrayLiteral) expr, expectedTypeRef, infCtx, + cache); + } else if (expr instanceof ObjectLiteral) { + return objectLiteralProcessor.processObjectLiteral(G, (ObjectLiteral) expr, expectedTypeRef, infCtx, + cache); + } else if (expr instanceof FunctionExpression) { + return functionExpressionProcessor.processFunctionExpression(G, (FunctionExpression) expr, + expectedTypeRef, infCtx, cache); + } else if (expr instanceof ParameterizedCallExpression) { + return callExpressionProcessor.processCallExpression(G, (ParameterizedCallExpression) expr, + expectedTypeRef, infCtx, cache); + } else if (expr instanceof ConditionalExpression) { + ConditionalExpression ce = (ConditionalExpression) expr; + if (isPoly(ce.getTrueExpression())) { + TypeRef typeRef = processExpr(G, ce.getTrueExpression(), expectedTypeRef, infCtx, cache); + // store a copy of the inferred type also at the conditional expression node + infCtx.onSolved(solution -> cache.storeType(ce, + TypeUtils.copy(cache.getTypeFailSafe(ce.getTrueExpression())))); + return typeRef; + } else if (isPoly(ce.getFalseExpression())) { + TypeRef typeRef = processExpr(G, ce.getFalseExpression(), expectedTypeRef, infCtx, cache); + // store a copy of the inferred type also at the conditional expression node + infCtx.onSolved(solution -> cache.storeType(ce, + TypeUtils.copy(cache.getTypeFailSafe(ce.getFalseExpression())))); + return typeRef; + } else { + throw new IllegalArgumentException("missing case in #processExpr() for poly expression: " + expr); + } + } + throw new IllegalArgumentException("missing case in #processExpr() for poly expression: " + expr); + } else { + // not poly -> directly infer type via type system + TypeRef result = ts.type(G, expr); + // do *not* store in cache (TypeProcessor responsible for storing types of non-poly expressions in cache!) + return result; + } + } + + /** + * Returns true if we are not allowed to ask for the expected type of 'node', because this would lead to illegal + * forward references (temporary). + */ + private boolean isProblematicCaseOfExpectedType(EObject node) { + return node != null && node.eContainer() instanceof RelationalExpression; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor.xtend deleted file mode 100644 index 6d5ebba220..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor.xtend +++ /dev/null @@ -1,260 +0,0 @@ -/** - * 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.postprocessing - -import com.google.inject.Inject -import com.google.inject.Singleton -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.Argument -import org.eclipse.n4js.n4JS.ArrayElement -import org.eclipse.n4js.n4JS.ArrayLiteral -import org.eclipse.n4js.n4JS.ConditionalExpression -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.FormalParameter -import org.eclipse.n4js.n4JS.FunctionExpression -import org.eclipse.n4js.n4JS.ObjectLiteral -import org.eclipse.n4js.n4JS.ParameterizedCallExpression -import org.eclipse.n4js.n4JS.PropertyAssignment -import org.eclipse.n4js.n4JS.PropertyMethodDeclaration -import org.eclipse.n4js.n4JS.RelationalExpression -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.TypableElement -import org.eclipse.n4js.ts.types.util.Variance -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.constraints.InferenceContext -import org.eclipse.n4js.typesystem.constraints.TypeConstraint -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper -import org.eclipse.n4js.utils.DeclMergingHelper -import org.eclipse.n4js.utils.DestructureHelper -import org.eclipse.n4js.validation.JavaScriptVariantHelper -import org.eclipse.xtext.service.OperationCanceledManager - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * The main poly processor responsible for typing poly expressions using a constraint-based approach. - *

- * It tells other processors which AST nodes it is responsible for (see {@link PolyProcessor#isResponsibleFor(TypableElement) isResponsibleFor()}) - * and which AST nodes are an entry point to constraint-based type inference (see {@link PolyProcessor#isEntryPoint(TypableElement) isEntryPoint()}). - * For those "entry points" method {@link PolyProcessor#inferType(RuleEnvironment,Expression,ASTMetaInfoCache) inferType()} - * should be invoked by the other processors (mainly the TypeProcessor). - */ -@Singleton -package class PolyProcessor extends AbstractPolyProcessor { - - @Inject - private PolyProcessor_ArrayLiteral arrayLiteralProcessor; - @Inject - private PolyProcessor_ObjectLiteral objectLiteralProcessor; - @Inject - private PolyProcessor_FunctionExpression functionExpressionProcessor; - @Inject - private PolyProcessor_CallExpression callExpressionProcessor; - - @Inject - private N4JSTypeSystem ts; - @Inject - private TypeSystemHelper tsh; - @Inject - private DeclMergingHelper declMergingHelper; - - @Inject - private DestructureHelper destructureHelper; - - @Inject - private OperationCanceledManager operationCanceledManager; - - @Inject - private JavaScriptVariantHelper jsVariantHelper; - - // ################################################################################################################ - - - /** - * Tells if the given AST node's type should be inferred through constraint-based type inference. In that case, - * no other processor is allowed to add a type for this node to the {@link ASTMetaInfoCache}! - */ - def package boolean isResponsibleFor(TypableElement astNode) { - astNode.isPoly - || (astNode instanceof Argument && astNode.eContainer instanceof ParameterizedCallExpression && astNode.eContainer.isPoly) - || (astNode instanceof FormalParameter && astNode.eContainer instanceof FunctionExpression && astNode.eContainer.isPoly) - || (astNode instanceof FormalParameter && astNode.eContainer instanceof PropertyMethodDeclaration && astNode.eContainer.isPoly) - || (astNode instanceof ArrayElement && astNode.eContainer instanceof ArrayLiteral && astNode.eContainer.isPoly) - || (astNode instanceof PropertyAssignment && astNode.eContainer instanceof ObjectLiteral && astNode.eContainer.isPoly) - // note in previous line: - // even if the PropertyAssignment itself is NOT poly, we claim responsibility for it if the containing ObjectLiteral is poly - } - - /** - * Tells if the given AST node is an entry point to constraint-based type inference. In that case, and only in that - * case, method {@link #inferType(RuleEnvironment,Expression,ASTMetaInfoCache) inferType()} must be invoked for this - * AST node. - */ - def package boolean isEntryPoint(TypableElement astNode) { - astNode.isRootPoly - } - - - // ################################################################################################################ - - - /** - * Main method for inferring the type of poly expressions, i.e. for constraint-based type inference. It should be - * invoked for all AST nodes for which method {@link #isEntryPoint(TypableElement) isEntryPoint()} - * returns true (and only for such nodes!). This will ensure that this method will be called for all - * roots of trees of nested poly expressions (including such trees that only consist of a root without children) but - * not for the nested children. - *

- * This method, together with its delegates, is responsible for adding to the cache types for all the following - * AST nodes: - *

    - *
  1. the given root poly expression rootPoly, - *
  2. all nested child poly expressions, - *
  3. some nested elements that aren't expressions but closely belong to one of the above expressions, e.g. formal - * parameters contained in a function expression (see code of {@link #isResponsibleFor(TypableElement)} for which - * elements are included here). - *
- *

- * The overall process of constraint-based type inference is as follows: - *

    - *
  1. create a new, empty {@link InferenceContext} called IC. - *
  2. invoke method {@link #processExpr(RuleEnvironment,Expression,TypeRef,InferenceContext,ASTMetaInfoCache) #processExpr()} - * for the given root poly expression and all its direct and indirect child poly expressions. This will ... - *
      - *
    1. add to IC (i) inference variables for all types to be inferred and (ii) appropriate - * constraints derived from the poly expressions and their relations. - *
    2. register onSolved handlers to IC (see below what these handlers are doing). - *
    - *
  3. solve the entire constraint system, i.e. invoke {@link #solve()} on IC. - *
  4. once solution is done (no matter if successful or failed) IC will automatically trigger the - * onSolved handlers: - *
      - *
    • in the success case, the handlers will use the solution in IC to add types to the cache for - * the given root poly expression and all its nested child poly expressions (and also for contained, typable - * elements such as fpars of function expressions). - *
    • in the failure case, the handlers will add fall-back types to the cache. - *
    - *
- */ - def package void inferType(RuleEnvironment G, Expression rootPoly, ASTMetaInfoCache cache) { - // create a new constraint system - val InferenceContext infCtx = new InferenceContext(ts, tsh, declMergingHelper, operationCanceledManager, G.cancelIndicator, G); - - // in plain JS files, we want to avoid searching for a solution (to avoid performance problems in some JS files - // with extremely large array/object literals) but to avoid having to deal with this case with additional code, - // we still build a constraint system as usual (TEMPORARAY HACK) - // TODO find proper way to deal with extremely large array/object literals - if (jsVariantHelper.doomTypeInference(rootPoly)) { - infCtx.addConstraint(TypeConstraint.FALSE); - } - - val expectedTypeOfPoly = destructureHelper.calculateExpectedType(rootPoly, G, infCtx); - // we have to pass the expected type to the #getType() method, so retrieve it first - // (until the expectedType judgment is integrated into AST traversal, we have to invoke this judgment here; - // in case of not-well-behaving expectedType rules, we use 'null' as expected type, i.e. no expectation) - // TODO integrate expectedType judgment into AST traversal and remove #isProblematicCaseOfExpectedType() - val expectedTypeRef = if (expectedTypeOfPoly !== null) { - expectedTypeOfPoly - } else if (!rootPoly.isProblematicCaseOfExpectedType) { - ts.expectedType(G, rootPoly.eContainer(), rootPoly); - }; - - // call #processExpr() (this will recursively call #processExpr() on nested expressions, even if non-poly) - val typeRef = processExpr(G, rootPoly, expectedTypeRef, infCtx, cache); - - // add constraint to ensure that type of 'rootPoly' is subtype of its expected type - if (!TypeUtils.isVoid(typeRef)) { - if (expectedTypeRef !== null) { - infCtx.addConstraint(0, typeRef, expectedTypeRef, Variance.CO); - } - } - - // compute solution - // (note: we're not actually interested in the solution, here; we just want to make sure to trigger the - // onSolved handlers registered by the #process*() methods of the other poly processors; see responsibilities of - // #processExpr(RuleEnvironment, Expression, TypeRef, InferenceContext, ASTMetaInfoCache) - infCtx.solve; - } - - - - /** - * Key method for handling poly expressions. - *

- * It has the following responsibilities: - *

    - *
  • if given expression is non-poly: simply return its type
    - * (note: in this case this method won't process nested expressions in any way). - *
  • if given expression is poly: - *
      - *
    1. introduce a new inference variable to the given inference context for each type to be inferred for the - * given poly expression (usually only 1, but may be several, e.g. for a function expression we introduce an - * inference variable for the return type and each fpar), - *
    2. add appropriate constraints to the given inference context, - *
    3. recursively invoke this method for nested expressions (no matter if poly or non-poly). - *
    4. register to the given inference context an onSolved handler that will - after the inference - * context will have been solved - add all required final types for 'expr' and its non-expression - * children (e.g. fpars) to the typing cache. - *
    5. return temporary type of the given expression expr. - *
    - *
- * IMPORTANT: the "temporary" type may contain inference variables; the "final" types must be proper, i.e. must not - * contain any inference variables! - */ - def protected TypeRef processExpr(RuleEnvironment G, Expression expr, TypeRef expectedTypeRef, - InferenceContext infCtx, ASTMetaInfoCache cache) { - - if (isPoly(expr)) { - // poly -> delegate this to the appropriate, specific PolyProcessor - return switch(expr) { - ArrayLiteral: - arrayLiteralProcessor.processArrayLiteral(G, expr, expectedTypeRef, infCtx, cache) - ObjectLiteral: - objectLiteralProcessor.processObjectLiteral(G, expr, expectedTypeRef, infCtx, cache) - FunctionExpression: - functionExpressionProcessor.processFunctionExpression(G, expr, expectedTypeRef, infCtx, cache) - ParameterizedCallExpression: - callExpressionProcessor.processCallExpression(G, expr, expectedTypeRef, infCtx, cache) - ConditionalExpression: - if (isPoly(expr.trueExpression)) { - val TypeRef typeRef = processExpr(G, expr.trueExpression, expectedTypeRef, infCtx, cache); - // store a copy of the inferred type also at the conditional expression node - infCtx.onSolved([ solution | cache.storeType(expr, TypeUtils.copy(cache.getTypeFailSafe(expr.trueExpression))) ]); - typeRef; - } else if (isPoly(expr.falseExpression)) { - val TypeRef typeRef = processExpr(G, expr.falseExpression, expectedTypeRef, infCtx, cache); - // store a copy of the inferred type also at the conditional expression node - infCtx.onSolved([ solution | cache.storeType(expr, TypeUtils.copy(cache.getTypeFailSafe(expr.falseExpression))) ]); - typeRef; - } else { - throw new IllegalArgumentException("missing case in #processExpr() for poly expression: " + expr) - } - default: - throw new IllegalArgumentException("missing case in #processExpr() for poly expression: " + expr) - }; - } else { - // not poly -> directly infer type via type system - val result = ts.type(G, expr); - // do *not* store in cache (TypeProcessor responsible for storing types of non-poly expressions in cache!) - return result; - } - } - - /** - * Returns true if we are not allowed to ask for the expected type of 'node', because this would lead to illegal - * forward references (temporary). - */ - def private boolean isProblematicCaseOfExpectedType(EObject node) { - return node?.eContainer instanceof RelationalExpression - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ArrayLiteral.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ArrayLiteral.java new file mode 100644 index 0000000000..9462748ec2 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ArrayLiteral.java @@ -0,0 +1,400 @@ +/** + * 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.postprocessing; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.anyTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.arrayNType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.arrayNTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.arrayType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.arrayTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.isArrayN; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.isIterableN; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.iterableType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.iterableTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.stringType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.stringTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.undefinedTypeRef; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.eclipse.n4js.n4JS.ArrayElement; +import org.eclipse.n4js.n4JS.ArrayLiteral; +import org.eclipse.n4js.n4JS.ArrayPadding; +import org.eclipse.n4js.n4JS.DestructureUtils; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory; +import org.eclipse.n4js.ts.typeRefs.UnionTypeExpression; +import org.eclipse.n4js.ts.types.InferenceVariable; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TInterface; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.ts.types.TypeVariable; +import org.eclipse.n4js.ts.types.util.Variance; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.constraints.InferenceContext; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.xtext.xbase.lib.IterableExtensions; + +import com.google.common.base.Optional; +import com.google.inject.Inject; +import com.google.inject.Singleton; + +/** + * {@link PolyProcessor} delegates here for processing array literals. + * + * @see PolyProcessor#inferType(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,ASTMetaInfoCache) + * @see PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache) + */ +@Singleton +class PolyProcessor_ArrayLiteral extends AbstractPolyProcessor { + @Inject + private PolyProcessor polyProcessor; + @Inject + private N4JSTypeSystem ts; + @Inject + private TypeSystemHelper tsh; + + /** + * BEFORE CHANGING THIS METHOD, READ THIS: + * {@link PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache)} + */ + TypeRef processArrayLiteral(RuleEnvironment G, ArrayLiteral arrLit, TypeRef expectedTypeRef, + InferenceContext infCtx, ASTMetaInfoCache cache) { + + // note: we do not have the case !arrLit.isPoly here, as in the other poly processors + // (array literals are always poly, because they cannot be explicitly typed in N4JS) + + int numOfElems = arrLit.getElements().size(); + + // we have to analyze the type expectation: + // 1. we have to know up-front whether we aim for an actual type of Array/Iterable or for ArrayN/IterableN + // 2. we have to know if we have concrete expectations for the element type(s) + // To do so, we prepare a helper variable 'expectedElemTypeRefs' + List expectedElemTypeRefs = getExpectedElemTypeRefs(G, expectedTypeRef); + + // hack: faking an expectation of ArrayN<...> here + // TODO instead we should get such an expectation in these cases from expectedType judgment! + boolean isValueToBeDestructured = DestructureUtils.isArrayOrObjectLiteralBeingDestructured(arrLit); + if (isValueToBeDestructured) { + while (expectedElemTypeRefs.size() < numOfElems) + expectedElemTypeRefs.add(anyTypeRef(G)); + } + + // performance tweak: + boolean haveUsableExpectedType = !expectedElemTypeRefs.isEmpty(); + if (!haveUsableExpectedType && !TypeUtils.isInferenceVariable(expectedTypeRef)) { + // no type expectation or some entirely wrong type expectation (i.e. other than Array, ArrayN) + // -> just derive type from elements (and do not introduce a new inference variable for this ArrayLiteral!) + List elemTypeRefs = new ArrayList<>(); + List nonNullElems = toList( + IterableExtensions.filter(arrLit.getElements(), ae -> ae.getExpression() != null)); + for (ArrayElement arrElem : nonNullElems) { + var arrElemTypeRef = polyProcessor.processExpr(G, arrElem.getExpression(), null, infCtx, cache); + arrElemTypeRef = ts.upperBoundWithReopen(G, arrElemTypeRef); + if (arrElem.isSpread()) { + // more than one in case of ArrayN; none in case of invalid value after spread operator + elemTypeRefs.addAll(extractSpreadTypeRefs(G, arrElemTypeRef)); + } else { + elemTypeRefs.add(arrElemTypeRef); + } + } + + infCtx.onSolved(solution -> handleOnSolvedPerformanceTweak(G, cache, arrLit, expectedElemTypeRefs)); + + TypeRef unionOfElemTypes = (!elemTypeRefs.isEmpty()) + ? tsh.createUnionType(G, elemTypeRefs.toArray(new TypeRef[0])) + : anyTypeRef(G); + return arrayTypeRef(G, unionOfElemTypes); + } + + int resultLen = getResultLength(arrLit, expectedElemTypeRefs); + TypeVariable[] resultInfVars = infCtx.newInferenceVariables(resultLen); + + processElements(G, cache, infCtx, arrLit, resultLen, resultInfVars); + + TypeRef resultTypeRef = getResultTypeRef(G, resultLen, resultInfVars); + + // register onSolved handlers to add final types to cache (i.e. may not contain inference variables) + infCtx.onSolved(solution -> handleOnSolved(G, cache, arrLit, expectedElemTypeRefs, resultTypeRef, solution)); + + // return temporary type of arrLit (i.e. may contain inference variables) + return resultTypeRef; + } + + /** + * The return value is as follows: + *
    + *
  • #[ T ] for an expectedTypeRef of the form Array<T> or Iterable<T>,
  • + *
  • #[ T1, T2, ..., TN ] for an expectedTypeRef of the form ArrayN<T1,T2,...,TN>,
  • + *
  • #[] for any other kind of expectedTypeRef
  • + *
+ */ + private List getExpectedElemTypeRefs(RuleEnvironment G, TypeRef expectedTypeRef) { + if (expectedTypeRef != null) { + List candidateTypeRefs = (expectedTypeRef instanceof UnionTypeExpression) + ? ((UnionTypeExpression) expectedTypeRef).getTypeRefs() + : List.of(expectedTypeRef); + TInterface iterableType = iterableType(G); + TClass arrayType = arrayType(G); + for (TypeRef candidateTypeRef : candidateTypeRefs) { + Type declType = candidateTypeRef.getDeclaredType(); + if (declType == iterableType + || declType == arrayType + || isIterableN(G, declType) + || isArrayN(G, declType)) { + List extractedTypeRefs = tsh.extractIterableElementTypes(G, candidateTypeRef); + if (extractedTypeRefs.size() > 0) { + return extractedTypeRefs; // will have len>1 iff expectation is IterableN + } + } + } + } + return new ArrayList<>(); // no or invalid type expectation + } + + /** + * Makes a best effort for building a type in case something went awry. It's only non-trivial in case we have an + * expectation of IterableN. + */ + private TypeRef buildFallbackTypeForArrayLiteral(boolean isArrayN, int resultLen, + List elemTypeRefsWithLiteralTypes, List expectedElemTypeRefs, RuleEnvironment G) { + + List elemTypeRefs = toList(map( + elemTypeRefsWithLiteralTypes, elem -> N4JSLanguageUtils.getLiteralTypeBase(G, elem))); + + if (isArrayN) { + TypeRef[] typeArgs = new TypeRef[resultLen]; + for (var i = 0; i < resultLen; i++) { + boolean isLastElem = i == (resultLen - 1); + TypeRef typeRef = null; + if (isLastElem && elemTypeRefs.size() > resultLen) { + // special case: + // we are at the last element AND we actually have more elements than we expect elements + // -> have to check all remaining elements against the last expectation! + List allRemainingElementTypeRefs = new ArrayList<>(); + TypeRef currExpectedElemTypeRef = expectedElemTypeRefs.get(i); + + // if all remaining elements are a subtype of the last expectation, then use expectation, otherwise + // form union + boolean allMatch = true; + for (var j = i; j < elemTypeRefs.size(); j++) { + + TypeRef currElementTypeRef = elemTypeRefs.get(j); + allRemainingElementTypeRefs.add(currElementTypeRef); + + if (allMatch) { // don't try further subtype checks if already failed + boolean actualIsSubtypeOfExpected = ts.subtypeSucceeded(G, currElementTypeRef, + currExpectedElemTypeRef); + if (!actualIsSubtypeOfExpected) { + allMatch = false; + } + } + } + if (allMatch) { + // use expected type + typeRef = currExpectedElemTypeRef; + } else { + // use actual types (will lead to follow-up errors caught by validations) + typeRef = tsh.createUnionType(G, allRemainingElementTypeRefs.toArray(new TypeRef[0])); + } + } else { + TypeRef currElemTypeRef = elemTypeRefs.get(i); + TypeRef currExpectedElemTypeRef = expectedElemTypeRefs.get(i); + boolean actualIsSubtypeOfExpected = ts.subtypeSucceeded(G, currElemTypeRef, + currExpectedElemTypeRef); + if (actualIsSubtypeOfExpected) { + // use expected type + typeRef = currExpectedElemTypeRef; + } else { + // use actual type (will lead to follow-up errors caught by validations) + typeRef = currElemTypeRef; + } + } + typeArgs[i] = typeRef; + } + + if (elemTypeRefs.size() > resultLen) { + // replace last entry in 'typeArgs' with union of all remaining in elemTypeRefs + TypeRef[] remaining = Arrays.copyOfRange(elemTypeRefs.toArray(new TypeRef[0]), resultLen - 1, + elemTypeRefs.size()); + + typeArgs[resultLen - 1] = tsh.createUnionType(G, remaining); + } + + return arrayNTypeRef(G, resultLen, typeArgs); + } else { + TypeRef unionOfElemTypes = (!elemTypeRefs.isEmpty()) + ? tsh.createUnionType(G, elemTypeRefs.toArray(new TypeRef[0])) + : anyTypeRef(G); + return arrayTypeRef(G, unionOfElemTypes); + } + } + + /** + * choose correct number of type arguments in our to-be-created resultTypeRef (always 1 for Array or Iterable + * but N for ArrayN<..>, e.g. 3 for Array3) + */ + private int getResultLength(ArrayLiteral arrLit, List expectedElemTypeRefs) { + int numOfElems = arrLit.getElements().size(); + int lenA = Math.min( + expectedElemTypeRefs.size(), // use number of type arguments provided by type expectation as a basis + numOfElems // ... but never more than we have elements in the array literal + ); + + int lenB = Math.min( + lenA, + BuiltInTypeScope.ITERABLE_N__MAX_LEN // ... and never more than the max. allowed number of type + // arguments for ArrayN + ); + + int resultLen = Math.max( + lenB, + 1 // ... but at least 1 (even if numOfElems is 0, for example) + ); + return resultLen; + } + + /** + * Creates temporary type (i.e. may contain inference variables): + *
    + *
  • Array (where T is a new inference variable) or
  • + *
  • ArrayN (where T1,...TN are new inference variables, N>=2)
  • + *
+ */ + private TypeRef getResultTypeRef(RuleEnvironment G, int resultLen, TypeVariable[] resultInfVars) { + boolean isArrayN = resultLen >= 2; + TClass declaredType = (isArrayN) ? arrayNType(G, resultLen) : arrayType(G); + List typeArgs = toList( + map(Arrays.asList(resultInfVars), v -> TypeUtils.createTypeRef(v))); + TypeRef resultTypeRef = TypeUtils.createTypeRef(declaredType, typeArgs.toArray(new ParameterizedTypeRef[0])); + return resultTypeRef; + } + + /** + * for each array element, add a constraint to ensure that its corresponding infVar in result type will be a super + * type of the array element's expression + */ + private void processElements(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, + ArrayLiteral arrLit, + int resultLen, TypeVariable[] resultInfVars) { + int numOfElems = arrLit.getElements().size(); + for (var idxElem = 0; idxElem < numOfElems; idxElem++) { + ArrayElement currElem = arrLit.getElements().get(idxElem); + if (currElem == null || currElem.getExpression() == null) { + // currElem is null, or has no expression (broken AST), or is an ArrayPadding element + // -> ignore (no constraint to add) + } else { + // currElem is a valid ArrayElement with an expression + // -> add constraint currElemTypeRef <: Ti (Ti being the corresponding inf. variable in resultTypeRef) + int idxResult = Math.min(idxElem, resultLen - 1); + TypeVariable currResultInfVar = resultInfVars[idxResult]; + TypeRef currResultInfVarTypeRef = TypeUtils.createTypeRef(currResultInfVar); + TypeRef currExpectedTypeRef = (currElem.isSpread()) + ? iterableTypeRef(G, TypeUtils.createWildcardExtends(currResultInfVarTypeRef)) + : currResultInfVarTypeRef; + TypeRef currElemTypeRef = polyProcessor.processExpr(G, currElem.getExpression(), currExpectedTypeRef, + infCtx, cache); + infCtx.addConstraint(currElemTypeRef, currExpectedTypeRef, Variance.CO); + } + } + } + + /** + * Writes final types to cache. + */ + private void handleOnSolvedPerformanceTweak(RuleEnvironment G, ASTMetaInfoCache cache, ArrayLiteral arrLit, + List expectedElemTypeRefs) { + List betterElemTypeRefs = storeTypesOfArrayElements(G, cache, arrLit); + TypeRef fallbackTypeRef = buildFallbackTypeForArrayLiteral(false, 1, betterElemTypeRefs, expectedElemTypeRefs, + G); + cache.storeType(arrLit, fallbackTypeRef); + } + + /** + * Writes final types to cache. + */ + private void handleOnSolved(RuleEnvironment G, ASTMetaInfoCache cache, ArrayLiteral arrLit, + List expectedElemTypeRefs, TypeRef resultTypeRef, + Optional> solution) { + int resultLen = getResultLength(arrLit, expectedElemTypeRefs); + boolean isArrayN = resultLen >= 2; + if (solution.isPresent()) { + // success case + TypeRef typeRef = applySolution(resultTypeRef, G, solution.get()); + cache.storeType(arrLit, typeRef); + } else { + // failure case (unsolvable constraint system) + List betterElemTypeRefs = toList(map( + arrLit.getElements(), ae -> getFinalResultTypeOfArrayElement(G, ae, Optional.absent()))); + TypeRef typeRef = buildFallbackTypeForArrayLiteral(isArrayN, resultLen, betterElemTypeRefs, + expectedElemTypeRefs, G); + cache.storeType(arrLit, typeRef); + } + storeTypesOfArrayElements(G, cache, arrLit); + } + + // PolyProcessor#isResponsibleFor(TypableElement) claims responsibility of AST nodes of type 'ArrayElement' + // contained in an ArrayLiteral which is poly, so we are responsible for storing the types of those + // 'ArrayElement' nodes in cache + // (note: compare this with similar handling of 'Argument' nodes in PolyProcessor_CallExpression) + private List storeTypesOfArrayElements(RuleEnvironment G, ASTMetaInfoCache cache, ArrayLiteral arrLit) { + List storedElemTypeRefs = new ArrayList<>(); + for (ArrayElement currElem : arrLit.getElements()) { + if (currElem instanceof ArrayPadding) { + cache.storeType(currElem, undefinedTypeRef(G)); + } else { + TypeRef currElemTypeRef = getFinalResultTypeOfArrayElement(G, currElem, + Optional.of(storedElemTypeRefs)); + cache.storeType(currElem, currElemTypeRef); + } + } + return storedElemTypeRefs; + } + + private TypeRef getFinalResultTypeOfArrayElement(RuleEnvironment G, ArrayElement currElem, + Optional> addTypeRefsHere) { + Expression currExpr = currElem == null ? null : currElem.getExpression(); + TypeRef currElemTypeRef = (currExpr != null) ? getFinalResultTypeOfNestedPolyExpression(currExpr) : null; + if (currElemTypeRef != null && currElem != null) { + currElemTypeRef = ts.upperBoundWithReopen(G, currElemTypeRef); + List currElemTypeRefs = (currElem.isSpread()) ? extractSpreadTypeRefs(G, currElemTypeRef) + : List.of(currElemTypeRef); + if (addTypeRefsHere.isPresent()) { + addTypeRefsHere.get().addAll(currElemTypeRefs); + } + return tsh.createUnionType(G, currElemTypeRefs.toArray(new TypeRef[0])); + } + return TypeRefsFactory.eINSTANCE.createUnknownTypeRef(); + } + + private List extractSpreadTypeRefs(RuleEnvironment G, TypeRef typeRef) { + // case 1: built-in type string + if (typeRef instanceof ParameterizedTypeRef) { + if (typeRef.getDeclaredType() == stringType(G)) { + return List.of(stringTypeRef(G)); // spreading a string yields zero or more strings + } + } + // case 2: Iterable or ArrayN + return tsh.extractIterableElementTypes(G, typeRef); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ArrayLiteral.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ArrayLiteral.xtend deleted file mode 100644 index 7111a4aedd..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ArrayLiteral.xtend +++ /dev/null @@ -1,361 +0,0 @@ -/** - * 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.postprocessing - -import com.google.common.base.Optional -import com.google.inject.Inject -import com.google.inject.Singleton -import java.util.Arrays -import java.util.Collection -import java.util.List -import java.util.Map -import org.eclipse.n4js.n4JS.ArrayElement -import org.eclipse.n4js.n4JS.ArrayLiteral -import org.eclipse.n4js.n4JS.ArrayPadding -import org.eclipse.n4js.n4JS.DestructureUtils -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory -import org.eclipse.n4js.ts.typeRefs.UnionTypeExpression -import org.eclipse.n4js.ts.types.InferenceVariable -import org.eclipse.n4js.ts.types.TypeVariable -import org.eclipse.n4js.ts.types.util.Variance -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.constraints.InferenceContext -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper -import org.eclipse.n4js.utils.N4JSLanguageUtils - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * {@link PolyProcessor} delegates here for processing array literals. - * - * @see PolyProcessor#inferType(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,ASTMetaInfoCache) - * @see PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache) - */ -@Singleton -package class PolyProcessor_ArrayLiteral extends AbstractPolyProcessor { - @Inject - private PolyProcessor polyProcessor; - @Inject - private N4JSTypeSystem ts; - @Inject - private TypeSystemHelper tsh; - - /** - * BEFORE CHANGING THIS METHOD, READ THIS: - * {@link PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache)} - */ - def package TypeRef processArrayLiteral(RuleEnvironment G, ArrayLiteral arrLit, TypeRef expectedTypeRef, - InferenceContext infCtx, ASTMetaInfoCache cache) { - - // note: we do not have the case !arrLit.isPoly here, as in the other poly processors - // (array literals are always poly, because they cannot be explicitly typed in N4JS) - - val numOfElems = arrLit.elements.size; - - // we have to analyze the type expectation: - // 1. we have to know up-front whether we aim for an actual type of Array/Iterable or for ArrayN/IterableN - // 2. we have to know if we have concrete expectations for the element type(s) - // To do so, we prepare a helper variable 'expectedElemTypeRefs' - val expectedElemTypeRefs = getExpectedElemTypeRefs(G, expectedTypeRef); - - -// hack: faking an expectation of ArrayN<...> here -// TODO instead we should get such an expectation in these cases from expectedType judgment! -val isValueToBeDestructured = DestructureUtils.isArrayOrObjectLiteralBeingDestructured(arrLit); -if(isValueToBeDestructured) { - while(expectedElemTypeRefs.size < numOfElems) - expectedElemTypeRefs.add(G.anyTypeRef); -} - - // performance tweak: - val haveUsableExpectedType = !expectedElemTypeRefs.empty; - if (!haveUsableExpectedType && !TypeUtils.isInferenceVariable(expectedTypeRef)) { - // no type expectation or some entirely wrong type expectation (i.e. other than Array, ArrayN) - // -> just derive type from elements (and do not introduce a new inference variable for this ArrayLiteral!) - val elemTypeRefs = newArrayList; - val nonNullElems = arrLit.elements.filter[expression !== null]; - for (arrElem : nonNullElems) { - var arrElemTypeRef = polyProcessor.processExpr(G, arrElem.expression, null, infCtx, cache); - arrElemTypeRef = ts.upperBoundWithReopen(G, arrElemTypeRef); - if (arrElem.spread) { - elemTypeRefs += extractSpreadTypeRefs(G, arrElemTypeRef); // more than one in case of ArrayN; none in case of invalid value after spread operator - } else { - elemTypeRefs += arrElemTypeRef; - } - } - - infCtx.onSolved [ solution | handleOnSolvedPerformanceTweak(G, cache, arrLit, expectedElemTypeRefs) ]; - - val unionOfElemTypes = if (!elemTypeRefs.empty) tsh.createUnionType(G, elemTypeRefs) else G.anyTypeRef; - return G.arrayTypeRef(unionOfElemTypes); - } - - val resultLen = getResultLength(arrLit, expectedElemTypeRefs); - val TypeVariable[] resultInfVars = infCtx.newInferenceVariables(resultLen); - - processElements(G, cache, infCtx, arrLit, resultLen, resultInfVars); - - val TypeRef resultTypeRef = getResultTypeRef(G, resultLen, resultInfVars); - - // register onSolved handlers to add final types to cache (i.e. may not contain inference variables) - infCtx.onSolved [ solution | handleOnSolved(G, cache, arrLit, expectedElemTypeRefs, resultTypeRef, solution) ]; - - // return temporary type of arrLit (i.e. may contain inference variables) - return resultTypeRef; - } - - /** - * The return value is as follows: - *
    - *
  • #[ T ] for an expectedTypeRef of the form Array<T> or Iterable<T>,
  • - *
  • #[ T1, T2, ..., TN ] for an expectedTypeRef of the form ArrayN<T1,T2,...,TN>,
  • - *
  • #[] for any other kind of expectedTypeRef
  • - *
- */ - private def List getExpectedElemTypeRefs(RuleEnvironment G, TypeRef expectedTypeRef) { - if (expectedTypeRef !== null) { - val candidateTypeRefs = if (expectedTypeRef instanceof UnionTypeExpression) { - expectedTypeRef.typeRefs - } else { - #[ expectedTypeRef ] - }; - val iterableType = G.iterableType; - val arrayType = G.arrayType; - for (candidateTypeRef : candidateTypeRefs) { - val declType = candidateTypeRef.declaredType; - if (declType === iterableType - || declType === arrayType - || G.isIterableN(declType) - || G.isArrayN(declType)) { - val extractedTypeRefs = tsh.extractIterableElementTypes(G, candidateTypeRef); - if (extractedTypeRefs.size > 0) { - return extractedTypeRefs; // will have len>1 iff expectation is IterableN - } - } - } - } - return newArrayList // no or invalid type expectation - } - - /** - * Makes a best effort for building a type in case something went awry. It's only non-trivial in case we have an - * expectation of IterableN. - */ - private def TypeRef buildFallbackTypeForArrayLiteral(boolean isArrayN, int resultLen, - List elemTypeRefsWithLiteralTypes, List expectedElemTypeRefs, RuleEnvironment G) { - - val elemTypeRefs = elemTypeRefsWithLiteralTypes.map[N4JSLanguageUtils.getLiteralTypeBase(G, it)].toList; - - if (isArrayN) { - val typeArgs = newArrayOfSize(resultLen); - for (var i = 0; i < resultLen; i++) { - val boolean isLastElem = i === (resultLen - 1); - var TypeRef typeRef = null; - if (isLastElem && elemTypeRefs.size > resultLen) { - // special case: - // we are at the last element AND we actually have more elements than we expect elements - // -> have to check all remaining elements against the last expectation! - val allRemainingElementTypeRefs = newArrayList; - val currExpectedElemTypeRef = expectedElemTypeRefs.get(i); - - // if all remaining elements are a subtype of the last expectation, then use expectation, otherwise form union - var boolean allMatch = true; - for (var j = i; j < elemTypeRefs.size; j++) { - - val currElementTypeRef = elemTypeRefs.get(j); - allRemainingElementTypeRefs.add(currElementTypeRef); - - if (allMatch) { // don't try further subtype checks if already failed - val actualIsSubtypeOfExpected = ts.subtypeSucceeded(G, currElementTypeRef, - currExpectedElemTypeRef); - if (!actualIsSubtypeOfExpected) { - allMatch = false; - } - } - } - if (allMatch) { - // use expected type - typeRef = currExpectedElemTypeRef; - } else { - // use actual types (will lead to follow-up errors caught by validations) - typeRef = tsh.createUnionType(G, allRemainingElementTypeRefs); - } - } else { - val currElemTypeRef = elemTypeRefs.get(i); - val currExpectedElemTypeRef = expectedElemTypeRefs.get(i); - val actualIsSubtypeOfExpected = ts.subtypeSucceeded(G, currElemTypeRef, currExpectedElemTypeRef); - if (actualIsSubtypeOfExpected) { - // use expected type - typeRef = currExpectedElemTypeRef; - } else { - // use actual type (will lead to follow-up errors caught by validations) - typeRef = currElemTypeRef; - } - } - typeArgs.set(i, typeRef); - } - - if (elemTypeRefs.size > resultLen) { - // replace last entry in 'typeArgs' with union of all remaining in elemTypeRefs - val remaining = Arrays.copyOfRange(elemTypeRefs, resultLen - 1, elemTypeRefs.size); - typeArgs.set(resultLen - 1, tsh.createUnionType(G, remaining)); - } - - return G.arrayNTypeRef(resultLen, typeArgs); - } else { - val unionOfElemTypes = if (!elemTypeRefs.empty) tsh.createUnionType(G, elemTypeRefs) else G.anyTypeRef; - return G.arrayTypeRef(unionOfElemTypes); - } - } - - /** - * choose correct number of type arguments in our to-be-created resultTypeRef - * (always 1 for Array or Iterable but N for ArrayN<..>, e.g. 3 for Array3) - */ - private def int getResultLength(ArrayLiteral arrLit, List expectedElemTypeRefs) { - val numOfElems = arrLit.elements.size; - val lenA = Math.min( - expectedElemTypeRefs.size, // use number of type arguments provided by type expectation as a basis - numOfElems // ... but never more than we have elements in the array literal - ); - - val lenB = Math.min( - lenA, - BuiltInTypeScope.ITERABLE_N__MAX_LEN // ... and never more than the max. allowed number of type arguments for ArrayN - ); - - val resultLen = Math.max( - lenB, - 1 // ... but at least 1 (even if numOfElems is 0, for example) - ); - return resultLen; - } - - /** - * Creates temporary type (i.e. may contain inference variables): - *
    - *
  • Array (where T is a new inference variable) or
  • - *
  • ArrayN (where T1,...TN are new inference variables, N>=2)
  • - *
- */ - private def TypeRef getResultTypeRef(RuleEnvironment G, int resultLen, TypeVariable[] resultInfVars) { - val isArrayN = resultLen >= 2; - val declaredType = if (isArrayN) G.arrayNType(resultLen) else G.arrayType; - val typeArgs = resultInfVars.map[TypeUtils.createTypeRef(it)]; - val TypeRef resultTypeRef = TypeUtils.createTypeRef(declaredType, typeArgs); - return resultTypeRef; - } - - /** - * for each array element, add a constraint to ensure that its corresponding infVar in result type will be - * a super type of the array element's expression - */ - private def void processElements(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, ArrayLiteral arrLit, - int resultLen, TypeVariable[] resultInfVars - ) { - val numOfElems = arrLit.elements.size; - for (var idxElem = 0; idxElem < numOfElems; idxElem++) { - val currElem = arrLit.elements.get(idxElem); - if (currElem?.expression === null) { - // currElem is null, or has no expression (broken AST), or is an ArrayPadding element - // -> ignore (no constraint to add) - } else { - // currElem is a valid ArrayElement with an expression - // -> add constraint currElemTypeRef <: Ti (Ti being the corresponding inf. variable in resultTypeRef) - val idxResult = Math.min(idxElem, resultLen - 1); - val currResultInfVar = resultInfVars.get(idxResult); - val currResultInfVarTypeRef = TypeUtils.createTypeRef(currResultInfVar); - val currExpectedTypeRef = if (currElem.spread) G.iterableTypeRef(TypeUtils.createWildcardExtends(currResultInfVarTypeRef)) else currResultInfVarTypeRef; - val currElemTypeRef = polyProcessor.processExpr(G, currElem.expression, currExpectedTypeRef, infCtx, cache); - infCtx.addConstraint(currElemTypeRef, currExpectedTypeRef, Variance.CO); - } - } - } - - /** - * Writes final types to cache. - */ - private def void handleOnSolvedPerformanceTweak(RuleEnvironment G, ASTMetaInfoCache cache, ArrayLiteral arrLit, - List expectedElemTypeRefs - ) { - val betterElemTypeRefs = storeTypesOfArrayElements(G, cache, arrLit); - val fallbackTypeRef = buildFallbackTypeForArrayLiteral(false, 1, betterElemTypeRefs, expectedElemTypeRefs, G); - cache.storeType(arrLit, fallbackTypeRef); - } - - /** - * Writes final types to cache. - */ - private def void handleOnSolved(RuleEnvironment G, ASTMetaInfoCache cache, ArrayLiteral arrLit, - List expectedElemTypeRefs, TypeRef resultTypeRef, Optional> solution - ) { - val resultLen = getResultLength(arrLit, expectedElemTypeRefs); - val isArrayN = resultLen >= 2; - if (solution.present) { - // success case - val typeRef = resultTypeRef.applySolution(G, solution.get); - cache.storeType(arrLit, typeRef); - } else { - // failure case (unsolvable constraint system) - val betterElemTypeRefs = arrLit.elements.map[getFinalResultTypeOfArrayElement(G, it, Optional.absent)]; - val typeRef = buildFallbackTypeForArrayLiteral(isArrayN, resultLen, betterElemTypeRefs, expectedElemTypeRefs, G); - cache.storeType(arrLit, typeRef); - } - storeTypesOfArrayElements(G, cache, arrLit); - } - - // PolyProcessor#isResponsibleFor(TypableElement) claims responsibility of AST nodes of type 'ArrayElement' - // contained in an ArrayLiteral which is poly, so we are responsible for storing the types of those - // 'ArrayElement' nodes in cache - // (note: compare this with similar handling of 'Argument' nodes in PolyProcessor_CallExpression) - private def List storeTypesOfArrayElements(RuleEnvironment G, ASTMetaInfoCache cache, ArrayLiteral arrLit) { - val List storedElemTypeRefs = newArrayList; - for (currElem : arrLit.elements) { - if (currElem instanceof ArrayPadding) { - cache.storeType(currElem, G.undefinedTypeRef); - } else { - val currElemTypeRef = getFinalResultTypeOfArrayElement(G, currElem, Optional.of(storedElemTypeRefs)); - cache.storeType(currElem, currElemTypeRef); - } - } - return storedElemTypeRefs; - } - - private def TypeRef getFinalResultTypeOfArrayElement(RuleEnvironment G, ArrayElement currElem, Optional> addTypeRefsHere) { - val currExpr = currElem?.expression; - var currElemTypeRef = if (currExpr!==null) getFinalResultTypeOfNestedPolyExpression(currExpr); - if (currElemTypeRef !== null) { - currElemTypeRef = ts.upperBoundWithReopen(G, currElemTypeRef); - val currElemTypeRefs = if (currElem.spread) extractSpreadTypeRefs(G, currElemTypeRef) else #[ currElemTypeRef ]; - if (addTypeRefsHere.present) { - addTypeRefsHere.get += currElemTypeRefs; - } - return tsh.createUnionType(G, currElemTypeRefs); - } - return TypeRefsFactory.eINSTANCE.createUnknownTypeRef; - } - - private def List extractSpreadTypeRefs(RuleEnvironment G, TypeRef typeRef) { - // case 1: built-in type string - if (typeRef instanceof ParameterizedTypeRef) { - if (typeRef.declaredType === G.stringType) { - return #[ G.stringTypeRef ]; // spreading a string yields zero or more strings - } - } - // case 2: Iterable or ArrayN - return tsh.extractIterableElementTypes(G, typeRef) - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_CallExpression.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_CallExpression.java new file mode 100644 index 0000000000..3433362e83 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_CallExpression.java @@ -0,0 +1,198 @@ +/** + * 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.postprocessing; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.n4js.n4JS.Argument; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory; +import org.eclipse.n4js.ts.types.InferenceVariable; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TypeVariable; +import org.eclipse.n4js.ts.types.util.Variance; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.constraints.InferenceContext; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper.Callable; +import org.eclipse.n4js.utils.N4JSLanguageUtils; + +import com.google.common.base.Optional; +import com.google.inject.Inject; +import com.google.inject.Singleton; + +/** + * {@link PolyProcessor} delegates here for processing array literals. + * + * @see PolyProcessor#inferType(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,ASTMetaInfoCache) + * @see PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache) + */ +@Singleton +class PolyProcessor_CallExpression extends AbstractPolyProcessor { + + @Inject + private PolyProcessor polyProcessor; + + @Inject + private N4JSTypeSystem ts; + @Inject + private TypeSystemHelper tsh; + + /** + * BEFORE CHANGING THIS METHOD, READ THIS: + * {@link PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache)} + */ + @SuppressWarnings("unused") + TypeRef processCallExpression(RuleEnvironment G, ParameterizedCallExpression callExpr, + TypeRef expectedTypeRef, InferenceContext infCtx, ASTMetaInfoCache cache) { + + Expression target = callExpr.getTarget(); + // IMPORTANT: do not use #processExpr() here (if target is a PolyExpression, it has been processed in a + // separate, independent inference!) + TypeRef targetTypeRef = ts.type(G, target); + Callable callable = tsh.getCallableTypeRef(G, targetTypeRef); + if (callable == null || !callable.getSignatureTypeRef().isPresent()) { + return TypeRefsFactory.eINSTANCE.createUnknownTypeRef(); + } + FunctionTypeExprOrRef sigTypeRef = callable.getSignatureTypeRef().get(); + + if (!N4JSLanguageUtils.isPoly(sigTypeRef, callExpr)) { + TypeRef result = ts.type(G, callExpr); + // do not store in cache (TypeProcessor responsible for storing types of non-poly expressions in cache) + return result; + } + + // create an inference variable for each type parameter of fteor + Map typeParam2infVar = new LinkedHashMap<>(); // type parameter of fteor -> + // inference variable + for (TypeVariable typeParam : sigTypeRef.getTypeVars()) { + typeParam2infVar.put(typeParam, infCtx.newInferenceVariable()); + } + + processParameters(G, cache, infCtx, callExpr, sigTypeRef, typeParam2infVar); + + // create temporary type (i.e. may contain inference variables) + TypeRef resultTypeRefRaw = sigTypeRef.getReturnTypeRef(); + TypeRef resultTypeRef = subst(resultTypeRefRaw, G, typeParam2infVar); + + // register onSolved handlers to add final types to cache (i.e. may not contain inference variables) + infCtx.onSolved(solution -> handleOnSolved(G, cache, callExpr, resultTypeRef, typeParam2infVar, solution)); + + // return temporary type of callExpr (i.e. may contain inference variables) + return resultTypeRef; + } + + /** + * Processes all parameters and derives constraints from their bounds and matching types. + */ + private void processParameters(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, + ParameterizedCallExpression callExpr, FunctionTypeExprOrRef fteor, + Map typeParam2infVar) { + // + // (1) derive constraints from the bounds of the type parameters + // + EList funcTypeVars = fteor.getTypeVars(); + for (TypeVariable currTypeVar : funcTypeVars) { + // don't use currTypeVar.getDeclaredUpperBound() in next line! + TypeRef currUB = fteor.getTypeVarUpperBound(currTypeVar); + if (currUB == null) { + currUB = N4JSLanguageUtils.getTypeVariableImplicitUpperBound(G); + } + // constraint: currTypeVar <: current upper bound + TypeRef leftTypeRef = TypeUtils.createTypeRef(currTypeVar); + TypeRef leftTypeRefSubst = subst(leftTypeRef, G, typeParam2infVar); + TypeRef rightTypeRef = currUB; + TypeRef rightTypeRefSubst = subst(rightTypeRef, G, typeParam2infVar); + infCtx.addConstraint(leftTypeRefSubst, rightTypeRefSubst, Variance.CO); + } + + // + // (2) derive constraints from matching type of each provided argument to type of corresponding fpar + // + int argsSize = callExpr.getArguments().size(); + for (var i = 0; i < argsSize; i++) { + Expression arg = callExpr.getArguments().get(i) == null ? null + : callExpr.getArguments().get(i).getExpression(); + TFormalParameter curr_fpar = fteor.getFparForArgIdx(i); + if (arg != null && curr_fpar != null) { + TypeRef fparTypeRef = curr_fpar.getTypeRef(); + TypeRef fparTypeRefSubst = subst(fparTypeRef, G, typeParam2infVar); + TypeRef argType = polyProcessor.processExpr(G, arg, fparTypeRefSubst, infCtx, cache); + if (argType != null) { + // constraint: argType <: fpar.type + infCtx.addConstraint(fparTypeRefSubst, argType, Variance.CONTRA); + // (note: no substitution in argType required, because it cannot contain any of the new inference + // variables introduced above) + } + } else if (arg != null) { + // more arguments provided than fpars available + // -> this is an error case, but make sure to process the surplus arguments to avoid + // inconsistencies later on (cache misses etc.) + polyProcessor.processExpr(G, arg, null, infCtx, cache); + } + } + + // + // (3) derive constraints from matching expected return type to return type of function + // + // --> not required here (will be done by caller) + } + + /** + * Writes final types to cache. + */ + private void handleOnSolved(RuleEnvironment G, ASTMetaInfoCache cache, ParameterizedCallExpression callExpr, + TypeRef resultTypeRef, Map typeParam2infVar, + Optional> solution) { + if (solution.isPresent()) { + // success case: + cache.storeType(callExpr, applySolution(resultTypeRef, G, solution.get())); + List inferredTypeArgs = toList(map(typeParam2infVar.values(), iv -> solution.get().get(iv))); + cache.storeInferredTypeArgs(callExpr, inferredTypeArgs); + } else { + // failure case (unsolvable constraint system) + // to avoid leaking inference variables, replace them by their original type parameter + Map fakeSolution = new HashMap<>(); + for (Entry e : typeParam2infVar.entrySet()) { + fakeSolution.put(e.getValue(), TypeUtils.createTypeRef(e.getKey())); + } + cache.storeType(callExpr, applySolution(resultTypeRef, G, fakeSolution)); + cache.storeInferredTypeArgs(callExpr, Collections.emptyList()); + } + // PolyProcessor#isResponsibleFor(TypableElement) claims responsibility of AST nodes of type 'Argument' + // contained in a ParameterizedCallExpression which is poly, so we are responsible for storing the types of + // those 'Argument' nodes in cache + // (note: compare this with similar handling of 'ArrayElement' nodes in PolyProcessor_ArrayLiteral) + for (Argument arg : callExpr.getArguments()) { + Expression expr = arg == null ? null : arg.getExpression(); + TypeRef exprType = (expr == null) ? null : getFinalResultTypeOfNestedPolyExpression(expr); + if (exprType != null) { + cache.storeType(arg, exprType); + } else { + cache.storeType(arg, TypeRefsFactory.eINSTANCE.createUnknownTypeRef()); + } + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_CallExpression.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_CallExpression.xtend deleted file mode 100644 index 42d0d6f62b..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_CallExpression.xtend +++ /dev/null @@ -1,177 +0,0 @@ -/** - * 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.postprocessing - -import com.google.common.base.Optional -import com.google.inject.Inject -import com.google.inject.Singleton -import java.util.Map -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.ParameterizedCallExpression -import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory -import org.eclipse.n4js.ts.types.InferenceVariable -import org.eclipse.n4js.ts.types.TFormalParameter -import org.eclipse.n4js.ts.types.TypeVariable -import org.eclipse.n4js.ts.types.util.Variance -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.constraints.InferenceContext -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper -import org.eclipse.n4js.utils.N4JSLanguageUtils - -/** - * {@link PolyProcessor} delegates here for processing array literals. - * - * @see PolyProcessor#inferType(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,ASTMetaInfoCache) - * @see PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache) - */ -@Singleton -package class PolyProcessor_CallExpression extends AbstractPolyProcessor { - - @Inject - private PolyProcessor polyProcessor; - - @Inject - private N4JSTypeSystem ts; - @Inject - private TypeSystemHelper tsh; - - /** - * BEFORE CHANGING THIS METHOD, READ THIS: - * {@link PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache)} - */ - def package TypeRef processCallExpression(RuleEnvironment G, ParameterizedCallExpression callExpr, - TypeRef expectedTypeRef, InferenceContext infCtx, ASTMetaInfoCache cache) { - - val target = callExpr.target; - // IMPORTANT: do not use #processExpr() here (if target is a PolyExpression, it has been processed in a separate, independent inference!) - val targetTypeRef = ts.type(G, target); - val callable = tsh.getCallableTypeRef(G, targetTypeRef); - if (callable === null || !callable.signatureTypeRef.present) - return TypeRefsFactory.eINSTANCE.createUnknownTypeRef; - val sigTypeRef = callable.signatureTypeRef.get(); - - if (!N4JSLanguageUtils.isPoly(sigTypeRef, callExpr)) { - val result = ts.type(G, callExpr); - // do not store in cache (TypeProcessor responsible for storing types of non-poly expressions in cache) - return result; - } - - // create an inference variable for each type parameter of fteor - val Map typeParam2infVar = newLinkedHashMap // type parameter of fteor -> inference variable - for (typeParam : sigTypeRef.typeVars) { - typeParam2infVar.put(typeParam, infCtx.newInferenceVariable); - } - - processParameters(G, cache, infCtx, callExpr, sigTypeRef, typeParam2infVar); - - // create temporary type (i.e. may contain inference variables) - val resultTypeRefRaw = sigTypeRef.getReturnTypeRef(); - val resultTypeRef = resultTypeRefRaw.subst(G, typeParam2infVar); - - // register onSolved handlers to add final types to cache (i.e. may not contain inference variables) - infCtx.onSolved [ solution | handleOnSolved(G, cache, callExpr, resultTypeRef, typeParam2infVar, solution) ]; - - // return temporary type of callExpr (i.e. may contain inference variables) - return resultTypeRef; - } - - /** - * Processes all parameters and derives constraints from their bounds and matching types. - */ - private def void processParameters(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, - ParameterizedCallExpression callExpr, FunctionTypeExprOrRef fteor, Map typeParam2infVar - ) { - // - // (1) derive constraints from the bounds of the type parameters - // - val funcTypeVars = fteor.typeVars; - for (TypeVariable currTypeVar : funcTypeVars) { - // don't use currTypeVar.getDeclaredUpperBound() in next line! - val currUB = fteor.getTypeVarUpperBound(currTypeVar) ?: N4JSLanguageUtils.getTypeVariableImplicitUpperBound(G); - // constraint: currTypeVar <: current upper bound - val leftTypeRef = TypeUtils.createTypeRef(currTypeVar); - val leftTypeRefSubst = leftTypeRef.subst(G, typeParam2infVar); - val rightTypeRef = currUB; - val rightTypeRefSubst = rightTypeRef.subst(G, typeParam2infVar); - infCtx.addConstraint(leftTypeRefSubst, rightTypeRefSubst, Variance.CO); - } - - // - // (2) derive constraints from matching type of each provided argument to type of corresponding fpar - // - val int argsSize = callExpr.getArguments().size(); - for (var i = 0; i < argsSize; i++) { - val Expression arg = callExpr.getArguments().get(i)?.expression; - val TFormalParameter curr_fpar = fteor.getFparForArgIdx(i); - if (arg !== null && curr_fpar !== null) { - val fparTypeRef = curr_fpar.getTypeRef(); - val fparTypeRefSubst = fparTypeRef.subst(G, typeParam2infVar); - val TypeRef argType = polyProcessor.processExpr(G, arg, fparTypeRefSubst, infCtx, cache); - if (argType !== null) { - // constraint: argType <: fpar.type - infCtx.addConstraint(fparTypeRefSubst, argType, Variance.CONTRA); - // (note: no substitution in argType required, because it cannot contain any of the new inference - // variables introduced above) - } - } else if (arg !== null) { - // more arguments provided than fpars available - // -> this is an error case, but make sure to process the surplus arguments to avoid - // inconsistencies later on (cache misses etc.) - polyProcessor.processExpr(G, arg, null, infCtx, cache); - } - } - - // - // (3) derive constraints from matching expected return type to return type of function - // - // --> not required here (will be done by caller) - } - - /** - * Writes final types to cache. - */ - private def void handleOnSolved(RuleEnvironment G, ASTMetaInfoCache cache, ParameterizedCallExpression callExpr, - TypeRef resultTypeRef, Map typeParam2infVar, Optional> solution - ) { - if (solution.present) { - // success case: - cache.storeType(callExpr, resultTypeRef.applySolution(G, solution.get)); - val inferredTypeArgs = typeParam2infVar.values.map[solution.get.get(it)].toList; - cache.storeInferredTypeArgs(callExpr, inferredTypeArgs); - } else { - // failure case (unsolvable constraint system) - // to avoid leaking inference variables, replace them by their original type parameter - val fakeSolution = newHashMap; - for (e : typeParam2infVar.entrySet) { - fakeSolution.put(e.value, TypeUtils.createTypeRef(e.key)); - } - cache.storeType(callExpr, resultTypeRef.applySolution(G, fakeSolution)); - cache.storeInferredTypeArgs(callExpr, #[]); - } - // PolyProcessor#isResponsibleFor(TypableElement) claims responsibility of AST nodes of type 'Argument' - // contained in a ParameterizedCallExpression which is poly, so we are responsible for storing the types of - // those 'Argument' nodes in cache - // (note: compare this with similar handling of 'ArrayElement' nodes in PolyProcessor_ArrayLiteral) - for (arg : callExpr.arguments) { - val expr = arg?.expression; - val exprType = if (expr!==null) getFinalResultTypeOfNestedPolyExpression(expr); - if (exprType!==null) { - cache.storeType(arg, exprType); - } else { - cache.storeType(arg, TypeRefsFactory.eINSTANCE.createUnknownTypeRef()); - } - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_FunctionExpression.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_FunctionExpression.java new file mode 100644 index 0000000000..e0c7caff77 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_FunctionExpression.java @@ -0,0 +1,457 @@ +/** + * 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.postprocessing; + +import static com.google.common.collect.Iterators.concat; +import static com.google.common.collect.Iterators.singletonIterator; +import static java.util.Collections.emptyList; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.addFixedCapture; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.addTypeMappings; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.anyTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.getBuiltInTypeScope; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.getContextResource; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.getPredefinedTypes; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.newRuleEnvironment; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.undefinedTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.voidTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.wrap; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.toIterable; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.n4js.n4JS.ArrowFunction; +import org.eclipse.n4js.n4JS.Block; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.ts.typeRefs.DeferredTypeRef; +import org.eclipse.n4js.ts.typeRefs.ExistentialTypeRef; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression; +import org.eclipse.n4js.ts.typeRefs.OptionalFieldStrategy; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory; +import org.eclipse.n4js.ts.types.ContainerType; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.InferenceVariable; +import org.eclipse.n4js.ts.types.SyntaxRelatedTElement; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.ts.types.TypesPackage; +import org.eclipse.n4js.ts.types.util.Variance; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.constraints.InferenceContext; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.n4js.utils.EcoreUtilN4; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.xtext.xbase.lib.IterableExtensions; + +import com.google.common.base.Optional; +import com.google.inject.Inject; +import com.google.inject.Singleton; + +/** + * {@link PolyProcessor} delegates here for processing array literals. + * + * @see PolyProcessor#inferType(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,ASTMetaInfoCache) + * @see PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache) + */ +@Singleton +class PolyProcessor_FunctionExpression extends AbstractPolyProcessor { + @Inject + private N4JSTypeSystem ts; + @Inject + private TypeSystemHelper tsh; + @Inject + private ASTProcessor astProcessor; + + /** + * BEFORE CHANGING THIS METHOD, READ THIS: + * {@link PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache)} + */ + TypeRef processFunctionExpression(RuleEnvironment G, FunctionExpression funExpr, TypeRef expectedTypeRef, + InferenceContext infCtx, ASTMetaInfoCache cache) { + TFunction fun = (TFunction) funExpr.getDefinedType(); // types builder will have created this already + + if (!isPoly(funExpr)) { // funExpr has declared types on all fpars and explicitly declared return type + // can't use xsemantics here, because it would give us a DeferredTypeRef + // return ts.type(G, funExpr).getValue(); + FunctionTypeExpression funTE = TypeUtils.createFunctionTypeExpression(null, emptyList(), fun.getFpars(), + fun.getReturnTypeRef()); // FIXME support for declared this type!! + // do not store in cache (TypeProcessor responsible for storing types of non-poly expressions in cache) + return funTE; + } + + // prepare temporary result type reference + FunctionTypeExpression funTE = TypeRefsFactory.eINSTANCE.createFunctionTypeExpression(); + + if (fun.getDeclaredThisType() != null) { + funTE.setDeclaredThisType(TypeUtils.copy(fun.getDeclaredThisType())); + } + + if (!fun.getTypeVars().isEmpty()) { + funTE.getOwnedTypeVars().addAll(toList(map(fun.getTypeVars(), tv -> TypeUtils.copy(tv)))); + } + + processFormalParameters(G, cache, infCtx, funExpr, funTE, expectedTypeRef); + processReturnType(G, cache, infCtx, funExpr, funTE); + + funTE.setReturnValueMarkedOptional(expectedTypeRef instanceof FunctionTypeExprOrRef + && ((FunctionTypeExprOrRef) expectedTypeRef).isReturnValueOptional()); + + // create temporary type (i.e. may contain inference variables) + + FunctionTypeExpression resultTypeRef; + if (fun.getTypeVars().isEmpty()) { + resultTypeRef = funTE; + } else { + // if fun is generic, we have to replace the type variables of fun by those of result1 + RuleEnvironment Gx = newRuleEnvironment(G); + addTypeMappings(Gx, fun.getTypeVars(), + toList(map(funTE.getOwnedTypeVars(), tv -> TypeUtils.createTypeRef(tv)))); + resultTypeRef = (FunctionTypeExpression) ts.substTypeVariables(Gx, funTE); + } + + // register onSolved handlers to add final types to cache (i.e. may not contain inference variables) + infCtx.onSolved( + solution -> handleOnSolved(G, cache, infCtx, funExpr, expectedTypeRef, resultTypeRef, solution)); + + // return temporary type of funExpr (i.e. may contain inference variables) + return resultTypeRef; + } + + /** + * Process formal parameters and also introduce inference variables for types of fpars, where needed. + */ + private void processFormalParameters(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, + FunctionExpression funExpr, FunctionTypeExpression funTE, TypeRef expectedTypeRef) { + TFunction fun = (TFunction) funExpr.getDefinedType(); // types builder will have created this already + FunctionTypeExprOrRef expectedFunctionTypeExprOrRef = (expectedTypeRef instanceof FunctionTypeExprOrRef) + ? (FunctionTypeExprOrRef) expectedTypeRef + : null; + + // first, new type refs for each formal parameter are created + int len = Math.min(funExpr.getFpars().size(), fun.getFpars().size()); + Map typeRefMap = new HashMap<>(); + for (var i = 0; i < len; i++) { + FormalParameter fparAST = funExpr.getFpars().get(i); + TFormalParameter fparT = fun.getFpars().get(i); + // use the TFormalParameter created by the types builder as a basis + TFormalParameter fparTCopy = TypeUtils.copy(fparT); + funTE.getFpars().add(fparTCopy); + typeRefMap.put(fparAST, fparTCopy); + + if (fparAST.getDeclaredTypeRef() == null) { + assertTrueIfRigid(cache, "type of formal parameter in TModule should be a DeferredTypeRef", + fparTCopy.getTypeRef() instanceof DeferredTypeRef); + + // Deferred type refs have to be resolved here + InferenceVariable iv = infCtx.newInferenceVariable(); + fparTCopy.setTypeRef(TypeUtils.createTypeRef(iv)); // <-- set new inference variable as type + } + } + + // Now, go through the map and check for deferred types. + // If any, include them into the constraint problem. + for (Map.Entry fparPair : typeRefMap.entrySet()) { + FormalParameter fparAST = fparPair.getKey(); + TFormalParameter fparTCopy = fparPair.getValue(); + if (fparAST.getDeclaredTypeRef() == null) { + InferenceVariable iv = (InferenceVariable) fparTCopy.getTypeRef().getDeclaredType(); + addConstraintForDefaultInitializers(fparAST, fparTCopy, G, cache, iv, infCtx, typeRefMap); + inferOptionalityFromExpectedFpar(funExpr, funTE, expectedFunctionTypeExprOrRef, fparAST, fparTCopy); + } + } + } + + /** + * When a function expression contains an initializer (in a default parameter), the type of this initializer is + * taken into account when calculating the parameter's type. + */ + private void addConstraintForDefaultInitializers(FormalParameter fparAST, TFormalParameter fparT, + RuleEnvironment G, ASTMetaInfoCache cache, InferenceVariable iv, InferenceContext infCtx, + Map typeRefMap) { + + if (fparAST.isHasInitializerAssignment()) { + // Check if the initializer refers to other fpars + + Expression fparInitializer = fparAST.getInitializer(); + TFormalParameter referredFparCopy = null; + boolean isPostponed = cache.postponedSubTrees.contains(fparInitializer); + if (fparInitializer instanceof IdentifierRef) { + IdentifierRef idRef = (IdentifierRef) fparInitializer; + IdentifiableElement id = idRef.getId(); + Object idInAST = (id instanceof SyntaxRelatedTElement) + ? id.eGet(TypesPackage.Literals.SYNTAX_RELATED_TELEMENT__AST_ELEMENT, false) + : null; + referredFparCopy = typeRefMap.get(idInAST); + } + + if (referredFparCopy != null) { + // example: f(a, b = a) {} + TypeRef tRef = referredFparCopy.getTypeRef(); // point to the inference variable introduced above + infCtx.addConstraint(TypeUtils.createTypeRef(iv), TypeUtils.copy(tRef), Variance.CONTRA); + } else if (!isPostponed) { + TypeRef context = (fparT.eContainer() instanceof ContainerType) + ? TypeUtils.createTypeRef((ContainerType) fparT.eContainer()) + : null; + RuleEnvironment G_withContext = ts.createRuleEnvironmentForContext(context, getContextResource(G)); + TypeRef iniTypeRef = (fparInitializer != null) ? ts.type(G_withContext, fparInitializer) + : undefinedTypeRef(G); + TypeRef iniTypeRefSubst = ts.substTypeVariables(G_withContext, iniTypeRef); + infCtx.addConstraint(TypeUtils.createTypeRef(iv), TypeUtils.copy(iniTypeRefSubst), Variance.CONTRA); + } + } + } + + /** + * if the corresponding fpar in the type expectation is optional, we make the fpar in the function expression + * optional as well Example: let fun: {function(string=)} = function(p) {}; + */ + private void inferOptionalityFromExpectedFpar(FunctionExpression funExpr, FunctionTypeExpression funTE, + FunctionTypeExprOrRef expectedFunctionTypeExprOrRef, FormalParameter fparAST, TFormalParameter fparTCopy) { + if (expectedFunctionTypeExprOrRef != null) { + int fparIdx = funExpr.getFpars().indexOf(fparAST); + TFormalParameter fparExpected = expectedFunctionTypeExprOrRef.getFparForArgIdx(fparIdx); + if (fparExpected != null && fparExpected.isOptional() && !fparExpected.isVariadic()) { + IterableExtensions.last(funTE.getFpars()).setHasInitializerAssignment(true); + EcoreUtilN4.doWithDeliver(false, () -> { + fparAST.setHasInitializerAssignment(true); + fparTCopy.setHasInitializerAssignment(true); + }, fparAST, fparTCopy); + } + } + } + + /** + * Processes return type (also introduce inference variable for return type, if needed) + */ + private void processReturnType(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, + FunctionExpression funExpr, FunctionTypeExpression funTE) { + TFunction fun = (TFunction) funExpr.getDefinedType(); // types builder will have created this already + TypeRef returnTypeRef; + if (funExpr.getDeclaredReturnTypeRef() != null) { + // explicitly declared return type + // -> take the type reference created by the types builder (but wrap in Promise if required) + returnTypeRef = TypeUtils.copy(fun.getReturnTypeRef()); + } else { + // undeclared return type + // -> create infVar for return type IFF funExpr contains return statements OR is single expr arrow function; + // otherwise use VOID as return type + assertTrueIfRigid(cache, "return type of TFunction in TModule should be a DeferredTypeRef", + fun.getReturnTypeRef() instanceof DeferredTypeRef); + + if (isReturningValue(funExpr)) { + // introduce new inference variable for (inner) return type + InferenceVariable iv = infCtx.newInferenceVariable(); + returnTypeRef = TypeUtils.createTypeRef(iv); + } else { + // void + returnTypeRef = voidTypeRef(G); + } + // to obtain outer return type: wrap in Promise if asynchronous and not Promise already + // for the time being, see N4JS Specification, Section 6.4.1 "Asynchronous Functions") + returnTypeRef = N4JSLanguageUtils.makePromiseIfAsync(funExpr, returnTypeRef, getBuiltInTypeScope(G)); + // to obtain outer return type: wrap in Generator if it is a generator function + // see N4JS Specification, Section 6.3.1 "Generator Functions") + returnTypeRef = N4JSLanguageUtils.makeGeneratorIfGeneratorFunction(funExpr, returnTypeRef, + getBuiltInTypeScope(G)); + } + funTE.setReturnTypeRef(returnTypeRef); + } + + /** + * Writes final types to cache + */ + private void handleOnSolved(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, + FunctionExpression funExpr, + TypeRef expectedTypeRef, FunctionTypeExpression resultTypeRef, + Optional> solution) { + Map solution2 = (solution.isPresent()) ? solution.get() + : createPseudoSolution(infCtx, anyTypeRef(G)); + // sanitize parameter types + // (but do not turn closed ExistentialTypeRefs into their upper bound that also appear in the expected type, + // by defining them as "fixed captures" via RuleEnvironmentExtensions#addFixedCapture()) + RuleEnvironment G2 = wrap(G); + Type returnTypeInfVar = resultTypeRef.getReturnTypeRef() == null ? null + : resultTypeRef.getReturnTypeRef().getDeclaredType(); // this infVar's solution must not be sanitized as + // it's not a parameter + TypeRef expectedTypeRefSubst = applySolution(expectedTypeRef, G, solution2); + if (expectedTypeRefSubst != null) { + Iterable capturesInExpectedTypeRef = filter(filter(toIterable( + concat(singletonIterator(expectedTypeRefSubst), expectedTypeRefSubst.eAllContents())), + ExistentialTypeRef.class), + etr -> !etr.isReopened()); + + for (ExistentialTypeRef it : capturesInExpectedTypeRef) { + addFixedCapture(G2, it); + } + } + Map solution3 = new HashMap<>(solution2); + boolean resolveLiteralTypes = false; // if we resolved here, we might break constraints (it's the responsibility + // of the constraint solver to avoid literal types as far as possible) + solution3.replaceAll((k, v) -> (k != returnTypeInfVar) + ? tsh.sanitizeTypeOfVariableFieldPropertyParameter(G2, v, resolveLiteralTypes) + : v); + // apply solution to resultTypeRef + FunctionTypeExprOrRef resultSolved0 = (FunctionTypeExprOrRef) applySolution(resultTypeRef, G, solution3); + if (resultSolved0 instanceof FunctionTypeExpression) { + resultSolved0 = TypeUtils.copy(resultSolved0); + ((FunctionTypeExpression) resultSolved0) + .setASTNodeOptionalFieldStrategy(OptionalFieldStrategy.FIELDS_AND_ACCESSORS_OPTIONAL); + } + FunctionTypeExprOrRef resultSolved = resultSolved0; + // store type of funExpr in cache ... + cache.storeType(funExpr, resultSolved); + // update the defined function in the TModule + TFunction fun = (TFunction) funExpr.getDefinedType(); // types builder will have created this already + replaceDeferredTypeRefs(fun, resultSolved); + if (fun.isReturnValueMarkedOptional() != resultSolved.isReturnValueOptional()) { + EcoreUtilN4.doWithDeliver(false, + () -> fun.setReturnValueMarkedOptional(resultSolved.isReturnValueOptional()), fun); + } + // store types of fpars in cache ... + int len = Math.min(funExpr.getFpars().size(), fun.getFpars().size()); + for (var i = 0; i < len; i++) { + FormalParameter fparAST = funExpr.getFpars().get(i); + TFormalParameter fparT = fun.getFpars().get(i); + TypeRef fparTw = TypeUtils.wrapIfVariadic(getPredefinedTypes(G).builtInTypeScope, fparT.getTypeRef(), + fparAST); + cache.storeType(fparAST, fparTw); + } + // tweak return type + if (funExpr instanceof ArrowFunction) { + log(0, "==START of special handling of single-expression arrow function"); + // NOTE: the next line requires the type of 'funExpr' and types of fpars to be in cache! For example: + // function foo(p: {function(int):T}) {return undefined;} + // foo( (i) => [i] ); + tweakReturnTypeOfSingleExpressionArrowFunction(G, cache, (ArrowFunction) funExpr, resultSolved); + log(0, "==END of special handling of single-expression arrow function"); + } + } + + /** + * Handling of a very specific special case of single-expression arrow functions. + *

+ * If the given arrow function is a single-expression arrow function, this method changes the return type of the + * given function type reference from non-void to void if the non-void return type would lead to a type error later + * on (for details see code of this method). + *

+ * This tweak is only required because our poor man's return type inferencer in the types builder infers a wrong + * non-void return type in some cases, which is corrected in this method. + *

+ * Example: + * + *

+	 * function foo(f : {function(): void}) {}
+	 * function none(): void {}
+	 * foo(() => none()); // will show bogus error when disabling this method
+	 * 
+ */ + private void tweakReturnTypeOfSingleExpressionArrowFunction(RuleEnvironment G, ASTMetaInfoCache cache, + ArrowFunction arrFun, FunctionTypeExprOrRef arrFunTypeRef) { + if (!arrFun.isSingleExprImplicitReturn()) { + return; // not applicable + } + // Step 1) process arrFun's body, which was postponed earlier according to ASTProcessor#isPostponedNode(EObject) + // Rationale: the body of a single-expression arrow function isn't a true block, so we do not have to + // postpone it AND we need its types in the next step. + Block block = arrFun.getBody(); + if (block == null) { + return; // broken AST + } + if (!cache.postponedSubTrees.remove(block)) { + throw new IllegalStateException( + "body of single-expression arrow function not among postponed subtrees, in resource: " + + arrFun.eResource().getURI()); + } + astProcessor.processSubtree(G, block, cache, 1); + // Step 2) adjust arrFun's return type stored in arrFunTypeRef (if required) + boolean didTweakReturnType = false; + Expression expr = arrFun.getSingleExpression(); + if (expr == null) { + return; // broken AST + } + TypeRef exprTypeRef = cache.getType(G, expr); // must now be in cache, because we just processed arrFun's body + if (TypeUtils.isVoid(exprTypeRef)) { + // the actual type of 'expr' is void + if (arrFunTypeRef instanceof FunctionTypeExpression) { + if (!TypeUtils.isVoid(arrFunTypeRef.getReturnTypeRef())) { + // the return type of the single-expression arrow function 'arrFun' is *not* void + // --> this would lead to a type error in N4JSTypeValidation, which we want to fix now + // in case the outer type expectation for the containing arrow function has a + // return type of 'void' OR there is no outer type expectation at all + FunctionTypeExprOrRef outerTypeExpectation = expectedTypeForArrowFunction(G, arrFun); + TypeRef outerReturnTypeExpectation = outerTypeExpectation == null ? null + : outerTypeExpectation.getReturnTypeRef(); + if (outerTypeExpectation == null + || (outerReturnTypeExpectation != null && TypeUtils.isVoid(outerReturnTypeExpectation))) { + // fix the future type error by changing the return type of the containing arrow function + // from non-void to void + if (isDEBUG_LOG()) { + log(1, "tweaking return type from " + (arrFunTypeRef.getReturnTypeRef() == null ? null + : arrFunTypeRef.getReturnTypeRef().getTypeRefAsString()) + " to void"); + } + EcoreUtilN4.doWithDeliver(false, + () -> ((FunctionTypeExpression) arrFunTypeRef).setReturnTypeRef(voidTypeRef(G)), + arrFunTypeRef); + if (isDEBUG_LOG()) { + log(1, "tweaked type of arrow function is: " + arrFunTypeRef.getTypeRefAsString()); + } + didTweakReturnType = true; + } + } + } + } + if (!didTweakReturnType) { + log(1, "tweaking of return type not required"); + } + } + + /** + * Replaces all DeferredTypeRefs in the given TFunction (i.e. in the fpars' types and the return type) by the + * corresponding types in 'result'. Argument 'result' must not contain any DeferredTypeRefs and, when this method + * returns, also the given TFunction 'fun' won't contain DeferredTypeRefs anymore. Will throw exception if 'fun' and + * 'result' do not match (e.g. 'result' has fewer fpars than 'fun'). + */ + private void replaceDeferredTypeRefs(TFunction fun, FunctionTypeExprOrRef result) { + int len = fun.getFpars().size(); // note: we do not take Math.min here (fail fast) + for (var i = 0; i < len; i++) { + TFormalParameter funFpar = fun.getFpars().get(i); + if (funFpar.getTypeRef() instanceof DeferredTypeRef) { + int idx = i; + EcoreUtilN4.doWithDeliver(false, + () -> funFpar.setTypeRef(TypeUtils.copy(result.getFpars().get(idx).getTypeRef())), funFpar); + } + } + if (fun.getReturnTypeRef() instanceof DeferredTypeRef) { + EcoreUtilN4.doWithDeliver(false, () -> fun.setReturnTypeRef(TypeUtils.copy(result.getReturnTypeRef())), + fun); + } + } + + private FunctionTypeExprOrRef expectedTypeForArrowFunction(RuleEnvironment G, ArrowFunction fe) { + RuleEnvironment G_new = newRuleEnvironment(G); + TypeRef tr = ts.expectedType(G_new, fe.eContainer(), fe); + if (tr instanceof FunctionTypeExprOrRef) { + return (FunctionTypeExprOrRef) tr; + } + return null; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_FunctionExpression.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_FunctionExpression.xtend deleted file mode 100644 index 1bf4f57c3b..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_FunctionExpression.xtend +++ /dev/null @@ -1,413 +0,0 @@ -/** - * 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.postprocessing - -import com.google.common.base.Optional -import com.google.common.collect.Iterators -import com.google.inject.Inject -import com.google.inject.Singleton -import java.util.HashMap -import java.util.Map -import org.eclipse.n4js.n4JS.ArrowFunction -import org.eclipse.n4js.n4JS.FormalParameter -import org.eclipse.n4js.n4JS.FunctionExpression -import org.eclipse.n4js.n4JS.IdentifierRef -import org.eclipse.n4js.ts.typeRefs.DeferredTypeRef -import org.eclipse.n4js.ts.typeRefs.ExistentialTypeRef -import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef -import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression -import org.eclipse.n4js.ts.typeRefs.OptionalFieldStrategy -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory -import org.eclipse.n4js.ts.types.ContainerType -import org.eclipse.n4js.ts.types.InferenceVariable -import org.eclipse.n4js.ts.types.SyntaxRelatedTElement -import org.eclipse.n4js.ts.types.TFormalParameter -import org.eclipse.n4js.ts.types.TFunction -import org.eclipse.n4js.ts.types.TypesPackage -import org.eclipse.n4js.ts.types.util.Variance -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.constraints.InferenceContext -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper -import org.eclipse.n4js.utils.EcoreUtilN4 -import org.eclipse.n4js.utils.N4JSLanguageUtils - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * {@link PolyProcessor} delegates here for processing array literals. - * - * @see PolyProcessor#inferType(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,ASTMetaInfoCache) - * @see PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache) - */ -@Singleton -package class PolyProcessor_FunctionExpression extends AbstractPolyProcessor { - @Inject - private N4JSTypeSystem ts; - @Inject - private TypeSystemHelper tsh; - @Inject - private ASTProcessor astProcessor; - - - /** - * BEFORE CHANGING THIS METHOD, READ THIS: - * {@link PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache)} - */ - def package TypeRef processFunctionExpression(RuleEnvironment G, FunctionExpression funExpr, TypeRef expectedTypeRef, - InferenceContext infCtx, ASTMetaInfoCache cache - ) { - val fun = funExpr.definedType as TFunction; // types builder will have created this already - - if (!funExpr.isPoly) { // funExpr has declared types on all fpars and explicitly declared return type - // can't use xsemantics here, because it would give us a DeferredTypeRef - // return ts.type(G, funExpr).getValue(); - val funTE = TypeUtils.createFunctionTypeExpression(null, #[], fun.fpars, fun.returnTypeRef); // FIXME support for declared this type!! - // do not store in cache (TypeProcessor responsible for storing types of non-poly expressions in cache) - return funTE; - } - - // prepare temporary result type reference - val funTE = TypeRefsFactory.eINSTANCE.createFunctionTypeExpression; - - if (fun.declaredThisType !== null) { - funTE.declaredThisType = TypeUtils.copy(fun.declaredThisType); - } - - if (!fun.typeVars.empty) { - funTE.ownedTypeVars += fun.typeVars.map[tv|TypeUtils.copy(tv)]; - } - - processFormalParameters(G, cache, infCtx, funExpr, funTE, expectedTypeRef); - processReturnType(G, cache, infCtx, funExpr, funTE); - - funTE.returnValueMarkedOptional = expectedTypeRef instanceof FunctionTypeExprOrRef - && (expectedTypeRef as FunctionTypeExprOrRef).returnValueOptional; - - // create temporary type (i.e. may contain inference variables) - val resultTypeRef = if (fun.typeVars.empty) { - funTE - } else { - // if fun is generic, we have to replace the type variables of fun by those of result1 - val Gx = G.newRuleEnvironment; - Gx.addTypeMappings(fun.typeVars, funTE.ownedTypeVars.map[TypeUtils.createTypeRef(it)]); - ts.substTypeVariables(Gx, funTE) as FunctionTypeExpression; - }; - - // register onSolved handlers to add final types to cache (i.e. may not contain inference variables) - infCtx.onSolved [ solution | handleOnSolved(G, cache, infCtx, funExpr, expectedTypeRef, resultTypeRef, solution)]; - - // return temporary type of funExpr (i.e. may contain inference variables) - return resultTypeRef; - } - - /** - * Process formal parameters and also introduce inference variables for types of fpars, where needed. - */ - private def void processFormalParameters(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, - FunctionExpression funExpr, FunctionTypeExpression funTE, TypeRef expectedTypeRef - ) { - val fun = funExpr.definedType as TFunction; // types builder will have created this already - val expectedFunctionTypeExprOrRef = if (expectedTypeRef instanceof FunctionTypeExprOrRef) { expectedTypeRef }; - - // first, new type refs for each formal parameter are created - val len = Math.min(funExpr.fpars.size, fun.fpars.size); - val Map typeRefMap = new HashMap(); - for (var i = 0; i < len; i++) { - val fparAST = funExpr.fpars.get(i); - val fparT = fun.fpars.get(i); - val fparTCopy = TypeUtils.copy(fparT); // use the TFormalParameter created by the types builder as a basis - funTE.fpars += fparTCopy; - typeRefMap.put(fparAST, fparTCopy); - - if (fparAST.declaredTypeRef === null) { - assertTrueIfRigid(cache, "type of formal parameter in TModule should be a DeferredTypeRef", - fparTCopy?.typeRef instanceof DeferredTypeRef); - - // Deferred type refs have to be resolved here - val iv = infCtx.newInferenceVariable; - fparTCopy.typeRef = TypeUtils.createTypeRef(iv); // <-- set new inference variable as type - } - } - - // Now, go through the map and check for deferred types. - // If any, include them into the constraint problem. - for (Map.Entry fparPair : typeRefMap.entrySet) { - val fparAST = fparPair.key; - val fparTCopy = fparPair.value; - if (fparAST.declaredTypeRef === null) { - val iv = fparTCopy.typeRef.declaredType as InferenceVariable; - addConstraintForDefaultInitializers(funExpr, fparAST, fparTCopy, G, cache, iv, infCtx, typeRefMap); - inferOptionalityFromExpectedFpar(funExpr, funTE, expectedFunctionTypeExprOrRef, fparAST, fparTCopy); - } - } - } - - /** - * When a function expression contains an initializer (in a default parameter), - * the type of this initializer is taken into account when calculating the parameter's type. - */ - private def void addConstraintForDefaultInitializers(FunctionExpression funExpr, FormalParameter fparAST, TFormalParameter fparT, - RuleEnvironment G, ASTMetaInfoCache cache, InferenceVariable iv, InferenceContext infCtx, Map typeRefMap - ) { - if (fparAST.hasInitializerAssignment) { - // Check if the initializer refers to other fpars - - val fparInitializer = fparAST.initializer; - var referredFparCopy = null as TFormalParameter; - val isPostponed = cache.postponedSubTrees.contains(fparInitializer); - if (fparInitializer instanceof IdentifierRef) { - val id = fparInitializer.getId(); - val idInAST = if (id instanceof SyntaxRelatedTElement) id.eGet(TypesPackage.Literals.SYNTAX_RELATED_TELEMENT__AST_ELEMENT, false); - referredFparCopy = typeRefMap.get(idInAST); - } - - if (referredFparCopy !== null) { - // example: f(a, b = a) {} - val TypeRef tRef = referredFparCopy.typeRef; // point to the inference variable introduced above - infCtx.addConstraint(TypeUtils.createTypeRef(iv), TypeUtils.copy(tRef), Variance.CONTRA); - } else if (!isPostponed) { - val context = if (fparT.eContainer instanceof ContainerType) - TypeUtils.createTypeRef(fparT.eContainer as ContainerType) else null; - val G_withContext = ts.createRuleEnvironmentForContext(context, G.contextResource); - val TypeRef iniTypeRef = if (fparInitializer !== null) ts.type(G_withContext, fparInitializer) else G.undefinedTypeRef; - val iniTypeRefSubst = ts.substTypeVariables(G_withContext, iniTypeRef); - infCtx.addConstraint(TypeUtils.createTypeRef(iv), TypeUtils.copy(iniTypeRefSubst), Variance.CONTRA); - } - } - } - - /** - * if the corresponding fpar in the type expectation is optional, we make the fpar in the - * function expression optional as well - * Example: - * let fun: {function(string=)} = function(p) {}; - */ - private def void inferOptionalityFromExpectedFpar(FunctionExpression funExpr, FunctionTypeExpression funTE, - FunctionTypeExprOrRef expectedFunctionTypeExprOrRef, FormalParameter fparAST, TFormalParameter fparTCopy - ) { - if (expectedFunctionTypeExprOrRef !== null) { - val int fparIdx = funExpr.fpars.indexOf(fparAST); - val fparExpected = expectedFunctionTypeExprOrRef.getFparForArgIdx(fparIdx); - if (fparExpected !== null && fparExpected.optional && !fparExpected.variadic) { - funTE.fpars.last.hasInitializerAssignment = true; - EcoreUtilN4.doWithDeliver(false, [ - fparAST.hasInitializerAssignment = true; - fparTCopy.hasInitializerAssignment = true; - ], fparAST, fparTCopy); - } - } - } - - /** - * Processes return type (also introduce inference variable for return type, if needed) - */ - private def void processReturnType(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, - FunctionExpression funExpr, FunctionTypeExpression funTE - ) { - val fun = funExpr.definedType as TFunction; // types builder will have created this already - var TypeRef returnTypeRef; - if (funExpr.declaredReturnTypeRef !== null) { - // explicitly declared return type - // -> take the type reference created by the types builder (but wrap in Promise if required) - returnTypeRef = TypeUtils.copy(fun.returnTypeRef); - } else { - // undeclared return type - // -> create infVar for return type IFF funExpr contains return statements OR is single expr arrow function; otherwise use VOID as return type - assertTrueIfRigid(cache, "return type of TFunction in TModule should be a DeferredTypeRef", - fun.returnTypeRef instanceof DeferredTypeRef); - - if (funExpr.isReturningValue) { - // introduce new inference variable for (inner) return type - val iv = infCtx.newInferenceVariable; - returnTypeRef = TypeUtils.createTypeRef(iv); - } else { - // void - returnTypeRef = G.voidTypeRef; - } - // to obtain outer return type: wrap in Promise if asynchronous and not Promise already - // for the time being, see N4JS Specification, Section 6.4.1 "Asynchronous Functions") - returnTypeRef = N4JSLanguageUtils.makePromiseIfAsync(funExpr, returnTypeRef, G.builtInTypeScope); - // to obtain outer return type: wrap in Generator if it is a generator function - // see N4JS Specification, Section 6.3.1 "Generator Functions") - returnTypeRef = N4JSLanguageUtils.makeGeneratorIfGeneratorFunction(funExpr, returnTypeRef, G.builtInTypeScope); - } - funTE.returnTypeRef = returnTypeRef; - } - - - /** - * Writes final types to cache - */ - private def void handleOnSolved(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, FunctionExpression funExpr, - TypeRef expectedTypeRef, FunctionTypeExpression resultTypeRef, Optional> solution - ) { - val solution2 = if (solution.present) solution.get else infCtx.createPseudoSolution(G.anyTypeRef); - // sanitize parameter types - // (but do not turn closed ExistentialTypeRefs into their upper bound that also appear in the expected type, - // by defining them as "fixed captures" via RuleEnvironmentExtensions#addFixedCapture()) - val G2 = G.wrap; - val returnTypeInfVar = resultTypeRef.returnTypeRef?.declaredType; // this infVar's solution must not be sanitized as it's not a parameter - val expectedTypeRefSubst = expectedTypeRef.applySolution(G, solution2); - if (expectedTypeRefSubst !== null) { - val capturesInExpectedTypeRef = Iterators.concat(Iterators.singletonIterator(expectedTypeRefSubst), expectedTypeRefSubst.eAllContents) - .filter(ExistentialTypeRef) - .filter[!reopened]; - capturesInExpectedTypeRef.forEach[G2.addFixedCapture(it)]; - } - val solution3 = new HashMap(solution2); - val resolveLiteralTypes = false; // if we resolved here, we might break constraints (it's the responsibility of the constraint solver to avoid literal types as far as possible) - solution3.replaceAll[k, v | if (k !== returnTypeInfVar) tsh.sanitizeTypeOfVariableFieldPropertyParameter(G2, v, resolveLiteralTypes) else v]; - // apply solution to resultTypeRef - var resultSolved0 = resultTypeRef.applySolution(G, solution3) as FunctionTypeExprOrRef; - if (resultSolved0 instanceof FunctionTypeExpression) { - resultSolved0 = TypeUtils.copy(resultSolved0); - (resultSolved0 as FunctionTypeExpression).ASTNodeOptionalFieldStrategy = OptionalFieldStrategy.FIELDS_AND_ACCESSORS_OPTIONAL; - } - val resultSolved = resultSolved0; - // store type of funExpr in cache ... - cache.storeType(funExpr, resultSolved); - // update the defined function in the TModule - val fun = funExpr.definedType as TFunction; // types builder will have created this already - fun.replaceDeferredTypeRefs(resultSolved); - if(fun.returnValueMarkedOptional !== resultSolved.returnValueOptional) { - EcoreUtilN4.doWithDeliver(false, [ - fun.returnValueMarkedOptional = resultSolved.returnValueOptional; - ], fun); - } - // store types of fpars in cache ... - val len = Math.min(funExpr.fpars.size, fun.fpars.size); - for (var i = 0; i < len; i++) { - val fparAST = funExpr.fpars.get(i); - val fparT = fun.fpars.get(i); - val fparTw = TypeUtils.wrapIfVariadic(G.getPredefinedTypes().builtInTypeScope, fparT.typeRef, fparAST); - cache.storeType(fparAST, fparTw); - } - // tweak return type - if (funExpr instanceof ArrowFunction) { - log(0, "===START of special handling of single-expression arrow function"); - // NOTE: the next line requires the type of 'funExpr' and types of fpars to be in cache! For example: - // function foo(p: {function(int):T}) {return undefined;} - // foo( (i) => [i] ); - tweakReturnTypeOfSingleExpressionArrowFunction(G, cache, funExpr, resultSolved); - log(0, "===END of special handling of single-expression arrow function"); - } - } - - /** - * Handling of a very specific special case of single-expression arrow functions. - *

- * If the given arrow function is a single-expression arrow function, this method changes the return type of the - * given function type reference from non-void to void if the non-void return type would lead to a type error later - * on (for details see code of this method). - *

- * This tweak is only required because our poor man's return type inferencer in the types builder infers a wrong - * non-void return type in some cases, which is corrected in this method. - *

- * Example: - *

-	 * function foo(f : {function(): void}) {}
-	 * function none(): void {}
-	 * foo(() => none()); // will show bogus error when disabling this method
-	 * 
- */ - def private void tweakReturnTypeOfSingleExpressionArrowFunction(RuleEnvironment G, ASTMetaInfoCache cache, - ArrowFunction arrFun, FunctionTypeExprOrRef arrFunTypeRef - ) { - if (!arrFun.isSingleExprImplicitReturn) { - return; // not applicable - } - // Step 1) process arrFun's body, which was postponed earlier according to ASTProcessor#isPostponedNode(EObject) - // Rationale: the body of a single-expression arrow function isn't a true block, so we do not have to - // postpone it AND we need its types in the next step. - val block = arrFun.body; - if (block === null) { - return; // broken AST - } - if(!cache.postponedSubTrees.remove(block)) { - throw new IllegalStateException("body of single-expression arrow function not among postponed subtrees, in resource: " + arrFun.eResource.URI); - } - astProcessor.processSubtree(G, block, cache, 1); - // Step 2) adjust arrFun's return type stored in arrFunTypeRef (if required) - var didTweakReturnType = false; - val expr = arrFun.getSingleExpression(); - if (expr === null) { - return; // broken AST - } - val exprTypeRef = cache.getType(G, expr); // must now be in cache, because we just processed arrFun's body - if (TypeUtils.isVoid(exprTypeRef)) { - // the actual type of 'expr' is void - if (arrFunTypeRef instanceof FunctionTypeExpression) { - if (!TypeUtils.isVoid(arrFunTypeRef.returnTypeRef)) { - // the return type of the single-expression arrow function 'arrFun' is *not* void - // --> this would lead to a type error in N4JSTypeValidation, which we want to fix now - // in case the outer type expectation for the containing arrow function has a - // return type of 'void' OR there is no outer type expectation at all - val outerTypeExpectation = expectedTypeForArrowFunction(G, arrFun); - val outerReturnTypeExpectation = outerTypeExpectation?.returnTypeRef; - if (outerTypeExpectation === null - || (outerReturnTypeExpectation !== null && TypeUtils.isVoid(outerReturnTypeExpectation))) { - // fix the future type error by changing the return type of the containing arrow function - // from non-void to void - if (isDEBUG_LOG) { - log(1, "tweaking return type from " + arrFunTypeRef.returnTypeRef?.typeRefAsString + " to void"); - } - EcoreUtilN4.doWithDeliver(false, [ - arrFunTypeRef.returnTypeRef = G.voidTypeRef; - ], arrFunTypeRef); - if (isDEBUG_LOG) { - log(1, "tweaked type of arrow function is: " + arrFunTypeRef.typeRefAsString); - } - didTweakReturnType = true; - } - } - } - } - if(!didTweakReturnType) { - log(1, "tweaking of return type not required"); - } - } - - /** - * Replaces all DeferredTypeRefs in the given TFunction (i.e. in the fpars' types and the return type) - * by the corresponding types in 'result'. Argument 'result' must not contain any DeferredTypeRefs and, - * when this method returns, also the given TFunction 'fun' won't contain DeferredTypeRefs anymore. - * Will throw exception if 'fun' and 'result' do not match (e.g. 'result' has fewer fpars than 'fun'). - */ - def private void replaceDeferredTypeRefs(TFunction fun, FunctionTypeExprOrRef result) { - val len = fun.fpars.length; // note: we do not take Math.min here (fail fast) - for (var i = 0; i < len; i++) { - val funFpar = fun.fpars.get(i); - if (funFpar.typeRef instanceof DeferredTypeRef) { - val idx = i; - EcoreUtilN4.doWithDeliver(false, [ - funFpar.typeRef = TypeUtils.copy(result.fpars.get(idx).typeRef); - ], funFpar); - } - } - if (fun.returnTypeRef instanceof DeferredTypeRef) { - EcoreUtilN4.doWithDeliver(false, [ - fun.returnTypeRef = TypeUtils.copy(result.returnTypeRef); - ], fun); - } - } - - def private FunctionTypeExprOrRef expectedTypeForArrowFunction(RuleEnvironment G, ArrowFunction fe) { - val G_new = G.newRuleEnvironment; - val tr = ts.expectedType(G_new, fe.eContainer(), fe); - if (tr instanceof FunctionTypeExprOrRef) { - return tr; - } - return null; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ObjectLiteral.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ObjectLiteral.java new file mode 100644 index 0000000000..e6d628825e --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ObjectLiteral.java @@ -0,0 +1,407 @@ +/** + * 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.postprocessing; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.anyTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.anyTypeRefDynamic; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.objectType; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.N4JSASTUtils; +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.PropertyAssignment; +import org.eclipse.n4js.n4JS.PropertyGetterDeclaration; +import org.eclipse.n4js.n4JS.PropertyMethodDeclaration; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.n4JS.PropertySetterDeclaration; +import org.eclipse.n4js.ts.typeRefs.DeferredTypeRef; +import org.eclipse.n4js.ts.typeRefs.LiteralTypeRef; +import org.eclipse.n4js.ts.typeRefs.OptionalFieldStrategy; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRefStructural; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.ContainerType; +import org.eclipse.n4js.ts.types.FieldAccessor; +import org.eclipse.n4js.ts.types.InferenceVariable; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.TStructGetter; +import org.eclipse.n4js.ts.types.TStructMember; +import org.eclipse.n4js.ts.types.TStructuralType; +import org.eclipse.n4js.ts.types.TypingStrategy; +import org.eclipse.n4js.ts.types.util.Variance; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.constraints.InferenceContext; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.n4js.utils.EcoreUtilN4; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.xtext.xbase.lib.Pair; + +import com.google.common.base.Optional; +import com.google.inject.Inject; +import com.google.inject.Singleton; + +/** + * {@link PolyProcessor} delegates here for processing array literals. + * + * @see PolyProcessor#inferType(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,ASTMetaInfoCache) + * @see PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache) + */ +@Singleton +class PolyProcessor_ObjectLiteral extends AbstractPolyProcessor { + + @Inject + private PolyProcessor polyProcessor; + @Inject + private N4JSTypeSystem ts; + @Inject + private TypeSystemHelper tsh; + + /** + * BEFORE CHANGING THIS METHOD, READ THIS: + * {@link PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache)} + */ + TypeRef processObjectLiteral(RuleEnvironment G, ObjectLiteral objLit, TypeRef expectedTypeRef, + InferenceContext infCtx, ASTMetaInfoCache cache) { + + if (!isPoly(objLit)) { + TypeRef result = ts.type(G, objLit); + // do not store in cache (TypeProcessor responsible for storing types of non-poly expressions in cache) + return result; + } + + // quick mode as a performance tweak: + boolean haveUsableExpectedType = expectedTypeRef != null && expectedTypeRef.isStructuralTyping(); // TODO + // reconsider + boolean quickMode = !haveUsableExpectedType && !TypeUtils.isInferenceVariable(expectedTypeRef); + + List tMembers = new ArrayList<>(); + // in standard mode: the following list will contain pairs from property assignments to inference variables + // in quick mode: the following list will contain pairs from property assignments to fallback types + List> props2InfVarOrFallbackType = new ArrayList<>(); + processProperties(G, cache, infCtx, objLit, tMembers, quickMode, props2InfVarOrFallbackType); + linkGetterSetterPairs(infCtx, tMembers, quickMode); + + // create temporary type (i.e. may contain inference variables) + ParameterizedTypeRefStructural resultTypeRef = TypeUtils.createParameterizedTypeRefStructural(objectType(G), + TypingStrategy.STRUCTURAL, tMembers.toArray(new TStructMember[0])); + resultTypeRef.setASTNodeOptionalFieldStrategy(OptionalFieldStrategy.FIELDS_AND_ACCESSORS_OPTIONAL); + + // register onSolved handlers to add final types to cache (i.e. may not contain inference variables) + infCtx.onSolved( + solution -> handleOnSolved(G, cache, infCtx, objLit, quickMode, props2InfVarOrFallbackType, solution)); + + // return temporary type of objLit (i.e. may contain inference variables) + return resultTypeRef; + } + + /** + * Processes all properties of an object literal. As of now, methods are not processed. + */ + private void processProperties(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, + ObjectLiteral objLit, List tMembers, + boolean quickMode, List> props2InfVarOrFallbackType) { + for (PropertyAssignment pa : objLit.getPropertyAssignments()) { + if (pa != null) { + TStructMember tMember = null; + if (pa.getDefinedMember() != null) { + tMember = TypeUtils.copy(pa.getDefinedMember()); + tMembers.add(tMember); + } else { + // this happens if member name in AST was null (bad syntax in code; types builder won't + // create a TMember in that case) or in case of an invalid computed name (not a compile-time + // expression, unresolved reference, etc.; ComputedNameProcessor will remote TMember for + // consistency with first case); this is an error case, but we still have to continue + // processing, because nested expression must still be typed as usual. + } + + if (isPoly(pa)) { + if (!(tMember instanceof TMethod)) { + processNonMethodProperties(G, cache, infCtx, tMember, pa, + quickMode, props2InfVarOrFallbackType); + } + } + } + } + } + + /** + * For each property in the object literal: a) introduce a new inference variable representing the property's type + * (except for methods) b) add a constraint: expressionTypeRef <: iv c) create a TStructMember to be used in the + * structural result type reference + * + * @param tMember + * may be null in case of invalid members. + */ + private void processNonMethodProperties(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, + TStructMember tMember, PropertyAssignment propAssignm, + boolean quickMode, List> props2InfVarOrFallbackType) { + if (tMember != null) { + TypeRef originalMemberType = getTypeOfMember(tMember); + + assertTrueIfRigid(cache, + "type of " + propAssignm.eClass().getName() + " in TModule should be a DeferredTypeRef", + originalMemberType instanceof DeferredTypeRef); + + if (!(originalMemberType instanceof DeferredTypeRef)) { + return; // if rigid assertions are turned off, we fail safe (should never happen) + } + } + + if (!quickMode) { + // standard mode: + // create new inference variable for the to-be-inferred type of this property + InferenceVariable iv = infCtx.newInferenceVariable(); + // set it as type in tMember + if (tMember != null) { + setTypeOfMember(tMember, TypeUtils.createTypeRef(iv)); + } + // add a constraint for the initializer expression (if any) + if (propAssignm instanceof PropertyNameValuePair) { + PropertyNameValuePair pnvp = (PropertyNameValuePair) propAssignm; + if (pnvp.getExpression() != null) { + TypeRef exprTypeRef = polyProcessor.processExpr(G, pnvp.getExpression(), + TypeUtils.createTypeRef(iv), infCtx, cache); + infCtx.addConstraint(exprTypeRef, TypeUtils.createTypeRef(iv), Variance.CO); // exprTypeRef <: iv + } + } + // remember for later + props2InfVarOrFallbackType.add(Pair.of(propAssignm, iv)); + } else { + // quick mode: + // compute a fall-back type + TypeRef fallbackType = anyTypeRef(G); + if (propAssignm instanceof PropertyNameValuePair) { + PropertyNameValuePair pnvp = (PropertyNameValuePair) propAssignm; + if (pnvp.getExpression() != null) { + fallbackType = polyProcessor.processExpr(G, pnvp.getExpression(), null, infCtx, cache); + } + } else if (propAssignm instanceof PropertyGetterDeclaration) { + fallbackType = getDeclaredTypeOfOtherAccessorInPair((PropertyGetterDeclaration) propAssignm); + } else if (propAssignm instanceof PropertySetterDeclaration) { + fallbackType = getDeclaredTypeOfOtherAccessorInPair((PropertySetterDeclaration) propAssignm); + } + if (fallbackType == null) { + fallbackType = anyTypeRef(G); + } + + // set it as type in tMember + if (tMember != null) { + setTypeOfMember(tMember, TypeUtils.copy(fallbackType)); + } + // remember for later + props2InfVarOrFallbackType.add(Pair.of(propAssignm, fallbackType)); + } + } + + private TypeRef getDeclaredTypeOfOtherAccessorInPair(org.eclipse.n4js.n4JS.FieldAccessor accAST) { + FieldAccessor otherPair = findOtherAccessorInPair(accAST.getDefinedAccessor()); + org.eclipse.n4js.n4JS.FieldAccessor otherPairAST = otherPair == null ? null + : (org.eclipse.n4js.n4JS.FieldAccessor) otherPair.getAstElement(); + TypeRef declTypeRef = otherPairAST == null ? null : otherPairAST.getDeclaredTypeRef(); + return declTypeRef; + } + + private FieldAccessor findOtherAccessorInPair(FieldAccessor acc) { + if (acc != null && acc.getName() != null) { + EObject type = acc.eContainer(); + if (type instanceof ContainerType) { + boolean lookForWriteAccess = acc instanceof TGetter; + EObject result = ((ContainerType) type).findOwnedMember(acc.getName(), lookForWriteAccess, + acc.isStatic()); + if (result instanceof FieldAccessor) { + return (FieldAccessor) result; + } + } + } + return null; + } + + /** + * Add a constraint for each getter/setter pair reflecting the relation between the getter's and setter's type. + * Required to make the getter obtain its implicit type from the corresponding setter, and vice versa. + */ + private void linkGetterSetterPairs(InferenceContext infCtx, List tMembers, boolean quickMode) { + if (!quickMode) { // not in quick mode + for (TStructMember tMember : tMembers) { + if (tMember instanceof TStructGetter) { + TStructGetter tsg = (TStructGetter) tMember; + FieldAccessor tOtherInPair = findOtherAccessorInPair(tsg); + if (tOtherInPair != null) { + TypeRef typeGetter = getTypeOfMember(tsg); + TypeRef typeSetter = getTypeOfMember(tOtherInPair); + if (TypeUtils.isInferenceVariable(typeGetter) || TypeUtils.isInferenceVariable(typeSetter)) { + infCtx.addConstraint(typeGetter, typeSetter, Variance.CO); + } else { + // do not add a constraint if both types were explicitly declared + // (then this constraint does not apply!!) + } + } + } + } + } + } + + /** + * Writes final types to cache + */ + private void handleOnSolved(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, + ObjectLiteral objLit, + boolean quickMode, List> props2InfVarOrFallbackType, + Optional> solution) { + for (Pair propPair : props2InfVarOrFallbackType) { + PropertyAssignment propAssignm = propPair.getKey(); + TStructMember memberInTModule = propAssignm.getDefinedMember(); + if (memberInTModule != null) { + TypeRef memberType = getMemberType(G, infCtx, solution, quickMode, propPair); + boolean resolveLiteralTypes = (quickMode) + ? // quick mode means we do not have a type expectation, so we handle literal types exactly + // as when inferring the implicit type of variables with an initializer expression + !N4JSASTUtils.isImmutable(propAssignm) + : + // standard mode means we have a type expectation; if we resolved here, we might break + // constraints (instead, it's the responsibility of the constraint solver to avoid literal + // types as far as possible) + false; + TypeRef memberTypeSane = tsh.sanitizeTypeOfVariableFieldPropertyParameter(G, memberType, + resolveLiteralTypes); + EcoreUtilN4.doWithDeliver(false, () -> setTypeOfMember(memberInTModule, TypeUtils.copy(memberTypeSane)), + memberInTModule); + } + } + + ParameterizedTypeRefStructural resultFinal = TypeUtils.createParameterizedTypeRefStructural(objectType(G), + TypingStrategy.STRUCTURAL, + (TStructuralType) objLit.getDefinedType()); + resultFinal.setASTNodeOptionalFieldStrategy(OptionalFieldStrategy.FIELDS_AND_ACCESSORS_OPTIONAL); + cache.storeType(objLit, resultFinal); + + for (PropertyAssignment currAss : objLit.getPropertyAssignments()) { + if (currAss.getDefinedMember() != null) { + if (currAss instanceof PropertyMethodDeclaration) { + cache.storeType(currAss, + TypeUtils.createTypeRef(((PropertyMethodDeclaration) currAss).getDefinedMember())); + } else { + cache.storeType(currAss, TypeUtils.copy(getTypeOfMember(currAss.getDefinedMember()))); + } + } else { + if (currAss instanceof PropertyNameValuePair + && ((PropertyNameValuePair) currAss).getExpression() != null) { + TypeRef exprType = ts.type(G, ((PropertyNameValuePair) currAss).getExpression()); + cache.storeType(currAss, exprType); + } else { + cache.storeType(currAss, anyTypeRefDynamic(G)); + } + } + } + } + + private TypeRef getMemberType(RuleEnvironment G, InferenceContext infCtx, + Optional> solution, + boolean quickMode, Pair prop2InfVarOrFallbackType) { + + TypeRef memberType = null; + PropertyAssignment propAssignm = prop2InfVarOrFallbackType.getKey(); + if (solution.isPresent()) { + if (quickMode) { + // success case (quick mode): + TypeRef fallbackType = (TypeRef) prop2InfVarOrFallbackType.getValue(); // value is a TypeRef + if (propAssignm instanceof PropertyNameValuePair) { + memberType = getFinalResultTypeOfNestedPolyExpression( + ((PropertyNameValuePair) propAssignm).getExpression()); + } else { + memberType = applySolution(TypeUtils.copy(fallbackType), G, solution.get()); + } + + } else { + // success case (standard mode): + InferenceVariable infVar = (InferenceVariable) prop2InfVarOrFallbackType.getValue(); // value is an + // infVar + TypeRef fromSolution = solution.get().get(infVar); + + if (propAssignm instanceof PropertyNameValuePair) { + TypeRef fromCache = (((PropertyNameValuePair) propAssignm).getExpression() instanceof ObjectLiteral) + ? getFinalResultTypeOfNestedPolyExpression( + ((PropertyNameValuePair) propAssignm).getExpression()) + : null; + if (fromCache != null && ts.equaltypeSucceeded(G, fromCache, fromSolution)) { + // tweak for nested ObjectLiterals in initializer expression of PropertyNameValuePairs: + // the solution from the infCtx will be a StructuralTypeRef with 'genStructuralMembers' + // but the result of the nested poly computation (via the cache) will give us a much more + // efficient StructuralTypeRef with 'structuralType' pointing to the TStructuralType in the + // TModule + memberType = fromCache; + } else { + memberType = fromSolution; + } + } else { + memberType = fromSolution; + } + } + } else { + // failure case (both modes): + if (propAssignm instanceof PropertyNameValuePair) { + memberType = getFinalResultTypeOfNestedPolyExpression( + ((PropertyNameValuePair) propAssignm).getExpression()); + memberType = adjustMemberTypeToAvoidMisleadingLiteralTypes(G, infCtx, quickMode, + prop2InfVarOrFallbackType, memberType); + } else { + memberType = anyTypeRef(G); + } + } + + return memberType; + } + + /** + * Replaces literal types by their base type to avoid confusing error messages. + *

+ * Without this tweak, the following code + * + *

+	 * let x: ~Object with { prop1: string, prop2: number } = { prop1: "hello", prop2: "BAD!" };
+	 * 
+ * + * would produce the misleading error message + * + *
+	 * ~Object with { prop1: "hello"; prop2: "BAD!" } is not a structural subtype of ~Object with { prop1: string; prop2: number }: prop1 failed: "hello" is not equal to string and 1 more problems.
+	 * 
+ * + * With this tweak it changes to: + * + *
+	 * ~Object with { prop1: string; prop2: "BAD!" } is not a structural subtype of ~Object with { prop1: string; prop2: number }: prop2 failed: "BAD!" is not equal to number.
+	 * 
+ */ + private TypeRef adjustMemberTypeToAvoidMisleadingLiteralTypes(RuleEnvironment G, InferenceContext infCtx, + boolean quickMode, Pair prop2InfVarOrFallbackType, + TypeRef memberType) { + if (!quickMode) { + if (memberType instanceof LiteralTypeRef) { + // value is an infVar + InferenceVariable infVar = (InferenceVariable) prop2InfVarOrFallbackType.getValue(); + if (!infCtx.isPromisingPartialSolution(infVar, memberType)) { + TypeRef baseType = N4JSLanguageUtils.getLiteralTypeBase(G, memberType); + if (infCtx.isPromisingPartialSolution(infVar, baseType)) { + return baseType; + } + } + } + } + return memberType; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ObjectLiteral.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ObjectLiteral.xtend deleted file mode 100644 index ebb4ac0fc4..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ObjectLiteral.xtend +++ /dev/null @@ -1,378 +0,0 @@ -/** - * 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.postprocessing - -import com.google.common.base.Optional -import com.google.inject.Inject -import com.google.inject.Singleton -import java.util.List -import java.util.Map -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.N4JSASTUtils -import org.eclipse.n4js.n4JS.ObjectLiteral -import org.eclipse.n4js.n4JS.PropertyAssignment -import org.eclipse.n4js.n4JS.PropertyGetterDeclaration -import org.eclipse.n4js.n4JS.PropertyMethodDeclaration -import org.eclipse.n4js.n4JS.PropertyNameValuePair -import org.eclipse.n4js.n4JS.PropertySetterDeclaration -import org.eclipse.n4js.ts.typeRefs.DeferredTypeRef -import org.eclipse.n4js.ts.typeRefs.LiteralTypeRef -import org.eclipse.n4js.ts.typeRefs.OptionalFieldStrategy -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.ContainerType -import org.eclipse.n4js.ts.types.FieldAccessor -import org.eclipse.n4js.ts.types.InferenceVariable -import org.eclipse.n4js.ts.types.TGetter -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.ts.types.TStructGetter -import org.eclipse.n4js.ts.types.TStructMember -import org.eclipse.n4js.ts.types.TStructuralType -import org.eclipse.n4js.ts.types.TypingStrategy -import org.eclipse.n4js.ts.types.util.Variance -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.constraints.InferenceContext -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper -import org.eclipse.n4js.utils.EcoreUtilN4 -import org.eclipse.n4js.utils.N4JSLanguageUtils - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * {@link PolyProcessor} delegates here for processing array literals. - * - * @see PolyProcessor#inferType(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,ASTMetaInfoCache) - * @see PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache) - */ -@Singleton -package class PolyProcessor_ObjectLiteral extends AbstractPolyProcessor { - - @Inject - private PolyProcessor polyProcessor; - - @Inject - private N4JSTypeSystem ts; - @Inject - private TypeSystemHelper tsh; - - /** - * BEFORE CHANGING THIS METHOD, READ THIS: - * {@link PolyProcessor#processExpr(RuleEnvironment,org.eclipse.n4js.n4JS.Expression,TypeRef,InferenceContext,ASTMetaInfoCache)} - */ - def package TypeRef processObjectLiteral(RuleEnvironment G, ObjectLiteral objLit, TypeRef expectedTypeRef, - InferenceContext infCtx, ASTMetaInfoCache cache) { - - if (!objLit.isPoly) { - val result = ts.type(G, objLit); - // do not store in cache (TypeProcessor responsible for storing types of non-poly expressions in cache) - return result; - } - - // quick mode as a performance tweak: - val haveUsableExpectedType = expectedTypeRef !== null && expectedTypeRef.structuralTyping; // TODO reconsider - val quickMode = !haveUsableExpectedType && !TypeUtils.isInferenceVariable(expectedTypeRef); - - val List tMembers = newArrayList; - // in standard mode: the following list will contain pairs from property assignments to inference variables - // in quick mode: the following list will contain pairs from property assignments to fallback types - val List> props2InfVarOrFallbackType = newArrayList; - processProperties(G, cache, infCtx, objLit, tMembers, quickMode, props2InfVarOrFallbackType); - linkGetterSetterPairs(infCtx, tMembers, quickMode); - - // create temporary type (i.e. may contain inference variables) - val resultTypeRef = TypeUtils.createParameterizedTypeRefStructural(G.objectType, TypingStrategy.STRUCTURAL, tMembers); - resultTypeRef.ASTNodeOptionalFieldStrategy = OptionalFieldStrategy.FIELDS_AND_ACCESSORS_OPTIONAL; - - // register onSolved handlers to add final types to cache (i.e. may not contain inference variables) - infCtx.onSolved [ solution | handleOnSolved(G, cache, infCtx, objLit, quickMode, props2InfVarOrFallbackType, solution) ]; - - // return temporary type of objLit (i.e. may contain inference variables) - return resultTypeRef; - } - - /** - * Processes all properties of an object literal. - * As of now, methods are not processed. - */ - def private void processProperties(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, - ObjectLiteral objLit, List tMembers, - boolean quickMode, List> props2InfVarOrFallbackType - ) { - for (pa : objLit.propertyAssignments) { - if (pa !== null) { - var TStructMember tMember = null; - if (pa.definedMember !== null) { - tMember = TypeUtils.copy(pa.definedMember); - tMembers += tMember; - } else { - // this happens if member name in AST was null (bad syntax in code; types builder won't - // create a TMember in that case) or in case of an invalid computed name (not a compile-time - // expression, unresolved reference, etc.; ComputedNameProcessor will remote TMember for - // consistency with first case); this is an error case, but we still have to continue - // processing, because nested expression must still be typed as usual. - } - - if (pa.isPoly) { - if (!(tMember instanceof TMethod)) { - processNonMethodProperties(G, cache, infCtx, tMember, pa, - quickMode, props2InfVarOrFallbackType); - } - } - } - } - } - - /** - * For each property in the object literal: - * a) introduce a new inference variable representing the property's type (except for methods) - * b) add a constraint: expressionTypeRef <: iv - * c) create a TStructMember to be used in the structural result type reference - * - * @param tMember may be null in case of invalid members. - */ - def private void processNonMethodProperties(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, - TStructMember tMember, PropertyAssignment propAssignm, - boolean quickMode, List> props2InfVarOrFallbackType - ) { - if(tMember!==null) { - val originalMemberType = tMember.typeOfMember; - - assertTrueIfRigid(cache, "type of " + propAssignm.eClass.name + " in TModule should be a DeferredTypeRef", - originalMemberType instanceof DeferredTypeRef); - - if (!(originalMemberType instanceof DeferredTypeRef)) { - return; // if rigid assertions are turned off, we fail safe (should never happen) - } - } - - if (!quickMode) { - // standard mode: - // create new inference variable for the to-be-inferred type of this property - val iv = infCtx.newInferenceVariable; - // set it as type in tMember - if (tMember !== null) { - tMember.typeOfMember = TypeUtils.createTypeRef(iv); - } - // add a constraint for the initializer expression (if any) - if (propAssignm instanceof PropertyNameValuePair) { - if (propAssignm.expression !== null) { - val exprTypeRef = polyProcessor.processExpr(G, propAssignm.expression, TypeUtils.createTypeRef(iv), infCtx, cache); - infCtx.addConstraint(exprTypeRef, TypeUtils.createTypeRef(iv), Variance.CO); // exprTypeRef <: iv - } - } - // remember for later - props2InfVarOrFallbackType += propAssignm -> iv; - } else { - // quick mode: - // compute a fall-back type - val TypeRef fallbackType = switch (propAssignm) { - PropertyNameValuePair case propAssignm.expression !== null: - polyProcessor.processExpr(G, propAssignm.expression, null, infCtx, cache) - PropertyGetterDeclaration: - propAssignm.declaredTypeOfOtherAccessorInPair ?: G.anyTypeRef - PropertySetterDeclaration: - propAssignm.declaredTypeOfOtherAccessorInPair ?: G.anyTypeRef - default: - G.anyTypeRef - }; - // set it as type in tMember - if (tMember !== null) { - tMember.typeOfMember = TypeUtils.copy(fallbackType); - } - // remember for later - props2InfVarOrFallbackType += propAssignm -> fallbackType; - } - } - - - def private TypeRef getDeclaredTypeOfOtherAccessorInPair(org.eclipse.n4js.n4JS.FieldAccessor accAST) { - val otherPair = findOtherAccessorInPair(accAST.definedAccessor); - val otherPairAST = otherPair?.astElement as org.eclipse.n4js.n4JS.FieldAccessor; - val declTypeRef = otherPairAST?.declaredTypeRef; - return declTypeRef; - } - - def private FieldAccessor findOtherAccessorInPair(FieldAccessor acc) { - if (acc?.name !== null) { - val type = acc.eContainer; - if (type instanceof ContainerType) { - val lookForWriteAccess = acc instanceof TGetter; - val result = type.findOwnedMember(acc.name, lookForWriteAccess, acc.static); - if (result instanceof FieldAccessor) { - return result; - } - } - } - return null; - } - - /** - * Add a constraint for each getter/setter pair reflecting the relation between the getter's and setter's type. - * Required to make the getter obtain its implicit type from the corresponding setter, and vice versa. - */ - private def void linkGetterSetterPairs(InferenceContext infCtx, List tMembers, boolean quickMode) { - if(!quickMode) { // not in quick mode - for (tMember : tMembers) { - if (tMember instanceof TStructGetter) { - val tOtherInPair = findOtherAccessorInPair(tMember); - if (tOtherInPair !== null) { - val typeGetter = tMember.typeOfMember; - val typeSetter = tOtherInPair.typeOfMember; - if (TypeUtils.isInferenceVariable(typeGetter) || TypeUtils.isInferenceVariable(typeSetter)) { - infCtx.addConstraint(typeGetter, typeSetter, Variance.CO); - } else { - // do not add a constraint if both types were explicitly declared - // (then this constraint does not apply!!) - } - } - } - } - } - } - - /** - * Writes final types to cache - */ - private def void handleOnSolved(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, ObjectLiteral objLit, - boolean quickMode, List> props2InfVarOrFallbackType, - Optional> solution - ) { - for (propPair : props2InfVarOrFallbackType) { - val propAssignm = propPair.key; - val memberInTModule = propAssignm.definedMember; - if (memberInTModule !== null) { - val memberType = getMemberType(G, infCtx, solution, quickMode, propPair); - val resolveLiteralTypes = if (quickMode) { - // quick mode means we do not have a type expectation, so we handle literal types exactly - // as when inferring the implicit type of variables with an initializer expression - !N4JSASTUtils.isImmutable(propAssignm) - } else { - // standard mode means we have a type expectation; if we resolved here, we might break - // constraints (instead, it's the responsibility of the constraint solver to avoid literal - // types as far as possible) - false - }; - val memberTypeSane = tsh.sanitizeTypeOfVariableFieldPropertyParameter(G, memberType, resolveLiteralTypes); - EcoreUtilN4.doWithDeliver(false, [ - memberInTModule.typeOfMember = TypeUtils.copy(memberTypeSane); - ], memberInTModule); - } - } - - val resultFinal = TypeUtils.createParameterizedTypeRefStructural(G.objectType, TypingStrategy.STRUCTURAL, - objLit.definedType as TStructuralType); - resultFinal.ASTNodeOptionalFieldStrategy = OptionalFieldStrategy.FIELDS_AND_ACCESSORS_OPTIONAL; - cache.storeType(objLit, resultFinal); - - for (currAss : objLit.propertyAssignments) { - if (currAss.definedMember !== null) { - if (currAss instanceof PropertyMethodDeclaration) { - cache.storeType(currAss, TypeUtils.createTypeRef(currAss.definedMember)); - } else { - cache.storeType(currAss, TypeUtils.copy(currAss.definedMember.typeOfMember)); - } - } else { - if (currAss instanceof PropertyNameValuePair && (currAss as PropertyNameValuePair).expression !== null) { - val exprType = ts.type(G, (currAss as PropertyNameValuePair).expression); - cache.storeType(currAss, exprType); - } else { - cache.storeType(currAss, anyTypeRefDynamic(G)); - } - } - } - } - - private def TypeRef getMemberType(RuleEnvironment G, InferenceContext infCtx, Optional> solution, - boolean quickMode, Pair prop2InfVarOrFallbackType - ) { - var TypeRef memberType = null; - val propAssignm = prop2InfVarOrFallbackType.key; - if (solution.present) { - if (quickMode) { - // success case (quick mode): - val fallbackType = prop2InfVarOrFallbackType.value as TypeRef; // value is a TypeRef - if (propAssignm instanceof PropertyNameValuePair) { - memberType = getFinalResultTypeOfNestedPolyExpression(propAssignm.expression) - } else { - memberType = TypeUtils.copy(fallbackType).applySolution(G, solution.get) - } - - } else { - // success case (standard mode): - val infVar = prop2InfVarOrFallbackType.value as InferenceVariable; // value is an infVar - val fromSolution = solution.get.get(infVar); - - if (propAssignm instanceof PropertyNameValuePair) { - val fromCache = if (propAssignm.expression instanceof ObjectLiteral) { - getFinalResultTypeOfNestedPolyExpression(propAssignm.expression) - } else { - null - }; - if (fromCache !== null && ts.equaltypeSucceeded(G, fromCache, fromSolution)) { - // tweak for nested ObjectLiterals in initializer expression of PropertyNameValuePairs: - // the solution from the infCtx will be a StructuralTypeRef with 'genStructuralMembers' - // but the result of the nested poly computation (via the cache) will give us a much more - // efficient StructuralTypeRef with 'structuralType' pointing to the TStructuralType in the TModule - memberType = fromCache - } else { - memberType = fromSolution - } - } else { - memberType = fromSolution - } - } - } else { - // failure case (both modes): - if (propAssignm instanceof PropertyNameValuePair) { - memberType = getFinalResultTypeOfNestedPolyExpression(propAssignm.expression) - memberType = adjustMemberTypeToAvoidMisleadingLiteralTypes(G, infCtx, quickMode, prop2InfVarOrFallbackType, memberType); - } else { - memberType = G.anyTypeRef - } - } - - return memberType; - } - - /** - * Replaces literal types by their base type to avoid confusing error messages. - *

- * Without this tweak, the following code - *

-	 * let x: ~Object with { prop1: string, prop2: number } = { prop1: "hello", prop2: "BAD!" };
-	 * 
- * would produce the misleading error message - *
-	 * ~Object with { prop1: "hello"; prop2: "BAD!" } is not a structural subtype of ~Object with { prop1: string; prop2: number }: prop1 failed: "hello" is not equal to string and 1 more problems.
-	 * 
- * With this tweak it changes to: - *
-	 * ~Object with { prop1: string; prop2: "BAD!" } is not a structural subtype of ~Object with { prop1: string; prop2: number }: prop2 failed: "BAD!" is not equal to number.
-	 * 
- */ - private def TypeRef adjustMemberTypeToAvoidMisleadingLiteralTypes(RuleEnvironment G, InferenceContext infCtx, - boolean quickMode, Pair prop2InfVarOrFallbackType, TypeRef memberType - ) { - if (!quickMode) { - if (memberType instanceof LiteralTypeRef) { - val infVar = prop2InfVarOrFallbackType.value as InferenceVariable; // value is an infVar - if (!infCtx.isPromisingPartialSolution(infVar, memberType)) { - val baseType = N4JSLanguageUtils.getLiteralTypeBase(G, memberType); - if (infCtx.isPromisingPartialSolution(infVar, baseType)) { - return baseType; - } - } - } - } - return memberType; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/RuntimeDependencyProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/RuntimeDependencyProcessor.java new file mode 100644 index 0000000000..a4e835cec4 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/RuntimeDependencyProcessor.java @@ -0,0 +1,252 @@ +/** + * Copyright (c) 2020 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.postprocessing; + +import static com.google.common.collect.Iterators.singletonIterator; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.head; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.ModuleRef; +import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; +import org.eclipse.n4js.n4JS.N4JSASTUtils; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.smith.Measurement; +import org.eclipse.n4js.smith.N4JSDataCollectors; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType; +import org.eclipse.n4js.ts.types.RuntimeDependency; +import org.eclipse.n4js.ts.types.TExportableElement; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.TNamespace; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.utils.EcoreUtilN4; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.SCCUtils; +import org.eclipse.xtext.EcoreUtil2; + +import com.google.inject.Singleton; + +/** + * Processor for computing direct load-time dependencies and import retention (during AST traversal) as well as + * load-time dependency cycles (during finalization of post-processing). + */ +@Singleton +@SuppressWarnings("all") +public class RuntimeDependencyProcessor { + /** + * Invoked during AST traversal (and thus during main post-processing). + */ + void recordRuntimeReferencesInCache(final EObject node, final ASTMetaInfoCache cache) { + if (node instanceof IdentifierRef) { + IdentifierRef idRef = (IdentifierRef) node; + if (idRef.eContainingFeature() == N4JSPackage.Literals.NAMED_EXPORT_SPECIFIER__EXPORTED_ELEMENT) { + return; // re-exports are not harmful + } + IdentifiableElement target = idRef.getTargetElement(); + if (N4JSLanguageUtils.hasRuntimeRepresentation(target)) { + cache.elementsReferencedAtRuntime.add(target); + // in case of namespace imports, we also want to remember that the namespace was referenced at run time: + IdentifiableElement targetRaw = idRef.getId(); + if (targetRaw != target && targetRaw instanceof ModuleNamespaceVirtualType) { + cache.elementsReferencedAtRuntime.add(targetRaw); + } + } + } else if (node instanceof N4ClassifierDeclaration) { + N4ClassifierDeclaration cd = (N4ClassifierDeclaration) node; + if (N4JSLanguageUtils.hasRuntimeRepresentation(cd)) { + for (TypeReferenceNode targetTypeRef : cd.getSuperClassifierRefs()) { + Type targetDeclType = targetTypeRef == null || targetTypeRef.getTypeRef() == null + ? null + : targetTypeRef.getTypeRef().getDeclaredType(); + + if (N4JSLanguageUtils.hasRuntimeRepresentation(targetDeclType)) { + cache.elementsReferencedAtRuntime.add(targetDeclType); + + // in case of namespace imports, we also want to remember that the namespace was referenced at + // run time: + @SuppressWarnings("null") + Type namespaceLikeType = targetTypeRef.getTypeRefInAST() == null + || targetTypeRef.getTypeRefInAST().getAstNamespaceLikeRefs() == null + || head(targetTypeRef.getTypeRefInAST().getAstNamespaceLikeRefs()) == null + ? null + : head(targetTypeRef.getTypeRefInAST().getAstNamespaceLikeRefs()) + .getDeclaredType(); + + if (namespaceLikeType instanceof ModuleNamespaceVirtualType + || namespaceLikeType instanceof TNamespace) { + cache.elementsReferencedAtRuntime.add(namespaceLikeType); + } + // remember that the target's containing module was referenced from an + // extends/implements clause: + @SuppressWarnings("null") + TModule targetModule = (!targetDeclType.eIsProxy()) + ? EcoreUtil2.getContainerOfType(targetDeclType, TModule.class) + : null; + if (isDifferentModuleInSameProject(targetModule, cache)) { + if (N4JSASTUtils.isTopLevelCode(node)) { + // nested classifiers not supported yet, but let's be future proof + cache.modulesReferencedAtLoadtimeForInheritance.add(targetModule); + } + } + } + } + } + } + } + + /** + * Invoked at the end of AST traversal (and thus, during main post-processing). + *

+ * Also sets the flag {@link ImportSpecifier#getRetainedAtRuntime() retainedAtRuntime}. + */ + void storeDirectRuntimeDependenciesInTModule(Script script, ASTMetaInfoCache cache) { + try (Measurement m = N4JSDataCollectors.dcRuntimeDepsCollect.getMeasurement()) { + doStoreDirectRuntimeDependenciesInTModule(script, cache); + } + } + + private void doStoreDirectRuntimeDependenciesInTModule(Script script, ASTMetaInfoCache cache) { + TModule module = script.getModule(); + + // step 1: set runtime retention flag in import specifiers + List importDecls = toList(filter(script.getScriptElements(), ImportDeclaration.class)); + for (ImportDeclaration importDecl : importDecls) { + for (ImportSpecifier importSpec : importDecl.getImportSpecifiers()) { + if (importSpec != null) { + TExportableElement element; + if (importSpec instanceof NamedImportSpecifier) { + element = ((NamedImportSpecifier) importSpec).getImportedElement(); + } else if (importSpec instanceof NamespaceImportSpecifier) { + element = ((NamespaceImportSpecifier) importSpec).getDefinedType(); + } else { + throw new IllegalStateException( + "unknown subclass of ImportSpecifier: " + importSpec.eClass().getName()); + } + boolean retained = cache.elementsReferencedAtRuntime.contains(element); + EcoreUtilN4.doWithDeliver(false, () -> importSpec.setRetainedAtRuntime(retained), importSpec); + } + } + } + + // step 2: derive direct runtime dependencies from runtime retention of imports + // + // NOTE: order of the dependencies is important, here, because a change in the TModule has + // significant implications (e.g. dependent modules will be rebuilt, see #isAffected() in + // incremental builder); so we want to avoid a random reordering of the same dependencies and + // therefore use a defined order derived from the order of import declarations in the AST. + // + Set modulesReferencedAtRuntime = new LinkedHashSet<>(); + List refsToOtherModules = toList( + filter(filter(script.getScriptElements(), ModuleRef.class), mr -> mr.isReferringToOtherModule())); + for (ModuleRef moduleRef : refsToOtherModules) { + if (moduleRef.isRetainedAtRuntime()) { // note: will also be true for bare imports and for all re-exports + TModule targetModule = moduleRef.getModule(); + if (isDifferentModuleInSameProject(targetModule, cache)) { + modulesReferencedAtRuntime.add(targetModule); + } + } + } + List dependenciesRuntime = new ArrayList<>(modulesReferencedAtRuntime.size()); + for (TModule currModule : modulesReferencedAtRuntime) { + RuntimeDependency currDep = TypesFactory.eINSTANCE.createRuntimeDependency(); + currDep.setTarget(currModule); + currDep.setLoadtimeForInheritance(cache.modulesReferencedAtLoadtimeForInheritance.contains(currModule)); + dependenciesRuntime.add(currDep); + } + + // step 3: store direct runtime dependencies in TModule + if (module != null) { + EcoreUtilN4.doWithDeliver(false, () -> { + module.getDependenciesRuntime().clear(); + module.getDependenciesRuntime().addAll(dependenciesRuntime); + }, module); + } + } + + /** + * Invoked during the finalization of post-processing (and thus, after the main post-processing of all directly or + * indirectly required resources has finished). + */ + void computeAndStoreRuntimeCyclesInTModule(TModule module) { + try (Measurement m = N4JSDataCollectors.dcRuntimeDepsFindCycles.getMeasurement()) { + doComputeAndStoreRuntimeCyclesInTModule(module); + } + } + + private void doComputeAndStoreRuntimeCyclesInTModule(TModule module) { + // NOTE: as above, the order of cyclicModulesRuntime and runtimeCyclicLoadtimeDependents stored in + // the TModule is important, because we want to avoid random reordering of the same set of modules + // to avoid unnecessary changes of the TModule (see above for details) + List cyclicModulesRuntime = getAllRuntimeCyclicModules(module, false); + List cyclicModulesLoadtimeForInheritance = getAllRuntimeCyclicModules(module, true); + Set runtimeCyclicLoadtimeDependents = new LinkedHashSet<>(); + for (TModule cyclicModule : cyclicModulesRuntime) { + if (hasDirectLoadtimeDependencyTo(cyclicModule, module)) { + runtimeCyclicLoadtimeDependents.add(cyclicModule); + } + } + + EcoreUtilN4.doWithDeliver(false, () -> { + module.getCyclicModulesRuntime().clear(); + module.getCyclicModulesLoadtimeForInheritance().clear(); + module.getRuntimeCyclicLoadtimeDependents().clear(); + module.getCyclicModulesRuntime().addAll(cyclicModulesRuntime); + module.getCyclicModulesLoadtimeForInheritance().addAll(cyclicModulesLoadtimeForInheritance); + module.getRuntimeCyclicLoadtimeDependents().addAll(runtimeCyclicLoadtimeDependents); + }, module); + } + + private static List getAllRuntimeCyclicModules(TModule module, boolean onlyLoadtime) { + // Note on performance: at this point we cannot search *all* strongly connected components in the + // graph, which would be more time efficient, because we are operating on a potentially (and usually) + // incomplete runtime dependency graph during the build. The only thing we can rely on is that the + // direct runtime dependencies of modules in our containing strongly connected component are up to + // date. Therefore, we are here only searching the SCC of 'module' (i.e. pass only 'module' as first + // argument to SCCUtils#findSCCs()) and do not make use of a more sophisticated algorithm for finding + // all SCCs such as Johnson's algorithm (cf. Johnson, SIAM Journal on Computing, Vol. 4, No. 1, 1975). + + List> sccs = SCCUtils.findSCCs( + singletonIterator(module), + m -> map(filter(m.getDependenciesRuntime(), dr -> !onlyLoadtime || dr.isLoadtimeForInheritance()), + dr -> dr.getTarget())); + + List cyclicModules = head(filter(sccs, l -> l.remove(module))); + return cyclicModules; + } + + private boolean hasDirectLoadtimeDependencyTo(TModule from, TModule to) { + return exists(from.getDependenciesRuntime(), rd -> rd.isLoadtimeForInheritance() && rd.getTarget() == to); + } + + private static boolean isDifferentModuleInSameProject(TModule module, ASTMetaInfoCache cache) { + return module != null && !module.eIsProxy() + && module.eResource() != cache.getResource() + && java.util.Objects.equals(module.getProjectID(), cache.getProjectID()); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/RuntimeDependencyProcessor.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/RuntimeDependencyProcessor.xtend deleted file mode 100644 index 158fdefbfb..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/RuntimeDependencyProcessor.xtend +++ /dev/null @@ -1,218 +0,0 @@ -/** - * Copyright (c) 2020 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.postprocessing - -import com.google.common.collect.Iterators -import com.google.inject.Singleton -import java.util.ArrayList -import java.util.LinkedHashSet -import java.util.List -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.IdentifierRef -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.ImportSpecifier -import org.eclipse.n4js.n4JS.ModuleRef -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.n4JS.N4JSASTUtils -import org.eclipse.n4js.n4JS.N4JSPackage -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.smith.N4JSDataCollectors -import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType -import org.eclipse.n4js.ts.types.RuntimeDependency -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.ts.types.TNamespace -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.utils.EcoreUtilN4 -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.SCCUtils -import org.eclipse.xtext.EcoreUtil2 - -/** - * Processor for computing direct load-time dependencies and import retention (during AST traversal) - * as well as load-time dependency cycles (during finalization of post-processing). - */ -@Singleton -class RuntimeDependencyProcessor { - - /** - * Invoked during AST traversal (and thus during main post-processing). - */ - def package recordRuntimeReferencesInCache(EObject node, ASTMetaInfoCache cache) { - if (node instanceof IdentifierRef) { - if (node.eContainingFeature === N4JSPackage.Literals.NAMED_EXPORT_SPECIFIER__EXPORTED_ELEMENT) { - return; // re-exports are not harmful - } - val target = node.targetElement; - if (N4JSLanguageUtils.hasRuntimeRepresentation(target)) { - cache.elementsReferencedAtRuntime += target; - // in case of namespace imports, we also want to remember that the namespace was referenced at run time: - val targetRaw = node.id; - if (targetRaw !== target && targetRaw instanceof ModuleNamespaceVirtualType) { - cache.elementsReferencedAtRuntime += targetRaw; - } - } - } else if (node instanceof N4ClassifierDeclaration) { - if (N4JSLanguageUtils.hasRuntimeRepresentation(node)) { - val targetTypeRefs = node.superClassifierRefs; - for (targetTypeRef : targetTypeRefs) { - val targetDeclType = targetTypeRef?.typeRef?.declaredType; - if (N4JSLanguageUtils.hasRuntimeRepresentation(targetDeclType)) { - cache.elementsReferencedAtRuntime += targetDeclType; - // in case of namespace imports, we also want to remember that the namespace was referenced at run time: - val namespaceLikeType = targetTypeRef.typeRefInAST?.astNamespaceLikeRefs?.head?.declaredType; - if (namespaceLikeType instanceof ModuleNamespaceVirtualType || namespaceLikeType instanceof TNamespace) { - cache.elementsReferencedAtRuntime += namespaceLikeType; - } - // remember that the target's containing module was referenced from an extends/implements clause: - val targetModule = if (!targetDeclType.eIsProxy) EcoreUtil2.getContainerOfType(targetDeclType, TModule); - if (isDifferentModuleInSameProject(targetModule, cache)) { - if (N4JSASTUtils.isTopLevelCode(node)) { // nested classifiers not supported yet, but let's be future proof - cache.modulesReferencedAtLoadtimeForInheritance += targetModule; - } - } - } - } - } - } - } - - /** - * Invoked at the end of AST traversal (and thus, during main post-processing). - *

- * Also sets the flag {@link ImportSpecifier#getRetainedAtRuntime() retainedAtRuntime}. - */ - def package void storeDirectRuntimeDependenciesInTModule(Script script, ASTMetaInfoCache cache) { - val m = N4JSDataCollectors.dcRuntimeDepsCollect.getMeasurement(); - try { - doStoreDirectRuntimeDependenciesInTModule(script, cache) - } finally { - m.close(); - } - } - - def private void doStoreDirectRuntimeDependenciesInTModule(Script script, ASTMetaInfoCache cache) { - val module = script.module; - - // step 1: set runtime retention flag in import specifiers - val importDecls = script.scriptElements.filter(ImportDeclaration).toList; - for (importDecl : importDecls) { - for (importSpec : importDecl.importSpecifiers) { - if (importSpec !== null) { - val element = switch(importSpec) { - NamedImportSpecifier: importSpec.importedElement - NamespaceImportSpecifier: importSpec.definedType - default: throw new IllegalStateException("unknown subclass of ImportSpecifier: " + importSpec.eClass.name) - }; - val retained = cache.elementsReferencedAtRuntime.contains(element); - EcoreUtilN4.doWithDeliver(false, [ - importSpec.retainedAtRuntime = retained; - ], importSpec); - } - } - } - - // step 2: derive direct runtime dependencies from runtime retention of imports - // - // NOTE: order of the dependencies is important, here, because a change in the TModule has - // significant implications (e.g. dependent modules will be rebuilt, see #isAffected() in - // incremental builder); so we want to avoid a random reordering of the same dependencies and - // therefore use a defined order derived from the order of import declarations in the AST. - // - val modulesReferencedAtRuntime = newLinkedHashSet; - val refsToOtherModules = script.scriptElements.filter(ModuleRef).filter[referringToOtherModule].toList; - for (moduleRef : refsToOtherModules) { - if (moduleRef.retainedAtRuntime) { // note: will also be true for bare imports and for all re-exports - val targetModule = moduleRef.module; - if (isDifferentModuleInSameProject(targetModule, cache)) { - modulesReferencedAtRuntime += targetModule; - } - } - } - val dependenciesRuntime = new ArrayList(modulesReferencedAtRuntime.size); - for (currModule : modulesReferencedAtRuntime) { - val currDep = TypesFactory.eINSTANCE.createRuntimeDependency(); - currDep.target = currModule; - currDep.loadtimeForInheritance = cache.modulesReferencedAtLoadtimeForInheritance.contains(currModule); - dependenciesRuntime += currDep; - } - - // step 3: store direct runtime dependencies in TModule - if (module !== null) { - EcoreUtilN4.doWithDeliver(false, [ - module.dependenciesRuntime.clear(); - module.dependenciesRuntime += dependenciesRuntime; - ], module); - } - } - - /** - * Invoked during the finalization of post-processing (and thus, after the main post-processing of all - * directly or indirectly required resources has finished). - */ - def package void computeAndStoreRuntimeCyclesInTModule(TModule module) { - val m = N4JSDataCollectors.dcRuntimeDepsFindCycles.getMeasurement(); - try { - doComputeAndStoreRuntimeCyclesInTModule(module); - } finally { - m.close(); - } - } - - def private void doComputeAndStoreRuntimeCyclesInTModule(TModule module) { - // NOTE: as above, the order of cyclicModulesRuntime and runtimeCyclicLoadtimeDependents stored in - // the TModule is important, because we want to avoid random reordering of the same set of modules - // to avoid unnecessary changes of the TModule (see above for details) - val cyclicModulesRuntime = getAllRuntimeCyclicModules(module, false); - val cyclicModulesLoadtimeForInheritance = getAllRuntimeCyclicModules(module, true); - val runtimeCyclicLoadtimeDependents = new LinkedHashSet(); - for (cyclicModule : cyclicModulesRuntime) { - if (cyclicModule.hasDirectLoadtimeDependencyTo(module)) { - runtimeCyclicLoadtimeDependents.add(cyclicModule); - } - } - - EcoreUtilN4.doWithDeliver(false, [ - module.cyclicModulesRuntime.clear(); - module.cyclicModulesLoadtimeForInheritance.clear(); - module.runtimeCyclicLoadtimeDependents.clear(); - module.cyclicModulesRuntime += cyclicModulesRuntime; - module.cyclicModulesLoadtimeForInheritance += cyclicModulesLoadtimeForInheritance; - module.runtimeCyclicLoadtimeDependents += runtimeCyclicLoadtimeDependents; - ], module); - } - - def private static List getAllRuntimeCyclicModules(TModule module, boolean onlyLoadtime) { - // Note on performance: at this point we cannot search *all* strongly connected components in the - // graph, which would be more time efficient, because we are operating on a potentially (and usually) - // incomplete runtime dependency graph during the build. The only thing we can rely on is that the - // direct runtime dependencies of modules in our containing strongly connected component are up to - // date. Therefore, we are here only searching the SCC of 'module' (i.e. pass only 'module' as first - // argument to SCCUtils#findSCCs()) and do not make use of a more sophisticated algorithm for finding - // all SCCs such as Johnson's algorithm (cf. Johnson, SIAM Journal on Computing, Vol. 4, No. 1, 1975). - val sccs = SCCUtils.findSCCs(Iterators.singletonIterator(module), [m| - m.dependenciesRuntime.filter[!onlyLoadtime || isLoadtimeForInheritance].map[target] - ]); - val cyclicModules = sccs.filter[remove(module)].head; - return cyclicModules; - } - - def private boolean hasDirectLoadtimeDependencyTo(TModule from, TModule to) { - return from.dependenciesRuntime.exists[isLoadtimeForInheritance && target === to]; - } - - def private static boolean isDifferentModuleInSameProject(TModule module, ASTMetaInfoCache cache) { - return module !== null && !module.eIsProxy - && module.eResource !== cache.resource - && module.projectID == cache.projectID; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeDeferredProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeDeferredProcessor.java new file mode 100644 index 0000000000..0af681cbc4 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeDeferredProcessor.java @@ -0,0 +1,170 @@ +/** + * 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.postprocessing; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.getContextResource; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4GetterDeclaration; +import org.eclipse.n4js.n4JS.N4JSASTUtils; +import org.eclipse.n4js.n4JS.N4MethodDeclaration; +import org.eclipse.n4js.n4JS.PropertyMethodDeclaration; +import org.eclipse.n4js.n4JS.SetterDeclaration; +import org.eclipse.n4js.n4JS.TypedElement; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.ts.typeRefs.DeferredTypeRef; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.ThisTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeArgument; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory; +import org.eclipse.n4js.ts.types.ContainerType; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.TTypedElement; +import org.eclipse.n4js.ts.types.TVariable; +import org.eclipse.n4js.ts.types.TypableElement; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.n4js.utils.EcoreUtilN4; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +/** + * Processor for handling {@link DeferredTypeRef}s, except those related to poly expressions, which are handled + * by the {@link PolyProcessor}s. + */ +@Singleton +class TypeDeferredProcessor extends AbstractProcessor { + + @Inject + private N4JSTypeSystem ts; + @Inject + private TypeSystemHelper tsh; + + void handleDeferredTypeRefs_preChildren(RuleEnvironment G, EObject astNode, ASTMetaInfoCache cache) { + // DeferredTypeRefs related to poly expressions should not be handled here (poly computer responsible for this!) + if (astNode instanceof N4MethodDeclaration) { + N4MethodDeclaration md = (N4MethodDeclaration) astNode; + TypeRef declReturnTypeRefInAST = md.getDeclaredReturnTypeRefNode() == null ? null + : md.getDeclaredReturnTypeRefNode().getTypeRefInAST(); + if (md.isConstructor()) { + TMethod tCtor = (TMethod) md.getDefinedType(); + if (null != tCtor) { + assertTrueIfRigid(cache, "TMethod in TModule should be a constructor", tCtor.isConstructor()); + assertTrueIfRigid(cache, "return type of constructor in TModule should be a DeferredTypeRef", + tCtor.getReturnTypeRef() instanceof DeferredTypeRef); + TypeRef implicitReturnTypeRef = TypeRefsFactory.eINSTANCE.createThisTypeRefNominal(); + TypeRef boundThisTypeRef = tsh.bindAndSubstituteThisTypeRef(G, md, implicitReturnTypeRef); + EcoreUtilN4.doWithDeliver(false, () -> { + tCtor.setReturnValueMarkedOptional(true); + tCtor.setReturnTypeRef(TypeUtils.copy(boundThisTypeRef)); + }, tCtor); + } + } else if (declReturnTypeRefInAST instanceof ThisTypeRef) { + TMethod tMethod = (TMethod) md.getDefinedType(); + if (null != tMethod) { + assertTrueIfRigid(cache, "return type of TMethod in TModule should be a DeferredTypeRef", + tMethod.getReturnTypeRef() instanceof DeferredTypeRef); + TypeRef boundThisTypeRef = tsh.bindAndSubstituteThisTypeRef(G, declReturnTypeRefInAST, + declReturnTypeRefInAST); + EcoreUtilN4.doWithDeliver(false, () -> tMethod.setReturnTypeRef(TypeUtils.copy(boundThisTypeRef)), + tMethod); + } + } + + } else if (astNode instanceof N4GetterDeclaration) { + N4GetterDeclaration gd = (N4GetterDeclaration) astNode; + TypeRef declReturnTypeRefInAST = gd.getDeclaredTypeRefNode() == null ? null + : gd.getDeclaredTypeRefNode().getTypeRefInAST(); + if (declReturnTypeRefInAST instanceof ThisTypeRef) { + TGetter tGetter = gd.getDefinedGetter(); + assertTrueIfRigid(cache, "return type of TGetter in TModule should be a DeferredTypeRef", + tGetter.getTypeRef() instanceof DeferredTypeRef); + // G |~ methodDecl.returnTypeRef ~> boundThisTypeRef + TypeRef boundThisTypeRef = tsh.getThisTypeAtLocation(G, declReturnTypeRefInAST); + EcoreUtilN4.doWithDeliver(false, () -> tGetter.setTypeRef(TypeUtils.copy(boundThisTypeRef)), tGetter); + } + } + } + + void handleDeferredTypeRefs_postChildren(RuleEnvironment G, EObject astNode, ASTMetaInfoCache cache) { + // DeferredTypeRefs related to poly expressions should not be handled here (poly computer responsible for this!) + if (astNode instanceof VariableDeclaration) { + VariableDeclaration vd = (VariableDeclaration) astNode; + TVariable tVariable = vd.getDefinedVariable(); + setTypeRef(vd, tVariable, false, G, cache); + } else if (astNode instanceof N4FieldDeclaration) { + N4FieldDeclaration fd = (N4FieldDeclaration) astNode; + TField tField = fd.getDefinedField(); + setTypeRef(fd, tField, true, G, cache); + } else if (astNode instanceof FormalParameter) { + FormalParameter fp = (FormalParameter) astNode; + EObject parent = astNode.eContainer(); + if (parent instanceof FunctionExpression) { + // do nothing since its DeferredTypes are computed in PolyProcessor_FunctionExpression + } else if (parent instanceof PropertyMethodDeclaration) { + // do nothing since its DeferredTypes are computed in PolyProcessor_ObjectLiteral + } else if (parent instanceof FunctionDefinition) { + TFormalParameter tFPar = fp.getDefinedVariable(); // tFPar can be null if we have a broken AST + if (tFPar != null && tFPar.getTypeRef() instanceof DeferredTypeRef) { + setTypeRef(fp, tFPar, true, G, cache); + } + } else if (parent instanceof SetterDeclaration) { + // do nothing since setters don't have Deferred Types (and cannot have a default initializer) + } else { + throw new IllegalArgumentException("Unsupported parent type of FormalParameter"); + } + } + } + + private void setTypeRef(T elemInAST, TTypedElement elemInTModule, + boolean useContext, + RuleEnvironment G, ASTMetaInfoCache cache) { + + if (elemInAST.getDeclaredTypeRef() == null) { + if (elemInTModule != null) { // note: tte==null happens if obj.name==null (see types builder) + assertTrueIfRigid(cache, + "return type of " + elemInAST.getClass().getName() + " in TModule should be a DeferredTypeRef", + elemInTModule.getTypeRef() instanceof DeferredTypeRef); + + RuleEnvironment G2 = G; + if (useContext) { + ParameterizedTypeRef context = null; + if (elemInTModule.eContainer() instanceof ContainerType) { + context = TypeUtils.createTypeRef((ContainerType) elemInTModule.eContainer()); + } + G2 = ts.createRuleEnvironmentForContext(context, getContextResource(G)); + } + // delegate to rule caseN4FieldDeclaration, etc. + TypeArgument typeRef = invokeTypeJudgmentToInferType(G2, elemInAST); + if (useContext) { + typeRef = ts.substTypeVariables(G2, typeRef); + } + // this runs after TypeAliasProcessor, so we need to resolve here + TypeArgument typeRefResolved = tsh.resolveTypeAliases(G, typeRef); + TypeRef typeRefSane = tsh.sanitizeTypeOfVariableFieldPropertyParameter(G, typeRefResolved, + !N4JSASTUtils.isImmutable(elemInAST)); + EcoreUtilN4.doWithDeliver(false, () -> elemInTModule.setTypeRef(TypeUtils.copy(typeRefSane)), + elemInTModule); + } + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeDeferredProcessor.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeDeferredProcessor.xtend deleted file mode 100644 index aa5dfaf8bc..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeDeferredProcessor.xtend +++ /dev/null @@ -1,164 +0,0 @@ -/** - * 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.postprocessing - -import com.google.inject.Inject -import com.google.inject.Singleton -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.FormalParameter -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.FunctionExpression -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.N4GetterDeclaration -import org.eclipse.n4js.n4JS.N4JSASTUtils -import org.eclipse.n4js.n4JS.N4MethodDeclaration -import org.eclipse.n4js.n4JS.PropertyMethodDeclaration -import org.eclipse.n4js.n4JS.SetterDeclaration -import org.eclipse.n4js.n4JS.TypedElement -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.ts.typeRefs.DeferredTypeRef -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.typeRefs.ThisTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeArgument -import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory -import org.eclipse.n4js.ts.types.ContainerType -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.ts.types.TTypedElement -import org.eclipse.n4js.ts.types.TypableElement -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper -import org.eclipse.n4js.utils.EcoreUtilN4 - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * Processor for handling {@link DeferredTypeRef}s, except those related to poly expressions, which are handled - * by the {@link PolyProcessor}s. - */ -@Singleton -package class TypeDeferredProcessor extends AbstractProcessor { - - @Inject - private N4JSTypeSystem ts; - @Inject - private TypeSystemHelper tsh; - - def void handleDeferredTypeRefs_preChildren(RuleEnvironment G, EObject astNode, ASTMetaInfoCache cache) { - // DeferredTypeRefs related to poly expressions should not be handled here (poly computer responsible for this!) - switch (astNode) { - N4MethodDeclaration: { - val declReturnTypeRefInAST = astNode.declaredReturnTypeRefNode?.typeRefInAST; - if (astNode.isConstructor) { - val tCtor = astNode.definedType as TMethod; - if (null !== tCtor) { - assertTrueIfRigid(cache, "TMethod in TModule should be a constructor", tCtor.isConstructor); - assertTrueIfRigid(cache, "return type of constructor in TModule should be a DeferredTypeRef", - tCtor.returnTypeRef instanceof DeferredTypeRef); - val implicitReturnTypeRef = TypeRefsFactory.eINSTANCE.createThisTypeRefNominal; - val boundThisTypeRef = tsh.bindAndSubstituteThisTypeRef(G, astNode, implicitReturnTypeRef); - EcoreUtilN4.doWithDeliver(false, [ - tCtor.returnValueMarkedOptional = true; - tCtor.returnTypeRef = TypeUtils.copy(boundThisTypeRef); - ], tCtor); - } - } else if (declReturnTypeRefInAST instanceof ThisTypeRef) { - val tMethod = astNode.definedType as TMethod; - if (null !== tMethod) { - assertTrueIfRigid(cache, "return type of TMethod in TModule should be a DeferredTypeRef", - tMethod.returnTypeRef instanceof DeferredTypeRef); - val boundThisTypeRef = tsh.bindAndSubstituteThisTypeRef(G, declReturnTypeRefInAST, declReturnTypeRefInAST); - EcoreUtilN4.doWithDeliver(false, [ - tMethod.returnTypeRef = TypeUtils.copy(boundThisTypeRef); - ], tMethod); - } - } - } - N4GetterDeclaration: { - val declReturnTypeRefInAST = astNode.declaredTypeRefNode?.typeRefInAST; - if (declReturnTypeRefInAST instanceof ThisTypeRef) { - val tGetter = astNode.definedGetter; - assertTrueIfRigid(cache, "return type of TGetter in TModule should be a DeferredTypeRef", - tGetter.typeRef instanceof DeferredTypeRef); - val boundThisTypeRef = tsh.getThisTypeAtLocation(G, declReturnTypeRefInAST); // G |~ methodDecl.returnTypeRef ~> boundThisTypeRef - EcoreUtilN4.doWithDeliver(false, [ - tGetter.typeRef = TypeUtils.copy(boundThisTypeRef); - ], tGetter); - } - } - }; - } - - def void handleDeferredTypeRefs_postChildren(RuleEnvironment G, EObject astNode, ASTMetaInfoCache cache) { - // DeferredTypeRefs related to poly expressions should not be handled here (poly computer responsible for this!) - switch (astNode) { - VariableDeclaration: { - val tVariable = astNode.definedVariable; - setTypeRef(astNode, tVariable, false, G, cache); - } - N4FieldDeclaration: { - val tField = astNode.definedField; - setTypeRef(astNode, tField, true, G, cache); - } - FormalParameter: { - val parent = astNode.eContainer; - switch (parent) { - FunctionExpression: { - // do nothing since its DeferredTypes are computed in PolyProcessor_FunctionExpression - } - PropertyMethodDeclaration: { - // do nothing since its DeferredTypes are computed in PolyProcessor_ObjectLiteral - } - FunctionDefinition: { - val tFPar = astNode.definedVariable; // tFPar can be null if we have a broken AST - if (tFPar?.typeRef instanceof DeferredTypeRef) { - setTypeRef(astNode, tFPar, true, G, cache); - } - } - SetterDeclaration: { - // do nothing since setters don't have Deferred Types (and cannot have a default initializer) - } - default: - throw new IllegalArgumentException("Unsupported parent type of FormalParameter") - } - } - } - } - - private def void setTypeRef(T elemInAST, TTypedElement elemInTModule, boolean useContext, - RuleEnvironment G, ASTMetaInfoCache cache) { - - if (elemInAST.declaredTypeRef === null) { - if (elemInTModule !== null) { // note: tte===null happens if obj.name===null (see types builder) - assertTrueIfRigid(cache, "return type of "+ elemInAST.class.name +" in TModule should be a DeferredTypeRef", - elemInTModule.typeRef instanceof DeferredTypeRef); - - var RuleEnvironment G2 = G; - if (useContext) { - var ParameterizedTypeRef context = null; - if (elemInTModule.eContainer instanceof ContainerType) - context = TypeUtils.createTypeRef(elemInTModule.eContainer as ContainerType); - G2 = ts.createRuleEnvironmentForContext(context, G.contextResource); - } - var TypeArgument typeRef = invokeTypeJudgmentToInferType(G2, elemInAST); // delegate to rule caseN4FieldDeclaration, etc. - if (useContext) { - typeRef = ts.substTypeVariables(G2, typeRef); - } - val typeRefResolved = tsh.resolveTypeAliases(G, typeRef); // this runs after TypeAliasProcessor, so we need to resolve here - val typeRefSane = tsh.sanitizeTypeOfVariableFieldPropertyParameter(G, typeRefResolved, !N4JSASTUtils.isImmutable(elemInAST)); - EcoreUtilN4.doWithDeliver(false, [ - elemInTModule.typeRef = TypeUtils.copy(typeRefSane); - ], elemInTModule); - } - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeProcessor.java new file mode 100644 index 0000000000..14d165f341 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeProcessor.java @@ -0,0 +1,480 @@ +/** + * 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.postprocessing; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.anyTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.getCancelIndicator; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.wrapTypeInTypeRef; +import static org.eclipse.n4js.utils.N4JSLanguageUtils.getDefinedTypeModelElement; +import static org.eclipse.n4js.utils.N4JSLanguageUtils.isASTNode; +import static org.eclipse.n4js.utils.N4JSLanguageUtils.isTypableNode; +import static org.eclipse.n4js.utils.N4JSLanguageUtils.isTypeModelElement; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.isEmpty; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.n4js.n4JS.DestructureUtils; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.FieldAccessor; +import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor; +import org.eclipse.n4js.n4JS.N4ClassExpression; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4JSASTUtils; +import org.eclipse.n4js.n4JS.NewExpression; +import org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.n4JS.TypeDefiningElement; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.YieldExpression; +import org.eclipse.n4js.resource.N4JSResource; +import org.eclipse.n4js.ts.typeRefs.DeferredTypeRef; +import org.eclipse.n4js.ts.typeRefs.OptionalFieldStrategy; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory; +import org.eclipse.n4js.ts.typeRefs.TypeTypeRef; +import org.eclipse.n4js.ts.types.SyntaxRelatedTElement; +import org.eclipse.n4js.ts.types.TypableElement; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.xtext.service.OperationCanceledManager; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +/** + * Processor for handling type inference during post-processing of an N4JS resource. Roughly corresponds to 'type' + * judgment in Xsemantics, but handles also more complex cases, e.g. poly expressions. + *

+ * Invoked from {@link ASTProcessor} and delegates to {@link PolyProcessor}s. + */ +@Singleton +public class TypeProcessor extends AbstractProcessor { + + @Inject + private ASTProcessor astProcessor; + @Inject + private PolyProcessor polyProcessor; + @Inject + private DestructureProcessor destructureProcessor; + @Inject + private N4JSTypeSystem ts; + @Inject + private TypeSystemHelper tsh; + @Inject + private OperationCanceledManager operationCanceledManager; + + /** + * If the given AST node is typable this method will infer its type and store the result in the given cache. + *

+ * This method mainly checks if the given node is typable. Main processing is done in + * {@link #typeNode2(RuleEnvironment, TypableElement, ASTMetaInfoCache, int) typeNode2()}. + */ + public void typeNode(RuleEnvironment G, EObject node, ASTMetaInfoCache cache, int indentLevel) { + if (isTypableNode(node)) { + TypableElement nodeCasted = (TypableElement) node; // because #isTypableNode() returned true + // we have a typable node + if (DestructureUtils.isArrayOrObjectLiteralUsedAsDestructuringPattern(node) + && polyProcessor.isEntryPoint(nodeCasted)) { + // special case: array or object literal being used as a destructuring pattern + log(indentLevel, "ignored (array or object literal being used as a destructuring pattern)"); + destructureProcessor.typeDestructuringPattern(G, node, cache); + + } else { + // standard case + typeNode2(G, nodeCasted, cache, indentLevel); + } + } else { + // not a typable node + log(indentLevel, "ignored (not a typable node: " + + (node == null || node.eClass() == null ? null : node.eClass().getName()) + ")"); + } + } + + /** + * Infers type of given AST node and stores the result in the given cache. + *

+ * More precisely: + *

    + *
  1. if given node is part of a poly expression: + *
      + *
    1. if given node is the root of a tree of nested poly expressions (including the case that node is a poly + * expression without any nested poly expressions):
      + * --> inference of entire tree of nested poly expressions AND storage of all results in cache is delegated to class + * {@link PolyProcessor}. + *
    2. otherwise:
      + * --> ignore this node ({@code PolyProcessor} will deal with it when processing the parent poly expression) + *
    + *
  2. otherwise (standard case):
    + * --> infer type of node by asking the TypeJudgment and store the result in the given cache. + *
+ */ + private void typeNode2(RuleEnvironment G, TypableElement node, ASTMetaInfoCache cache, int indentLevel) { + try { + if (polyProcessor.isResponsibleFor(node)) { + if (polyProcessor.isEntryPoint(node)) { + log(indentLevel, "asking PolyComputer ..."); + polyProcessor.inferType(G, (Expression) node, cache); + // in this case, the polyComputer will store the type in the cache; + // also, the poly computer is responsible for replacing all DeferredTypeRefs + assertTrueIfRigid(cache, "poly computer did not replace DeferredTypeRef", () -> { + EObject typeModelElem = getDefinedTypeModelElement(node); + return typeModelElem == null + || isEmpty(filter(typeModelElem.eAllContents(), DeferredTypeRef.class)); + }); + } else { + // we have a poly expression, but one that is nested in another poly expression + // -> ignore here, because polyProcessor will deal with it when processing the parent poly + // expression + log(indentLevel, + "deferred (nested in poly expression --> will be inferred during inference of outer poly expression)"); + + cache.nonEntryPolyProcessorNodes.add(node); + + return; // return only required to avoid confusing logging of cache.getFailSafe(node) below + } + } else { + // ordinary typing of typable AST nodes by asking the TypeJudgment + log(indentLevel, "asking Xsemantics ..."); + TypeRef result = invokeTypeJudgmentToInferType(G, node); + + TypeRef resultAdjusted = adjustResultForLocationInAST(G, result, node); + + // in this case, we are responsible for storing the type in the cache + // (Xsemantics does not know of the cache) + checkCanceled(G); + cache.storeType(node, resultAdjusted); + } + } catch (Throwable th) { + operationCanceledManager.propagateIfCancelException(th); + logException("exception while obtaining type from type system: " + th.getMessage(), th); + th.printStackTrace(); + cache.storeType(node, TypeRefsFactory.eINSTANCE.createUnknownTypeRef()); + } + + log(indentLevel, cache.getTypeFailSafe(node)); + } + + private T adjustResultForLocationInAST(RuleEnvironment G, T typeRef, TypableElement astNode) { + var result = typeRef; + result = adjustForIndexSignatures(result, astNode); + result = adjustForLocationDependentSpecialProperties(G, result, astNode); + return result; + } + + /** + * Poor man's support for index signatures (intended only for .d.ts but must also be checked in N4JS, because N4JS + * may contain classifiers that extend a classifier from .d.ts containing an index signature). + *

+ * TODO IDE-3620 remove this method once index signatures are properly supported + */ + @SuppressWarnings("unchecked") + private T adjustForIndexSignatures(T typeRef, TypableElement astNode) { + EObject parent = astNode == null ? null : astNode.eContainer(); + if (parent instanceof ParameterizedPropertyAccessExpression) { + ParameterizedPropertyAccessExpression ppae = (ParameterizedPropertyAccessExpression) parent; + if (astNode == ppae.getTarget() && !typeRef.isDynamic()) { + if (typeRef instanceof ParameterizedTypeRef) { + if (N4JSLanguageUtils.hasIndexSignature(typeRef)) { + ParameterizedTypeRef typeRefCpy = TypeUtils.copy((ParameterizedTypeRef) typeRef); + typeRefCpy.setDynamic(true); + return (T) typeRefCpy; + } + } + } + } + return typeRef; + } + + /** + * Make sure that the value of the two location-dependent special properties typeOfObjectLiteral and + * typeOfNewExpressionOrFinalNominal in {@link ParameterizedTypeRef} correctly reflect the current + * location in the AST, i.e. the the location of the given astNode, no matter where the type reference + * in the given result stems from. + */ + @SuppressWarnings("unchecked") + private T adjustForLocationDependentSpecialProperties(RuleEnvironment G, T result, + TypableElement astNode) { + T typeRef = result; + if (typeRef instanceof ParameterizedTypeRef) { + TypableElement astNodeSkipParen = N4JSASTUtils.skipParenExpressionDownward(astNode); + OptionalFieldStrategy optionalFieldStrategy = N4JSLanguageUtils.calculateOptionalFieldStrategy(ts, G, + astNodeSkipParen, typeRef); + if (typeRef.getASTNodeOptionalFieldStrategy() != optionalFieldStrategy) { + ParameterizedTypeRef typeRefCpy = TypeUtils.copy((ParameterizedTypeRef) typeRef); + // TODO: also remember the cause for opt-field-strat! + typeRefCpy.setASTNodeOptionalFieldStrategy(optionalFieldStrategy); + return (T) typeRefCpy; + } + } + return result; + } + + // --------------------------------------------------------------------------------------------------------------- + + /** + * This is the single, central method for obtaining the type of a typable element (AST node or TModule element). + * It should never be invoked directly by client code! Instead, client code should always call + * {@link N4JSTypeSystem#type(RuleEnvironment,TypableElement) N4JSTypeSystem#type()}. + *

+ * The behavior of this method depends on the state the containing {@link N4JSResource} is in: + *

    + *
  • before post-processing has started:
    + * -> simply initiate post-processing; once it's finished, return type from AST meta-info cache. + *
  • during post-processing: + *
      + *
    • in case of a backward reference:
      + * -> simply return type from AST meta-info cache. + *
    • in case of a forward reference:
      + * -> trigger forward-processing of the identifiable subtree below the given typable element, see + * {@link #getTypeOfForwardReference(RuleEnvironment,TypableElement,ASTMetaInfoCache) #getTypeOfForwardReference()}, + * which delegates to + * {@link ASTProcessor#processSubtree_forwardReference( RuleEnvironment,TypableElement,ASTMetaInfoCache) + * ASTProcessor#processSubtree_forwardReference()}. + *
    + *
  • after post-processing has completed:
    + * -> simply return type from AST meta-info cache. + *
+ * This overview is simplified, check the code for precise rules! + *

+ * Only a single method delegates here (no one else should call this method): + *

    + *
  1. {@link N4JSTypeSystem#type(RuleEnvironment,TypableElement)} + *
+ */ + public TypeRef getType(RuleEnvironment G, TypableElement objRaw) { + + if (objRaw == null) { + // failing safely here; otherwise we would need preemptive null-checks wherever type inference is applied + return TypeRefsFactory.eINSTANCE.createUnknownTypeRef(); + } + + TypableElement obj = objRaw; + if (objRaw.eIsProxy()) { + ResourceSet resSet = RuleEnvironmentExtensions.getContextResource(G).getResourceSet(); + obj = (TypableElement) EcoreUtil.resolve(objRaw, resSet); + } + + Resource res = obj.eResource(); + if (res instanceof N4JSResource) { + N4JSResource n4Res = (N4JSResource) res; + + if (n4Res.isFullyProcessed() && n4Res.getScript().eIsProxy()) { + // special case: this is a resource loaded from the index! + // -> for now, we entirely by-pass ASTMetaInfoCache and just directly wrap the type model element in a + // TypeRef + if (!isTypeModelElement(obj)) { + throw new IllegalStateException("not a type model element: " + obj); + } + return invokeTypeJudgmentToInferType(G, obj); // obj is a type model element, so this will just wrap it + // in a TypeRef (no actual inference) + } + + // make sure post-processing on the containing N4JS resource is initiated + n4Res.performPostProcessing(getCancelIndicator(G)); + + // NOTE: at this point, we know: if *before* the above call to #performPostProcessing() ... + // a) post-processing of 'res' had not been started yet: it will now be *completed* + // b) post-processing of 'res' was in progress: it will now still be *in progress* + // c) post-processing of 'res' was completed: it will now still be *completed* + // See API doc of method PostProcessingAwareResource#performPostProcessing(CancelIndicator). + + // if post-processing is in progress AND 'obj' is a type model element AND it corresponds to an AST node + // --> redirect processing to the AST node, in order to properly handle backward/forward references, esp. + // forward processing of identifiable subtrees + if (n4Res.isPostProcessing() && isTypeModelElement(obj)) { + EObject astNodeToProcess = (obj instanceof SyntaxRelatedTElement) + // NOTE: we've made sure above that we are *NOT* in a Resource loaded from the index! + ? ((SyntaxRelatedTElement) obj).getAstElement() + : null; + boolean isImplicitArgumentsVariable = (astNodeToProcess instanceof FunctionOrFieldAccessor) + ? ((FunctionOrFieldAccessor) astNodeToProcess).getImplicitArgumentsVariable() == obj + : false; + if (!isImplicitArgumentsVariable) { + if (astNodeToProcess instanceof TypableElement) { + // proceed with the corresponding AST node instead of the type model element + obj = (TypableElement) astNodeToProcess; + } + } + } + + // obtain type of 'obj' + return getTypeInN4JSResource(G, n4Res, obj); + + } else { + + // obj not contained in an N4JSResource -> fall back to default behavior + // can happen for: + // - objects that are not contained in a Resource + // - objects that are contained in a Resource but not an N4JSResource + return invokeTypeJudgmentToInferType(G, obj); + } + } + + /** See {@link TypeProcessor#getType(RuleEnvironment, TypableElement)}. */ + private TypeRef getTypeInN4JSResource(RuleEnvironment G, N4JSResource res, TypableElement obj) { + // obtain type of 'obj' depending on whether it's an AST node or type model element AND depending on current + // load state of containing N4JS resource + if (isTypeModelElement(obj)) { + // for type model elements, we by-pass all caching ... + return invokeTypeJudgmentToInferType(G, obj); // obj is a type model element, so this will just wrap it in a + // TypeRef (no actual inference) + } else if (isASTNode(obj) && isTypableNode(obj)) { + // here we read from the cache (if AST node 'obj' was already processed) or forward-process 'obj' + ASTMetaInfoCache cache = res.getASTMetaInfoCacheVerifyContext(); + if (!res.isPostProcessing() && !res.isFullyProcessed()) { + // we have called #performPostProcessing() on the containing resource above, so this is "impossible" + throw new IllegalStateException( + "post-processing neither in progress nor completed after calling #performPostProcessing() in resource: " + + res.getURI()); + } else if (!cache.isPostProcessing() && !cache.isFullyProcessed()) { + // "res.isProcessing() || res.isFullyProcessed()" but not "cache.isProcessing || cache.isFullyProcessed" + // so: the post-processing flags are out of sync between the resource and cache + // (HINT: if you get an exception here, this often indicates an accidental cache clear; use the + // debug code in ASTMetaInfoCacheHelper to track creation/deletion of typing caches to investigate this) + IllegalStateException e = new IllegalStateException( + "post-processing flags out of sync between resource and cache (hint: this is often caused by an accidental cache clear!!)"); + e.printStackTrace(); // make sure we see this on the console (some clients eat up all exceptions!) + throw e; + } else if (cache.isPostProcessing()) { + + // while AST typing is in progress, just read from the cache we are currently filling + TypeRef resultFromCache = cache.getTypeFailSafe(obj); + + if (resultFromCache == null) { + // cache does not contain type for 'obj' (i.e. not processed yet) + // -> we have a forward reference! + log(0, "***** forward reference to: " + obj); + + return getTypeOfForwardReference(G, obj, cache); + } else { + // cache contains a type for 'obj' (i.e. it was already processed) + // -> simply read from cache + return resultFromCache; + } + } else if (cache.isFullyProcessed()) { + return cache.getType(G, obj); // will throw exception in case of cache miss + } + // should not happen + return TypeRefsFactory.eINSTANCE.createUnknownTypeRef(); + } else { + // a non-typable AST node OR some entity in the TModule for which obj.isTypeModelElement returns false + return TypeRefsFactory.eINSTANCE.createUnknownTypeRef(); + } + } + + /** See {@link TypeProcessor#getType(RuleEnvironment, TypableElement)}. */ + private TypeRef getTypeOfForwardReference(RuleEnvironment G, TypableElement node, ASTMetaInfoCache cache) { + assertTrueIfRigid(cache, "argument 'node' must be an AST node", isASTNode(node)); + + // TODO improve handling of destructuring patterns in ASTProcessor/TypeProcessor + // (this is a temporary hack to avoid many illegal forward references within destructuring patterns) + if (destructureProcessor.isForwardReferenceWhileTypingDestructuringPattern(node)) { + return destructureProcessor.handleForwardReferenceWhileTypingDestructuringPattern(G, node, cache); + } + + boolean isLegal = astProcessor.processSubtree_forwardReference(G, node, cache); + if (isLegal) { + boolean isCyclicForwardReference = cache.astNodesCurrentlyBeingTyped.contains(node); + if (isCyclicForwardReference) { + // in case of a legal cyclic forward reference, we cannot obtain the type of 'node' in the usual + // way by fully processing 'node' and its subtree, so we have to "guess" a type + if (node instanceof VariableDeclaration || node instanceof N4FieldDeclaration || + node instanceof PropertyNameValuePair) { + + Expression expr = getExpressionOfVFP(node); + if (expr instanceof N4ClassExpression) { + return invokeTypeJudgmentToInferType(G, expr); + } + if (expr instanceof NewExpression) { + Expression callee = ((NewExpression) expr).getCallee(); + if (callee instanceof N4ClassExpression) { + TypeRef calleeType = invokeTypeJudgmentToInferType(G, callee); + Type calleeTypeStaticType = tsh.getStaticType(G, (TypeTypeRef) calleeType); + return TypeUtils.createTypeRef(calleeTypeStaticType); + } + } + TypeRef declTypeRef = getDeclaredTypeRefOfVFP(node); + return (declTypeRef != null) ? declTypeRef : anyTypeRef(G); + } else if (node instanceof FieldAccessor) { + TypeRef declTypeRef = ((FieldAccessor) node).getDeclaredTypeRef(); + return (declTypeRef != null) ? declTypeRef : anyTypeRef(G); + } else if (node instanceof TypeDefiningElement) { + return wrapTypeInTypeRef(G, ((TypeDefiningElement) node).getDefinedType()); + } else if (node instanceof Expression && node.eContainer() instanceof YieldExpression) { + return invokeTypeJudgmentToInferType(G, node); + } else { + String msg = "handling of a legal case of cyclic forward references missing in TypeProcessor"; + logErr(msg); + IllegalStateException e = new IllegalStateException(msg); + e.printStackTrace(); + return TypeRefsFactory.eINSTANCE.createUnknownTypeRef(); + } + } else if (astProcessor.isSemiCyclicForwardReferenceInForLoop(node, cache)) { + // semi-cyclic forward reference to a variable declaration in a for in/of loop: + // -> similar to cyclic variable declarations, we have to "guess" a type. + TypeReferenceNode declTypeRefNode = ((VariableDeclaration) node).getDeclaredTypeRefNode(); + TypeRef declTypeRefInAST = declTypeRefNode == null ? null : declTypeRefNode.getTypeRefInAST(); + if (declTypeRefInAST != null && declTypeRefNode != null) { + if (declTypeRefNode.getCachedProcessedTypeRef() != null) { + return declTypeRefNode.getCachedProcessedTypeRef(); + } else { + return tsh.resolveTypeAliases(G, declTypeRefInAST); + } + } + + return anyTypeRef(G); + } else { + // in case of a legal, *non*-cyclic forward reference, we can assume that the subtree below 'node' + // has now been processed, which means node's type is now in the typing cache + return cache.getType(G, node); + } + } else { + String msg = "*#*#*#*#*#* ILLEGAL FORWARD REFERENCE to " + node + + " in " + (node.eResource() == null ? null : node.eResource().getURI()); + logErr(msg); + return TypeRefsFactory.eINSTANCE.createUnknownTypeRef(); + } + } + + // --------------------------------------------------------------------------------------------------------------- + + private static Expression getExpressionOfVFP(EObject vfp) { + if (vfp instanceof VariableDeclaration) { + return ((VariableDeclaration) vfp).getExpression(); + } else if (vfp instanceof N4FieldDeclaration) { + return ((N4FieldDeclaration) vfp).getExpression(); + } else if (vfp instanceof PropertyNameValuePair) { + return ((PropertyNameValuePair) vfp).getExpression(); + } + return null; + } + + private static TypeRef getDeclaredTypeRefOfVFP(EObject vfp) { + if (vfp instanceof VariableDeclaration) { + return ((VariableDeclaration) vfp).getDeclaredTypeRef(); + } else if (vfp instanceof N4FieldDeclaration) { + return ((N4FieldDeclaration) vfp).getDeclaredTypeRef(); + } else if (vfp instanceof PropertyNameValuePair) { + return ((PropertyNameValuePair) vfp).getDeclaredTypeRef(); + } + return null; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeProcessor.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeProcessor.xtend deleted file mode 100644 index f5a5de20b2..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeProcessor.xtend +++ /dev/null @@ -1,456 +0,0 @@ -/** - * 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.postprocessing - -import com.google.inject.Inject -import com.google.inject.Singleton -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.util.EcoreUtil -import org.eclipse.n4js.n4JS.DestructureUtils -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.FieldAccessor -import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor -import org.eclipse.n4js.n4JS.N4ClassExpression -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.N4JSASTUtils -import org.eclipse.n4js.n4JS.NewExpression -import org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression -import org.eclipse.n4js.n4JS.PropertyNameValuePair -import org.eclipse.n4js.n4JS.TypeDefiningElement -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.n4JS.YieldExpression -import org.eclipse.n4js.resource.N4JSResource -import org.eclipse.n4js.ts.typeRefs.DeferredTypeRef -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory -import org.eclipse.n4js.ts.typeRefs.TypeTypeRef -import org.eclipse.n4js.ts.types.SyntaxRelatedTElement -import org.eclipse.n4js.ts.types.TypableElement -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.xtext.service.OperationCanceledManager - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* -import static extension org.eclipse.n4js.utils.N4JSLanguageUtils.* - -/** - * Processor for handling type inference during post-processing of an N4JS resource. Roughly corresponds to - * 'type' judgment in Xsemantics, but handles also more complex cases, e.g. poly expressions. - *

- * Invoked from {@link ASTProcessor} and delegates to {@link PolyProcessor}s. - */ -@Singleton -public class TypeProcessor extends AbstractProcessor { - - @Inject - private ASTProcessor astProcessor; - @Inject - private PolyProcessor polyProcessor; - @Inject - private DestructureProcessor destructureProcessor; - @Inject - private N4JSTypeSystem ts; - @Inject - private TypeSystemHelper tsh; - @Inject - private OperationCanceledManager operationCanceledManager; - - - /** - * If the given AST node is typable this method will infer its type and store the result in the given cache. - *

- * This method mainly checks if the given node is typable. Main processing is done in - * {@link #typeNode2(RuleEnvironment, TypableElement, ASTMetaInfoCache, int) typeNode2()}. - */ - def public void typeNode(RuleEnvironment G, EObject node, ASTMetaInfoCache cache, int indentLevel) { - if (node.isTypableNode) { - val nodeCasted = node as TypableElement; // because #isTypableNode() returned true - // we have a typable node - if (DestructureUtils.isArrayOrObjectLiteralUsedAsDestructuringPattern(node) - && polyProcessor.isEntryPoint(nodeCasted)) { - // special case: array or object literal being used as a destructuring pattern - log(indentLevel, "ignored (array or object literal being used as a destructuring pattern)") - destructureProcessor.typeDestructuringPattern(G, node, cache, indentLevel); - - } else { - // standard case - typeNode2(G, nodeCasted, cache, indentLevel); - } - } else { - // not a typable node - log(indentLevel, "ignored (not a typable node: " + node?.eClass?.name + ")") - } - } - - /** - * Infers type of given AST node and stores the result in the given cache. - *

- * More precisely: - *

    - *
  1. if given node is part of a poly expression: - *
      - *
    1. if given node is the root of a tree of nested poly expressions (including the case that node is a poly - * expression without any nested poly expressions):
      - * --> inference of entire tree of nested poly expressions AND storage of all results in cache is delegated - * to class {@link PolyProcessor}. - *
    2. otherwise:
      - * --> ignore this node ({@code PolyProcessor} will deal with it when processing the parent poly expression) - *
    - *
  2. otherwise (standard case):
    - * --> infer type of node by asking the TypeJudgment and store the result in the given cache. - *
- */ - def private void typeNode2(RuleEnvironment G, TypableElement node, ASTMetaInfoCache cache, int indentLevel) { - try { - if (polyProcessor.isResponsibleFor(node)) { - if (polyProcessor.isEntryPoint(node)) { - log(indentLevel, "asking PolyComputer ..."); - polyProcessor.inferType(G, node as Expression, cache); - // in this case, the polyComputer will store the type in the cache; - // also, the poly computer is responsible for replacing all DeferredTypeRefs - assertTrueIfRigid(cache, "poly computer did not replace DeferredTypeRef", [ - val typeModelElem = node.definedTypeModelElement; - return typeModelElem === null || typeModelElem.eAllContents.filter(DeferredTypeRef).empty - ]); - } else { - // we have a poly expression, but one that is nested in another poly expression - // -> ignore here, because polyProcessor will deal with it when processing the parent poly expression - log(indentLevel, - "deferred (nested in poly expression --> will be inferred during inference of outer poly expression)"); - - cache.nonEntryPolyProcessorNodes.add(node); - - return; // return only required to avoid confusing logging of cache.getFailSafe(node) below - } - } else { - // ordinary typing of typable AST nodes by asking the TypeJudgment - log(indentLevel, "asking Xsemantics ..."); - val result = invokeTypeJudgmentToInferType(G, node); - - val resultAdjusted = adjustResultForLocationInAST(G, result, node); - - // in this case, we are responsible for storing the type in the cache - // (Xsemantics does not know of the cache) - checkCanceled(G); - cache.storeType(node, resultAdjusted); - } - } catch (Throwable th) { - operationCanceledManager.propagateIfCancelException(th); - logException("exception while obtaining type from type system: " + th.message, th); - th.printStackTrace - cache.storeType(node, TypeRefsFactory.eINSTANCE.createUnknownTypeRef); - } - - log(indentLevel, cache.getTypeFailSafe(node)); - } - - def private T adjustResultForLocationInAST(RuleEnvironment G, T typeRef, TypableElement astNode) { - var result = typeRef; - result = adjustForIndexSignatures(G, result, astNode); - result = adjustForLocationDependentSpecialProperties(G, result, astNode); - return result; - } - - /** - * Poor man's support for index signatures (intended only for .d.ts but must also be checked in N4JS, - * because N4JS may contain classifiers that extend a classifier from .d.ts containing an index signature). - *

- * TODO IDE-3620 remove this method once index signatures are properly supported - */ - def private T adjustForIndexSignatures(RuleEnvironment G, T typeRef, TypableElement astNode) { - val parent = astNode?.eContainer; - if (parent instanceof ParameterizedPropertyAccessExpression) { - if (astNode === parent.target && !typeRef.dynamic) { - if (typeRef instanceof ParameterizedTypeRef) { - if (N4JSLanguageUtils.hasIndexSignature(typeRef)) { - val typeRefCpy = TypeUtils.copy(typeRef); - typeRefCpy.dynamic = true; - return typeRefCpy; - } - } - } - } - return typeRef; - } - - /** - * Make sure that the value of the two location-dependent special properties typeOfObjectLiteral and - * typeOfNewExpressionOrFinalNominal in {@link ParameterizedTypeRef} correctly reflect the current - * location in the AST, i.e. the the location of the given astNode, no matter where the type reference - * in the given result stems from. - *

- * For more details see {@link TypeRef#isTypeOfObjectLiteral()}. - */ - def private T adjustForLocationDependentSpecialProperties(RuleEnvironment G, T result, TypableElement astNode) { - val typeRef = result; - if (typeRef instanceof ParameterizedTypeRef) { - val astNodeSkipParen = N4JSASTUtils.skipParenExpressionDownward(astNode); - val optionalFieldStrategy = N4JSLanguageUtils.calculateOptionalFieldStrategy(ts, G, astNodeSkipParen, typeRef); - if (typeRef.ASTNodeOptionalFieldStrategy !== optionalFieldStrategy) { - val typeRefCpy = TypeUtils.copy(typeRef); - typeRefCpy.ASTNodeOptionalFieldStrategy = optionalFieldStrategy; // TODO: also remember the cause for opt-field-strat! - return typeRefCpy; - } - } - return result; - } - - - // --------------------------------------------------------------------------------------------------------------- - - - /** - * This is the single, central method for obtaining the type of a typable element (AST node or TModule element). - * It should never be invoked directly by client code! Instead, client code should always call - * {@link N4JSTypeSystem#type(RuleEnvironment,TypableElement) N4JSTypeSystem#type()}. - *

- * The behavior of this method depends on the state the containing {@link N4JSResource} is in: - *

    - *
  • before post-processing has started:
    - * -> simply initiate post-processing; once it's finished, return type from AST meta-info cache. - *
  • during post-processing: - *
      - *
    • in case of a backward reference:
      - * -> simply return type from AST meta-info cache. - *
    • in case of a forward reference:
      - * -> trigger forward-processing of the identifiable subtree below the given typable element, see - * {@link #getTypeOfForwardReference(RuleEnvironment,TypableElement,ASTMetaInfoCache) #getTypeOfForwardReference()}, - * which delegates to {@link ASTProcessor#processSubtree_forwardReference( - * RuleEnvironment,TypableElement,ASTMetaInfoCache) ASTProcessor#processSubtree_forwardReference()}. - *
    - *
  • after post-processing has completed:
    - * -> simply return type from AST meta-info cache. - *
- * This overview is simplified, check the code for precise rules! - *

- * Only a single method delegates here (no one else should call this method): - *

    - *
  1. {@link N4JSTypeSystem#type(RuleEnvironment,TypableElement)} - *
- */ - def public TypeRef getType(RuleEnvironment G, TypableElement objRaw) { - - if (objRaw === null) { - // failing safely here; otherwise we would need preemptive null-checks wherever type inference is applied - return TypeRefsFactory.eINSTANCE.createUnknownTypeRef; - } - - var obj = if (objRaw.eIsProxy) { - val resSet = RuleEnvironmentExtensions.getContextResource(G).resourceSet; - EcoreUtil.resolve(objRaw, resSet) as TypableElement - } else { - objRaw - }; - - val res = obj.eResource; - if (res instanceof N4JSResource) { - - if (res.isFullyProcessed && res.script.eIsProxy) { - // special case: this is a resource loaded from the index! - // -> for now, we entirely by-pass ASTMetaInfoCache and just directly wrap the type model element in a TypeRef - if (!obj.isTypeModelElement) { - throw new IllegalStateException("not a type model element: " + obj) - } - return invokeTypeJudgmentToInferType(G, obj); // obj is a type model element, so this will just wrap it in a TypeRef (no actual inference) - } - - // make sure post-processing on the containing N4JS resource is initiated - res.performPostProcessing(G.cancelIndicator); - - // NOTE: at this point, we know: if *before* the above call to #performPostProcessing() ... - // a) post-processing of 'res' had not been started yet: it will now be *completed* - // b) post-processing of 'res' was in progress: it will now still be *in progress* - // c) post-processing of 'res' was completed: it will now still be *completed* - // See API doc of method PostProcessingAwareResource#performPostProcessing(CancelIndicator). - - // if post-processing is in progress AND 'obj' is a type model element AND it corresponds to an AST node - // --> redirect processing to the AST node, in order to properly handle backward/forward references, esp. - // forward processing of identifiable subtrees - if(res.isPostProcessing && obj.isTypeModelElement) { - val astNodeToProcess = if (obj instanceof SyntaxRelatedTElement) { - obj.astElement // NOTE: we've made sure above that we are *NOT* in a Resource loaded from the index! - }; - val isImplicitArgumentsVariable = if (astNodeToProcess instanceof FunctionOrFieldAccessor) astNodeToProcess.implicitArgumentsVariable === obj else false; - if (!isImplicitArgumentsVariable) { - if (astNodeToProcess instanceof TypableElement) { - // proceed with the corresponding AST node instead of the type model element - obj = astNodeToProcess; - } - } - } - - // obtain type of 'obj' - return getTypeInN4JSResource(G, res, obj); - - } else { - - // obj not contained in an N4JSResource -> fall back to default behavior - // can happen for: - // - objects that are not contained in a Resource - // - objects that are contained in a Resource but not an N4JSResource - return invokeTypeJudgmentToInferType(G, obj); - } - } - - /** See {@link TypeProcessor#getType(RuleEnvironment,RuleApplicationTrace,TypableElement)}. */ - def private TypeRef getTypeInN4JSResource(RuleEnvironment G, N4JSResource res, TypableElement obj) { - // obtain type of 'obj' depending on whether it's an AST node or type model element AND depending on current - // load state of containing N4JS resource - if (obj.isTypeModelElement) { - // for type model elements, we by-pass all caching ... - return invokeTypeJudgmentToInferType(G, obj); // obj is a type model element, so this will just wrap it in a TypeRef (no actual inference) - } else if (obj.isASTNode && obj.isTypableNode) { - // here we read from the cache (if AST node 'obj' was already processed) or forward-process 'obj' - val cache = res.getASTMetaInfoCacheVerifyContext(); - if (!res.isPostProcessing && !res.isFullyProcessed) { - // we have called #performPostProcessing() on the containing resource above, so this is "impossible" - throw new IllegalStateException("post-processing neither in progress nor completed after calling #performPostProcessing() in resource: " + res.URI); - } else if (!cache.isPostProcessing && !cache.isFullyProcessed) { - // "res.isProcessing() || res.isFullyProcessed()" but not "cache.isProcessing || cache.isFullyProcessed" - // so: the post-processing flags are out of sync between the resource and cache - // (HINT: if you get an exception here, this often indicates an accidental cache clear; use the - // debug code in ASTMetaInfoCacheHelper to track creation/deletion of typing caches to investigate this) - val e = new IllegalStateException("post-processing flags out of sync between resource and cache (hint: this is often caused by an accidental cache clear!!)"); - e.printStackTrace // make sure we see this on the console (some clients eat up all exceptions!) - throw e; - } else if (cache.isPostProcessing) { - - // while AST typing is in progress, just read from the cache we are currently filling - val resultFromCache = cache.getTypeFailSafe(obj); - - if (resultFromCache === null) { - // cache does not contain type for 'obj' (i.e. not processed yet) - // -> we have a forward reference! - log(0, "***** forward reference to: " + obj); - - return getTypeOfForwardReference(G, obj, cache); - } else { - // cache contains a type for 'obj' (i.e. it was already processed) - // -> simply read from cache - return resultFromCache; - } - } else if (cache.isFullyProcessed) { - return cache.getType(G, obj); // will throw exception in case of cache miss - } - } else { - // a non-typable AST node OR some entity in the TModule for which obj.isTypeModelElement returns false - return TypeRefsFactory.eINSTANCE.createUnknownTypeRef; - } - } - - /** See {@link TypeProcessor#getType(RuleEnvironment,RuleApplicationTrace,TypableElement)}. */ - def private TypeRef getTypeOfForwardReference(RuleEnvironment G, TypableElement node, ASTMetaInfoCache cache) { - assertTrueIfRigid(cache, "argument 'node' must be an AST node", node.isASTNode); - - // TODO improve handling of destructuring patterns in ASTProcessor/TypeProcessor - // (this is a temporary hack to avoid many illegal forward references within destructuring patterns) - if (destructureProcessor.isForwardReferenceWhileTypingDestructuringPattern(node)) { - return destructureProcessor.handleForwardReferenceWhileTypingDestructuringPattern(G, node, cache); - } - - val isLegal = astProcessor.processSubtree_forwardReference(G, node, cache); - if (isLegal) { - val isCyclicForwardReference = cache.astNodesCurrentlyBeingTyped.contains(node); - if (isCyclicForwardReference) { - // in case of a legal cyclic forward reference, we cannot obtain the type of 'node' in the usual - // way by fully processing 'node' and its subtree, so we have to "guess" a type - if (node instanceof VariableDeclaration || node instanceof N4FieldDeclaration || - node instanceof PropertyNameValuePair) { - - val expr = node.expressionOfVFP; - if (expr instanceof N4ClassExpression) { - return invokeTypeJudgmentToInferType(G, expr); - } - if (expr instanceof NewExpression) { - val callee = expr.callee; - if (callee instanceof N4ClassExpression) { - val calleeType = invokeTypeJudgmentToInferType(G, callee); - val calleeTypeStaticType = tsh.getStaticType(G, calleeType as TypeTypeRef); - return TypeUtils.createTypeRef(calleeTypeStaticType); - } - } - val declTypeRef = node.declaredTypeRefOfVFP; - return if (declTypeRef !== null) { - declTypeRef - } else { - G.anyTypeRef - }; - } else if (node instanceof FieldAccessor) { - val declTypeRef = node.declaredTypeRef; - return if (declTypeRef !== null) { - declTypeRef - } else { - G.anyTypeRef - }; - } else if (node instanceof TypeDefiningElement) { - return wrapTypeInTypeRef(G, node.definedType); - } else if (node instanceof Expression && node.eContainer instanceof YieldExpression) { - return invokeTypeJudgmentToInferType(G, node); - } else { - val msg = "handling of a legal case of cyclic forward references missing in TypeProcessor"; - logErr(msg); - val e = new IllegalStateException(msg); - e.printStackTrace; - return TypeRefsFactory.eINSTANCE.createUnknownTypeRef; - } - } else if (astProcessor.isSemiCyclicForwardReferenceInForLoop(node, cache)) { - // semi-cyclic forward reference to a variable declaration in a for in/of loop: - // -> similar to cyclic variable declarations, we have to "guess" a type. - val declTypeRefNode = (node as VariableDeclaration).declaredTypeRefNode; - val declTypeRefInAST = declTypeRefNode?.typeRefInAST; - return if (declTypeRefInAST !== null) { - declTypeRefNode.cachedProcessedTypeRef ?: tsh.resolveTypeAliases(G, declTypeRefInAST) - } else { - G.anyTypeRef - }; - } else { - // in case of a legal, *non*-cyclic forward reference, we can assume that the subtree below 'node' - // has now been processed, which means node's type is now in the typing cache - return cache.getType(G, node); - } - } else { - val msg = "*#*#*#*#*#* ILLEGAL FORWARD REFERENCE to " + node + " in " + node.eResource?.URI; - logErr(msg); - return TypeRefsFactory.eINSTANCE.createUnknownTypeRef; - } - } - - - // --------------------------------------------------------------------------------------------------------------- - - - def private static Expression getExpressionOfVFP(EObject vfp) { - switch (vfp) { - VariableDeclaration: - vfp.expression - N4FieldDeclaration: - vfp.expression - PropertyNameValuePair: - vfp.expression - } - } - - def private static TypeRef getDeclaredTypeRefOfVFP(EObject vfp) { - switch (vfp) { - VariableDeclaration: - vfp.declaredTypeRef - N4FieldDeclaration: - vfp.declaredTypeRef - PropertyNameValuePair: - vfp.declaredTypeRef - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeRefProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeRefProcessor.java new file mode 100644 index 0000000000..740ac47c49 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeRefProcessor.java @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2021 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.postprocessing; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.last; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import org.eclipse.emf.common.util.TreeIterator; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.n4js.n4JS.N4JSASTUtils; +import org.eclipse.n4js.n4JS.TypeDefiningElement; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.ts.typeRefs.EnumLiteralTypeRef; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.StructuralTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeArgument; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory; +import org.eclipse.n4js.ts.typeRefs.Wildcard; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.TEnum; +import org.eclipse.n4js.ts.types.TEnumLiteral; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.ts.types.TypeAlias; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.utils.NestedTypeRefsSwitch; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.n4js.utils.EcoreUtilN4; + +import com.google.inject.Inject; + +/** + * Processor for converting the raw type references provided by the parser into valid type references that can be used + * internally. + *

+ * Most type references created by the parser are already valid and can be used directly; the only exceptions are: + *

    + *
  • references to the literal of an enum must be converted to an {@link EnumLiteralTypeRef}. + *
  • {@link TypeRef#isAliasUnresolved() unresolved} references to type aliases must be converted to + * {@link TypeRef#isAliasResolved() resolved} references to type aliases. + *
+ */ +class TypeRefProcessor extends AbstractProcessor { + + @Inject + private TypeSystemHelper tsh; + + @SuppressWarnings("unused") + void handleTypeRefs(RuleEnvironment G, EObject astNode, ASTMetaInfoCache cache) { + handleTypeRefsInAST(G, astNode); + handleTypeRefsInTModule(G, astNode); + } + + private void handleTypeRefsInAST(RuleEnvironment G, EObject astNode) { + for (TypeReferenceNode typeRefNode : N4JSASTUtils.getContainedTypeReferenceNodes(astNode)) { + TypeRef typeRef = typeRefNode.getTypeRefInAST(); + TypeRef typeRefProcessed = processTypeArg(G, typeRef); + if (typeRefProcessed != null) { + if (typeRefProcessed == typeRef) { + // temporary tweak to ensure correctness of code base: + // if nothing was resolved, we could directly use 'typeRef' as the value of property + // TypeReferenceNode#cachedProcessedTypeRef; however, then the return value of operation + // TypeReferenceNode#getTypeRef() would sometimes be contained in the AST and sometimes not; + // by always creating a copy here, we force the entire code base to be able to cope with the + // fact that the return value of TypeReferenceNode#getTypeRef() might not be contained in the + // AST (similarly as type aliases were used everywhere in the code, for testing) + typeRefProcessed = TypeUtils.copy(typeRef); + } + TypeRef typeRefProcessedFinal = typeRefProcessed; + EcoreUtilN4.doWithDeliver(false, () -> typeRefNode.setCachedProcessedTypeRef(typeRefProcessedFinal), + typeRefNode); + } + } + } + + private void handleTypeRefsInTModule(RuleEnvironment G, EObject astNode) { + IdentifiableElement defType = null; + + if (astNode instanceof TypeDefiningElement) { + defType = ((TypeDefiningElement) astNode).getDefinedType(); + } else if (astNode instanceof StructuralTypeRef) { + defType = ((StructuralTypeRef) astNode).getStructuralType(); + } else if (astNode instanceof FunctionTypeExpression) { + defType = ((FunctionTypeExpression) astNode).getDeclaredType(); + } else if (astNode instanceof VariableDeclaration) { + defType = ((VariableDeclaration) astNode).getDefinedVariable(); + } + + if (defType != null) { + handleTypeRefsInIdentifiableElement(G, defType); + } + } + + private void handleTypeRefsInIdentifiableElement(RuleEnvironment G, IdentifiableElement elem) { + if (elem instanceof TypeAlias) { + return; // do not resolve the 'actualTypeRef' property in type alias itself + } + List allNestedTypeArgs = new ArrayList<>(); // create list up-front to not confuse tree iterator + // when replacing nodes! + TreeIterator iter = elem.eAllContents(); + while (iter.hasNext()) { + EObject obj = iter.next(); + if (obj instanceof TypeArgument) { + allNestedTypeArgs.add((TypeArgument) obj); + iter.prune(); + } + } + for (TypeArgument typeArg : allNestedTypeArgs) { + TypeArgument typeArgProcessed = processTypeArg(G, typeArg); + if (typeArgProcessed != null && typeArgProcessed != typeArg) { + EReference containmentFeature = typeArg.eContainmentFeature(); + boolean isValidType = containmentFeature != null + && containmentFeature.getEReferenceType().isSuperTypeOf(typeArgProcessed.eClass()); + if (isValidType) { + EcoreUtilN4.doWithDeliver(false, () -> EcoreUtil.replace(typeArg, typeArgProcessed), + typeArg.eContainer()); + } + } + } + } + + /** This overload implements the rule that when passing in a {@link TypeRef}, you get a {@code TypeRef} back. */ + private TypeRef processTypeArg(RuleEnvironment G, TypeRef typeRef) { + return (TypeRef) processTypeArg(G, (TypeArgument) typeRef); + } + + /** + * Guarantee: type references are never converted to {@link Wildcard}s, i.e. when passing in a {@link TypeRef}, you + * get a {@code TypeRef} back. + */ + private TypeArgument processTypeArg(RuleEnvironment G, TypeArgument typeArg) { + if (typeArg == null) { + return null; + } + var processed = typeArg; + + processed = processEnumLiteralTypeRefs(G, processed); + processed = processTypeAliases(G, processed); + + return processed; + } + + private TypeArgument processEnumLiteralTypeRefs(RuleEnvironment G, TypeArgument typeArg) { + // note: we also have to handle parameterized type refs that might be nested below some other TypeRef! + return new ResolveParameterizedTypeRefPointingToTEnumLiteralSwitch(G).doSwitch(typeArg); + } + + private TypeArgument processTypeAliases(RuleEnvironment G, TypeArgument typeArg) { + // note: we also have to resolve type aliases that might be nested below a non-alias TypeRef! + return tsh.resolveTypeAliases(G, typeArg); + } + + private static class ResolveParameterizedTypeRefPointingToTEnumLiteralSwitch extends NestedTypeRefsSwitch { + + ResolveParameterizedTypeRefPointingToTEnumLiteralSwitch(RuleEnvironment G) { + super(G); + } + + @Override + protected ResolveParameterizedTypeRefPointingToTEnumLiteralSwitch derive(RuleEnvironment G_NEW) { + return new ResolveParameterizedTypeRefPointingToTEnumLiteralSwitch(G_NEW); + } + + @Override + protected TypeRef caseParameterizedTypeRef_processDeclaredType(ParameterizedTypeRef typeRef) { + Type astQualifier = typeRef.getAstNamespaceLikeRefs() != null + && last(typeRef.getAstNamespaceLikeRefs()) != null + ? last(typeRef.getAstNamespaceLikeRefs()).getDeclaredType() + : null; + + if (astQualifier instanceof TEnum) { + String enumLiteralName = typeRef.getDeclaredTypeAsText(); + TEnumLiteral enumLiteral = findFirst(((TEnum) astQualifier).getLiterals(), + lit -> Objects.equals(lit.getName(), enumLiteralName)); + if (enumLiteral != null) { + EnumLiteralTypeRef litTypeRef = TypeRefsFactory.eINSTANCE.createEnumLiteralTypeRef(); + litTypeRef.setValue(enumLiteral); + return litTypeRef; + } + } + return typeRef; + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeRefProcessor.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeRefProcessor.xtend deleted file mode 100644 index b95af04838..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeRefProcessor.xtend +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Copyright (c) 2021 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.postprocessing - -import com.google.inject.Inject -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.util.EcoreUtil -import org.eclipse.n4js.n4JS.N4JSASTUtils -import org.eclipse.n4js.n4JS.TypeDefiningElement -import org.eclipse.n4js.n4JS.TypeReferenceNode -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.ts.typeRefs.EnumLiteralTypeRef -import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.typeRefs.StructuralTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeArgument -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory -import org.eclipse.n4js.ts.typeRefs.Wildcard -import org.eclipse.n4js.ts.types.IdentifiableElement -import org.eclipse.n4js.ts.types.TEnum -import org.eclipse.n4js.ts.types.TypeAlias -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.utils.NestedTypeRefsSwitch -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper -import org.eclipse.n4js.utils.EcoreUtilN4 - -/** - * Processor for converting the raw type references provided by the parser into valid type references that - * can be used internally. - *

- * Most type references created by the parser are already valid and can be used directly; the only exceptions - * are: - *

    - *
  • references to the literal of an enum must be converted to an {@link EnumLiteralTypeRef}. - *
  • {@link TypeRef#isAliasUnresolved() unresolved} references to type aliases must be converted to - * {@link TypeRef#isAliasResolved() resolved} references to type aliases. - *
- */ -package class TypeRefProcessor extends AbstractProcessor { - - @Inject - private TypeSystemHelper tsh; - - def void handleTypeRefs(RuleEnvironment G, EObject astNode, ASTMetaInfoCache cache) { - handleTypeRefsInAST(G, astNode); - handleTypeRefsInTModule(G, astNode); - } - - def private void handleTypeRefsInAST(RuleEnvironment G, EObject astNode) { - for (TypeReferenceNode typeRefNode : N4JSASTUtils.getContainedTypeReferenceNodes(astNode)) { - val typeRef = typeRefNode.typeRefInAST; - var typeRefProcessed = processTypeArg(G, typeRef); - if (typeRefProcessed !== null) { - if (typeRefProcessed === typeRef) { - // temporary tweak to ensure correctness of code base: - // if nothing was resolved, we could directly use 'typeRef' as the value of property - // TypeReferenceNode#cachedProcessedTypeRef; however, then the return value of operation - // TypeReferenceNode#getTypeRef() would sometimes be contained in the AST and sometimes not; - // by always creating a copy here, we force the entire code base to be able to cope with the - // fact that the return value of TypeReferenceNode#getTypeRef() might not be contained in the - // AST (similarly as type aliases were used everywhere in the code, for testing) - typeRefProcessed = TypeUtils.copy(typeRef); - } - val typeRefProcessedFinal = typeRefProcessed; - EcoreUtilN4.doWithDeliver(false, [ - typeRefNode.cachedProcessedTypeRef = typeRefProcessedFinal; - ], typeRefNode); - } - } - } - - def private void handleTypeRefsInTModule(RuleEnvironment G, EObject astNode) { - val defType = switch(astNode) { - TypeDefiningElement: - astNode.definedType - StructuralTypeRef: - astNode.structuralType - FunctionTypeExpression: - astNode.declaredType - VariableDeclaration: - astNode.definedVariable - }; - if (defType !== null) { - handleTypeRefsInIdentifiableElement(G, defType); - } - } - - def private void handleTypeRefsInIdentifiableElement(RuleEnvironment G, IdentifiableElement elem) { - if (elem instanceof TypeAlias) { - return; // do not resolve the 'actualTypeRef' property in type alias itself - } - val allNestedTypeArgs = newArrayList; // create list up-front to not confuse tree iterator when replacing nodes! - val iter = elem.eAllContents; - while (iter.hasNext) { - val obj = iter.next; - if (obj instanceof TypeArgument) { - allNestedTypeArgs.add(obj); - iter.prune(); - } - } - for (typeArg : allNestedTypeArgs) { - val typeArgProcessed = processTypeArg(G, typeArg); - if (typeArgProcessed !== null && typeArgProcessed !== typeArg) { - val containmentFeature = typeArg.eContainmentFeature; - val isValidType = containmentFeature !== null - && containmentFeature.getEReferenceType().isSuperTypeOf(typeArgProcessed.eClass); - if (isValidType) { - EcoreUtilN4.doWithDeliver(false, [ - EcoreUtil.replace(typeArg, typeArgProcessed); - ], typeArg.eContainer); - } - } - } - } - - /** This overload implements the rule that when passing in a {@link TypeRef}, you get a {@code TypeRef} back. */ - def private TypeRef processTypeArg(RuleEnvironment G, TypeRef typeRef) { - return processTypeArg(G, typeRef as TypeArgument) as TypeRef; - } - - /** - * Guarantee: type references are never converted to {@link Wildcard}s, i.e. when passing in a {@link TypeRef}, - * you get a {@code TypeRef} back. - */ - def private TypeArgument processTypeArg(RuleEnvironment G, TypeArgument typeArg) { - if (typeArg === null) { - return null; - } - var processed = typeArg; - - processed = processEnumLiteralTypeRefs(G, processed); - processed = processTypeAliases(G, processed); - - return processed; - } - - def private TypeArgument processEnumLiteralTypeRefs(RuleEnvironment G, TypeArgument typeArg) { - // note: we also have to handle parameterized type refs that might be nested below some other TypeRef! - return new ResolveParameterizedTypeRefPointingToTEnumLiteralSwitch(G).doSwitch(typeArg); - } - - def private TypeArgument processTypeAliases(RuleEnvironment G, TypeArgument typeArg) { - // note: we also have to resolve type aliases that might be nested below a non-alias TypeRef! - return tsh.resolveTypeAliases(G, typeArg); - } - - - private static class ResolveParameterizedTypeRefPointingToTEnumLiteralSwitch extends NestedTypeRefsSwitch { - - new(RuleEnvironment G) { - super(G); - } - - override protected derive(RuleEnvironment G_NEW) { - return new ResolveParameterizedTypeRefPointingToTEnumLiteralSwitch(G_NEW); - } - - override protected caseParameterizedTypeRef_processDeclaredType(ParameterizedTypeRef typeRef) { - val astQualifier = typeRef.astNamespaceLikeRefs?.last?.declaredType; - if (astQualifier instanceof TEnum) { - val enumLiteralName = typeRef.declaredTypeAsText; - val enumLiteral = astQualifier.literals.findFirst[name == enumLiteralName]; - if (enumLiteral !== null) { - val litTypeRef = TypeRefsFactory.eINSTANCE.createEnumLiteralTypeRef(); - litTypeRef.value = enumLiteral; - return litTypeRef; - } - } - return typeRef; - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDerivedStateComputer.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDerivedStateComputer.java new file mode 100644 index 0000000000..9057422f25 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDerivedStateComputer.java @@ -0,0 +1,71 @@ +/** + * 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.resource; + +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.typesbuilder.N4JSTypesBuilder; +import org.eclipse.xtext.resource.DerivedStateAwareResource; +import org.eclipse.xtext.resource.IDerivedStateComputer; + +import com.google.inject.Inject; + +/** + * Derives the types model from the AST and stores it at the second index of the resource. See {@link N4JSTypesBuilder}. + */ +public class N4JSDerivedStateComputer implements IDerivedStateComputer { + + @Inject + private N4JSUnloader n4jsUnloader; + @Inject + private N4JSTypesBuilder typesBuilder; + + /** + * Creates an {@link TModule} on the second slot of the resource. when the resource contents is not empty. + */ + @Override + public void installDerivedState(DerivedStateAwareResource resource, boolean preLinkingPhase) { + List contents = resource.getContents(); + if (contents.isEmpty()) { + String msg = "cannot install derived state in resource '" + resource.getURI().toString() + "' without AST"; + throw new IllegalStateException(msg); + } else if (contents.size() == 1) { + typesBuilder.createTModuleFromSource(resource, preLinkingPhase); + } else if (contents.size() == 2) { + typesBuilder.relinkTModuleToSource(resource, preLinkingPhase); + } else { + throw new IllegalStateException("resource '" + resource.getURI().toString() + "' with more than two roots"); + } + } + + /** + * Calls {@link N4JSUnloader#unloadRoot(EObject)} for the second slot root. Then all contents of the resource are + * cleared. + */ + @Override + public void discardDerivedState(DerivedStateAwareResource resource) { + List contents = resource.getContents(); + // resource.getContents().get(1-n)clear + if (contents.isEmpty()) { + return; + } + + // other resources may hold references to the derived state thus we + // have to unload (proxify) it explicitly before it is removed from the resource + List tail = contents.subList(1, contents.size()); + for (EObject eo : tail) { + n4jsUnloader.unloadRoot(eo); + } + tail.clear(); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDerivedStateComputer.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDerivedStateComputer.xtend deleted file mode 100644 index 1714a8d0ef..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDerivedStateComputer.xtend +++ /dev/null @@ -1,62 +0,0 @@ -/** - * 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.resource; - -import com.google.inject.Inject -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.typesbuilder.N4JSTypesBuilder -import org.eclipse.xtext.resource.DerivedStateAwareResource -import org.eclipse.xtext.resource.IDerivedStateComputer - -/** - * Derives the types model from the AST and stores it at the second index of the resource. - * See {@link N4JSTypesBuilder}. - */ -public class N4JSDerivedStateComputer implements IDerivedStateComputer { - - @Inject extension N4JSUnloader - @Inject private N4JSTypesBuilder typesBuilder; - - /** - * Creates an {@link TModule} on the second slot of the resource. when the resource contents is not empty. - */ - override void installDerivedState(DerivedStateAwareResource resource, boolean preLinkingPhase) { - val contents = resource.contents; - if (contents.nullOrEmpty) { - val msg = "cannot install derived state in resource '"+ resource.URI.toString +"' without AST"; - throw new IllegalStateException(msg) - } else if (contents.size == 1) { - typesBuilder.createTModuleFromSource(resource, preLinkingPhase); - } else if (contents.size == 2) { - typesBuilder.relinkTModuleToSource(resource, preLinkingPhase); - } else { - throw new IllegalStateException("resource '"+ resource.URI.toString +"' with more than two roots"); - } - } - - /** - * Calls {@link N4JSUnloader#unloadRoot(EObject} for the second slot root. - * Then all contents of the resource are cleared. - */ - override void discardDerivedState(DerivedStateAwareResource resource) { - val contents = resource.contents; - // resource.getContents().get(1-n)clear - if (contents.empty) { - return; - } - - // other resources may hold references to the derived state thus we - // have to unload (proxify) it explicitly before it is removed from the resource - val tail = contents.subList(1, contents.size) - tail.forEach[unloadRoot] - tail.clear - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDescriptionUtils.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDescriptionUtils.java new file mode 100644 index 0000000000..6092ddb6ed --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSDescriptionUtils.java @@ -0,0 +1,28 @@ +/** + * 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.resource; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.xtext.resource.DescriptionUtils; +import org.eclipse.xtext.resource.IResourceDescription; + +/** + */ +public class N4JSDescriptionUtils extends DescriptionUtils { + + @Override + public Set collectOutgoingReferences(IResourceDescription description) { + return new HashSet<>(); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSLocationInFileProvider.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSLocationInFileProvider.java new file mode 100644 index 0000000000..74acf719bc --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSLocationInFileProvider.java @@ -0,0 +1,223 @@ +/** + * 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.resource; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst; + +import java.util.List; +import java.util.Objects; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.n4js.N4JSGlobals; +import org.eclipse.n4js.n4JS.GenericDeclaration; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.PropertyNameOwner; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression; +import org.eclipse.n4js.ts.types.SyntaxRelatedTElement; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TStructMember; +import org.eclipse.n4js.ts.types.TStructMethod; +import org.eclipse.n4js.ts.types.TStructuralType; +import org.eclipse.n4js.ts.types.TypeVariable; +import org.eclipse.n4js.utils.URIUtils; +import org.eclipse.n4js.xtext.resource.XITextRegionWithLineInformation; +import org.eclipse.xtext.nodemodel.util.NodeModelUtils; +import org.eclipse.xtext.resource.DefaultLocationInFileProvider; +import org.eclipse.xtext.resource.ILocationInFileProviderExtension; +import org.eclipse.xtext.util.ITextRegion; + +/** + * A location in file provider that is aware of inferred types. The location of the referenced AST element is used + * instead. + */ +public class N4JSLocationInFileProvider extends DefaultLocationInFileProvider { + + @Override + public ITextRegion getFullTextRegion(EObject element) { + EObject srcObj = convertToSource(element); + if (srcObj == null) { + return null; + } + return super.getFullTextRegion(srcObj); + } + + @Override + public ITextRegion getFullTextRegion(EObject owner, EStructuralFeature feature, int indexInList) { + EObject srcObj = convertToSource(owner); + if (srcObj == null) { + return null; + } + return super.getFullTextRegion(srcObj, feature, indexInList); + } + + @Override + public ITextRegion getSignificantTextRegion(EObject element) { + if (element instanceof NamedImportSpecifier) { + NamedImportSpecifier nis = (NamedImportSpecifier) element; + if (!nis.isDefaultImport()) { + if (nis.getAlias() != null) { + return super.getSignificantTextRegion(element, + N4JSPackage.eINSTANCE.getNamedImportSpecifier_Alias(), -1); + } + } + } else if (element instanceof NamespaceImportSpecifier) { + NamespaceImportSpecifier nis = (NamespaceImportSpecifier) element; + if (nis.getAlias() != null) { + return super.getSignificantTextRegion(element, + N4JSPackage.eINSTANCE.getNamespaceImportSpecifier_Alias(), -1); + } + } + EObject srcObj = convertToSource(element); + if (srcObj == null) { + return null; + } + return super.getSignificantTextRegion(srcObj); + } + + @Override + public ITextRegion getSignificantTextRegion(EObject owner, EStructuralFeature feature, int indexInList) { + EObject srcObj = convertToSource(owner); + if (srcObj == null) { + return null; + } + return super.getSignificantTextRegion(srcObj, feature, indexInList); + } + + @Override + public ITextRegion getTextRegion(EObject object, EStructuralFeature feature, int indexInList, + ILocationInFileProviderExtension.RegionDescription query) { + + EObject srcObj = convertToSource(object); + if (srcObj == null) { + return null; + } + return super.getTextRegion(srcObj, feature, indexInList, query); + } + + @Override + public ITextRegion getTextRegion(EObject object, ILocationInFileProviderExtension.RegionDescription query) { + EObject srcObj = convertToSource(object); + if (srcObj == null) { + return null; + } + return super.getTextRegion(srcObj, query); + } + + @Override + protected ITextRegion doGetTextRegion(EObject obj, /* @NonNull */ RegionDescription query) { + if (Objects.equals(N4JSGlobals.DTS_FILE_EXTENSION, + URIUtils.fileExtension(obj.eResource() == null ? null : obj.eResource().getURI()))) { + for (Adapter adapter : obj.eAdapters()) { + if (adapter instanceof XITextRegionWithLineInformation) { + return toZeroBasedRegion((XITextRegionWithLineInformation) adapter); + } + } + } else if (obj instanceof TMember && !((TMember) obj).getConstituentMembers().isEmpty()) { + TMember tMember = (TMember) obj; + TMember fst = tMember.getConstituentMembers().get(0); + return super.doGetTextRegion(fst.getAstElement(), query); + } else if (obj instanceof PropertyNameValuePair && ((PropertyNameValuePair) obj).getProperty() != null) { + return super.getFullTextRegion(obj, N4JSPackage.eINSTANCE.getPropertyNameValuePair_Property(), 0); + } + return super.doGetTextRegion(obj, query); + } + + // TODO use N4JSASTUtils#getCorrespondingASTNode() instead, if possible + /***/ + public EObject convertToSource(EObject element) { + if (element == null || element.eIsProxy()) { + return null; + } + + EObject astElem = (element instanceof SyntaxRelatedTElement) + ? ((SyntaxRelatedTElement) element).getAstElement() + : null; + + if (element instanceof TypeVariable) { + EObject parentAST = convertToSource(element.eContainer()); + if (parentAST instanceof GenericDeclaration || parentAST instanceof TStructMethod + || parentAST instanceof FunctionTypeExpression) { + String typeVarName = ((TypeVariable) element).getName(); + if (typeVarName != null && typeVarName.trim().length() > 0) { + EObject correspondingTypeVarInAST = null; + if (parentAST instanceof GenericDeclaration) { + correspondingTypeVarInAST = findFirst(((GenericDeclaration) parentAST) + .getTypeVars(), tv -> Objects.equals(tv.getName(), typeVarName)); + } else if (parentAST instanceof TStructMethod) { + correspondingTypeVarInAST = findFirst(((TStructMethod) parentAST) + .getTypeVars(), tv -> Objects.equals(tv.getName(), typeVarName)); + } else if (parentAST instanceof FunctionTypeExpression) { + correspondingTypeVarInAST = findFirst(((FunctionTypeExpression) parentAST) + .getOwnedTypeVars(), tv -> Objects.equals(tv.getName(), typeVarName)); + } + if (correspondingTypeVarInAST != null) { + return correspondingTypeVarInAST; + } + } + } + return element; + + } else if (element instanceof TFormalParameter && astElem == null) { + return element; + } else if (element instanceof TStructMember && astElem == null) { + return element; + } else if (element instanceof TMember && ((TMember) element).isComposed()) { + return element; + } else if (element instanceof TStructuralType) { + if (((TStructuralType) element).getName() == null && astElem == null) { + EObject parent = element.eContainer(); + return convertToSource(parent); + } + } else if (element instanceof SyntaxRelatedTElement) { + if (astElem == null) { + if (NodeModelUtils.getNode(element) != null) { + return element; + } + throw new IllegalStateException(); + } + return astElem; + } + return element; + } + + @Override + protected EStructuralFeature getIdentifierFeature(EObject obj) { + if (obj instanceof PropertyNameOwner) { + return N4JSPackage.eINSTANCE.getPropertyNameOwner_DeclaredName(); + } + return super.getIdentifierFeature(obj); + } + + @Override + protected ITextRegion getLocationOfContainmentReference(EObject owner, EReference feature, + int indexInList, RegionDescription query) { + + EObject referencedElement = null; + if (feature.isMany()) { + List values = (List) owner.eGet(feature); + if (indexInList >= values.size()) { + referencedElement = owner; + } else if (indexInList >= 0) { + referencedElement = (EObject) values.get(indexInList); + } + } else { + referencedElement = (EObject) owner.eGet(feature); + } + return getTextRegion(referencedElement, query); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSLocationInFileProvider.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSLocationInFileProvider.xtend deleted file mode 100644 index d30d5f9c8f..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSLocationInFileProvider.xtend +++ /dev/null @@ -1,196 +0,0 @@ -/** - * 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.resource - -import java.util.Objects -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.EStructuralFeature -import org.eclipse.n4js.N4JSGlobals -import org.eclipse.n4js.n4JS.GenericDeclaration -import org.eclipse.n4js.n4JS.N4JSPackage -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.n4JS.PropertyNameOwner -import org.eclipse.n4js.n4JS.PropertyNameValuePair -import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression -import org.eclipse.n4js.ts.types.SyntaxRelatedTElement -import org.eclipse.n4js.ts.types.TFormalParameter -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.ts.types.TStructMember -import org.eclipse.n4js.ts.types.TStructMethod -import org.eclipse.n4js.ts.types.TStructuralType -import org.eclipse.n4js.ts.types.TypeVariable -import org.eclipse.n4js.utils.URIUtils -import org.eclipse.n4js.xtext.resource.XITextRegionWithLineInformation -import org.eclipse.xtext.nodemodel.util.NodeModelUtils -import org.eclipse.xtext.resource.DefaultLocationInFileProvider -import org.eclipse.xtext.resource.ILocationInFileProviderExtension -import org.eclipse.xtext.util.ITextRegion -import org.eclipse.xtext.resource.ILocationInFileProviderExtension.RegionDescription -import java.util.List -import org.eclipse.emf.ecore.EReference - -/** - * A location in file provider that is aware of inferred types. The location - * of the referenced AST element is used instead. - */ -class N4JSLocationInFileProvider extends DefaultLocationInFileProvider { - - override getFullTextRegion(EObject element) { - val srcObj = convertToSource(element); - if (srcObj === null) { - return null; - } - return super.getFullTextRegion(srcObj); - } - - override getFullTextRegion(EObject owner, EStructuralFeature feature, int indexInList) { - val srcObj = convertToSource(owner); - if (srcObj === null) { - return null; - } - return super.getFullTextRegion(srcObj, feature, indexInList); - } - - override getSignificantTextRegion(EObject element) { - if(element instanceof NamedImportSpecifier) { - if(!element.isDefaultImport()) { - if(element.getAlias() !== null) { - return super.getSignificantTextRegion(element, N4JSPackage.eINSTANCE.getNamedImportSpecifier_Alias(), -1); - } - } - } else if(element instanceof NamespaceImportSpecifier) { - if (element.getAlias() !== null) { - return super.getSignificantTextRegion(element, N4JSPackage.eINSTANCE.getNamespaceImportSpecifier_Alias(), -1); - } - } - val srcObj = convertToSource(element); - if (srcObj === null) { - return null; - } - return super.getSignificantTextRegion(srcObj); - } - - override getSignificantTextRegion(EObject owner, EStructuralFeature feature, int indexInList) { - val srcObj = convertToSource(owner); - if (srcObj === null) { - return null; - } - return super.getSignificantTextRegion(srcObj, feature, indexInList); - } - - override getTextRegion(EObject object, EStructuralFeature feature, int indexInList, - ILocationInFileProviderExtension.RegionDescription query) { - - val srcObj = convertToSource(object); - if (srcObj === null) { - return null; - } - return super.getTextRegion(srcObj, feature, indexInList, query); - } - - override getTextRegion(EObject object, ILocationInFileProviderExtension.RegionDescription query) { - val srcObj = convertToSource(object); - if (srcObj === null) { - return null; - } - return super.getTextRegion(srcObj, query); - } - - override protected ITextRegion doGetTextRegion(EObject obj, /* @NonNull */ RegionDescription query) { - if (Objects.equals(N4JSGlobals.DTS_FILE_EXTENSION, URIUtils.fileExtension(obj.eResource?.URI))) { - for (adapter : obj.eAdapters) { - if (adapter instanceof XITextRegionWithLineInformation) { - return toZeroBasedRegion(adapter); - } - } - } else if (obj instanceof TMember && !(obj as TMember).constituentMembers.empty) { - val tMember = obj as TMember; - val fst = tMember.constituentMembers.get(0); - return super.doGetTextRegion(fst.astElement, query); - } else if (obj instanceof PropertyNameValuePair && (obj as PropertyNameValuePair).property !== null) { - return super.getFullTextRegion(obj, N4JSPackage.eINSTANCE.propertyNameValuePair_Property, 0); - } else { - return super.doGetTextRegion(obj, query); - } - } - - - // TODO use N4JSASTUtils#getCorrespondingASTNode() instead, if possible - def public EObject convertToSource(EObject element) { - if (element === null || element.eIsProxy) - return null; - switch (element) { - TypeVariable: { - val parentAST = convertToSource(element.eContainer); - if(parentAST instanceof GenericDeclaration || parentAST instanceof TStructMethod || parentAST instanceof FunctionTypeExpression) { - val typeVarName = element.name; - if(typeVarName!==null && typeVarName.trim.length>0) { - val correspondingTypeVarInAST = switch parentAST { - GenericDeclaration: parentAST.typeVars.findFirst[name==typeVarName] - TStructMethod: parentAST.typeVars.findFirst[name==typeVarName] - FunctionTypeExpression: parentAST.ownedTypeVars.findFirst[name==typeVarName] - }; - if(correspondingTypeVarInAST!==null) - return correspondingTypeVarInAST; - } - } - return element; - } - TFormalParameter case element.astElement === null: - element - TStructMember case element.astElement === null: - element - TMember case element.composed: - element - TStructuralType case element.name === null && element.astElement === null: { - val parent = element.eContainer - return convertToSource(parent) - } - SyntaxRelatedTElement: { - if (element.astElement === null) { - if (NodeModelUtils.getNode(element) !== null) { - return element; - } - throw new IllegalStateException() - } - element.astElement - } - default: - element - } - } - - override protected EStructuralFeature getIdentifierFeature(EObject obj) { - if(obj instanceof PropertyNameOwner) { - return N4JSPackage.eINSTANCE.propertyNameOwner_DeclaredName; - } - return super.getIdentifierFeature(obj); - } - - - override protected ITextRegion getLocationOfContainmentReference(EObject owner, EReference feature, - int indexInList, RegionDescription query) { - - var EObject referencedElement = null; - if (feature.isMany()) { - val List values = owner.eGet(feature) as List; - if (indexInList >= values.size()) { - referencedElement = owner; - } else if (indexInList >= 0) { - referencedElement = values.get(indexInList) as EObject; - } - } else { - referencedElement = owner.eGet(feature) as EObject; - } - return getTextRegion(referencedElement, query); - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSPreProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSPreProcessor.java new file mode 100644 index 0000000000..0da071af04 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSPreProcessor.java @@ -0,0 +1,132 @@ +/** + * 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.resource; + +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.toIterable; + +import java.math.BigDecimal; +import java.util.Objects; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.ts.typeRefs.BooleanLiteralTypeRef; +import org.eclipse.n4js.ts.typeRefs.EnumLiteralTypeRef; +import org.eclipse.n4js.ts.typeRefs.NumericLiteralTypeRef; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.StringLiteralTypeRef; +import org.eclipse.n4js.validation.ASTStructureValidator; + +import com.google.inject.Singleton; + +/** + * This class performs some early pre-processing of the AST. This happens after {@link N4JSLinker lazy linking} and + * before {@link ASTStructureValidator AST structure validation}. + */ +@Singleton +@SuppressWarnings("unused") +final class N4JSPreProcessor { + + /** + * Performs an early processing of the AST, e.g. initialization of transient helper values. This method assumes + * that it is allowed to change the AST! Thus, it should be invoked from an "exec without cache clear" handler, + * see {@code OnChangeEvictingCache#execWithoutCacheClear(N4JSResource,IUnitOfWork)}. + */ + public void process(Script script, N4JSResource resource) { + ResourceSet resourceSet = resource.getResourceSet(); + if (resourceSet == null) { + // null-safe exit - required in smoke test where Resources detached from a ResourceSet are used. + return; + } + BuiltInTypeScope builtInTypes = BuiltInTypeScope.get(resourceSet); + for (EObject node : toIterable(resource.getScript().eAllContents())) { + processNode(node, resource, builtInTypes); + } + } + + private void processNode(EObject astNode, N4JSResource resource, BuiltInTypeScope builtInTypes) { + if (astNode instanceof ParameterizedTypeRef) { + processNode((ParameterizedTypeRef) astNode, resource, builtInTypes); + } else if (astNode instanceof BooleanLiteralTypeRef) { + processNode((BooleanLiteralTypeRef) astNode, resource, builtInTypes); + } else if (astNode instanceof NumericLiteralTypeRef) { + processNode((NumericLiteralTypeRef) astNode, resource, builtInTypes); + } else if (astNode instanceof StringLiteralTypeRef) { + processNode((StringLiteralTypeRef) astNode, resource, builtInTypes); + } else if (astNode instanceof EnumLiteralTypeRef) { + processNode((EnumLiteralTypeRef) astNode, resource, builtInTypes); + } else { + // by default, do nothing + } + } + + /** + * Support for array type syntax: + * + *
+	 * let arr: string[];
+	 * 
+ * + * and arrrayN syntax: + * + *
+	 * let tup: [string, int];
+	 * 
+ * + * Note that both {@code string[]} and {@code [string]} results in an {@code Array} + */ + private void processNode(ParameterizedTypeRef typeRef, N4JSResource resource, BuiltInTypeScope builtInTypes) { + if (typeRef.isArrayTypeExpression()) { + typeRef.setDeclaredType(builtInTypes.getArrayType()); + } else if (typeRef.isArrayNTypeExpression()) { + int n = typeRef.getDeclaredTypeArgs().size(); + if (n < 2) { + typeRef.setDeclaredType(builtInTypes.getArrayType()); + } else if (n <= BuiltInTypeScope.ITERABLE_N__MAX_LEN) { + typeRef.setDeclaredType(builtInTypes.getArrayNType(n)); + } else { + // error (a validation will create an issue) + // NOTE: it would be nice to create an InterableN with a union as last type argument + // containing those element types that exceed the ITERABLE_N__MAX_LEN; however, this + // would require AST rewriting, which isn't allowed. + typeRef.setDeclaredType(builtInTypes.getArrayNType(BuiltInTypeScope.ITERABLE_N__MAX_LEN)); + } + } + } + + private void processNode(BooleanLiteralTypeRef typeRef, N4JSResource resource, BuiltInTypeScope builtInTypes) { + typeRef.setValue(Objects.equals(typeRef.getAstValue(), "true")); + } + + private void processNode(NumericLiteralTypeRef typeRef, N4JSResource resource, BuiltInTypeScope builtInTypes) { + BigDecimal valueRaw = (BigDecimal) typeRef.getAstValue(); // validity of this cast is enforced by the grammar + if (valueRaw != null) { + valueRaw = valueRaw.stripTrailingZeros(); + if (typeRef.isAstNegated()) { + valueRaw = valueRaw.negate(); + } + typeRef.setValue(valueRaw); + } else { + // syntax error + typeRef.setValue(BigDecimal.ZERO); + } + } + + private void processNode(StringLiteralTypeRef typeRef, N4JSResource resource, BuiltInTypeScope builtInTypes) { + typeRef.setValue((String) typeRef.getAstValue()); // validity of this cast is enforced by the grammar + } + + private void processNode(EnumLiteralTypeRef typeRef, N4JSResource resource, BuiltInTypeScope builtInTypes) { + // setting the value of an EnumLiteralTypeRef requires scoping and can therefore not be done here; + // see N4JSScopeProvider#getScopeByShortcut() and TypeRefProcessor#processEnumLiteralTypeRefs() + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSPreProcessor.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSPreProcessor.xtend deleted file mode 100644 index 89bc76d73f..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSPreProcessor.xtend +++ /dev/null @@ -1,109 +0,0 @@ -/** - * 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.resource - -import com.google.inject.Singleton -import java.math.BigDecimal -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.ts.typeRefs.BooleanLiteralTypeRef -import org.eclipse.n4js.ts.typeRefs.EnumLiteralTypeRef -import org.eclipse.n4js.ts.typeRefs.NumericLiteralTypeRef -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.typeRefs.StringLiteralTypeRef -import org.eclipse.n4js.validation.ASTStructureValidator - -/** - * This class performs some early pre-processing of the AST. This happens after {@link N4JSLinker lazy linking} and - * before {@link ASTStructureValidator AST structure validation}. - */ -@Singleton -package final class N4JSPreProcessor { - - /** - * Performs an early processing of the AST, e.g. initialization of transient helper values. - * This method assumes that it is allowed to change the AST! Thus, it should be invoked from an "exec without - * cache clear" handler, see {@code OnChangeEvictingCache#execWithoutCacheClear(N4JSResource,IUnitOfWork)}. - */ - def public void process(Script script, N4JSResource resource) { - val resourceSet = resource.resourceSet; - if( resourceSet === null ) { - // null-safe exit - required in smoke test where Resources detached from a ResourceSet are used. - return; - } - val builtInTypes = BuiltInTypeScope.get( resourceSet ); - for (node : resource.script.eAllContents.toIterable) { - processNode(node, resource, builtInTypes); - } - } - - def private dispatch void processNode(EObject astNode, N4JSResource resource, BuiltInTypeScope builtInTypes) { - // by default, do nothing - } - - /** - * Support for array type syntax: - *
-	 * let arr: string[];
-	 * 
- * and arrrayN syntax: - *
-	 * let tup: [string, int];
-	 * 
- * Note that both {@code string[]} and {@code [string]} results in an {@code Array} - */ - def private dispatch void processNode(ParameterizedTypeRef typeRef, N4JSResource resource, BuiltInTypeScope builtInTypes) { - if (typeRef.isArrayTypeExpression) { - typeRef.declaredType = builtInTypes.arrayType; - } else if (typeRef.isArrayNTypeExpression) { - val n = typeRef.declaredTypeArgs.size; - if (n < 2) { - typeRef.declaredType = builtInTypes.arrayType; - } else if (n <= BuiltInTypeScope.ITERABLE_N__MAX_LEN) { - typeRef.declaredType = builtInTypes.getArrayNType(n); - } else { - // error (a validation will create an issue) - // NOTE: it would be nice to create an InterableN with a union as last type argument - // containing those element types that exceed the ITERABLE_N__MAX_LEN; however, this - // would require AST rewriting, which isn't allowed. - typeRef.declaredType = builtInTypes.getArrayNType(BuiltInTypeScope.ITERABLE_N__MAX_LEN); - } - } - } - - def private dispatch void processNode(BooleanLiteralTypeRef typeRef, N4JSResource resource, BuiltInTypeScope builtInTypes) { - typeRef.value = typeRef.astValue == "true"; - } - - def private dispatch void processNode(NumericLiteralTypeRef typeRef, N4JSResource resource, BuiltInTypeScope builtInTypes) { - var valueRaw = typeRef.astValue as BigDecimal; // validity of this cast is enforced by the grammar - if (valueRaw !== null) { - valueRaw = valueRaw.stripTrailingZeros; - if (typeRef.astNegated) { - valueRaw = valueRaw.negate(); - } - typeRef.value = valueRaw; - } else { - // syntax error - typeRef.value = BigDecimal.ZERO; - } - } - - def private dispatch void processNode(StringLiteralTypeRef typeRef, N4JSResource resource, BuiltInTypeScope builtInTypes) { - typeRef.value = typeRef.astValue as String; // validity of this cast is enforced by the grammar - } - - def private dispatch void processNode(EnumLiteralTypeRef typeRef, N4JSResource resource, BuiltInTypeScope builtInTypes) { - // setting the value of an EnumLiteralTypeRef requires scoping and can therefore not be done here; - // see N4JSScopeProvider#getScopeByShortcut() and TypeRefProcessor#processEnumLiteralTypeRefs() - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/PackageJsonResourceDescriptionExtension.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/PackageJsonResourceDescriptionExtension.java new file mode 100644 index 0000000000..61074a98b5 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/PackageJsonResourceDescriptionExtension.java @@ -0,0 +1,380 @@ +/** + * Copyright (c) 2018 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.resource; + +import static com.google.common.base.Strings.nullToEmpty; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filterNull; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.isNullOrEmpty; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toSet; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.n4js.N4JSGlobals; +import org.eclipse.n4js.json.JSON.JSONDocument; +import org.eclipse.n4js.json.JSON.JSONPackage; +import org.eclipse.n4js.json.extension.IJSONResourceDescriptionExtension; +import org.eclipse.n4js.packagejson.PackageJsonUtils; +import org.eclipse.n4js.packagejson.projectDescription.ProjectDependency; +import org.eclipse.n4js.packagejson.projectDescription.ProjectDescription; +import org.eclipse.n4js.packagejson.projectDescription.ProjectReference; +import org.eclipse.n4js.packagejson.projectDescription.ProjectType; +import org.eclipse.n4js.semver.Semver.VersionNumber; +import org.eclipse.n4js.semver.model.SemverSerializer; +import org.eclipse.n4js.utils.ProjectDescriptionLoader; +import org.eclipse.n4js.workspace.locations.FileURI; +import org.eclipse.n4js.workspace.utils.SemanticDependencySupplier; +import org.eclipse.xtext.naming.IQualifiedNameProvider; +import org.eclipse.xtext.naming.QualifiedName; +import org.eclipse.xtext.resource.EObjectDescription; +import org.eclipse.xtext.resource.IEObjectDescription; +import org.eclipse.xtext.resource.IResourceDescription; +import org.eclipse.xtext.resource.IResourceDescription.Delta; +import org.eclipse.xtext.resource.IResourceDescriptions; +import org.eclipse.xtext.util.IAcceptor; + +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; +import com.google.inject.Inject; + +/** + * {@link IJSONResourceDescriptionExtension} implementation that provides custom resource descriptions of + * {@code package.json} resources. + */ +public class PackageJsonResourceDescriptionExtension implements IJSONResourceDescriptionExtension { + + /** + * Separator that is used to serialize multiple project identifiers as a string. + */ + private static String SEPARATOR = ";"; + + /** The key of the user data for retrieving the project name. */ + public static String PROJECT_NAME_KEY = "projectName"; + + /** The key of the user data for retrieving the project version. */ + public static String PROJECT_VERSION_KEY = "projectVersion"; + + /** The key of the user data for retrieving the project type as a string. */ + private static String PROJECT_TYPE_KEY = "projectType"; + + /** Key for the project implementation ID value. {@code null} value will be mapped to empty string. */ + private static String IMPLEMENTATION_ID_KEY = "implementationId"; + + /** + * Key for storing the test project names. If a project does not have any tested projects this key will be missing + * from the user data. The values are separated with the {@link PackageJsonResourceDescriptionExtension#SEPARATOR} + * character. + */ + private static String TESTED_PROJECT_NAMES_KEY = "testedProjectNames"; + + /** + * Key for storing the implemented project names. If a project does not implement any projects this key will be + * missing from the user data. The values are separated with the + * {@link PackageJsonResourceDescriptionExtension#SEPARATOR} character. + */ + private static String IMPLEMENTED_PROJECT_NAMES_KEY = "implementedProjectNames"; + + /** + * Key for storing the project names of all direct dependencies. If a project does not have any direct projects this + * key will be missing from the user data. The values are separated with the + * {@link PackageJsonResourceDescriptionExtension#SEPARATOR} character. + */ + private static String PROJECT_DEPENDENCY_NAMES_KEY = "projectDependencyNames"; + + /** + * Key for storing the project names of all provided runtime libraries. If the project does not provide any runtime + * libraries, then this value will be omitted form the user data. Multiple values are separated with the + * {@link PackageJsonResourceDescriptionExtension#SEPARATOR} character. + */ + private static String PROVIDED_RUNTIME_LIBRARY_NAMES_KEY = "providedRuntimeLibraryNames"; + + /** + * Key for storing the project names of all required runtime libraries. If the project does not have any runtime + * library requirement, this value will not be present in the user data. Multiple values will be joined with the + * {@link PackageJsonResourceDescriptionExtension#SEPARATOR} separator. + */ + private static String REQUIRED_RUNTIME_LIBRARY_NAMES_KEY = "requiredRuntimeLibraryNames"; + + /** + * Key for storing the unique project identifier of the extended runtime environment. If the project does not extend + * any runtime environment, then this value will not exist in the user data. + */ + private static String EXTENDED_RUNTIME_ENVIRONMENT_NAME_KEY = "extendedRuntimeEnvironmentName"; + + @Inject + private IQualifiedNameProvider qualifiedNameProvider; + + @Inject + private ProjectDescriptionLoader projectDescriptionLoader; + + private static final Logger LOGGER = Logger.getLogger(PackageJsonResourceDescriptionExtension.class); + + @Override + public QualifiedName getFullyQualifiedName(EObject obj) { + if (!isPackageJSON(obj)) { + return null; // not responsible + } + + // delegate to the N4JS qualified name provider + // (will return non-null only for JSONDocument, i.e. the root AST node in JSON files) + return qualifiedNameProvider.getFullyQualifiedName(obj); + } + + @Override + public boolean isAffected(Collection deltas, IResourceDescription candidate, IResourceDescriptions context) { + if (!isPackageJSON(candidate)) { + return false; // not responsible + } + + Set changedProjectNames = new LinkedHashSet<>(); + + for (Delta delta : deltas) { + if ((delta.getNew() == null || delta.getOld() == null || delta.haveEObjectDescriptionsChanged()) + && isPackageJSON(delta.getUri())) { + + Iterable exportedObjects = ((delta.getNew() == null) + ? delta.getOld() + : delta.getNew()).getExportedObjects(); + + Iterator iter = exportedObjects.iterator(); + if (iter.hasNext()) { + String projectName = getProjectName(iter.next()); + String packageName = SemanticDependencySupplier.convertProjectIdToPackageName(projectName); + changedProjectNames.add(packageName); + } + } + } + + // Collect all referenced project IDs of the candidate. + List referencedProjectNames = new LinkedList<>(); + for (IEObjectDescription od : candidate.getExportedObjectsByType(JSONPackage.Literals.JSON_DOCUMENT)) { + if (getProjectType(od) == ProjectType.PLAINJS) { + // never rebuild plain-js projects on incremental builds + // return false; + } + referencedProjectNames.addAll(getTestedProjectNames(od)); + referencedProjectNames.addAll(getImplementedProjectNames(od)); + referencedProjectNames.addAll(getProjectDependencyNames(od)); + referencedProjectNames.addAll(getProvidedRuntimeLibraryNames(od)); + referencedProjectNames.addAll(getRequiredRuntimeLibraryNames(od)); + String extRuntimeEnvironmentId = getExtendedRuntimeEnvironmentName(od); + if (!Strings.isNullOrEmpty(extRuntimeEnvironmentId)) { + referencedProjectNames.add(extRuntimeEnvironmentId); + } + } + + // Here we consider only direct project dependencies because this implementation is aligned to the + // N4JS based resource description manager's #isAffected logic. In the N4JS implementation we consider + // only direct project dependencies when checking whether a candidate is affected or not. + // + // See: N4JSResourceDescriptionManager#basicIsAffected and N4JSResourceDescriptionManager#hasDependencyTo + for (String referencedProjectName : referencedProjectNames) { + if (changedProjectNames.contains(referencedProjectName)) { + return true; + } + } + + return false; + } + + @Override + public void createJSONDocumentDescriptions(JSONDocument document, IAcceptor acceptor) { + QualifiedName qualifiedName = getFullyQualifiedName(document); + if (qualifiedName == null) { + return; // not responsible + } + + URI projectLocation = document == null || document.eResource() == null || document.eResource().getURI() == null + ? null + : document.eResource().getURI().trimSegments(1); + if (projectLocation == null) { + LOGGER.error("creation of EObjectDescriptions failed: cannot derive project location from document"); + return; + } + ProjectDescription description = projectDescriptionLoader + .loadProjectDescriptionAtLocation(new FileURI(projectLocation), null, document); + if (description == null) { + // this can happen when package.json files are opened that do not belong to a valid N4JS or PLAINJS project + // (maybe during manual creation of a new project); therefore we cannot log an error here: + // LOGGER.error("creation of EObjectDescriptions failed: cannot load project description at location: " + + // projectLocation); + return; + } + Map userData = createProjectDescriptionUserData(description); + acceptor.accept(new EObjectDescription(qualifiedName, document, userData)); + } + + /** + * Creates the user data of a {@link ProjectDescription} {@link IEObjectDescription}. + */ + private Map createProjectDescriptionUserData(ProjectDescription pd) { + Builder builder = ImmutableMap.builder(); + builder.put(PROJECT_TYPE_KEY, PackageJsonUtils.getProjectTypeStringRepresentation(pd.getProjectType())); + builder.put(PROJECT_NAME_KEY, nullToEmpty(pd.getId())); + builder.put(IMPLEMENTATION_ID_KEY, nullToEmpty(pd.getImplementationId())); + + VersionNumber vers = pd.getVersion(); + if (vers != null) { + String versionStr = SemverSerializer.serialize(vers); + builder.put(PROJECT_VERSION_KEY, versionStr); + } + + List testedProjects = pd.getTestedProjects(); + if (!isNullOrEmpty(testedProjects)) { + builder.put(PackageJsonResourceDescriptionExtension.TESTED_PROJECT_NAMES_KEY, asString(testedProjects)); + } + + List implementedProjects = pd.getImplementedProjects(); + if (!isNullOrEmpty(implementedProjects)) { + builder.put(IMPLEMENTED_PROJECT_NAMES_KEY, asString(implementedProjects)); + } + + List projectDependencies = pd.getProjectDependencies(); + if (!isNullOrEmpty(projectDependencies)) { + builder.put(PROJECT_DEPENDENCY_NAMES_KEY, asString(projectDependencies)); + } + + List providedRuntimeLibraries = pd.getProvidedRuntimeLibraries(); + if (!isNullOrEmpty(providedRuntimeLibraries)) { + builder.put(PROVIDED_RUNTIME_LIBRARY_NAMES_KEY, asString(providedRuntimeLibraries)); + } + + List requiredRuntimeLibraries = pd.getRequiredRuntimeLibraries(); + if (!isNullOrEmpty(requiredRuntimeLibraries)) { + builder.put(REQUIRED_RUNTIME_LIBRARY_NAMES_KEY, asString(requiredRuntimeLibraries)); + } + + ProjectReference extRuntimeEnvironment = pd.getExtendedRuntimeEnvironment(); + if (extRuntimeEnvironment != null) { + builder.put(EXTENDED_RUNTIME_ENVIRONMENT_NAME_KEY, + asString(Collections.singleton(pd.getExtendedRuntimeEnvironment()))); + } + + return builder.build(); + } + + /** + * Optionally returns with the project type extracted from the user data of the given EObject description argument. + */ + public static ProjectType getProjectType(IEObjectDescription it) { + if (it == null) { + return null; + } + String projectTypeStr = it.getUserData(PROJECT_TYPE_KEY); + if (projectTypeStr == null) { + return null; + } + return PackageJsonUtils.parseProjectType(projectTypeStr); + } + + /** + * Optionally returns with the project name extracted from the user data of the given EObject description argument. + */ + public static String getProjectName(IEObjectDescription it) { + if (it == null) { + return null; + } + return it.getUserData(PROJECT_NAME_KEY); + } + + /** + * Returns with a collection of distinct IDs of the tested projects. Never returns with {@code null}. + */ + public static Set getTestedProjectNames(IEObjectDescription od) { + return getProjectNamesUserDataOf(od, PackageJsonResourceDescriptionExtension.TESTED_PROJECT_NAMES_KEY); + } + + /** + * Returns with a collection of distinct IDs of the implemented projects. Never returns with {@code null}. + */ + public static Set getImplementedProjectNames(IEObjectDescription od) { + return getProjectNamesUserDataOf(od, IMPLEMENTED_PROJECT_NAMES_KEY); + } + + /** + * Returns with a collection of distinct IDs of the project dependencies. Never returns with {@code null}. + */ + public static Set getProjectDependencyNames(IEObjectDescription od) { + return getProjectNamesUserDataOf(od, PROJECT_DEPENDENCY_NAMES_KEY); + } + + /** + * Returns with a collection of distinct IDs of the provided runtime libraries. Never returns with {@code null}. + */ + public static Set getProvidedRuntimeLibraryNames(IEObjectDescription od) { + return getProjectNamesUserDataOf(od, PROVIDED_RUNTIME_LIBRARY_NAMES_KEY); + } + + /** + * Returns with a collection of distinct IDs of the required runtime libraries. Never returns with {@code null}. + */ + public static Set getRequiredRuntimeLibraryNames(IEObjectDescription od) { + return getProjectNamesUserDataOf(od, REQUIRED_RUNTIME_LIBRARY_NAMES_KEY); + } + + /** + * Returns with the ID of the extended runtime environment. May return with {@code null} if argument is {@code null} + * or if the value of the user data key is {@code null}. In a nutshell, if a project does not extend a RE. + */ + public static String getExtendedRuntimeEnvironmentName(IEObjectDescription od) { + if (od == null) { + return null; + } + return od.getUserData(EXTENDED_RUNTIME_ENVIRONMENT_NAME_KEY); + } + + /** + * Returns with a collection of distinct project IDs extracted from the user data. Never returns with {@code null}. + */ + private static Set getProjectNamesUserDataOf(IEObjectDescription it, String key) { + if (it == null) { + return Collections.emptySet(); + } + return toSet(filter(Arrays.asList(nullToEmpty(it.getUserData(key)).split(SEPARATOR)), + str -> !Strings.isNullOrEmpty(str))); + } + + private static String asString(Iterable it) { + return org.eclipse.n4js.utils.Strings.join(SEPARATOR, + filterNull(map(filterNull(it), pr -> pr.getPackageName()))); + } + + private static boolean isPackageJSON(IResourceDescription desc) { + return desc != null && isPackageJSON(desc.getURI()); + } + + private static boolean isPackageJSON(EObject obj) { + return obj != null && isPackageJSON(obj.eResource()); + } + + private static boolean isPackageJSON(Resource res) { + return res != null && isPackageJSON(res.getURI()); + } + + private static boolean isPackageJSON(URI uri) { + return uri != null && Objects.equals(uri.lastSegment(), N4JSGlobals.PACKAGE_JSON); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/PackageJsonResourceDescriptionExtension.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/PackageJsonResourceDescriptionExtension.xtend deleted file mode 100644 index 4e812d1c84..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/PackageJsonResourceDescriptionExtension.xtend +++ /dev/null @@ -1,344 +0,0 @@ -/** - * Copyright (c) 2018 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.resource - -import com.google.common.collect.ImmutableMap -import com.google.inject.Inject -import java.util.Collection -import java.util.Collections -import java.util.Map -import org.apache.log4j.Logger -import org.eclipse.emf.common.util.URI -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.resource.Resource -import org.eclipse.n4js.N4JSGlobals -import org.eclipse.n4js.json.JSON.JSONDocument -import org.eclipse.n4js.json.JSON.JSONPackage -import org.eclipse.n4js.json.^extension.IJSONResourceDescriptionExtension -import org.eclipse.n4js.packagejson.PackageJsonUtils -import org.eclipse.n4js.packagejson.projectDescription.ProjectDescription -import org.eclipse.n4js.packagejson.projectDescription.ProjectReference -import org.eclipse.n4js.semver.model.SemverSerializer -import org.eclipse.n4js.utils.ProjectDescriptionLoader -import org.eclipse.n4js.workspace.locations.FileURI -import org.eclipse.n4js.workspace.utils.SemanticDependencySupplier -import org.eclipse.xtext.naming.IQualifiedNameProvider -import org.eclipse.xtext.naming.QualifiedName -import org.eclipse.xtext.resource.EObjectDescription -import org.eclipse.xtext.resource.IEObjectDescription -import org.eclipse.xtext.resource.IResourceDescription -import org.eclipse.xtext.resource.IResourceDescription.Delta -import org.eclipse.xtext.resource.IResourceDescriptions -import org.eclipse.xtext.util.IAcceptor - -import static extension com.google.common.base.Strings.nullToEmpty -import org.eclipse.n4js.packagejson.projectDescription.ProjectType - -/** - * {@link IJSONResourceDescriptionExtension} implementation that provides custom resource descriptions of - * {@code package.json} resources. - */ -class PackageJsonResourceDescriptionExtension implements IJSONResourceDescriptionExtension { - - /** - * Separator that is used to serialize multiple project identifiers as a string. - */ - private static val SEPARATOR = ";"; - - /** The key of the user data for retrieving the project name. */ - public static val PROJECT_NAME_KEY = 'projectName'; - - /** The key of the user data for retrieving the project version. */ - public static val PROJECT_VERSION_KEY = 'projectVersion'; - - /** The key of the user data for retrieving the project type as a string. */ - private static val PROJECT_TYPE_KEY = 'projectType'; - - /** Key for the project implementation ID value. {@code null} value will be mapped to empty string. */ - private static val IMPLEMENTATION_ID_KEY = 'implementationId'; - - /** - * Key for storing the test project names. - * If a project does not have any tested projects this key will be missing from the user data. - * The values are separated with the {@link PackageJsonResourceDescriptionExtension#SEPARATOR} character. - */ - private static val TESTED_PROJECT_NAMES_KEY = 'testedProjectNames'; - - /** - * Key for storing the implemented project names. - * If a project does not implement any projects this key will be missing from the user data. - * The values are separated with the {@link PackageJsonResourceDescriptionExtension#SEPARATOR} character. - */ - private static val IMPLEMENTED_PROJECT_NAMES_KEY = 'implementedProjectNames'; - - /** - * Key for storing the project names of all direct dependencies. - * If a project does not have any direct projects this key will be missing from the user data. - * The values are separated with the {@link PackageJsonResourceDescriptionExtension#SEPARATOR} character. - */ - private static val PROJECT_DEPENDENCY_NAMES_KEY = 'projectDependencyNames'; - - /** - * Key for storing the project names of all provided runtime libraries. - * If the project does not provide any runtime libraries, then this value will be omitted form the user data. - * Multiple values are separated with the {@link PackageJsonResourceDescriptionExtension#SEPARATOR} character. - */ - private static val PROVIDED_RUNTIME_LIBRARY_NAMES_KEY = 'providedRuntimeLibraryNames'; - - /** - * Key for storing the project names of all required runtime libraries. - * If the project does not have any runtime library requirement, this value will not be present in the user data. - * Multiple values will be joined with the {@link PackageJsonResourceDescriptionExtension#SEPARATOR} separator. - */ - private static val REQUIRED_RUNTIME_LIBRARY_NAMES_KEY = 'requiredRuntimeLibraryNames'; - - /** - * Key for storing the unique project identifier of the extended runtime environment. If the project does not - * extend any runtime environment, then this value will not exist in the user data. - */ - private static val EXTENDED_RUNTIME_ENVIRONMENT_NAME_KEY = 'extendedRuntimeEnvironmentName'; - - @Inject - private IQualifiedNameProvider qualifiedNameProvider; - - @Inject - private ProjectDescriptionLoader projectDescriptionLoader; - - private static final Logger LOGGER = Logger.getLogger(PackageJsonResourceDescriptionExtension); - - - override QualifiedName getFullyQualifiedName(EObject obj) { - if (!obj.isPackageJSON) { - return null; // not responsible - } - - // delegate to the N4JS qualified name provider - // (will return non-null only for JSONDocument, i.e. the root AST node in JSON files) - return qualifiedNameProvider.getFullyQualifiedName(obj); - } - - - override boolean isAffected(Collection deltas, IResourceDescription candidate, IResourceDescriptions context) { - if (!candidate.isPackageJSON) { - return false; // not responsible - } - - val changedProjectNames = deltas - .filter[(it.getNew === null || it.getOld === null || it.haveEObjectDescriptionsChanged) && it.uri.isPackageJSON] - .map[(if (it.getNew === null) it.old else it.getNew).exportedObjects] - .filter[!it.empty] - .map[it.get(0).getProjectName] - .map[SemanticDependencySupplier.convertProjectIdToPackageName(it)] - .toSet; - - - // Collect all referenced project IDs of the candidate. - val referencedProjectNames = newLinkedList; - for (it : candidate.getExportedObjectsByType(JSONPackage.Literals.JSON_DOCUMENT)) { - if (getProjectType === ProjectType.PLAINJS) { - // never rebuild plain-js projects on incremental builds - // return false; - } - referencedProjectNames.addAll(testedProjectNames); - referencedProjectNames.addAll(implementedProjectNames); - referencedProjectNames.addAll(projectDependencyNames); - referencedProjectNames.addAll(providedRuntimeLibraryNames); - referencedProjectNames.addAll(requiredRuntimeLibraryNames); - val extRuntimeEnvironmentId = extendedRuntimeEnvironmentName; - if (!extRuntimeEnvironmentId.nullOrEmpty) { - referencedProjectNames.add(extRuntimeEnvironmentId); - } - } - - // Here we consider only direct project dependencies because this implementation is aligned to the - // N4JS based resource description manager's #isAffected logic. In the N4JS implementation we consider - // only direct project dependencies when checking whether a candidate is affected or not. - // - // See: N4JSResourceDescriptionManager#basicIsAffected and N4JSResourceDescriptionManager#hasDependencyTo - for (referencedProjectName : referencedProjectNames) { - if (changedProjectNames.contains(referencedProjectName)) { - return true; - } - } - - return false; - } - - override void createJSONDocumentDescriptions(JSONDocument document, IAcceptor acceptor) { - val qualifiedName = getFullyQualifiedName(document); - if (qualifiedName === null) { - return; // not responsible - } - - val projectLocation = document?.eResource?.URI?.trimSegments(1); - if(projectLocation === null) { - LOGGER.error("creation of EObjectDescriptions failed: cannot derive project location from document"); - return; - } - val description = projectDescriptionLoader.loadProjectDescriptionAtLocation(new FileURI(projectLocation), null, document); - if(description === null) { - // this can happen when package.json files are opened that do not belong to a valid N4JS or PLAINJS project - // (maybe during manual creation of a new project); therefore we cannot log an error here: - // LOGGER.error("creation of EObjectDescriptions failed: cannot load project description at location: " + projectLocation); - return; - } - val userData = createProjectDescriptionUserData(description); - acceptor.accept(new EObjectDescription(qualifiedName, document, userData)); - } - - /** - * Creates the user data of a {@link ProjectDescription} {@link IEObjectDescription}. - */ - private def Map createProjectDescriptionUserData(ProjectDescription it) { - val builder = ImmutableMap.builder; - builder.put(PROJECT_TYPE_KEY, '''«PackageJsonUtils.getProjectTypeStringRepresentation(getProjectType)»'''); - builder.put(PROJECT_NAME_KEY, id.nullToEmpty); - builder.put(IMPLEMENTATION_ID_KEY, implementationId.nullToEmpty); - - val vers = getVersion; - if (vers !== null) { - val versionStr = SemverSerializer.serialize(vers); - builder.put(PROJECT_VERSION_KEY, versionStr); - } - - val testedProjects = it.testedProjects; - if (!testedProjects.nullOrEmpty) { - builder.put(PackageJsonResourceDescriptionExtension.TESTED_PROJECT_NAMES_KEY, testedProjects.asString); - } - - val implementedProjects = it.implementedProjects; - if (!implementedProjects.nullOrEmpty) { - builder.put(IMPLEMENTED_PROJECT_NAMES_KEY, implementedProjects.asString); - } - - val projectDependencies = it.projectDependencies; - if (!projectDependencies.nullOrEmpty) { - builder.put(PROJECT_DEPENDENCY_NAMES_KEY, projectDependencies.asString); - } - - val providedRuntimeLibraries = providedRuntimeLibraries; - if (!providedRuntimeLibraries.nullOrEmpty) { - builder.put(PROVIDED_RUNTIME_LIBRARY_NAMES_KEY, providedRuntimeLibraries.asString); - } - - val requiredRuntimeLibraries = requiredRuntimeLibraries; - if (!requiredRuntimeLibraries.nullOrEmpty) { - builder.put(REQUIRED_RUNTIME_LIBRARY_NAMES_KEY, requiredRuntimeLibraries.asString); - } - - val extRuntimeEnvironment = it.extendedRuntimeEnvironment; - if (extRuntimeEnvironment !== null) { - builder.put(EXTENDED_RUNTIME_ENVIRONMENT_NAME_KEY, Collections.singleton(it.extendedRuntimeEnvironment).asString); - } - - return builder.build; - } - - /** - * Optionally returns with the project type extracted from the user data of the given EObject description argument. - */ - public static def getProjectType(IEObjectDescription it) { - if (it === null) { - return null; - } - val projectTypeStr = it.getUserData(PROJECT_TYPE_KEY); - if (projectTypeStr === null) { - return null; - } - return PackageJsonUtils.parseProjectType(projectTypeStr); - } - - /** - * Optionally returns with the project name extracted from the user data of the given EObject description argument. - */ - public static def getProjectName(IEObjectDescription it) { - if (it === null) { - return null; - } - return it.getUserData(PROJECT_NAME_KEY); - } - - /** - * Returns with a collection of distinct IDs of the tested projects. Never returns with {@code null}. - */ - public static def getTestedProjectNames(IEObjectDescription it) { - return getProjectNamesUserDataOf(PackageJsonResourceDescriptionExtension.TESTED_PROJECT_NAMES_KEY); - } - - /** - * Returns with a collection of distinct IDs of the implemented projects. Never returns with {@code null}. - */ - public static def getImplementedProjectNames(IEObjectDescription it) { - return getProjectNamesUserDataOf(IMPLEMENTED_PROJECT_NAMES_KEY); - } - - /** - * Returns with a collection of distinct IDs of the project dependencies. Never returns with {@code null}. - */ - public static def getProjectDependencyNames(IEObjectDescription it) { - return getProjectNamesUserDataOf(PROJECT_DEPENDENCY_NAMES_KEY); - } - - /** - * Returns with a collection of distinct IDs of the provided runtime libraries. Never returns with {@code null}. - */ - public static def getProvidedRuntimeLibraryNames(IEObjectDescription it) { - return getProjectNamesUserDataOf(PROVIDED_RUNTIME_LIBRARY_NAMES_KEY); - } - - /** - * Returns with a collection of distinct IDs of the required runtime libraries. Never returns with {@code null}. - */ - public static def getRequiredRuntimeLibraryNames(IEObjectDescription it) { - return getProjectNamesUserDataOf(REQUIRED_RUNTIME_LIBRARY_NAMES_KEY); - } - - /** - * Returns with the ID of the extended runtime environment. May return with {@code null} if argument is {@code null} - * or if the value of the user data key is {@code null}. In a nutshell, if a project does not extend a RE. - */ - public static def getExtendedRuntimeEnvironmentName(IEObjectDescription it) { - if (it === null) { - return null; - } - return it.getUserData(EXTENDED_RUNTIME_ENVIRONMENT_NAME_KEY); - } - - /** - * Returns with a collection of distinct project IDs extracted from the user data. Never returns with {@code null}. - */ - private static def getProjectNamesUserDataOf(IEObjectDescription it, String key) { - if (it === null) { - return emptySet; - } - return it.getUserData(key).nullToEmpty.split(SEPARATOR).filter[!nullOrEmpty].toSet; - } - - private static def String asString(Iterable it) { - it.filterNull.map[getPackageName].filterNull.join(SEPARATOR) - } - - private static def boolean isPackageJSON(IResourceDescription desc) { - return desc !== null && isPackageJSON(desc.URI); - } - - private static def boolean isPackageJSON(EObject obj) { - return obj !== null && isPackageJSON(obj.eResource); - } - - private static def boolean isPackageJSON(Resource res) { - return res !== null && isPackageJSON(res.URI); - } - - private static def boolean isPackageJSON(URI uri) { - return uri !== null && uri.lastSegment == N4JSGlobals.PACKAGE_JSON; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/XpectAwareFileExtensionCalculator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/XpectAwareFileExtensionCalculator.java new file mode 100644 index 0000000000..1f37ad8e47 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/XpectAwareFileExtensionCalculator.java @@ -0,0 +1,97 @@ +/** + * 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.resource; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; +import org.eclipse.n4js.N4JSGlobals; +import org.eclipse.n4js.utils.URIUtils; + +import com.google.common.base.Objects; +import com.google.common.base.Strings; +import com.google.inject.Singleton; + +/** + * This class provides methods for calculating file extensions. The calculation takes into account Xpect file extension + * {@code .xt}. Custom file Xpect file extensions are not supported e.g. when your Xpect tests are configured to run + * with {@code .xt} file extension. Deeply nested structures are also not supported e.g. using {@code file.n4js.xt.xt}. + */ +@Singleton +public class XpectAwareFileExtensionCalculator { + + /***/ + public String getXpectAwareFileExtension(EObject eob) { + URI uri = getURI(eob); + return getXpectAwareFileExtension(uri); + } + + private URI getURI(EObject eob) { + if (eob == null) { + return null; + } + if (eob.eResource() != null) { + return eob.eResource().getURI(); + } + if (eob instanceof MinimalEObjectImpl) { + return ((MinimalEObjectImpl) eob).eProxyURI().trimFragment(); + } + return null; + } + + /** + * Return the file extension of an URI + */ + public String getXpectAwareFileExtension(URI uri) { + if (uri == null) { + return ""; + } + return getXpectAwareFileExtensionOrEmpty(uri); + } + + /** + * Returns the name of the file that is referenced by {@code uri} without the potential additional X!PECT file + * extension. + */ + public String getFilenameWithoutXpectExtension(URI uri) { + if (!Objects.equal(URIUtils.fileExtension(uri), getXpectAwareFileExtension(uri))) { + return URIUtils.trimFileExtension(uri).lastSegment(); + } else { + return uri.lastSegment(); + } + } + + /** + * Returns the URI of the given EObject but without the Xpect file extension in case that is present. + */ + public URI getUriWithoutXpectExtension(EObject eob) { + URI uri = getURI(eob); + return getUriWithoutXpectExtension(uri); + } + + /** + * Removes the Xpect file extension in case that is present of the given URI. + */ + public URI getUriWithoutXpectExtension(URI uri) { + String fileName = getFilenameWithoutXpectExtension(uri); + URI uriWithoutXpectExtension = uri.trimSegments(1).appendSegment(fileName); + return uriWithoutXpectExtension; + } + + private String getXpectAwareFileExtensionOrEmpty(URI uri) { + String ext = URIUtils.fileExtension(uri); + if (N4JSGlobals.XT_FILE_EXTENSION.equals(ext)) { + // get nested file ext + ext = URIUtils.fileExtension(uri.trimFileExtension()); + } + return Strings.nullToEmpty(ext); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/XpectAwareFileExtensionCalculator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/XpectAwareFileExtensionCalculator.xtend deleted file mode 100644 index 93f1ba5d6e..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/XpectAwareFileExtensionCalculator.xtend +++ /dev/null @@ -1,95 +0,0 @@ -/** - * 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.resource - -import com.google.common.base.Strings -import com.google.inject.Singleton -import org.eclipse.emf.common.util.URI -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.impl.MinimalEObjectImpl -import org.eclipse.n4js.N4JSGlobals -import org.eclipse.n4js.utils.URIUtils - -/** - * This class provides methods for calculating file extensions. The calculation takes into account Xpect file extension - * {@code .xt}. Custom file Xpect file extensions are not supported e.g. when your Xpect tests are configured to run with {@code .xxt} file extension. - * Deeply nested structures are also not supported e.g. using {@code file.n4js.xt.xt}. - */ - @Singleton -public class XpectAwareFileExtensionCalculator { - - def public String getXpectAwareFileExtension(EObject eob) { - val uri = getURI(eob); - return getXpectAwareFileExtension(uri); - } - - def private URI getURI(EObject eob) { - if (eob === null) { - return null; - } - if (eob.eResource !== null) { - return eob.eResource.URI; - } - if (eob instanceof MinimalEObjectImpl) { - return eob.eProxyURI.trimFragment; - } - return null; - } - - /** - * Return the file extension of an URI - */ - def public String getXpectAwareFileExtension(URI uri) { - if (uri === null) { - return ""; - } - return getXpectAwareFileExtensionOrEmpty(uri) - } - - /** - * Returns the name of the file that is referenced by {@code uri} - * without the potential additional X!PECT file extension. - */ - def public String getFilenameWithoutXpectExtension(URI uri) { - if (URIUtils.fileExtension(uri) != getXpectAwareFileExtension(uri)) { - return URIUtils.trimFileExtension(uri).lastSegment; - } else { - return uri.lastSegment; - } - } - - /** - * Returns the URI of the given EObject but without the Xpect file - * extension in case that is present. - */ - def public URI getUriWithoutXpectExtension(EObject eob) { - val uri = getURI(eob); - return getUriWithoutXpectExtension(uri); - } - - /** - * Removes the Xpect file extension in case that is present of the given URI. - */ - def public URI getUriWithoutXpectExtension(URI uri) { - val fileName = getFilenameWithoutXpectExtension(uri); - val uriWithoutXpectExtension = uri.trimSegments(1).appendSegment(fileName); - return uriWithoutXpectExtension; - } - - def private String getXpectAwareFileExtensionOrEmpty(URI uri){ - var ext = URIUtils.fileExtension(uri); - if(N4JSGlobals.XT_FILE_EXTENSION.equals(ext)){ - //get nested file ext - ext = URIUtils.fileExtension(uri.trimFileExtension) - } - return Strings.nullToEmpty(ext) - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/N4JSScopeProvider.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/N4JSScopeProvider.java new file mode 100644 index 0000000000..054978a157 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/N4JSScopeProvider.java @@ -0,0 +1,1121 @@ +/** + * 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.scoping; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.isIterableN; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.newRuleEnvironment; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.flatten; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.last; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.toIterable; +import static org.eclipse.xtext.xbase.lib.ListExtensions.reverseView; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.n4js.n4JS.Argument; +import org.eclipse.n4js.n4JS.ArrayBindingPattern; +import org.eclipse.n4js.n4JS.BindingElement; +import org.eclipse.n4js.n4JS.BindingProperty; +import org.eclipse.n4js.n4JS.DestructNode; +import org.eclipse.n4js.n4JS.DestructureUtils; +import org.eclipse.n4js.n4JS.ExportDeclaration; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.JSXElement; +import org.eclipse.n4js.n4JS.JSXElementName; +import org.eclipse.n4js.n4JS.JSXPropertyAttribute; +import org.eclipse.n4js.n4JS.LabelledStatement; +import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName; +import org.eclipse.n4js.n4JS.MemberAccess; +import org.eclipse.n4js.n4JS.ModuleRef; +import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; +import org.eclipse.n4js.n4JS.N4ClassifierDefinition; +import org.eclipse.n4js.n4JS.N4FieldAccessor; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.N4NamespaceDeclaration; +import org.eclipse.n4js.n4JS.N4TypeDeclaration; +import org.eclipse.n4js.n4JS.NamedExportSpecifier; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NewExpression; +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.n4JS.Statement; +import org.eclipse.n4js.n4JS.TypeDefiningElement; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.VariableEnvironmentElement; +import org.eclipse.n4js.resource.N4JSCache; +import org.eclipse.n4js.resource.N4JSResource; +import org.eclipse.n4js.scoping.accessModifiers.ContextAwareTypeScope; +import org.eclipse.n4js.scoping.accessModifiers.MemberVisibilityChecker; +import org.eclipse.n4js.scoping.imports.ImportedElementsScopingHelper; +import org.eclipse.n4js.scoping.imports.N4JSImportedNamespaceAwareLocalScopeProvider; +import org.eclipse.n4js.scoping.members.MemberScopingHelper; +import org.eclipse.n4js.scoping.utils.DynamicPseudoScope; +import org.eclipse.n4js.scoping.utils.LocallyKnownTypesScopingHelper; +import org.eclipse.n4js.scoping.utils.MainModuleAwareSelectableBasedScope; +import org.eclipse.n4js.scoping.utils.MergedScope; +import org.eclipse.n4js.scoping.utils.ProjectImportEnablingScope; +import org.eclipse.n4js.scoping.utils.ScopeSnapshotHelper; +import org.eclipse.n4js.scoping.utils.SourceElementExtensions; +import org.eclipse.n4js.scoping.utils.UberParentScope; +import org.eclipse.n4js.scoping.validation.ContextAwareTypeScopeValidator; +import org.eclipse.n4js.scoping.validation.ScopeInfo; +import org.eclipse.n4js.scoping.validation.VeeScopeValidator; +import org.eclipse.n4js.scoping.validation.VisibilityAwareCtorScopeValidator; +import org.eclipse.n4js.tooling.react.ReactHelper; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression; +import org.eclipse.n4js.ts.typeRefs.NamespaceLikeRef; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRefStructural; +import org.eclipse.n4js.ts.typeRefs.TypeArgument; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRefsPackage; +import org.eclipse.n4js.ts.typeRefs.TypeTypeRef; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TEnum; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.TNamespace; +import org.eclipse.n4js.ts.types.TStructMethod; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.ts.types.TypesPackage; +import org.eclipse.n4js.ts.types.TypingStrategy; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.n4js.utils.ContainerTypesHelper; +import org.eclipse.n4js.utils.DeclMergingHelper; +import org.eclipse.n4js.utils.DeclMergingUtils; +import org.eclipse.n4js.utils.EObjectDescriptionHelper; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.ResourceType; +import org.eclipse.n4js.utils.URIUtils; +import org.eclipse.n4js.validation.JavaScriptVariantHelper; +import org.eclipse.n4js.workspace.N4JSWorkspaceConfigSnapshot; +import org.eclipse.n4js.workspace.WorkspaceAccess; +import org.eclipse.n4js.xtext.scoping.FilteringScope; +import org.eclipse.xtext.EcoreUtil2; +import org.eclipse.xtext.naming.QualifiedName; +import org.eclipse.xtext.resource.EObjectDescription; +import org.eclipse.xtext.resource.IEObjectDescription; +import org.eclipse.xtext.resource.IResourceDescriptions; +import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider; +import org.eclipse.xtext.scoping.IScope; +import org.eclipse.xtext.scoping.IScopeProvider; +import org.eclipse.xtext.scoping.impl.AbstractScopeProvider; +import org.eclipse.xtext.scoping.impl.IDelegatingScopeProvider; + +import com.google.common.base.Optional; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import com.google.inject.name.Named; + +/** + * This class contains custom scoping description. + * + * Although some methods are called according to declarative scope provider, no reflection in + * {@link #getScope(EObject,EReference)}. + * + * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping on how and when to use it + */ +@Singleton +public class N4JSScopeProvider extends AbstractScopeProvider + implements IDelegatingScopeProvider, IContentAssistScopeProvider { + + /***/ + public final static String NAMED_DELEGATE = "org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.delegate"; + + @Inject + N4JSCache cache; + + /** + * The scope provider creating the "parent" scope, i.e. including elements from the index. At runtime, the value + * will be of type {@link N4JSImportedNamespaceAwareLocalScopeProvider}. + */ + @Inject + @Named(NAMED_DELEGATE) + IScopeProvider delegate; + + @Inject + WorkspaceAccess workspaceAccess; + + @Inject + ResourceDescriptionsProvider resourceDescriptionsProvider; + + @Inject + N4JSTypeSystem ts; + + @Inject + TypeSystemHelper tsh; + + @Inject + MemberScopingHelper memberScopingHelper; + + @Inject + LocallyKnownTypesScopingHelper locallyKnownTypesScopingHelper; + + @Inject + ImportedElementsScopingHelper importedElementsScopingHelper; + + @Inject + SourceElementExtensions sourceElementExtensions; + + @Inject + EObjectDescriptionHelper descriptionsHelper; + + @Inject + ReactHelper reactHelper; + + @Inject + JavaScriptVariantHelper jsVariantHelper; + + @Inject + MemberVisibilityChecker checker; + + @Inject + ContainerTypesHelper containerTypesHelper; + + @Inject + ExportedElementsCollector exportedElementCollector; + + @Inject + ScopeSnapshotHelper scopeSnapshotHelper; + + @Inject + DeclMergingHelper declMergingHelper; + + /***/ + protected boolean isSuppressCrossFileResolutionOfIdentifierRefs() { + return false; + } + + /** + * Delegates to {@link N4JSImportedNamespaceAwareLocalScopeProvider#getScope(EObject, EReference)}, which in turn + * delegates further to {@link N4JSGlobalScopeProvider}. + */ + protected IScope delegateGetScope(EObject context, EReference reference) { + return delegate.getScope(context, reference); + } + + @Override + public IScopeProvider getDelegate() { + return delegate; + } + + /** Dispatches to concrete scopes based on the context and reference inspection */ + @Override + public IScope getScope(EObject context, EReference reference) { + try { + // dispatch based on language variant + ResourceType resourceType = ResourceType.getResourceType(context); + switch (resourceType) { + case N4JSX: + return getN4JSXScope(context, reference); + case JSX: + return getN4JSXScope(context, reference); + default: + return getN4JSScope(context, reference); + } + + } catch (Error ex) { + if (context != null && context.eResource().getErrors().isEmpty()) { + throw ex; + } else { + // swallow exception, we got a parse error anyway + } + } + + return IScope.NULLSCOPE; + } + + /** + * Returns the N4JS scope for the given context and reference. + * + * The returned scope is not sensitive to any of the language variants of N4JS. In order to obtain a + * variant-specific scope, please use {@link N4JSScopeProvider#getScope(EObject, EReference)}. + */ + public IScope getN4JSScope(EObject context, EReference reference) { + // maybe can use scope shortcut + IScope maybeScopeShortcut = getScopeByShortcut(context, reference); + if (maybeScopeShortcut != IScope.NULLSCOPE) { + return maybeScopeShortcut; + } + + // otherwise use context: + return getScopeForContext(context, reference); + } + + /** + * shortcut to concrete scopes based on reference sniffing. Will return {@link IScope#NULLSCOPE} if no suitable + * scope found + */ + private IScope getScopeByShortcut(EObject context, EReference reference) { + if (reference == TypeRefsPackage.Literals.NAMESPACE_LIKE_REF__DECLARED_TYPE) { + if (context instanceof NamespaceLikeRef) { + NamespaceLikeRef nslr = (NamespaceLikeRef) context; + Type namespaceLikeType = nslr.getPreviousSibling() == null + ? null + : nslr.getPreviousSibling().getDeclaredType(); + + Script script = EcoreUtil2.getContainerOfType(context, Script.class); + N4NamespaceDeclaration parentNamespace = EcoreUtil2.getContainerOfType(context, + N4NamespaceDeclaration.class); + EObject parentContainer = parentNamespace == null ? script : parentNamespace; + // also check for eIsProxy in case of broken AST + EObject namespace = namespaceLikeType == null || namespaceLikeType.eIsProxy() ? parentContainer + : namespaceLikeType; + return new FilteringScope(getTypeScope(namespace, false, true), + descr -> TypesPackage.Literals.MODULE_NAMESPACE_VIRTUAL_TYPE.isSuperTypeOf(descr.getEClass()) + // only included, because classes might have a namespace merged onto them! + || TypesPackage.Literals.TCLASS.isSuperTypeOf(descr.getEClass()) + || TypesPackage.Literals.TENUM.isSuperTypeOf(descr.getEClass()) + || TypesPackage.Literals.TNAMESPACE.isSuperTypeOf(descr.getEClass())); + } + } else if (reference == TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF__DECLARED_TYPE) { + if (context instanceof ParameterizedTypeRef) { + ParameterizedTypeRef ptr = (ParameterizedTypeRef) context; + Type namespaceLikeType = null; + if (ptr.getAstNamespaceLikeRefs() != null && !ptr.getAstNamespaceLikeRefs().isEmpty()) { + namespaceLikeType = last(ptr.getAstNamespaceLikeRefs()).getDeclaredType(); + } + if (namespaceLikeType instanceof ModuleNamespaceVirtualType) { + return createScopeForNamespaceAccess((ModuleNamespaceVirtualType) namespaceLikeType, context, true, + false); + } else if (namespaceLikeType instanceof TClass) { + return createScopeForMergedNamespaces(context, namespaceLikeType, IScope.NULLSCOPE); + } else if (namespaceLikeType instanceof TEnum) { + return new DynamicPseudoScope(); + } else if (namespaceLikeType instanceof TNamespace) { + return scope_AllTopLevelElementsFromAbstractNamespace((TNamespace) namespaceLikeType, context, true, + false); + } + } + return getTypeScope(context, false, false); + } else if (reference.getEReferenceType() == N4JSPackage.Literals.LABELLED_STATEMENT) { + return scope_LabelledStatement(context); + } + return IScope.NULLSCOPE; + } + + /** dispatch to internal methods based on the context */ + private IScope getScopeForContext(EObject context, EReference reference) { + if (context instanceof ImportDeclaration) { + return scope_ImportedModule((ImportDeclaration) context); + } else if (context instanceof NamedImportSpecifier) { + return scope_ImportedElement((NamedImportSpecifier) context); + } else if (context instanceof ExportDeclaration) { + return scope_ImportedModule((ExportDeclaration) context); + } else if (context instanceof IdentifierRef) { + return scope_IdentifierRef_id((IdentifierRef) context, reference); + } else if (context instanceof BindingProperty) { + return scope_BindingProperty_property((BindingProperty) context); + } else if (context instanceof PropertyNameValuePair) { + return scope_PropertyNameValuePair_property((PropertyNameValuePair) context); + } else if (context instanceof ParameterizedPropertyAccessExpression) { + return scope_PropertyAccessExpression_property((ParameterizedPropertyAccessExpression) context); + } else if (context instanceof N4FieldAccessor) { + N4ClassifierDefinition container = EcoreUtil2.getContainerOfType((N4FieldAccessor) context, + N4ClassifierDefinition.class); + return scopeSnapshotHelper.scopeForEObjects("N4FieldAccessor", container, container.getOwnedFields()); + } + return IScope.NULLSCOPE; + } + + @Override + public IScope getScopeForContentAssist(EObject context, EReference reference) { + IScope scope = getScope(context, reference); + + if (scope == IScope.NULLSCOPE) { + // used for type references in JSDoc (see JSDocCompletionProposalComputer): + if (reference == N4JSPackage.Literals.MODULE_REF__MODULE) { + return scope_ImportedAndCurrentModule(context, reference); + } + + // the following cases are only required for content assist (i.e. scoping on broken ASTs or at unusual + // locations) otherwise use context: + + if (context instanceof Script) { + return scope_EObject_id(context, reference); + } else if (context instanceof N4TypeDeclaration) { + return scope_EObject_id(context, reference); + } else if (context instanceof VariableDeclaration) { + return scope_EObject_id(context, reference); + } else if (context instanceof Statement) { + return scope_EObject_id(context, reference); + } else if (context instanceof NewExpression) { + return scope_EObject_id(context, reference); + } else if (context instanceof ParameterizedCallExpression) { + return scope_EObject_id(context, reference); + } else if (context instanceof Argument) { + return scope_EObject_id(context, reference); + } else if (context instanceof Expression) { + return scope_EObject_id(context, reference); + } else if (context instanceof LiteralOrComputedPropertyName) { + return scope_EObject_id(context, reference); + } + } + + return scope; + } + + /** + * Returns a scope as created by {@link #getScope(EObject, EReference)} for the "from" part of an import declaration + * in the AST, but without the need for providing any AST nodes. This can be used to implement implicit imports + * without duplicating any logic from the scoping. + *

+ * There are two minor differences to the scope created by {@code #getScope()}: + *

    + *
  1. the current module, i.e. the module represented by the given resource, won"t be filtered out, and + *
  2. advanced error reporting will be disabled, i.e. {@link IScope#getSingleElement(QualifiedName)} will simply + * return null instead of returning an {@code IEObjectDescriptionWithError}. + *
+ */ + public IScope getScopeForImplicitImports(N4JSResource resource) { + return scope_ImportedModule(resource, Optional.absent()); + } + + /** + * In + * + *
+	 * continue XYZ
+	 * 
+ * + * , bind XYZ to label. Bind to ALL labels in script, although not all of them are valid. Later is to be validated + * in ASTStructureValidator and allows for better error and quick fix handling. However, most inner (and correct) + * scope is preferred (solving problems in case of duplicate names). + */ + private IScope scope_LabelledStatement(EObject context) { + IScope parent = getAllLabels((Script) EcoreUtil.getRootContainer(context)); + Set names = new HashSet<>(); + List elements = new ArrayList<>(); + EObject current = context; + while (current != null) { + if (current instanceof LabelledStatement) { + LabelledStatement ls = (LabelledStatement) current; + if (names.add(ls.getName())) { + elements.add(EObjectDescription.create(ls.getName(), current)); + } + } + current = current.eContainer(); // labeled statement must be a container + } + if (elements.isEmpty()) { + return parent; + } + IScope result = scopeSnapshotHelper.scopeFor("contextLabels", current, parent, elements); + return result; + } + + private IScope getAllLabels(Script script) { + return scopeSnapshotHelper.scopeForEObjects("allLabels", script, + toIterable(filter(script.eAllContents(), LabelledStatement.class))); + } + + /** + * E.g. in + * + *
+	 * import { e1,e2 } from "a/b/importedModule"
+	 * 
+ * + * bind "a/b/importedModule" to module with qualified name "a.b.importedModule" + */ + private IScope scope_ImportedModule(ModuleRef importOrExportDecl) { + + N4JSResource resource = (N4JSResource) importOrExportDecl.eResource(); + IScope projectImportEnabledScope = scope_ImportedModule(resource, Optional.of(importOrExportDecl)); + + // filter out clashing module name (can be main module with the same name but in different project) + return new FilteringScope(projectImportEnabledScope, descr -> (descr == null) ? false + : !descriptionsHelper.isDescriptionOfModuleWith(resource, descr, importOrExportDecl)); + } + + private IScope scope_ImportedModule(N4JSResource resource, Optional importOrExportDecl) { + + EReference reference = N4JSPackage.eINSTANCE.getModuleRef_Module(); + + IScope initialScope = scope_ImportedAndCurrentModule(resource.getScript(), reference); + + IResourceDescriptions resourceDescriptions = resourceDescriptionsProvider.getResourceDescriptions(resource); + IScope delegateMainModuleAwareScope = MainModuleAwareSelectableBasedScope.createMainModuleAwareScope( + initialScope, + resourceDescriptions, reference.getEReferenceType()); + + N4JSWorkspaceConfigSnapshot ws = workspaceAccess.getWorkspaceConfig(resource); + IScope projectImportEnabledScope = ProjectImportEnablingScope.create(ws, resource, importOrExportDecl, + initialScope, delegateMainModuleAwareScope, declMergingHelper); + + return projectImportEnabledScope; + } + + /** + * Same as {@link #scope_ImportedModule(ModuleRef )}, but also includes the current module. + */ + private IScope scope_ImportedAndCurrentModule(EObject importDeclaration, EReference reference) { + return delegateGetScope(importDeclaration, reference); + } + + /** + * E.g. in + * + *
+	 * import { e1,e2 } from "importedModule"
+	 * 
+ * + * bind e1 or e2 by retrieving all (not only exported, see below!) top level elements of importedModule (variables, + * types; functions are types!). All elements enables better error handling and quick fixes, as links are not + * broken. + */ + protected IScope scope_ImportedElement(NamedImportSpecifier specifier) { + ImportDeclaration impDecl = EcoreUtil2.getContainerOfType(specifier, ImportDeclaration.class); + TModule targetModule = impDecl.getModule(); // may trigger reentrant scoping for module specifier (cf. + // #scope_ImportedModule()) + return scope_AllTopLevelElementsFromAbstractNamespace(targetModule, impDecl, true, true); + } + + /** + * E.g. in + * + *
+	 * export { e1, e2 } from "importedModule"
+	 * 
+ * + * See {@link #scope_ImportedElement(NamedImportSpecifier )}. + */ + protected IScope scope_ImportedElement(NamedExportSpecifier specifier) { + ExportDeclaration expDecl = EcoreUtil2.getContainerOfType(specifier, ExportDeclaration.class); + TModule targetModule = expDecl.getModule(); // may trigger reentrant scoping for module specifier (cf. + // #scope_ImportedModule()) + return scope_AllTopLevelElementsFromAbstractNamespace(targetModule, expDecl, true, true); + } + + /** + * Called from getScope(), binds an identifier reference. + */ + private IScope scope_IdentifierRef_id(IdentifierRef identifierRef, EReference ref) { + EObject parent = identifierRef.eContainer(); + // handle re-exports + if (parent instanceof NamedExportSpecifier) { + EObject grandParent = parent.eContainer(); + if (grandParent instanceof ExportDeclaration) { + if (((ExportDeclaration) grandParent).isReexport()) { + if (isSuppressCrossFileResolutionOfIdentifierRefs()) { + return IScope.NULLSCOPE; + } + return scope_ImportedElement((NamedExportSpecifier) parent); + } + } + } + VariableEnvironmentElement vee = ancestor(identifierRef, VariableEnvironmentElement.class); + if (vee == null) { + return IScope.NULLSCOPE; + } + ScopeInfo scope = getLexicalEnvironmentScope(vee, identifierRef, ref); + // Handle constructor visibility + if (parent instanceof NewExpression) { + return scope.addValidator( + new VisibilityAwareCtorScopeValidator(checker, containerTypesHelper, (NewExpression) parent)); + } + return scope; + } + + /** + * Only used for content assist. Modeled after method {@link #scope_IdentifierRef_id(IdentifierRef,EReference)}. + */ + private IScope scope_EObject_id(EObject obj, EReference ref) { + VariableEnvironmentElement vee = (obj instanceof VariableEnvironmentElement) + ? (VariableEnvironmentElement) obj + : ancestor(obj, VariableEnvironmentElement.class); + + if (vee == null) { + return IScope.NULLSCOPE; + } + return getLexicalEnvironmentScope(vee, obj, ref); + } + + private ScopeInfo getLexicalEnvironmentScope(VariableEnvironmentElement vee, EObject context, EReference ref) { + ensureLexicalEnvironmentScopes(context, ref); + return cache.mustGet(vee.eResource(), "scope_IdentifierRef_id", vee); + } + + private void ensureLexicalEnvironmentScopes(EObject context, EReference reference) { + Script script = (Script) EcoreUtil.getRootContainer(context); + Resource resource = script.eResource(); + Object key = N4JSCache.makeKey("scope_IdentifierRef_id", script); + boolean veeScopesBuilt = cache.contains(resource, key); // note that a script is a vee + if (!veeScopesBuilt) { + cache.get(resource, () -> buildLexicalEnvironmentScope(script, context, reference), key); + Iterator scriptIterator = script.eAllContents(); + while (scriptIterator.hasNext()) { + EObject veeObj = scriptIterator.next(); + if (veeObj instanceof VariableEnvironmentElement) { + // fill the cache + VariableEnvironmentElement vee = (VariableEnvironmentElement) veeObj; + cache.get(resource, () -> buildLexicalEnvironmentScope(vee, context, reference), + "scope_IdentifierRef_id", vee); + } + } + } + } + + /** + * Builds a lexical environment scope with the given parameters. Filters out primitive types. + */ + private ScopeInfo buildLexicalEnvironmentScope(VariableEnvironmentElement vee, EObject context, + EReference reference) { + List> scopeLists = new ArrayList<>(); + // variables declared in module + collectLexialEnvironmentsScopeLists(vee, scopeLists); + + IScope scope; + if (isSuppressCrossFileResolutionOfIdentifierRefs()) { + // Suppressing cross-file resolution is necessary for the CFG/DFG analysis + // triggered in N4JSPostProcessor#postProcessN4JSResource(...). + scope = IScope.NULLSCOPE; + } else { + Script script = (Script) EcoreUtil.getRootContainer(vee); + Resource resource = script.eResource(); + // TODO GH-2338 reconsider the following recursion guard (required for chains of re-exports in cyclic + // modules) + AtomicBoolean guard = cache.get(resource, () -> new AtomicBoolean(false), + "buildLexicalEnvironmentScope__importedValuesComputationGuard", script); + boolean alreadyInProgress = guard.getAndSet(true); + if (alreadyInProgress) { + scope = IScope.NULLSCOPE; + } else { + try { + IScope baseScope = getScriptBaseScope(script, context, reference); + // imported variables (added as second step to enable shadowing of imported elements) + scope = importedElementsScopingHelper.getImportedValues(baseScope, script); + } finally { + guard.set(false); + } + } + } + + scope = scopeSnapshotHelper.scopeForEObjects("buildLexicalEnvironmentScope", context, scope, false, + flatten(scopeLists)); + + ScopeInfo scopeInfo = new ScopeInfo(scope, scope, new VeeScopeValidator(context)); + + return scopeInfo; + } + + private IScope getScriptBaseScope(Script script, EObject context, EReference ref) { + // IDE-1065: there may be user declared globals (i.e. @@Global) + IScope globalScope = delegateGetScope(script, ref); + + if (jsVariantHelper.activateDynamicPseudoScope(context)) { // cf. sec. 13.1 + return new DynamicPseudoScope(globalScope); + } + return globalScope; + } + + private void collectLexialEnvironmentsScopeLists(VariableEnvironmentElement vee, + List> result) { + + result.add(sourceElementExtensions.collectVisibleIdentifiableElements(vee)); + + // implicit variable "arguments" must be in own outer scope in order to enable shadowing of inner variables + // named "arguments" + result.add(sourceElementExtensions.collectLocalArguments(vee)); + + VariableEnvironmentElement parent = ancestor(vee, VariableEnvironmentElement.class); + if (parent != null) { + collectLexialEnvironmentsScopeLists(parent, result); + } + } + + /** + * Creates IScope with all top level elements (variables and types, including functions), from target module or + * namespace. Provided resource is used to check visibility of module elements. Not visible elements are imported + * too, which allows better error handling and quick fixes, as links are not broken. + * + * Used for elements imported with named import and to access elements via namespace import. + * + * @param ns + * target {@link TModule} from which elements are imported + * @param context + * Receiver context {@link EObject} which is importing elements + */ + private IScope scope_AllTopLevelElementsFromAbstractNamespace(AbstractNamespace ns, EObject context, + boolean includeHollows, boolean includeValueOnlyElements) { + + return scope_AllTopLevelElementsFromAbstractNamespace(ns, context, IScope.NULLSCOPE, includeHollows, + includeValueOnlyElements); + } + + private IScope scope_AllTopLevelElementsFromAbstractNamespace(AbstractNamespace ns, EObject context, + IScope parentOrNull, + boolean includeHollows, boolean includeValueOnlyElements) { + + if (ns == null) { + return parentOrNull; + } + + Resource resource = context.eResource(); + + // TODO GH-2338 reconsider the following recursion guard (required for chains of re-exports in cyclic modules) + AtomicBoolean guard = cache.get(resource, () -> new AtomicBoolean(false), + "scope_AllTopLevelElementsFromAbstractNamespace__exportedElementsComputationGuard", context); + boolean alreadyInProgress = guard.getAndSet(true); + if (alreadyInProgress) { + return parentOrNull; + } + try { + // get regular top-level elements scope + Optional memberAccess = (context instanceof MemberAccess) + ? Optional.of((MemberAccess) context) + : Optional.absent(); + Iterable tlElems = exportedElementCollector.getExportedElements(ns, + (N4JSResource) context.eResource(), memberAccess, includeHollows, includeValueOnlyElements); + IScope topLevelElementsScope = scopeSnapshotHelper.scopeFor( + "scope_AllTopLevelElementsFromAbstractNamespace", ns, + parentOrNull != null ? parentOrNull : IScope.NULLSCOPE, false, tlElems); + return topLevelElementsScope; + } finally { + guard.set(false); + } + } + + /** + * Called from getScope(), binds a property reference. + */ + private IScope scope_BindingProperty_property(BindingProperty bindingProperty) { + return scope_DestructPattern_property(bindingProperty); + } + + /** + * Called from getScope(), binds a property reference. + */ + private IScope scope_PropertyNameValuePair_property(PropertyNameValuePair pnvPair) { + return scope_DestructPattern_property(pnvPair); + } + + private IScope scope_DestructPattern_property(EObject propertyContainer) { + TypeRef cTypeRef = null; + DestructNode destNodeTop = DestructNode.unify(DestructureUtils.getTop(propertyContainer)); + DestructNode parentDestNode = destNodeTop == null ? null + : destNodeTop.findNodeOrParentForElement(propertyContainer, true); + RuleEnvironment G = newRuleEnvironment(propertyContainer); + + if (parentDestNode != null) { + EObject parentAstElem = parentDestNode.astElement; + if (parentAstElem instanceof BindingProperty) { + BindingProperty bp = (BindingProperty) parentAstElem; + if (bp.getProperty() != null) { + cTypeRef = ts.type(G, bp.getProperty()); + } + } else if (parentAstElem instanceof BindingElement + && parentAstElem.eContainer() instanceof ArrayBindingPattern) { + DestructNode parent2DestNode = destNodeTop == null ? null + : destNodeTop.findNodeOrParentForElement(parentAstElem, true); + if (parent2DestNode != null) { + TypeRef arrayType = null; + EObject parent2AstElem = parent2DestNode.astElement; + if (parent2AstElem instanceof BindingProperty) { + BindingProperty bp = (BindingProperty) parent2AstElem; + if (bp.getProperty() != null) { + arrayType = ts.type(G, bp.getProperty()); + } + } else { + arrayType = ts.type(G, parent2DestNode.assignedElem); + } + + int idx = Arrays.asList(parent2DestNode.nestedNodes).indexOf(parentDestNode); + if (arrayType != null && arrayType.getTypeArgsWithDefaults().size() > idx + && isIterableN(G, arrayType) && arrayType.eResource() != null) { + TypeArgument typeArg = arrayType.getTypeArgsWithDefaults().get(idx); + if (typeArg instanceof TypeRef) { + cTypeRef = (TypeRef) typeArg; + } + } + } + } else if (parentDestNode.assignedElem instanceof TypeDefiningElement + && ((TypeDefiningElement) parentDestNode.assignedElem).getDefinedType() != null) { + cTypeRef = TypeUtils + .createTypeRef(((TypeDefiningElement) parentDestNode.assignedElem).getDefinedType()); + } else { + // fallback + cTypeRef = ts.type(G, parentDestNode.assignedElem); + } + if (DestructureUtils.isTopOfDestructuringForStatement(parentDestNode.astElement) && + cTypeRef != null && cTypeRef.isArrayLike()) { + tsh.addSubstitutions(G, cTypeRef); + cTypeRef = ts.substTypeVariables(G, cTypeRef.getDeclaredType().getElementType()); + } + } + + if (cTypeRef == null && propertyContainer instanceof PropertyNameValuePair + && propertyContainer.eContainer() instanceof ObjectLiteral) { + ObjectLiteral objLit = (ObjectLiteral) propertyContainer.eContainer(); + if (objLit.getDefinedType() != null) { + cTypeRef = TypeUtils.createTypeRef(objLit.getDefinedType()); + } + } + + if (cTypeRef != null && isContained(cTypeRef)) { + return new UberParentScope("scope_DestructPattern_property", + createScopeForMemberAccess(cTypeRef, propertyContainer), new DynamicPseudoScope()); + } + return new DynamicPseudoScope(); + } + + private boolean isContained(TypeRef tRef) { + if (tRef.eResource() != null) { + // type ref is contained + return true; + } + if (tRef instanceof ParameterizedTypeRefStructural) { + ParameterizedTypeRefStructural ptrs = (ParameterizedTypeRefStructural) tRef; + if (!ptrs.getAstStructuralMembers().isEmpty() || !ptrs.getGenStructuralMembers().isEmpty()) { + // type ref is not contained, hence structural members are not contained + return false; + } + } + if (tRef.getDeclaredType() != null && tRef.getDeclaredType().eResource() != null) { + // nominal type (or similar) is contained + return true; + } + return false; + } + + /* + * In
receiver.property
, binds "property". + * + */ + private IScope scope_PropertyAccessExpression_property(ParameterizedPropertyAccessExpression propertyAccess) { + Expression receiver = propertyAccess.getTarget(); + + RuleEnvironment G = newRuleEnvironment(propertyAccess); + TypeRef typeRefRaw = ts.type(G, receiver); + // take upper bound to get rid of ExistentialTypeRefs, ThisTypeRefs, etc. + // (literal types are handled in dispatch method #members() of MemberScopingHelper) + TypeRef typeRef = ts.upperBoundWithReopenAndResolveTypeVars(G, typeRefRaw); + Type declaredType = typeRef.getDeclaredType(); + if (declaredType instanceof TNamespace) { + return scope_AllTopLevelElementsFromAbstractNamespace((TNamespace) declaredType, propertyAccess, false, + true); + } + if (declaredType instanceof ModuleNamespaceVirtualType) { + return createScopeForNamespaceAccess((ModuleNamespaceVirtualType) declaredType, propertyAccess, false, + true); + } + + var result = createScopeForMemberAccess(typeRef, propertyAccess); + + // functions and classes may have namespaces merged onto them + result = handleDeclMergingForPropertyAccess(G, propertyAccess, typeRef, result); + + return result; + } + + private IScope createScopeForNamespaceAccess(ModuleNamespaceVirtualType namespace, EObject context, + boolean includeHollows, boolean includeValueOnlyElements) { + TModule module = namespace.getModule(); + + IScope result; + + if (module != null && !module.eIsProxy()) { + result = scope_AllTopLevelElementsFromAbstractNamespace(module, context, includeHollows, + includeValueOnlyElements); + } else { + // error cases + if (namespace.eIsProxy()) { + // name space does not exist -> avoid duplicate error messages + // (cf. MemberScopingHelper#members(UnknownTypeRef, MemberScopeRequest)) + result = new DynamicPseudoScope(); + } else { + // name space exists, but imported module does not -> show additional error at location of reference + result = IScope.NULLSCOPE; + } + } + if (namespace.isDeclaredDynamic() && !(result instanceof DynamicPseudoScope)) { + return new DynamicPseudoScope(result); + } + return result; + } + + private IScope createScopeForMemberAccess(TypeRef targetTypeRef, EObject context) { + boolean staticAccess = targetTypeRef instanceof TypeTypeRef; + boolean structFieldInitMode = targetTypeRef.getTypingStrategy() == TypingStrategy.STRUCTURAL_FIELD_INITIALIZER; + boolean checkVisibility = true; + IScope result = memberScopingHelper.createMemberScope(targetTypeRef, context, checkVisibility, staticAccess, + structFieldInitMode); + return result; + } + + private IScope handleDeclMergingForPropertyAccess(RuleEnvironment G, + ParameterizedPropertyAccessExpression propertyAccess, + TypeRef typeRef, IScope parent) { + + boolean staticAccess = typeRef instanceof TypeTypeRef; + + Type mergeCandidate = null; + if (staticAccess) { + Type staticType = tsh.getStaticType(G, (TypeTypeRef) typeRef, true); + if (staticType instanceof TClass) { + mergeCandidate = staticType; + } + } else { + Type declaredType = typeRef.getDeclaredType(); + if (declaredType instanceof TFunction) { + mergeCandidate = declaredType; + } + } + + if (mergeCandidate != null) { + IScope scopeNamespace = createScopeForMergedNamespaces(propertyAccess, mergeCandidate, null); + if (scopeNamespace != null) { + return new MergedScope(scopeNamespace, parent); + } + } + + return parent; + } + + /** Returns parentOrNull unchanged if no namespaces are merged onto "elem". */ + private IScope createScopeForMergedNamespaces(EObject context, Type elem, IScope parentOrNull) { + var result = parentOrNull; + if (DeclMergingUtils.mayBeMerged(elem)) { + Set mergedElems = declMergingHelper.getMergedElements((N4JSResource) context.eResource(), elem); + List mergedNamespaces = toList(filter(mergedElems, TNamespace.class)); + if (mergedNamespaces.size() > 1) { + Collections.sort(mergedNamespaces, + Comparator.comparing(ns -> ((InternalEObject) ns).eProxyURI(), new URIUtils.URIComparator())); + } + for (TNamespace mergedNS : reverseView(mergedNamespaces)) { + if (mergedNS != null) { + result = scope_AllTopLevelElementsFromAbstractNamespace(mergedNS, context, result, false, true); + } + } + } + return result; + } + + /** Returns parentOrNull unchanged if no TModules are merged onto "script". */ + private IScope createScopeForMergedTModules(Script script, boolean onlyNamespaces, IScope parentOrNull) { + if (!DeclMergingUtils.mayBeMerged(script)) { + return parentOrNull; + } + IScope result = parentOrNull; + N4JSResource resource = (N4JSResource) script.eResource(); + List mergedTModules = new ArrayList<>( + declMergingHelper.getMergedElements(resource, script.getModule())); // can be empty + if (mergedTModules.size() > 1) { + Collections.sort(mergedTModules, + Comparator.comparing(m -> ((InternalEObject) m).eProxyURI(), new URIUtils.URIComparator())); + } + for (AbstractNamespace mergedTModule : reverseView(mergedTModules)) { + if (mergedTModule != null) { + result = locallyKnownTypesScopingHelper.scopeWithLocallyDeclaredElems(mergedTModule, result, + onlyNamespaces); + } + } + return result; + } + + /** + * Is entered to initially bind "T" in + * + *
+	 * var x : T;
+	 * 
+ * + * or other parameterized type references. + */ + public IScope getTypeScope(EObject context, boolean fromStaticContext, boolean onlyNamespaces) { + IScope internal = getTypeScopeInternal(context, fromStaticContext, onlyNamespaces); + + IScope legacy = new ContextAwareTypeScope(internal, context); + ScopeInfo scopeInfo = new ScopeInfo(internal, legacy, new ContextAwareTypeScopeValidator(context)); + + return scopeInfo; + } + + private IScope getTypeScopeInternal(EObject context, boolean fromStaticContext, boolean onlyNamespaces) { + if (context instanceof Script) { + Script script = (Script) context; + return locallyKnownTypesScopingHelper.scopeWithLocallyDeclaredElems(script, () -> { + // provide any reference that expects instances of Type as target objects + IScope parent = delegateGetScope(script, + TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF__DECLARED_TYPE); + parent = createScopeForMergedTModules(script, onlyNamespaces, parent); + return parent; + }, onlyNamespaces); + + } else if (context instanceof N4NamespaceDeclaration) { + N4NamespaceDeclaration ns = (N4NamespaceDeclaration) context; + IScope parent = getTypeScopeInternal(ns.eContainer(), fromStaticContext, onlyNamespaces); + TNamespace tns = ns.getDefinedNamespace(); + if (tns != null && DeclMergingUtils.mayBeMerged(tns)) { + parent = createScopeForMergedNamespaces(tns, tns, parent); + } + return locallyKnownTypesScopingHelper.scopeWithLocallyDeclaredElems(ns, parent, onlyNamespaces); + } else if (context instanceof TNamespace) { + TNamespace tns = (TNamespace) context; + var parent = getTypeScopeInternal(tns.eContainer(), fromStaticContext, onlyNamespaces); + if (DeclMergingUtils.mayBeMerged(tns)) { + parent = createScopeForMergedNamespaces(tns, tns, parent); + } + return locallyKnownTypesScopingHelper.scopeWithLocallyDeclaredElems(tns, parent, onlyNamespaces); + } else if (context instanceof TModule) { + TModule module = (TModule) context; + Script script = (Script) module.getAstElement(); + return getTypeScopeInternal(script, fromStaticContext, onlyNamespaces); + } else if (context instanceof N4FieldDeclaration) { + N4FieldDeclaration fd = (N4FieldDeclaration) context; + boolean isStaticContext = fd.isStatic(); + // use new static access status for parent scope + return getTypeScopeInternal(fd.eContainer(), isStaticContext, onlyNamespaces); + } else if (context instanceof N4FieldAccessor) { + N4FieldAccessor fa = (N4FieldAccessor) context; + boolean isStaticContext = fa.isStatic(); + // use new static access status for parent scope + return getTypeScopeInternal(fa.eContainer(), isStaticContext, onlyNamespaces); + } else if (context instanceof TypeDefiningElement) { + TypeDefiningElement tde = (TypeDefiningElement) context; + boolean isStaticContext = tde instanceof N4MemberDeclaration && ((N4MemberDeclaration) tde).isStatic(); + // use new static access status for parent scope + IScope parent = getTypeScopeInternal(tde.eContainer(), isStaticContext, onlyNamespaces); + Type polyfilledOrOriginalType = sourceElementExtensions.getTypeOrPolyfilledType(tde); + + // use old static access status for current scope + return locallyKnownTypesScopingHelper.scopeWithTypeAndItsTypeVariables(parent, polyfilledOrOriginalType, + fromStaticContext); + } else if (context instanceof TStructMethod) { + IScope parent = getTypeScopeInternal(context.eContainer(), fromStaticContext, onlyNamespaces); + return locallyKnownTypesScopingHelper.scopeWithTypeVarsOfTStructMethod(parent, (TStructMethod) context); + } else if (context instanceof FunctionTypeExpression) { + IScope parent = getTypeScopeInternal(context.eContainer(), fromStaticContext, onlyNamespaces); + return locallyKnownTypesScopingHelper.scopeWithTypeVarsOfFunctionTypeExpression(parent, + (FunctionTypeExpression) context); + } else { + EObject container = context.eContainer(); + + // handle special areas inside a polyfill that should *not* get the usual polyfill handling implemented + // in the above case for "TypeDefiningElement": + if (container instanceof N4ClassifierDeclaration) { + N4ClassifierDeclaration cd = (N4ClassifierDeclaration) container; + if (N4JSLanguageUtils.isNonStaticPolyfill(cd) || N4JSLanguageUtils.isStaticPolyfill(cd)) { + if (cd.getTypeVars().contains(context)) { + // area #1: upper/lower bound of type parameter of polyfill, e.g. the 2nd "T" in: + // @@StaticPolyfillModule + // @StaticPolyfill export public class ToBeFilled extends ToBeFilled {} + IScope parent = getTypeScopeInternal(context.eContainer(), false, onlyNamespaces); + return locallyKnownTypesScopingHelper.scopeWithTypeAndItsTypeVariables(parent, + cd.getDefinedType(), fromStaticContext); + } else if (toList(cd.getSuperClassifierRefs()).contains(context)) { + // area #2: super type reference of polyfill, e.g. everything after "extends" in: + // @@StaticPolyfillModule + // @StaticPolyfill export public class ToBeFilled extends ToBeFilled {} + Script script = EcoreUtil2.getContainerOfType(cd, Script.class); + IScope globalScope = delegateGetScope(script, + TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF__DECLARED_TYPE); + IScope parent = locallyKnownTypesScopingHelper.scopeWithLocallyKnownTypesForPolyfillSuperRef( + script, globalScope, + cd.getDefinedType()); + return parent; + } + } + } + + return getTypeScopeInternal(container, fromStaticContext, onlyNamespaces); + } + } + + /** + * Returns ancestor of given type, or null, if no such container exists. Note that this method is slightly different + * from EcoreUtil2::getContainerOfType, as it only returns a container and not the element itself. That is, ancestor + * is not reflexive here. + */ + private T ancestor(EObject obj, Class ancestorType) { + if (obj == null) { + return null; + } + return EcoreUtil2.getContainerOfType(obj.eContainer(), ancestorType); + } + + private IScope getN4JSXScope(EObject context, EReference reference) { + IScope jsxPropertyAttributeScope = getJSXPropertyAttributeScope(context, reference); + if (jsxPropertyAttributeScope != IScope.NULLSCOPE) { + return jsxPropertyAttributeScope; + } + + IScope jsxElementScope = getJSXElementScope(context, reference); + if (jsxElementScope != IScope.NULLSCOPE) { + return jsxElementScope; + } + + // delegate to host -> N4JS scope + return getN4JSScope(context, reference); + } + + /** Returns scope for the {@link JSXPropertyAttribute} (obtained from context) or {@link IScope#NULLSCOPE} */ + private IScope getJSXPropertyAttributeScope(EObject context, EReference reference) { + if (reference == N4JSPackage.Literals.JSX_PROPERTY_ATTRIBUTE__PROPERTY) { + if (context instanceof JSXPropertyAttribute) { + JSXElement jsxElem = (JSXElement) context.eContainer(); + TypeRef propsTypeRef = reactHelper.getPropsType(jsxElem); + boolean checkVisibility = true; + boolean staticAccess = false; + boolean structFieldInitMode = false; + if (propsTypeRef != null) { + // Prevent "Cannot resolve to element" error message of unknown attributes since + // we want to issue a warning instead + TypeRef propsTypeRefUB = ts.upperBoundWithReopenAndResolveTypeVars(newRuleEnvironment(context), + propsTypeRef); + IScope memberScope = memberScopingHelper.createMemberScope(propsTypeRefUB, context, checkVisibility, + staticAccess, structFieldInitMode); + return new DynamicPseudoScope(memberScope); + } else { + IScope scope = getN4JSScope(context, reference); + return new DynamicPseudoScope(scope); + } + } + } + return IScope.NULLSCOPE; + } + + /** Returns scope for the JSXElement (obtained from context) or {@link IScope#NULLSCOPE} */ + private IScope getJSXElementScope(EObject context, EReference reference) { + + if (EcoreUtil2.getContainerOfType(context, JSXElementName.class) == null) + return IScope.NULLSCOPE; + + IScope scope = getN4JSScope(context, reference); + return new DynamicPseudoScope(scope); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/N4JSScopeProvider.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/N4JSScopeProvider.xtend deleted file mode 100644 index 42031179f7..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/N4JSScopeProvider.xtend +++ /dev/null @@ -1,977 +0,0 @@ -/** - * 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.scoping - -import com.google.common.base.Optional -import com.google.inject.Inject -import com.google.inject.Singleton -import com.google.inject.name.Named -import java.util.Collections -import java.util.Comparator -import java.util.Iterator -import java.util.List -import java.util.concurrent.atomic.AtomicBoolean -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.EReference -import org.eclipse.emf.ecore.InternalEObject -import org.eclipse.emf.ecore.util.EcoreUtil -import org.eclipse.n4js.n4JS.Argument -import org.eclipse.n4js.n4JS.ArrayBindingPattern -import org.eclipse.n4js.n4JS.BindingElement -import org.eclipse.n4js.n4JS.BindingProperty -import org.eclipse.n4js.n4JS.DestructNode -import org.eclipse.n4js.n4JS.DestructureUtils -import org.eclipse.n4js.n4JS.ExportDeclaration -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.n4js.n4JS.IdentifierRef -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.JSXElement -import org.eclipse.n4js.n4JS.JSXElementName -import org.eclipse.n4js.n4JS.JSXPropertyAttribute -import org.eclipse.n4js.n4JS.LabelledStatement -import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName -import org.eclipse.n4js.n4JS.MemberAccess -import org.eclipse.n4js.n4JS.ModuleRef -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.n4JS.N4ClassifierDefinition -import org.eclipse.n4js.n4JS.N4FieldAccessor -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.N4JSPackage -import org.eclipse.n4js.n4JS.N4MemberDeclaration -import org.eclipse.n4js.n4JS.N4NamespaceDeclaration -import org.eclipse.n4js.n4JS.N4TypeDeclaration -import org.eclipse.n4js.n4JS.NamedExportSpecifier -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NewExpression -import org.eclipse.n4js.n4JS.ObjectLiteral -import org.eclipse.n4js.n4JS.ParameterizedCallExpression -import org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression -import org.eclipse.n4js.n4JS.PropertyNameValuePair -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.n4JS.Statement -import org.eclipse.n4js.n4JS.TypeDefiningElement -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.n4JS.VariableEnvironmentElement -import org.eclipse.n4js.resource.N4JSCache -import org.eclipse.n4js.resource.N4JSResource -import org.eclipse.n4js.scoping.accessModifiers.ContextAwareTypeScope -import org.eclipse.n4js.scoping.accessModifiers.MemberVisibilityChecker -import org.eclipse.n4js.scoping.imports.ImportedElementsScopingHelper -import org.eclipse.n4js.scoping.imports.N4JSImportedNamespaceAwareLocalScopeProvider -import org.eclipse.n4js.scoping.members.MemberScopingHelper -import org.eclipse.n4js.scoping.utils.DynamicPseudoScope -import org.eclipse.n4js.scoping.utils.LocallyKnownTypesScopingHelper -import org.eclipse.n4js.scoping.utils.MainModuleAwareSelectableBasedScope -import org.eclipse.n4js.scoping.utils.MergedScope -import org.eclipse.n4js.scoping.utils.ProjectImportEnablingScope -import org.eclipse.n4js.scoping.utils.ScopeSnapshotHelper -import org.eclipse.n4js.scoping.utils.SourceElementExtensions -import org.eclipse.n4js.scoping.utils.UberParentScope -import org.eclipse.n4js.scoping.validation.ContextAwareTypeScopeValidator -import org.eclipse.n4js.scoping.validation.ScopeInfo -import org.eclipse.n4js.scoping.validation.VeeScopeValidator -import org.eclipse.n4js.scoping.validation.VisibilityAwareCtorScopeValidator -import org.eclipse.n4js.tooling.react.ReactHelper -import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression -import org.eclipse.n4js.ts.typeRefs.NamespaceLikeRef -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRefStructural -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRefsPackage -import org.eclipse.n4js.ts.typeRefs.TypeTypeRef -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.TEnum -import org.eclipse.n4js.ts.types.TFunction -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.ts.types.TNamespace -import org.eclipse.n4js.ts.types.TStructMethod -import org.eclipse.n4js.ts.types.Type -import org.eclipse.n4js.ts.types.TypesPackage -import org.eclipse.n4js.ts.types.TypingStrategy -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.utils.RuleEnvironment -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper -import org.eclipse.n4js.utils.ContainerTypesHelper -import org.eclipse.n4js.utils.DeclMergingHelper -import org.eclipse.n4js.utils.DeclMergingUtils -import org.eclipse.n4js.utils.EObjectDescriptionHelper -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.ResourceType -import org.eclipse.n4js.utils.URIUtils -import org.eclipse.n4js.validation.JavaScriptVariantHelper -import org.eclipse.n4js.workspace.WorkspaceAccess -import org.eclipse.n4js.xtext.scoping.FilteringScope -import org.eclipse.xtext.EcoreUtil2 -import org.eclipse.xtext.resource.EObjectDescription -import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider -import org.eclipse.xtext.scoping.IScope -import org.eclipse.xtext.scoping.IScopeProvider -import org.eclipse.xtext.scoping.impl.AbstractScopeProvider -import org.eclipse.xtext.scoping.impl.IDelegatingScopeProvider - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * This class contains custom scoping description. - * - * Although some methods are called according to declarative scope provider, no reflection in - * {@link #getScope(EObject,EReference)}. - * - * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping - * on how and when to use it - */ -@Singleton -class N4JSScopeProvider extends AbstractScopeProvider implements IDelegatingScopeProvider, IContentAssistScopeProvider { - - public final static String NAMED_DELEGATE = "org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.delegate"; - - @Inject - N4JSCache cache - - /** - * The scope provider creating the "parent" scope, i.e. including elements from the index. - * At runtime, the value will be of type {@link N4JSImportedNamespaceAwareLocalScopeProvider}. - */ - @Inject - @Named(NAMED_DELEGATE) - IScopeProvider delegate; - - @Inject WorkspaceAccess workspaceAccess; - - @Inject ResourceDescriptionsProvider resourceDescriptionsProvider; - - @Inject N4JSTypeSystem ts - - @Inject TypeSystemHelper tsh - - @Inject MemberScopingHelper memberScopingHelper - - @Inject LocallyKnownTypesScopingHelper locallyKnownTypesScopingHelper - - @Inject ImportedElementsScopingHelper importedElementsScopingHelper - - @Inject SourceElementExtensions sourceElementExtensions; - - @Inject EObjectDescriptionHelper descriptionsHelper; - - @Inject ReactHelper reactHelper; - - @Inject JavaScriptVariantHelper jsVariantHelper; - - @Inject MemberVisibilityChecker checker; - - @Inject ContainerTypesHelper containerTypesHelper; - - @Inject ExportedElementsCollector exportedElementCollector - - @Inject ScopeSnapshotHelper scopeSnapshotHelper - - @Inject DeclMergingHelper declMergingHelper; - - - protected def boolean isSuppressCrossFileResolutionOfIdentifierRefs() { - return false; - } - - /** - * Delegates to {@link N4JSImportedNamespaceAwareLocalScopeProvider#getScope(EObject, EReference)}, which in turn - * delegates further to {@link N4JSGlobalScopeProvider}. - */ - protected def IScope delegateGetScope(EObject context, EReference reference) { - return delegate.getScope(context, reference) - } - - override IScopeProvider getDelegate() { - return delegate; - } - - /** Dispatches to concrete scopes based on the context and reference inspection */ - override getScope(EObject context, EReference reference) { - try { - // dispatch based on language variant - val resourceType = ResourceType.getResourceType(context) - switch (resourceType) { - case ResourceType.N4JSX : return getN4JSXScope(context, reference) - case ResourceType.JSX : return getN4JSXScope(context, reference) - default : return getN4JSScope(context, reference) - } - - } catch (Error ex) { - if (context !== null && context.eResource.errors.empty) { - throw ex; - } else { - // swallow exception, we got a parse error anyway - } - } - - return IScope.NULLSCOPE; - } - - /** - * Returns the N4JS scope for the given context and reference. - * - * The returned scope is not sensitive to any of the language variants of N4JS. In order - * to obtain a variant-specific scope, please use {@link N4JSScopeProvider#getScope(EObject, EReference)}. - */ - public def getN4JSScope(EObject context, EReference reference) { - // maybe can use scope shortcut - val maybeScopeShortcut = getScopeByShortcut(context, reference); - if (maybeScopeShortcut !== IScope.NULLSCOPE) - return maybeScopeShortcut; - - // otherwise use context: - return getScopeForContext(context, reference) - } - - /** shortcut to concrete scopes based on reference sniffing. Will return {@link IScope#NULLSCOPE} if no suitable scope found */ - private def getScopeByShortcut(EObject context, EReference reference) { - if (reference == TypeRefsPackage.Literals.NAMESPACE_LIKE_REF__DECLARED_TYPE) { - if (context instanceof NamespaceLikeRef) { - val namespaceLikeType = context.previousSibling?.declaredType; - val script = EcoreUtil2.getContainerOfType(context, Script); - val parentNamespace = EcoreUtil2.getContainerOfType(context, N4NamespaceDeclaration); - val parentContainer = parentNamespace === null ? script : parentNamespace; - // also check for eIsProxy in case of broken AST - val namespace = namespaceLikeType === null || namespaceLikeType.eIsProxy ? parentContainer : namespaceLikeType; - return new FilteringScope(getTypeScope(namespace, false, true), [ - TypesPackage.Literals.MODULE_NAMESPACE_VIRTUAL_TYPE.isSuperTypeOf(it.getEClass) - || TypesPackage.Literals.TCLASS.isSuperTypeOf(it.getEClass) // only included, because classes might have a namespace merged onto them! - || TypesPackage.Literals.TENUM.isSuperTypeOf(it.getEClass) - || TypesPackage.Literals.TNAMESPACE.isSuperTypeOf(it.getEClass) - ]); - } - } else if (reference == TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF__DECLARED_TYPE) { - if (context instanceof ParameterizedTypeRef) { - val namespaceLikeType = context.astNamespaceLikeRefs?.last?.declaredType; - switch (namespaceLikeType) { - ModuleNamespaceVirtualType: - return createScopeForNamespaceAccess(namespaceLikeType, context, true, false) - TClass: - return createScopeForMergedNamespaces(context, namespaceLikeType, IScope.NULLSCOPE) - TEnum: - return new DynamicPseudoScope() - TNamespace: - return scope_AllTopLevelElementsFromAbstractNamespace(namespaceLikeType, context, true, false) - } - } - return getTypeScope(context, false, false); - } else if (reference.EReferenceType == N4JSPackage.Literals.LABELLED_STATEMENT) { - return scope_LabelledStatement(context); - } - return IScope.NULLSCOPE; - } - - /** dispatch to internal methods based on the context */ - private def getScopeForContext(EObject context, EReference reference) { - switch (context) { - ImportDeclaration : return scope_ImportedModule(context, reference) - NamedImportSpecifier : return scope_ImportedElement(context, reference) - ExportDeclaration : return scope_ImportedModule(context, reference) - IdentifierRef : return scope_IdentifierRef_id(context, reference) - BindingProperty : return scope_BindingProperty_property(context, reference) - PropertyNameValuePair : return scope_PropertyNameValuePair_property(context, reference) - ParameterizedPropertyAccessExpression : return scope_PropertyAccessExpression_property(context, reference) - N4FieldAccessor : { - val container = EcoreUtil2.getContainerOfType(context, N4ClassifierDefinition); - return scopeSnapshotHelper.scopeForEObjects("N4FieldAccessor", container, container.ownedFields); - } - default : return IScope.NULLSCOPE - } - } - - override getScopeForContentAssist(EObject context, EReference reference) { - val scope = getScope(context, reference); - - if (scope === IScope.NULLSCOPE) { - // used for type references in JSDoc (see JSDocCompletionProposalComputer): - if (reference == N4JSPackage.Literals.MODULE_REF__MODULE) { - return scope_ImportedAndCurrentModule(context, reference); - } - - // the following cases are only required for content assist (i.e. scoping on broken ASTs or at unusual - // locations) otherwise use context: - switch (context) { - Script: - return scope_EObject_id(context, reference) - N4TypeDeclaration: - return scope_EObject_id(context, reference) - VariableDeclaration: - return scope_EObject_id(context, reference) - Statement: - return scope_EObject_id(context, reference) - NewExpression: - return scope_EObject_id(context, reference) - ParameterizedCallExpression: - return scope_EObject_id(context, reference) - Argument: - return scope_EObject_id(context, reference) - Expression: - return scope_EObject_id(context, reference) - LiteralOrComputedPropertyName: - return scope_EObject_id(context, reference) - } - } - - return scope; - } - - /** - * Returns a scope as created by {@link #getScope(EObject, EReference)} for the 'from' part of an import declaration - * in the AST, but without the need for providing any AST nodes. This can be used to implement implicit imports - * without duplicating any logic from the scoping. - *

- * There are two minor differences to the scope created by {@code #getScope()}: - *

    - *
  1. the current module, i.e. the module represented by the given resource, won't be filtered out, and - *
  2. advanced error reporting will be disabled, i.e. {@link IScope#getSingleElement(QualifiedName)} will simply - * return null instead of returning an {@code IEObjectDescriptionWithError}. - *
- */ - public def IScope getScopeForImplicitImports(N4JSResource resource) { - return scope_ImportedModule(resource, Optional.absent()); - } - - /** - * In
continue XYZ
, bind XYZ to label. - * Bind to ALL labels in script, although not all of them are valid. Later is to be validated in ASTStructureValidator and - * allows for better error and quick fix handling. However, most inner (and correct) scope is preferred (solving problems in case of duplicate names). - */ - private def IScope scope_LabelledStatement(EObject context) { - val parent = getAllLabels(EcoreUtil.getRootContainer(context) as Script); - val names = newHashSet; - val elements = newArrayList; - var current = context; - while (current !== null) { - switch (current) { - LabelledStatement: - if (names.add(current.name)) { - elements += EObjectDescription.create(current.name, current); - } - } - current = current.eContainer; // labeled statement must be a container - } - if (elements.empty) { - return parent; - } - val result = scopeSnapshotHelper.scopeFor("contextLabels", current, parent, elements); - return result; - } - - private def IScope getAllLabels(Script script) { - return scopeSnapshotHelper.scopeForEObjects("allLabels", script, script.eAllContents.filter(LabelledStatement).toIterable); - } - - /** - * E.g. in - *
import { e1,e2 } from "a/b/importedModule"
bind "a/b/importedModule" to module with qualified name "a.b.importedModule" - */ - private def IScope scope_ImportedModule(ModuleRef importOrExportDecl, EReference reference) { - - val resource = importOrExportDecl.eResource as N4JSResource; - val projectImportEnabledScope = scope_ImportedModule(resource, Optional.of(importOrExportDecl)); - - // filter out clashing module name (can be main module with the same name but in different project) - return new FilteringScope(projectImportEnabledScope, [ - if (it === null) false else !descriptionsHelper.isDescriptionOfModuleWith(resource, it, importOrExportDecl); - ]); - } - - private def IScope scope_ImportedModule(N4JSResource resource, Optional importOrExportDecl) { - - val reference = N4JSPackage.eINSTANCE.moduleRef_Module; - - val initialScope = scope_ImportedAndCurrentModule(resource.script, reference); - - val resourceDescriptions = resourceDescriptionsProvider.getResourceDescriptions(resource); - val delegateMainModuleAwareScope = MainModuleAwareSelectableBasedScope.createMainModuleAwareScope(initialScope, - resourceDescriptions, reference.EReferenceType); - - val ws = workspaceAccess.getWorkspaceConfig(resource); - val projectImportEnabledScope = ProjectImportEnablingScope.create(ws, resource, importOrExportDecl, - initialScope, delegateMainModuleAwareScope, declMergingHelper); - - return projectImportEnabledScope; - } - - /** - * Same as {@link #scope_ImportedModule(EObject,EReference)}, but also includes the current module. - */ - private def IScope scope_ImportedAndCurrentModule(EObject importDeclaration, EReference reference) { - return delegateGetScope(importDeclaration, reference); - } - - /** - * E.g. in - *
import { e1,e2 } from "importedModule"
- * bind e1 or e2 by retrieving all (not only exported, see below!) top level elements of - * importedModule (variables, types; functions are types!). All elements enables better error handling and quick fixes, as links are not broken. - */ - protected def IScope scope_ImportedElement(NamedImportSpecifier specifier, EReference reference) { - val impDecl = EcoreUtil2.getContainerOfType(specifier, ImportDeclaration); - val targetModule = impDecl.module; // may trigger reentrant scoping for module specifier (cf. #scope_ImportedModule()) - return scope_AllTopLevelElementsFromAbstractNamespace(targetModule, impDecl, true, true); - } - - /** - * E.g. in - *
export { e1, e2 } from "importedModule"
- * See {@link #scope_ImportedElement(NamedImportSpecifier, EReference)}. - */ - protected def IScope scope_ImportedElement(NamedExportSpecifier specifier, EReference reference) { - val expDecl = EcoreUtil2.getContainerOfType(specifier, ExportDeclaration); - val targetModule = expDecl.module; // may trigger reentrant scoping for module specifier (cf. #scope_ImportedModule()) - return scope_AllTopLevelElementsFromAbstractNamespace(targetModule, expDecl, true, true); - } - - /** - * Called from getScope(), binds an identifier reference. - */ - private def IScope scope_IdentifierRef_id(IdentifierRef identifierRef, EReference ref) { - val parent = identifierRef.eContainer; - // handle re-exports - if (parent instanceof NamedExportSpecifier) { - val grandParent = parent.eContainer; - if (grandParent instanceof ExportDeclaration) { - if (grandParent.isReexport()) { - if (suppressCrossFileResolutionOfIdentifierRefs) { - return IScope.NULLSCOPE; - } - return scope_ImportedElement(parent, ref); - } - } - } - val VariableEnvironmentElement vee = ancestor(identifierRef, VariableEnvironmentElement); - if (vee === null) { - return IScope.NULLSCOPE; - } - val scope = getLexicalEnvironmentScope(vee, identifierRef, ref); - // Handle constructor visibility - if (parent instanceof NewExpression) { - return scope.addValidator(new VisibilityAwareCtorScopeValidator(checker, containerTypesHelper, parent)); - } - return scope; - } - - /** - * Only used for content assist. Modeled after method {@link #scope_IdentifierRef_id(IdentifierRef,EReference)}. - */ - private def IScope scope_EObject_id(EObject obj, EReference ref) { - val VariableEnvironmentElement vee = if (obj instanceof VariableEnvironmentElement) - obj - else - ancestor(obj, VariableEnvironmentElement); - - if (vee === null) { - return IScope.NULLSCOPE; - } - return getLexicalEnvironmentScope(vee, obj, ref); - } - - private def ScopeInfo getLexicalEnvironmentScope(VariableEnvironmentElement vee, EObject context, EReference ref) { - ensureLexicalEnvironmentScopes(context, ref); - return cache.mustGet(vee.eResource, 'scope_IdentifierRef_id', vee); - } - - - private def void ensureLexicalEnvironmentScopes(EObject context, EReference reference) { - val Script script = EcoreUtil.getRootContainer(context) as Script; - val resource = script.eResource; - val key = N4JSCache.makeKey('scope_IdentifierRef_id', script); - val veeScopesBuilt = cache.contains(resource, key); // note that a script is a vee - if (!veeScopesBuilt) { - cache.get(resource, [buildLexicalEnvironmentScope(script, context, reference)], key); - val Iterator scriptIterator = script.eAllContents; - while (scriptIterator.hasNext) { - val vee = scriptIterator.next; - if (vee instanceof VariableEnvironmentElement) { - // fill the cache - cache.get(resource, [buildLexicalEnvironmentScope(vee, context, reference)], 'scope_IdentifierRef_id', vee); - } - } - } - } - - /** - * Builds a lexical environment scope with the given parameters. - * Filters out primitive types. - */ - private def ScopeInfo buildLexicalEnvironmentScope(VariableEnvironmentElement vee, EObject context, EReference reference) { - val scopeLists = newArrayList; - // variables declared in module - collectLexialEnvironmentsScopeLists(vee, scopeLists); - - var IScope scope; - if (suppressCrossFileResolutionOfIdentifierRefs) { - // Suppressing cross-file resolution is necessary for the CFG/DFG analysis - // triggered in N4JSPostProcessor#postProcessN4JSResource(...). - scope = IScope.NULLSCOPE; - } else { - val Script script = EcoreUtil.getRootContainer(vee) as Script; - val resource = script.eResource; - // TODO GH-2338 reconsider the following recursion guard (required for chains of re-exports in cyclic modules) - val guard = cache.get(resource, [new AtomicBoolean(false)], "buildLexicalEnvironmentScope__importedValuesComputationGuard", script); - val alreadyInProgress = guard.getAndSet(true); - if (alreadyInProgress) { - scope = IScope.NULLSCOPE; - } else { - try { - val IScope baseScope = getScriptBaseScope(script, context, reference); - // imported variables (added as second step to enable shadowing of imported elements) - scope = importedElementsScopingHelper.getImportedValues(baseScope, script); - } finally { - guard.set(false); - } - } - } - - - scope = scopeSnapshotHelper.scopeForEObjects("buildLexicalEnvironmentScope", context, scope, false, scopeLists.flatten); - - val scopeInfo = new ScopeInfo(scope, scope, new VeeScopeValidator(context)); - - return scopeInfo; - } - - private def IScope getScriptBaseScope(Script script, EObject context, EReference ref) { - // IDE-1065: there may be user declared globals (i.e. @@Global) - val IScope globalScope = delegateGetScope(script, ref); - - if (jsVariantHelper.activateDynamicPseudoScope(context)) { // cf. sec. 13.1 - return new DynamicPseudoScope(globalScope); - } - return globalScope; - } - - def private void collectLexialEnvironmentsScopeLists(VariableEnvironmentElement vee, - List> result) { - - result.add(sourceElementExtensions.collectVisibleIdentifiableElements(vee)); - - // implicit variable "arguments" must be in own outer scope in order to enable shadowing of inner variables named "arguments" - result.add(sourceElementExtensions.collectLocalArguments(vee)); - - val parent = ancestor(vee, VariableEnvironmentElement); - if (parent !== null) { - collectLexialEnvironmentsScopeLists(parent, result); - } - } - - /** - * Creates IScope with all top level elements (variables and types, including functions), from target module or namespace. - * Provided resource is used to check visibility of module elements. Not visible elements are imported too, which - * allows better error handling and quick fixes, as links are not broken. - * - * Used for elements imported with named import and to access elements via namespace import. - * - * @param importedModule target {@link TModule} from which elements are imported - * @param contextResource Receiver context {@link EObject} which is importing elements - */ - private def IScope scope_AllTopLevelElementsFromAbstractNamespace(AbstractNamespace ns, EObject context, - boolean includeHollows, boolean includeValueOnlyElements) { - - return scope_AllTopLevelElementsFromAbstractNamespace(ns, context, IScope.NULLSCOPE, includeHollows, includeValueOnlyElements); - } - - private def IScope scope_AllTopLevelElementsFromAbstractNamespace(AbstractNamespace ns, EObject context, IScope parentOrNull, - boolean includeHollows, boolean includeValueOnlyElements) { - - if (ns === null) { - return parentOrNull; - } - - val resource = context.eResource; - - // TODO GH-2338 reconsider the following recursion guard (required for chains of re-exports in cyclic modules) - val guard = cache.get(resource, [new AtomicBoolean(false)], "scope_AllTopLevelElementsFromAbstractNamespace__exportedElementsComputationGuard", context); - val alreadyInProgress = guard.getAndSet(true); - if (alreadyInProgress) { - return parentOrNull; - } - try { - // get regular top-level elements scope - val memberAccess = if (context instanceof MemberAccess) Optional.of(context) else Optional.absent(); - val tlElems = exportedElementCollector.getExportedElements(ns, context.eResource as N4JSResource, memberAccess, includeHollows, includeValueOnlyElements); - val topLevelElementsScope = scopeSnapshotHelper.scopeFor("scope_AllTopLevelElementsFromAbstractNamespace", ns, parentOrNull ?: IScope.NULLSCOPE, false, tlElems); - return topLevelElementsScope; - } finally { - guard.set(false); - } - } - - /** - * Called from getScope(), binds a property reference. - */ - private def IScope scope_BindingProperty_property(BindingProperty bindingProperty, EReference ref) { - return scope_DestructPattern_property(bindingProperty, ref); - } - - - /** - * Called from getScope(), binds a property reference. - */ - private def IScope scope_PropertyNameValuePair_property(PropertyNameValuePair pnvPair, EReference ref) { - return scope_DestructPattern_property(pnvPair, ref); - } - - private def IScope scope_DestructPattern_property(EObject propertyContainer, EReference ref) { - var TypeRef cTypeRef = null; - val destNodeTop = DestructNode.unify(DestructureUtils.getTop(propertyContainer)); - val parentDestNode = destNodeTop?.findNodeOrParentForElement(propertyContainer, true); - val G = newRuleEnvironment(propertyContainer); - - if (parentDestNode !== null) { - val parentAstElem = parentDestNode.astElement; - if (parentAstElem instanceof BindingProperty) { - if (parentAstElem.property !== null) { - cTypeRef = ts.type(G, parentAstElem.property); - } - } else if (parentAstElem instanceof BindingElement && parentAstElem.eContainer instanceof ArrayBindingPattern) { - val parent2DestNode = destNodeTop?.findNodeOrParentForElement(parentAstElem, true); - if (parent2DestNode !== null) { - var TypeRef arrayType = null; - val parent2AstElem = parent2DestNode.astElement; - if (parent2AstElem instanceof BindingProperty) { - if (parent2AstElem.property !== null) { - arrayType = ts.type(G, parent2AstElem.property); - } - } else { - arrayType = ts.type(G, parent2DestNode.assignedElem); - } - - val idx = parent2DestNode.nestedNodes.indexOf(parentDestNode); - if (arrayType !== null && arrayType.typeArgsWithDefaults.size > idx && G.isIterableN(arrayType) && arrayType.eResource !== null) { - val typeArg = arrayType.typeArgsWithDefaults.get(idx); - if (typeArg instanceof TypeRef) { - cTypeRef = typeArg; - } - } - } - } else if (parentDestNode.assignedElem instanceof TypeDefiningElement && (parentDestNode.assignedElem as TypeDefiningElement).definedType !== null) { - cTypeRef = TypeUtils.createTypeRef((parentDestNode.assignedElem as TypeDefiningElement).definedType); - } else { - // fallback - cTypeRef = ts.type(G, parentDestNode.assignedElem); - } - if (DestructureUtils.isTopOfDestructuringForStatement(parentDestNode.astElement) && cTypeRef.isArrayLike) { - tsh.addSubstitutions(G, cTypeRef); - cTypeRef = ts.substTypeVariables(G, cTypeRef.declaredType.elementType); - } - } - - if (cTypeRef === null && propertyContainer instanceof PropertyNameValuePair && propertyContainer.eContainer instanceof ObjectLiteral) { - val objLit = propertyContainer.eContainer as ObjectLiteral; - if (objLit.definedType !== null) { - cTypeRef = TypeUtils.createTypeRef(objLit.definedType); - } - } - - if (cTypeRef !== null && isContained(cTypeRef)) { - return new UberParentScope("scope_DestructPattern_property", createScopeForMemberAccess(cTypeRef, propertyContainer), new DynamicPseudoScope()); - } - return new DynamicPseudoScope(); - } - - private def boolean isContained(TypeRef tRef) { - if (tRef.eResource !== null) { - // type ref is contained - return true; - } - if (tRef instanceof ParameterizedTypeRefStructural) { - if (!tRef.astStructuralMembers.empty || !tRef.genStructuralMembers.empty) { - // type ref is not contained, hence structural members are not contained - return false; - } - } - if (tRef.declaredType !== null && tRef.declaredType.eResource !== null) { - // nominal type (or similar) is contained - return true; - } - return false; - } - - /* - * In
receiver.property
, binds "property". - * - */ - private def IScope scope_PropertyAccessExpression_property(ParameterizedPropertyAccessExpression propertyAccess, EReference ref) { - val Expression receiver = propertyAccess.target; - - val G = propertyAccess.newRuleEnvironment; - val TypeRef typeRefRaw = ts.type(G, receiver); - // take upper bound to get rid of ExistentialTypeRefs, ThisTypeRefs, etc. - // (literal types are handled in dispatch method #members() of MemberScopingHelper) - val TypeRef typeRef = ts.upperBoundWithReopenAndResolveTypeVars(G, typeRefRaw); - val declaredType = typeRef.declaredType; - if (declaredType instanceof TNamespace) { - return scope_AllTopLevelElementsFromAbstractNamespace(declaredType, propertyAccess, false, true); - } - if (declaredType instanceof ModuleNamespaceVirtualType) { - return createScopeForNamespaceAccess(declaredType, propertyAccess, false, true); - } - - var result = createScopeForMemberAccess(typeRef, propertyAccess); - - // functions and classes may have namespaces merged onto them - result = handleDeclMergingForPropertyAccess(G, propertyAccess, typeRef, result); - - return result; - } - - private def IScope createScopeForNamespaceAccess(ModuleNamespaceVirtualType namespace, EObject context, - boolean includeHollows, boolean includeValueOnlyElements - ) { - val module = namespace.module; - - val result = if (module !== null && !module.eIsProxy) { - scope_AllTopLevelElementsFromAbstractNamespace(module, context, includeHollows, includeValueOnlyElements); - } else { - // error cases - if (namespace.eIsProxy) { - // name space does not exist -> avoid duplicate error messages - // (cf. MemberScopingHelper#members(UnknownTypeRef, MemberScopeRequest)) - new DynamicPseudoScope() - } else { - // name space exists, but imported module does not -> show additional error at location of reference - IScope.NULLSCOPE - } - }; - if (namespace.declaredDynamic && !(result instanceof DynamicPseudoScope)) { - return new DynamicPseudoScope(result); - } - return result; - } - - private def IScope createScopeForMemberAccess(TypeRef targetTypeRef, EObject context) { - val staticAccess = targetTypeRef instanceof TypeTypeRef; - val structFieldInitMode = targetTypeRef.typingStrategy === TypingStrategy.STRUCTURAL_FIELD_INITIALIZER; - val checkVisibility = true; - val result = memberScopingHelper.createMemberScope(targetTypeRef, context, checkVisibility, staticAccess, structFieldInitMode); - return result; - } - - private def IScope handleDeclMergingForPropertyAccess(RuleEnvironment G, ParameterizedPropertyAccessExpression propertyAccess, - TypeRef typeRef, IScope parent) { - - val staticAccess = typeRef instanceof TypeTypeRef; - - var Type mergeCandidate; - if (staticAccess) { - val staticType = tsh.getStaticType(G, typeRef as TypeTypeRef, true); - if (staticType instanceof TClass) { - mergeCandidate = staticType; - } - } else { - val declaredType = typeRef.declaredType; - if (declaredType instanceof TFunction) { - mergeCandidate = declaredType; - } - } - - if (mergeCandidate !== null) { - val scopeNamespace = createScopeForMergedNamespaces(propertyAccess, mergeCandidate, null); - if (scopeNamespace !== null) { - return new MergedScope(scopeNamespace, parent); - } - } - - return parent; - } - - /** Returns parentOrNull unchanged if no namespaces are merged onto 'elem'. */ - private def IScope createScopeForMergedNamespaces(EObject context, Type elem, IScope parentOrNull) { - var result = parentOrNull; - if (DeclMergingUtils.mayBeMerged(elem)) { - val mergedElems = declMergingHelper.getMergedElements(context.eResource as N4JSResource, elem); - val mergedNamespaces = mergedElems.filter(TNamespace).toList; - if (mergedNamespaces.size > 1) { - Collections.sort(mergedNamespaces, Comparator.comparing([(it as InternalEObject).eProxyURI], new URIUtils.URIComparator())); - } - for (mergedNS : mergedNamespaces.reverseView) { - if (mergedNS !== null) { - result = scope_AllTopLevelElementsFromAbstractNamespace(mergedNS, context, result, false, true); - } - } - } - return result; - } - - /** Returns parentOrNull unchanged if no TModules are merged onto 'script'. */ - private def IScope createScopeForMergedTModules(Script script, boolean onlyNamespaces, IScope parentOrNull) { - if (!DeclMergingUtils.mayBeMerged(script)) { - return parentOrNull; - } - var result = parentOrNull; - val resource = script.eResource as N4JSResource; - val mergedTModules = declMergingHelper.getMergedElements(resource, script.module).toList(); // can be empty - if (mergedTModules.size > 1) { - Collections.sort(mergedTModules, Comparator.comparing([(it as InternalEObject).eProxyURI], new URIUtils.URIComparator())); - } - for (mergedTModule : mergedTModules.reverseView) { - if (mergedTModule !== null) { - result = locallyKnownTypesScopingHelper.scopeWithLocallyDeclaredElems(mergedTModule, result, onlyNamespaces); - } - } - return result; - } - - /** - * Is entered to initially bind "T" in
var x : T;
or other parameterized type references. - */ - def public IScope getTypeScope(EObject context, boolean fromStaticContext, boolean onlyNamespaces) { - val internal = getTypeScopeInternal(context, fromStaticContext, onlyNamespaces); - - val legacy = new ContextAwareTypeScope(internal, context); - val scopeInfo = new ScopeInfo(internal, legacy, new ContextAwareTypeScopeValidator(context)); - - return scopeInfo; - } - - def private IScope getTypeScopeInternal(EObject context, boolean fromStaticContext, boolean onlyNamespaces) { - switch context { - Script: { - return locallyKnownTypesScopingHelper.scopeWithLocallyDeclaredElems(context, [ - var parent = delegateGetScope(context, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF__DECLARED_TYPE); // provide any reference that expects instances of Type as target objects - parent = createScopeForMergedTModules(context, onlyNamespaces, parent); - return parent; - ], onlyNamespaces); - } - N4NamespaceDeclaration: { - var parent = getTypeScopeInternal(context.eContainer, fromStaticContext, onlyNamespaces); - val ns = context.definedNamespace; - if (ns !== null && DeclMergingUtils.mayBeMerged(ns)) { - parent = createScopeForMergedNamespaces(context, ns, parent); - } - return locallyKnownTypesScopingHelper.scopeWithLocallyDeclaredElems(context, parent, onlyNamespaces); - } - TNamespace: { - var parent = getTypeScopeInternal(context.eContainer, fromStaticContext, onlyNamespaces); - if (DeclMergingUtils.mayBeMerged(context)) { - parent = createScopeForMergedNamespaces(context, context, parent); - } - return locallyKnownTypesScopingHelper.scopeWithLocallyDeclaredElems(context, parent, onlyNamespaces); - } - TModule: { - val script = context.astElement as Script; - return getTypeScopeInternal(script, fromStaticContext, onlyNamespaces); - } - N4FieldDeclaration: { - val isStaticContext = context.static; - return getTypeScopeInternal(context.eContainer, isStaticContext, onlyNamespaces); // use new static access status for parent scope - } - N4FieldAccessor: { - val isStaticContext = context.static; - return getTypeScopeInternal(context.eContainer, isStaticContext, onlyNamespaces); // use new static access status for parent scope - } - TypeDefiningElement: { - val isStaticContext = context instanceof N4MemberDeclaration && (context as N4MemberDeclaration).static; - val IScope parent = getTypeScopeInternal(context.eContainer, isStaticContext, onlyNamespaces); // use new static access status for parent scope - val polyfilledOrOriginalType = sourceElementExtensions.getTypeOrPolyfilledType(context); - - return locallyKnownTypesScopingHelper.scopeWithTypeAndItsTypeVariables(parent, polyfilledOrOriginalType, fromStaticContext); // use old static access status for current scope - } - TStructMethod: { - val parent = getTypeScopeInternal(context.eContainer, fromStaticContext, onlyNamespaces); - return locallyKnownTypesScopingHelper.scopeWithTypeVarsOfTStructMethod(parent, context); - } - FunctionTypeExpression: { - val parent = getTypeScopeInternal(context.eContainer, fromStaticContext, onlyNamespaces); - return locallyKnownTypesScopingHelper.scopeWithTypeVarsOfFunctionTypeExpression(parent, context); - } - default: { - val container = context.eContainer; - - // handle special areas inside a polyfill that should *not* get the usual polyfill handling implemented - // in the above case for "TypeDefiningElement": - if (container instanceof N4ClassifierDeclaration) { - if (N4JSLanguageUtils.isNonStaticPolyfill(container) || N4JSLanguageUtils.isStaticPolyfill(container)) { - if (container.typeVars.contains(context)) { - // area #1: upper/lower bound of type parameter of polyfill, e.g. the 2nd 'T' in: - // @@StaticPolyfillModule - // @StaticPolyfill export public class ToBeFilled extends ToBeFilled {} - val IScope parent = getTypeScopeInternal(context.eContainer, false, onlyNamespaces); - return locallyKnownTypesScopingHelper.scopeWithTypeAndItsTypeVariables(parent, container.definedType, fromStaticContext); - } else if (container.superClassifierRefs.contains(context)) { - // area #2: super type reference of polyfill, e.g. everything after 'extends' in: - // @@StaticPolyfillModule - // @StaticPolyfill export public class ToBeFilled extends ToBeFilled {} - val script = EcoreUtil2.getContainerOfType(container, Script); - val globalScope = delegateGetScope(script, TypeRefsPackage.Literals.PARAMETERIZED_TYPE_REF__DECLARED_TYPE); - val parent = locallyKnownTypesScopingHelper.scopeWithLocallyKnownTypesForPolyfillSuperRef(script, globalScope, - container.definedType); - return parent; - } - } - } - - return getTypeScopeInternal(container, fromStaticContext, onlyNamespaces); - } - } - } - - /** - * Returns ancestor of given type, or null, if no such container exists. Note that this method is slightly different from - * EcoreUtil2::getContainerOfType, as it only returns a container and not the element itself. That is, ancestor is not reflexive here. - */ - private def T ancestor(EObject obj, Class ancestorType) { - if (obj === null) return null; - return EcoreUtil2.getContainerOfType(obj.eContainer, ancestorType); - } - - private def getN4JSXScope(EObject context, EReference reference) { - val jsxPropertyAttributeScope = getJSXPropertyAttributeScope(context, reference) - if(jsxPropertyAttributeScope !== IScope.NULLSCOPE) - return jsxPropertyAttributeScope - - val jsxElementScope = getJSXElementScope(context, reference) - if(jsxElementScope !== IScope.NULLSCOPE) - return jsxElementScope - - //delegate to host -> N4JS scope - return getN4JSScope(context, reference); - } - /** Returns scope for the {@link JSXPropertyAttribute} (obtained from context) or {@link IScope#NULLSCOPE} */ - private def getJSXPropertyAttributeScope(EObject context, EReference reference) { - if (reference == N4JSPackage.Literals.JSX_PROPERTY_ATTRIBUTE__PROPERTY) { - if (context instanceof JSXPropertyAttribute) { - val jsxElem = (context.eContainer as JSXElement); - val TypeRef propsTypeRef = reactHelper.getPropsType(jsxElem); - val checkVisibility = true; - val staticAccess = false; - val structFieldInitMode = false; - if (propsTypeRef !== null) { - // Prevent "Cannot resolve to element" error message of unknown attributes since - // we want to issue a warning instead - val TypeRef propsTypeRefUB = ts.upperBoundWithReopenAndResolveTypeVars(context.newRuleEnvironment, propsTypeRef); - val memberScope = memberScopingHelper.createMemberScope(propsTypeRefUB, context, checkVisibility, - staticAccess, structFieldInitMode); - return new DynamicPseudoScope(memberScope); - } else { - val scope = getN4JSScope(context, reference); - return new DynamicPseudoScope(scope); - } - } - } - return IScope.NULLSCOPE; - } - - /** Returns scope for the JSXElement (obtained from context) or {@link IScope#NULLSCOPE} */ - private def getJSXElementScope(EObject context, EReference reference) { - - if(EcoreUtil2.getContainerOfType(context, JSXElementName) === null) - return IScope.NULLSCOPE; - - val scope = getN4JSScope(context, reference) - return new DynamicPseudoScope(scope); - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingDiagnostician.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingDiagnostician.java new file mode 100644 index 0000000000..98207d262e --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingDiagnostician.java @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2017 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.scoping.diagnosing; + +import java.util.Arrays; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression; +import org.eclipse.n4js.n4JS.ParenExpression; +import org.eclipse.n4js.n4JS.RelationalExpression; +import org.eclipse.n4js.n4JS.RelationalOperator; +import org.eclipse.n4js.n4JS.SuperLiteral; +import org.eclipse.n4js.resource.ErrorAwareLinkingService; +import org.eclipse.xtext.diagnostics.DiagnosticMessage; +import org.eclipse.xtext.naming.IQualifiedNameConverter; +import org.eclipse.xtext.naming.QualifiedName; +import org.eclipse.xtext.nodemodel.INode; + +import com.google.inject.Inject; + +/** + * This class provides enhanced error reporting in the case that a reference can't be resolved by the N4JS scoping + * mechanisms. + * + * This class can be extended by more special cases to provide the user with more informative error messages. + */ +@SuppressWarnings("all") +public class N4JSScopingDiagnostician { + /** + * Special value to denote that no diagnostic message should be shown. + */ + public static final DiagnosticMessage NO_MESSAGE = new DiagnosticMessage( + N4JSScopingDiagnostician.class.getSimpleName() + ".NO_MESSAGE", null, null); + @Inject + private N4JSScopingConsumableMethodsDiagnosis consumableMethodsDiagnosis; + + @Inject + private N4JSScopingInstanceOfPrimitivTypeDiagnosis instanceOfPrimitiveTypeDiagnosis; + + @Inject + private ErrorAwareLinkingService linkingService; + + @Inject + private IQualifiedNameConverter qualifiedNameConverter; + + /** + * Returns a custom {@link DiagnosticMessage} for the given unresolvable reference or {@code null} if no supported + * special case is applicable and the default message should be shown. + *

+ * May return special value {@link #NO_MESSAGE} to not show an error at all for the given unresolved reference (e.g. + * to avoid duplicate error messages) . + *

+ * Note that this methods already assumes, that the given reference actually isn't resolvable. + */ + public DiagnosticMessage getMessageFor(EObject context, EReference reference, INode node) { + // use linking service here to work with the same qualified name as we do in scoping + String crossRefAsString = linkingService.getCrossRefNodeAsString(context, reference, node); + + if (null != crossRefAsString && !crossRefAsString.equals("")) { + QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(crossRefAsString); + return diagnose(qualifiedName, context); + } + return null; + } + + /** Default dispatch method */ + private DiagnosticMessage diagnose(QualifiedName name, EObject context) { + if (context instanceof IdentifierRef) { + return diagnose(name, (IdentifierRef) context); + } else if (context instanceof ParameterizedPropertyAccessExpression) { + return diagnose(name, (ParameterizedPropertyAccessExpression) context); + } else if (context instanceof NamedImportSpecifier) { + return diagnose(name, (NamedImportSpecifier) context); + } else if (context != null) { + return null; + } + throw new IllegalArgumentException("Unhandled parameter types: " + + Arrays. asList(name, context).toString()); + } + + /** Handle {@link NamedImportSpecifier} */ + @SuppressWarnings("unused") + private DiagnosticMessage diagnose(QualifiedName name, NamedImportSpecifier context) { + // avoid duplicate error messages in case of unresolved imports + return NO_MESSAGE; + } + + /** Handle {@link ParameterizedPropertyAccessExpression} */ + private DiagnosticMessage diagnose(QualifiedName name, ParameterizedPropertyAccessExpression context) { + if (context.getTarget() instanceof SuperLiteral) { + // custom error message for referring to consumable methods via super + return consumableMethodsDiagnosis.diagnose(name, context); + } + return null; + } + + /** Handle {@link IdentifierRef}s */ + private DiagnosticMessage diagnose(QualifiedName name, IdentifierRef context) { + var container = context.eContainer(); + var containingFeature = context.eContainingFeature(); + // Skip all parenthesis-expression containers to allow + // for expressions like '((int))' + while (container instanceof ParenExpression) { + containingFeature = container.eContainmentFeature(); + container = container.eContainer(); + } + // Handle instanceof expressions + if (container instanceof RelationalExpression) { + // Check that the unresolved identifier is on the RHS of the + // operator and the operator is INSTANCEOF + RelationalExpression re = (RelationalExpression) container; + if (java.util.Objects.equals(re.getOp(), RelationalOperator.INSTANCEOF) && + java.util.Objects.equals(containingFeature, N4JSPackage.Literals.RELATIONAL_EXPRESSION__RHS)) { + return instanceOfPrimitiveTypeDiagnosis.diagnose(name, re); + } + } + return null; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingDiagnostician.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingDiagnostician.xtend deleted file mode 100644 index 4c6f4de05c..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/diagnosing/N4JSScopingDiagnostician.xtend +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Copyright (c) 2017 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.scoping.diagnosing - -import com.google.inject.Inject -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.EReference -import org.eclipse.n4js.n4JS.IdentifierRef -import org.eclipse.n4js.n4JS.N4JSPackage -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression -import org.eclipse.n4js.n4JS.ParenExpression -import org.eclipse.n4js.n4JS.RelationalExpression -import org.eclipse.n4js.n4JS.RelationalOperator -import org.eclipse.n4js.n4JS.SuperLiteral -import org.eclipse.n4js.resource.ErrorAwareLinkingService -import org.eclipse.xtext.diagnostics.DiagnosticMessage -import org.eclipse.xtext.naming.IQualifiedNameConverter -import org.eclipse.xtext.naming.QualifiedName -import org.eclipse.xtext.nodemodel.INode - -/** - * This class provides enhanced error reporting in the case that - * a reference can't be resolved by the N4JS scoping mechanisms. - * - * This class can be extended by more special cases - * to provide the user with more informative error messages. - */ -class N4JSScopingDiagnostician { - - /** Special value to denote that no diagnostic message should be shown. */ - public static final DiagnosticMessage NO_MESSAGE = new DiagnosticMessage(N4JSScopingDiagnostician.simpleName + ".NO_MESSAGE", null, null); - - @Inject - N4JSScopingConsumableMethodsDiagnosis consumableMethodsDiagnosis; - - @Inject - N4JSScopingInstanceOfPrimitivTypeDiagnosis instanceOfPrimitiveTypeDiagnosis; - - @Inject - ErrorAwareLinkingService linkingService; - - @Inject - IQualifiedNameConverter qualifiedNameConverter; - - - /** - * Returns a custom {@link DiagnosticMessage} for the given unresolvable reference or {@code null} if no - * supported special case is applicable and the default message should be shown. - *

- * May return special value {@link #NO_MESSAGE} to not show an error at all for the given unresolved reference - * (e.g. to avoid duplicate error messages) . - *

- * Note that this methods already assumes, that the given reference actually isn't resolvable. - */ - public def DiagnosticMessage getMessageFor(EObject context, EReference reference, INode node) { - // use linking service here to work with the same qualified name as we do in scoping - val crossRefAsString = linkingService.getCrossRefNodeAsString(context, reference, node); - - if (null !== crossRefAsString && !crossRefAsString.equals("")) { - val qualifiedName = qualifiedNameConverter.toQualifiedName(crossRefAsString); - return diagnose(qualifiedName, context, reference); - } - return null; - } - - // Handle {@link NamedImportSpecifier} - private def dispatch DiagnosticMessage diagnose(QualifiedName name, NamedImportSpecifier context, EReference reference) { - // avoid duplicate error messages in case of unresolved imports - return NO_MESSAGE; - } - - // Handle {@link ParameterizedPropertyAccessExpressions} - private def dispatch DiagnosticMessage diagnose(QualifiedName name, ParameterizedPropertyAccessExpression context, EReference reference) { - if (context.target instanceof SuperLiteral) { - // custom error message for referring to consumable methods via super - return consumableMethodsDiagnosis.diagnose(name, context); - } - } - - // Handle {@link IdentifierRef}s - private def dispatch DiagnosticMessage diagnose(QualifiedName name, IdentifierRef context, EReference reference) { - var container = context.eContainer; - var containingFeature = context.eContainingFeature(); - // Skip all parenthesis-expression containers to allow - // for expressions like '((int))' - while (container instanceof ParenExpression) { - containingFeature = container.eContainmentFeature; - container = container.eContainer; - } - // Handle instanceof expressions - if (container instanceof RelationalExpression) { - // Check that the unresolved identifier is on the RHS of the - // operator and the operator is INSTANCEOF - if (container.op == RelationalOperator.INSTANCEOF && - containingFeature == N4JSPackage.Literals.RELATIONAL_EXPRESSION__RHS) { - return instanceOfPrimitiveTypeDiagnosis.diagnose(name, container); - } - } - } - - - // Default dispatch method - private def dispatch DiagnosticMessage diagnose(QualifiedName name, EObject context, EReference reference) { - return null; - } - -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/ImportedElementsScopingHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/ImportedElementsScopingHelper.java new file mode 100644 index 0000000000..7ed5729253 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/ImportedElementsScopingHelper.java @@ -0,0 +1,506 @@ +/** + * 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.scoping.imports; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.HashMap; +import java.util.List; +import java.util.Objects; + +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.n4js.n4JS.DefaultImportSpecifier; +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.resource.N4JSCache; +import org.eclipse.n4js.resource.N4JSResource; +import org.eclipse.n4js.scoping.ExportedElementsCollector; +import org.eclipse.n4js.scoping.N4JSScopeProvider; +import org.eclipse.n4js.scoping.accessModifiers.AbstractTypeVisibilityChecker; +import org.eclipse.n4js.scoping.accessModifiers.AbstractTypeVisibilityChecker.TypeVisibility; +import org.eclipse.n4js.scoping.accessModifiers.InvisibleTypeOrVariableDescription; +import org.eclipse.n4js.scoping.accessModifiers.TypeVisibilityChecker; +import org.eclipse.n4js.scoping.accessModifiers.VariableVisibilityChecker; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.scoping.builtin.GlobalObjectScope; +import org.eclipse.n4js.scoping.builtin.NoPrimitiveTypesScope; +import org.eclipse.n4js.scoping.members.MemberScope.MemberScopeFactory; +import org.eclipse.n4js.scoping.utils.LocallyKnownTypesScopingHelper; +import org.eclipse.n4js.scoping.utils.MultiImportedElementsMap; +import org.eclipse.n4js.scoping.utils.ScopeSnapshotHelper; +import org.eclipse.n4js.scoping.utils.UberParentScope; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TDynamicElement; +import org.eclipse.n4js.ts.types.TExportableElement; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.TVariable; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.utils.ResourceType; +import org.eclipse.n4js.validation.IssueCodes; +import org.eclipse.xtext.naming.IQualifiedNameProvider; +import org.eclipse.xtext.naming.QualifiedName; +import org.eclipse.xtext.resource.EObjectDescription; +import org.eclipse.xtext.resource.IEObjectDescription; +import org.eclipse.xtext.resource.impl.AliasedEObjectDescription; +import org.eclipse.xtext.scoping.IScope; + +import com.google.common.base.Optional; +import com.google.common.base.Throwables; +import com.google.common.collect.Iterables; +import com.google.inject.Inject; +import com.google.inject.Singleton; + +/** + * Helper for {@link N4JSScopeProvider N4JSScopeProvider} + * {@link N4JSScopeProvider#scope_IdentifierRef_id(IdentifierRef, EReference) .scope_IdentifierRef_id()}, also used by + * helper {@link LocallyKnownTypesScopingHelper LocallyKnownTypesScopingHelper}. + */ +@Singleton +public class ImportedElementsScopingHelper { + /** internal helper collection type */ + static public class IEODesc2ISpec extends HashMap { + /// empty + } + + private final static Logger LOGGER = Logger.getLogger(ImportedElementsScopingHelper.class); + + @Inject + N4JSCache cache; + + @Inject + private TypeVisibilityChecker typeVisibilityChecker; + + @Inject + private IQualifiedNameProvider qualifiedNameProvider; + + @Inject + private VariableVisibilityChecker variableVisibilityChecker; + + @Inject + private ImportedElementsMap.Provider elementsMapProvider; + + @Inject + private MemberScopeFactory memberScopeFactory; + + @Inject + private ScopeSnapshotHelper scopesHelper; + + @Inject + private ExportedElementsCollector exportedElementsCollector; + + /***/ + public IScope getImportedTypes(IScope parentScope, Script script) { + IScope scriptScope = cache.get(script.eResource(), () -> findImportedElements(script, parentScope, true, false), + "importedTypes", script); + return scriptScope; + } + + /***/ + public IScope getImportedValues(IScope parentScope, Script script) { + IScope scriptScope = cache.get(script.eResource(), () -> { + // filter out primitive types in next line (otherwise code like "let x = int;" would be allowed) + NoPrimitiveTypesScope noPrimitiveBuiltIns = new NoPrimitiveTypesScope( + BuiltInTypeScope.get(script.eResource().getResourceSet())); + UberParentScope uberParent = new UberParentScope("ImportedElementsScopingHelper-uberParent", + noPrimitiveBuiltIns, parentScope); + IScope globalObjectScope = getGlobalObjectProperties(uberParent, script); + IScope result = findImportedElements(script, globalObjectScope, false, true); + return result; + }, "importedValues", script); + return scriptScope; + } + + /** + * Creates a new QualifiedNamed for the given named import specifier. + * + * Determines the local name of the imported element based on the given import specifier. + */ + private QualifiedName createQualifiedNameForAlias(NamedImportSpecifier specifier) { + String importedName = (specifier.isDefaultImport()) + // we got a default import of the form: import localName from "some/module" + // -> use the string "localName" (but this is not the alias property!) + ? specifier.getImportedElementAsText() + : specifier.getAlias() != null ? specifier.getAlias() : specifier.getImportedElementAsText(); + + return QualifiedName.create(importedName); + } + + private QualifiedName createImportedQualifiedTypeName(Type type) { + return QualifiedName.create(getImportedName(type)); + } + + private String getImportedName(Type type) { + return type.getName(); + } + + private QualifiedName createImportedQualifiedTypeName(String namespace, Type type) { + return QualifiedName.create(namespace, getImportedName(type)); + } + + private IScope findImportedElements(Script script, IScope parentScope, boolean includeHollows, + boolean includeValueOnlyElements) { + N4JSResource contextResource = (N4JSResource) script.eResource(); + List imports = toList(filter(script.getScriptElements(), ImportDeclaration.class)); + + if (imports.isEmpty()) { + return parentScope; + } + + /** + * broken/invisible imported eObjects descriptions - in case of broken state of imports this can be + * {@link AmbiguousImportDescription} - in case of alias/namespace imports multiple imported elements can have + * the same qualified name + */ + MultiImportedElementsMap invalidImports = new MultiImportedElementsMap(); + /** + * valid imported eObjects descriptions (in case of broken state of imports this can be + * {@link AmbiguousImportDescription}) + */ + ImportedElementsMap validImports = elementsMapProvider.get(script); + IEODesc2ISpec originatorMap = new IEODesc2ISpec(); + + for (ImportDeclaration imp : imports) { + TModule module = imp == null ? null : imp.getModule(); + if (imp != null && module != null) { + + Iterable topLevelElements = exportedElementsCollector.getExportedElements(module, + contextResource, Optional.of(imp), includeHollows, includeValueOnlyElements); + IScope tleScope = scopesHelper.scopeFor("scope_AllTopLevelElementsFromModule", module, IScope.NULLSCOPE, + false, topLevelElements); + + for (ImportSpecifier specifier : imp.getImportSpecifiers()) { + if (specifier instanceof NamedImportSpecifier) { + processNamedImportSpecifier((NamedImportSpecifier) specifier, imp, contextResource, + originatorMap, validImports, + invalidImports, includeValueOnlyElements, tleScope); + } else if (specifier instanceof NamespaceImportSpecifier) { + processNamespaceSpecifier((NamespaceImportSpecifier) specifier, imp, script, contextResource, + originatorMap, validImports, + invalidImports, includeValueOnlyElements); + } + } + } + } + + // local broken elements are hidden by parent scope, both are hidden by valid local elements + IScope invalidLocalScope = scopesHelper.scopeFor("findImportedElements-invalidImports", script, + invalidImports.values()); + IScope localValidScope = scopesHelper.scopeFor("findImportedElements-validImports", script, parentScope, + validImports.values()); + UberParentScope importScope = new UberParentScope("findImportedElements-uberParent", localValidScope, + invalidLocalScope); + return new OriginAwareScope(script, importScope, originatorMap); + } + + private void processNamedImportSpecifier(NamedImportSpecifier specifier, ImportDeclaration imp, + Resource contextResource, IEODesc2ISpec originatorMap, + ImportedElementsMap validImports, + ImportedElementsMap invalidImports, boolean includeValueOnlyElements, IScope tleScope) { + + TExportableElement element = null; + if (specifier.isDeclaredDynamic()) { + element = findFirst(((N4JSResource) specifier.eResource()).getModule().getInternalDynamicElements(), + de -> de.getAstElement() == specifier); + } else { + String name = (specifier instanceof DefaultImportSpecifier) + ? "default" + : specifier.getImportedElementAsText(); + QualifiedName qName = QualifiedName.create(name); + + IEObjectDescription importedElem = tleScope.getSingleElement(qName); + if (importedElem != null && importedElem.getEObjectOrProxy() instanceof TExportableElement) { + element = (TExportableElement) importedElem.getEObjectOrProxy(); + } + } + + if (element != null && !element.eIsProxy()) { + + if (!includeValueOnlyElements && isValueOnlyFrom(element, imp)) { + return; + } + + QualifiedName importedQName = createQualifiedNameForAlias(specifier); + TypeVisibility typeVisibility = isVisible(contextResource, element); + if (typeVisibility.visibility) { + + addNamedImports(specifier, element, importedQName, + originatorMap, validImports); + + QualifiedName originalName = QualifiedName.create(element.getName()); + + if (specifier.getAlias() != null) { + handleAliasedAccess(element, originalName, importedQName.toString(), invalidImports); + } + } else { + handleInvisible(element, invalidImports, importedQName, typeVisibility.accessModifierSuggestion, + originatorMap, specifier); + } + } + } + + private void addNamedImports(NamedImportSpecifier specifier, TExportableElement element, QualifiedName importedName, + IEODesc2ISpec originatorMap, ImportedElementsMap validImports) { + IEObjectDescription ieod = putOrError(validImports, element, importedName, IssueCodes.IMP_AMBIGUOUS.name()); + putWithOrigin(originatorMap, ieod, specifier); + } + + private void processNamespaceSpecifier( + NamespaceImportSpecifier specifier, + ImportDeclaration imp, + Script script, + Resource contextResource, + IEODesc2ISpec originatorMap, + ImportedElementsMap validImports, + ImportedElementsMap invalidImports, + boolean includeValueOnlyElements) { + if (specifier.getAlias() == null) { + return; // if broken code, e.g. "import * as 123 as N from "some/Module"" + } + if (script.getModule() == null) { + return; // when reconciliation of TModule fails due to hash mismatch + } + + // add namespace to scope + String namespaceName = specifier.getAlias(); + QualifiedName namespaceQName = QualifiedName.create(namespaceName); + TModule sModule = script.getModule(); + + Iterable allTypes = Iterables.concat(sModule.getInternalTypes(), sModule.getExposedInternalTypes()); + + Type namespaceType = findFirst(allTypes, (interType) -> interType instanceof ModuleNamespaceVirtualType && + ((ModuleNamespaceVirtualType) interType).getModule() == imp.getModule()); + + if (namespaceType == null) { + // TODO GH-2002 remove this temporary debug logging + StringBuilder sb = new StringBuilder(); + sb.append( + "contextResource?.getURI(): " + (contextResource == null ? null : contextResource.getURI()) + "\n"); + sb.append("specifier.definedType: " + specifier.getDefinedType() + "\n"); + sb.append("imp.module: " + imp.getModule() + "\n"); + sb.append("script.module: " + sModule + "\n"); + sb.append("script.module.isPreLinkingPhase: " + sModule.isPreLinkingPhase() + "\n"); + sb.append("script.module.isReconciled: " + sModule.isReconciled() + "\n"); + sb.append("script.module.internalTypes.size: " + sModule.getInternalTypes().size() + "\n"); + sb.append("script.module.exposedInternalTypes.size: " + sModule.getExposedInternalTypes().size() + "\n"); + for (Type type : allTypes) { + if (type instanceof ModuleNamespaceVirtualType) { + sb.append("type[n].module: " + ((ModuleNamespaceVirtualType) type).getModule() + "\n"); + } + } + sb.append("\n"); + sb.append(Throwables.getStackTraceAsString(new IllegalStateException())); + LOGGER.error("namespaceType not found\n" + sb.toString()); + return; + } + IEObjectDescription ieodx = putOrError(validImports, namespaceType, namespaceQName, + IssueCodes.IMP_AMBIGUOUS.name()); + putWithOrigin(originatorMap, ieodx, specifier); + + if (includeValueOnlyElements) { + // add vars to namespace + // (this is *only* about adding some IEObjectDescriptionWithError to improve error messages) + for (TVariable importedVar : imp.getModule().getExportedVariables()) { + TypeVisibility varVisibility = variableVisibilityChecker.isVisible(contextResource, importedVar); + String varName = importedVar.getName(); + QualifiedName qn = QualifiedName.create(namespaceName, varName); + if (varVisibility.visibility) { + QualifiedName originalName = QualifiedName.create(varName); + if (!invalidImports.containsElement(originalName)) { + handleNamespacedAccess(importedVar, originalName, qn, invalidImports); + } + } + } + // add functions to namespace + // (this is *only* about adding some IEObjectDescriptionWithError to improve error messages) + for (TFunction importedFun : imp.getModule().getFunctions()) { + TypeVisibility varVisibility = typeVisibilityChecker.isVisible(contextResource, importedFun); + String varName = importedFun.getName(); + QualifiedName qn = QualifiedName.create(namespaceName, varName); + if (varVisibility.visibility) { + QualifiedName originalName = QualifiedName.create(varName); + if (!invalidImports.containsElement(originalName)) { + handleNamespacedAccess(importedFun, originalName, qn, invalidImports); + } + } + } + } + + // add types + // (this is *only* about adding some IEObjectDescriptionWithError to improve error messages) + for (Type importedType : imp.getModule().getTypes()) { + TypeVisibility typeVisibility = typeVisibilityChecker.isVisible(contextResource, importedType); + + QualifiedName qn = createImportedQualifiedTypeName(namespaceName, importedType); + if (typeVisibility.visibility) { + QualifiedName originalName = createImportedQualifiedTypeName(importedType); + if (!invalidImports.containsElement(originalName)) { + handleNamespacedAccess(importedType, originalName, qn, invalidImports); + } + } + } + } + + private void handleAliasedAccess(IdentifiableElement element, QualifiedName originalName, String importedName, + ImportedElementsMap invalidImports) { + PlainAccessOfAliasedImportDescription invalidAccess = new PlainAccessOfAliasedImportDescription( + EObjectDescription.create(originalName, element), + importedName); + invalidImports.put(originalName, invalidAccess); + // TODO IDEBUG-702 originatorMap.putWithOrigin(invalidAccess, specifier) + } + + private void handleNamespacedAccess(IdentifiableElement importedType, QualifiedName originalName, QualifiedName qn, + ImportedElementsMap invalidImports) { + PlainAccessOfNamespacedImportDescription invalidAccess = new PlainAccessOfNamespacedImportDescription( + EObjectDescription.create(originalName, importedType), qn); + invalidImports.put(originalName, invalidAccess); + // TODO IDEBUG-702 originatorMap.putWithOrigin(invalidAccess, specifier) + } + + private void handleInvisible(IdentifiableElement importedElement, ImportedElementsMap invalidImports, + QualifiedName qn, + String visibilitySuggestion, IEODesc2ISpec originatorMap, ImportSpecifier specifier) { + // TODO IDEBUG-702 val invalidAccess = new InvisibleTypeOrVariableDescription(EObjectDescription.create(qn, + // importedElement)) + IEObjectDescription invalidAccess = putOrError(invalidImports, importedElement, qn, null); + addAccessModifierSuggestion(invalidAccess, visibilitySuggestion); + putWithOrigin(originatorMap, invalidAccess, specifier); + } + + /** + * Add the description to the orginatorMap and include trace to the specifier in special Error-Aware + * IEObjectDesciptoins like AmbigousImportDescriptions. + */ + private void putWithOrigin(HashMap originiatorMap, + IEObjectDescription description, ImportSpecifier specifier) { + originiatorMap.put(description, specifier); + if (description instanceof AmbiguousImportDescription) { + AmbiguousImportDescription aid = (AmbiguousImportDescription) description; + aid.getOriginatingImports().add(specifier); + // Handling of wrapped delegatee, since this information will not be available in other cases: + ImportSpecifier firstPlaceSpec = originiatorMap.get(aid.delegate()); + // add only if not there yet: + if (firstPlaceSpec != null && !aid.getOriginatingImports().contains(firstPlaceSpec)) { + aid.getOriginatingImports().add(firstPlaceSpec); + } + } + } + + private boolean isValueOnlyFrom(IdentifiableElement element, ImportDeclaration imp) { + if (imp == null || imp.getModule() == null) { + return false; + } + if (imp.getModule().getFunctions().contains(element)) { + return true; + } + if (imp.getModule().getExportedVariables().contains(element)) { + return true; + } + return false; + } + + private AbstractTypeVisibilityChecker.TypeVisibility isVisible(Resource contextResource, + IdentifiableElement element) { + if (element instanceof TMember && ResourceType.getResourceType(element) == ResourceType.DTS) + return new AbstractTypeVisibilityChecker.TypeVisibility(true); + else if (element instanceof Type) + return typeVisibilityChecker.isVisible(contextResource, (Type) element); + else if (element instanceof TVariable) + return variableVisibilityChecker.isVisible(contextResource, (TVariable) element); + else if (element instanceof TDynamicElement) + return new AbstractTypeVisibilityChecker.TypeVisibility(true); + else + return new AbstractTypeVisibilityChecker.TypeVisibility(false); + } + + /** + * Returns {@code true} if an import of the given {@link IEObjectDescription} should be regarded as ambiguous with + * the given {@link IdentifiableElement}. + */ + @SuppressWarnings("unused") + protected boolean isAmbiguous(IEObjectDescription existing, IdentifiableElement element) { + // make sure ambiguity is only detected in case of the same imported version of a type + return true; + } + + private IEObjectDescription putOrError(ImportedElementsMap result, + IdentifiableElement element, QualifiedName importedName, String issueCode) { + // TODO IDEBUG-702 refactor InvisibleTypeOrVariableDescription / AmbiguousImportDescription relation + IEObjectDescription ret = null; + List existing = toList(result.getElements(importedName)); + + if (!existing.isEmpty() && existing.get(0) != null) { + if (issueCode != null) { + if (existing instanceof AmbiguousImportDescription) { + ((AmbiguousImportDescription) existing).getElements().add(element); + ret = (AmbiguousImportDescription) existing; + } else { + AmbiguousImportDescription error = new AmbiguousImportDescription(existing.get(0), issueCode, + element); + result.put(importedName, error); + error.getElements().add(element); + ret = error; + } + } + } else if (issueCode == null) { + ret = createDescription(importedName, element); + ret = new InvisibleTypeOrVariableDescription(ret); + result.put(importedName, ret); + } else { + ret = createDescription(importedName, element); + result.put(importedName, ret); + } + return ret; + } + + private IEObjectDescription createDescription(QualifiedName name, IdentifiableElement element) { + if (!Objects.equals(name.getLastSegment(), element.getName())) { + var qn = qualifiedNameProvider.getFullyQualifiedName(element); + if (qn == null) { + // non-directly-exported variable / function / type alias that is exported under an alias via a separate + // export declaration: + QualifiedName base = qualifiedNameProvider.getFullyQualifiedName(element.getContainingModule()); + qn = base == null ? null : base.append(element.getName()); + } + return new AliasedEObjectDescription(name, EObjectDescription.create(qn, element)); + } else { + return EObjectDescription.create(name, element); + } + } + + /** + * global object scope indirectly cached, as this method is only called by getImportedIdentifiables (which is + * cached) + */ + private IScope getGlobalObjectProperties(IScope parent, EObject context) { + TClass globalObject = GlobalObjectScope.get(context.eResource().getResourceSet()).getGlobalObject(); + return memberScopeFactory.create(parent, globalObject, context, false, false, false); + } + + private void addAccessModifierSuggestion(IEObjectDescription description, String suggestion) { + if (description instanceof InvisibleTypeOrVariableDescription) { + ((InvisibleTypeOrVariableDescription) description).setAccessModifierSuggestion(suggestion); + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/ImportedElementsScopingHelper.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/ImportedElementsScopingHelper.xtend deleted file mode 100644 index 9f40a9b446..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/ImportedElementsScopingHelper.xtend +++ /dev/null @@ -1,471 +0,0 @@ -/** - * 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.scoping.imports - -import com.google.common.base.Optional -import com.google.common.base.Throwables -import com.google.inject.Inject -import com.google.inject.Singleton -import java.util.HashMap -import org.apache.log4j.Logger -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.resource.Resource -import org.eclipse.n4js.n4JS.DefaultImportSpecifier -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.ImportSpecifier -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.resource.N4JSCache -import org.eclipse.n4js.resource.N4JSResource -import org.eclipse.n4js.scoping.ExportedElementsCollector -import org.eclipse.n4js.scoping.N4JSScopeProvider -import org.eclipse.n4js.scoping.accessModifiers.AbstractTypeVisibilityChecker -import org.eclipse.n4js.scoping.accessModifiers.InvisibleTypeOrVariableDescription -import org.eclipse.n4js.scoping.accessModifiers.TypeVisibilityChecker -import org.eclipse.n4js.scoping.accessModifiers.VariableVisibilityChecker -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.scoping.builtin.GlobalObjectScope -import org.eclipse.n4js.scoping.builtin.NoPrimitiveTypesScope -import org.eclipse.n4js.scoping.members.MemberScope.MemberScopeFactory -import org.eclipse.n4js.scoping.utils.LocallyKnownTypesScopingHelper -import org.eclipse.n4js.scoping.utils.MultiImportedElementsMap -import org.eclipse.n4js.scoping.utils.ScopeSnapshotHelper -import org.eclipse.n4js.scoping.utils.UberParentScope -import org.eclipse.n4js.ts.types.IdentifiableElement -import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType -import org.eclipse.n4js.ts.types.TDynamicElement -import org.eclipse.n4js.ts.types.TExportableElement -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.ts.types.TVariable -import org.eclipse.n4js.ts.types.Type -import org.eclipse.n4js.utils.ResourceType -import org.eclipse.n4js.validation.IssueCodes -import org.eclipse.xtext.naming.IQualifiedNameProvider -import org.eclipse.xtext.naming.QualifiedName -import org.eclipse.xtext.resource.EObjectDescription -import org.eclipse.xtext.resource.IEObjectDescription -import org.eclipse.xtext.resource.impl.AliasedEObjectDescription -import org.eclipse.xtext.scoping.IScope - -/** internal helper collection type */ -class IEODesc2ISpec extends HashMap {} - -/** - * Helper for {@link N4JSScopeProvider N4JSScopeProvider} - * {@link N4JSScopeProvider#scope_IdentifierRef_id(org.eclipse.n4js.n4JS.VariableEnvironmentElement) .scope_IdentifierRef_id()}, - * also used by helper {@link LocallyKnownTypesScopingHelper LocallyKnownTypesScopingHelper}. - */ -@Singleton -class ImportedElementsScopingHelper { - - private final static Logger LOGGER = Logger.getLogger(ImportedElementsScopingHelper); - - @Inject - N4JSCache cache - - @Inject - private TypeVisibilityChecker typeVisibilityChecker - - @Inject - private IQualifiedNameProvider qualifiedNameProvider - - @Inject - private VariableVisibilityChecker variableVisibilityChecker - - @Inject - private ImportedElementsMap.Provider elementsMapProvider - - @Inject - private MemberScopeFactory memberScopeFactory - - @Inject - private ScopeSnapshotHelper scopesHelper; - - @Inject - private ExportedElementsCollector exportedElementsCollector - - - - def IScope getImportedTypes(IScope parentScope, Script script) { - val IScope scriptScope = cache.get(script.eResource, [| - return findImportedElements(script, parentScope, true, false); - ], 'importedTypes', script) - return scriptScope - } - - def IScope getImportedValues(IScope parentScope, Script script) { - val IScope scriptScope = cache.get(script.eResource, [| - // filter out primitive types in next line (otherwise code like "let x = int;" would be allowed) - val noPrimitiveBuiltIns = new NoPrimitiveTypesScope(BuiltInTypeScope.get(script.eResource.resourceSet)); - val uberParent = new UberParentScope("ImportedElementsScopingHelper-uberParent", noPrimitiveBuiltIns, parentScope); - val globalObjectScope = getGlobalObjectProperties(uberParent, script); - val result = findImportedElements(script, globalObjectScope, false, true); - return result; - ], 'importedValues', script); - return scriptScope - } - - /** - * Creates a new QualifiedNamed for the given named import specifier. - * - * Determines the local name of the imported element based on the given import specifier. - */ - private def QualifiedName createQualifiedNameForAlias(NamedImportSpecifier specifier, - TExportableElement importedElement) { - val importedName = if (specifier.isDefaultImport) { - // we got a default import of the form: import localName from "some/module" - // -> use the string 'localName' (but this is not the alias property!) - specifier.importedElementAsText - } else { - specifier.alias ?: specifier.importedElementAsText - }; - return QualifiedName.create(importedName) - } - - private def QualifiedName createImportedQualifiedTypeName(Type type) { - return QualifiedName.create(getImportedName(type)); - } - - private def String getImportedName(Type type) { - return type.name; - } - - private def QualifiedName createImportedQualifiedTypeName(String namespace, Type type) { - return QualifiedName.create(namespace, getImportedName(type)); - } - - private def IScope findImportedElements(Script script, IScope parentScope, boolean includeHollows, boolean includeValueOnlyElements) { - val contextResource = script.eResource as N4JSResource; - val imports = script.scriptElements.filter(ImportDeclaration) - - if (imports.empty) return parentScope; - - /** broken/invisible imported eObjects descriptions - * - in case of broken state of imports this can be {@link AmbiguousImportDescription} - * - in case of alias/namespace imports multiple imported elements can have the same qualified name - */ - val invalidImports = new MultiImportedElementsMap(); - /** valid imported eObjects descriptions (in case of broken state of imports this can be {@link AmbiguousImportDescription})*/ - val validImports = elementsMapProvider.get(script); - val originatorMap = new IEODesc2ISpec - - for (imp : imports) { - val module = imp?.module; - if (module !== null) { - - val topLevelElements = exportedElementsCollector.getExportedElements(module, contextResource, Optional.of(imp), includeHollows, includeValueOnlyElements); - val tleScope = scopesHelper.scopeFor("scope_AllTopLevelElementsFromModule", module, IScope.NULLSCOPE, false, topLevelElements) - - for (specifier : imp.importSpecifiers) { - switch (specifier) { - NamedImportSpecifier: { - processNamedImportSpecifier(specifier, imp, contextResource, originatorMap, validImports, - invalidImports, includeValueOnlyElements, tleScope) - } - NamespaceImportSpecifier: { - processNamespaceSpecifier(specifier, imp, script, contextResource, originatorMap, validImports, - invalidImports, includeValueOnlyElements) - } - } - } - } - } - - -// local broken elements are hidden by parent scope, both are hidden by valid local elements - val invalidLocalScope = scopesHelper.scopeFor("findImportedElements-invalidImports", script, invalidImports.values) - val localValidScope = scopesHelper.scopeFor("findImportedElements-validImports", script, parentScope, validImports.values) - val importScope = new UberParentScope("findImportedElements-uberParent", localValidScope, invalidLocalScope) - return new OriginAwareScope(script, importScope, originatorMap); - } - - private def void processNamedImportSpecifier(NamedImportSpecifier specifier, ImportDeclaration imp, - Resource contextResource, IEODesc2ISpec originatorMap, - ImportedElementsMap validImports, - ImportedElementsMap invalidImports, boolean includeValueOnlyElements, IScope tleScope) { - - val element = if (specifier.declaredDynamic) { - (specifier.eResource as N4JSResource).module.internalDynamicElements.findFirst[it.astElement === specifier]; - } else { - val name = if (specifier instanceof DefaultImportSpecifier) - "default" else specifier.importedElementAsText; - val qName = QualifiedName.create(name); - - val importedElem = tleScope.getSingleElement(qName); - if (importedElem !== null && importedElem.EObjectOrProxy instanceof TExportableElement) { - importedElem.EObjectOrProxy as TExportableElement - } else { - null - } - }; - - if (element !== null && !element.eIsProxy) { - - if (!includeValueOnlyElements && element.isValueOnlyFrom(imp)) { - return; - } - - val importedQName = createQualifiedNameForAlias(specifier, element); - val typeVisibility = isVisible(contextResource, element); - if (typeVisibility.visibility) { - - addNamedImports(specifier, element, importedQName, - originatorMap, validImports); - - val originalName = QualifiedName.create(element.name) - - if (specifier.alias !== null) { - element.handleAliasedAccess(originalName, importedQName.toString, invalidImports, originatorMap, specifier) - } - } else { - element.handleInvisible(invalidImports, importedQName, typeVisibility.accessModifierSuggestion, - originatorMap, specifier) - } - } - } - - private def void addNamedImports(NamedImportSpecifier specifier, TExportableElement element, QualifiedName importedName, - IEODesc2ISpec originatorMap, ImportedElementsMap validImports) { - val ieod = validImports.putOrError(element, importedName, IssueCodes.IMP_AMBIGUOUS.name); - originatorMap.putWithOrigin(ieod, specifier) - } - - private def void processNamespaceSpecifier( - NamespaceImportSpecifier specifier, - ImportDeclaration imp, - Script script, - Resource contextResource, - IEODesc2ISpec originatorMap, - ImportedElementsMap validImports, - ImportedElementsMap invalidImports, - boolean includeValueOnlyElements - ) { - if (specifier.alias === null) { - return; // if broken code, e.g. "import * as 123 as N from 'some/Module'" - } - if (script.module === null) { - return; // when reconciliation of TModule fails due to hash mismatch - } - - // add namespace to scope - val namespaceName = specifier.alias; - val namespaceQName = QualifiedName.create(namespaceName) - val Type namespaceType = (script.module.internalTypes + script.module.exposedInternalTypes).findFirst [ interType | - interType instanceof ModuleNamespaceVirtualType && - (interType as ModuleNamespaceVirtualType).module === imp.module - ] - if (namespaceType === null) { - // TODO GH-2002 remove this temporary debug logging - val sb = new StringBuilder(); - sb.append("contextResource?.getURI(): " + contextResource?.getURI() + "\n"); - sb.append("specifier.definedType: " + specifier.definedType + "\n"); - sb.append("imp.module: " + imp.module + "\n"); - sb.append("script.module: " + script.module + "\n"); - sb.append("script.module.isPreLinkingPhase: " + script.module.isPreLinkingPhase + "\n"); - sb.append("script.module.isReconciled: " + script.module.isReconciled + "\n"); - sb.append("script.module.internalTypes.size: " + script.module.internalTypes.size + "\n"); - sb.append("script.module.exposedInternalTypes.size: " + script.module.exposedInternalTypes.size + "\n"); - for (type : (script.module.internalTypes + script.module.exposedInternalTypes)) { - if (type instanceof ModuleNamespaceVirtualType) { - sb.append("type[n].module: " + type.module + "\n"); - } - } - sb.append("\n"); - sb.append(Throwables.getStackTraceAsString(new IllegalStateException())); - LOGGER.error("namespaceType not found\n" + sb.toString); - return; - } - val ieodx = validImports.putOrError(namespaceType, namespaceQName, IssueCodes.IMP_AMBIGUOUS.name) - originatorMap.putWithOrigin(ieodx, specifier) - - if (includeValueOnlyElements) { - // add vars to namespace - // (this is *only* about adding some IEObjectDescriptionWithError to improve error messages) - for (importedVar : imp.module.exportedVariables) { - val varVisibility = variableVisibilityChecker.isVisible(contextResource, importedVar); - val varName = importedVar.name - val qn = QualifiedName.create(namespaceName, varName) - if (varVisibility.visibility) { - val originalName = QualifiedName.create(varName) - if (!invalidImports.containsElement(originalName)) { - importedVar.handleNamespacedAccess(originalName, qn, invalidImports, originatorMap, specifier) - } - } - } - // add functions to namespace - // (this is *only* about adding some IEObjectDescriptionWithError to improve error messages) - for (importedFun : imp.module.functions) { - val varVisibility = typeVisibilityChecker.isVisible(contextResource, importedFun); - val varName = importedFun.name - val qn = QualifiedName.create(namespaceName, varName) - if (varVisibility.visibility) { - val originalName = QualifiedName.create(varName) - if (!invalidImports.containsElement(originalName)) { - importedFun.handleNamespacedAccess(originalName, qn, invalidImports, originatorMap, specifier) - } - } - } - } - - // add types - // (this is *only* about adding some IEObjectDescriptionWithError to improve error messages) - for (importedType : imp.module.types) { - val typeVisibility = typeVisibilityChecker.isVisible(contextResource, importedType); - - val qn = createImportedQualifiedTypeName(namespaceName, importedType) - if (typeVisibility.visibility) { - val originalName = createImportedQualifiedTypeName(importedType) - if (!invalidImports.containsElement(originalName)) { - importedType.handleNamespacedAccess(originalName, qn, invalidImports, originatorMap, specifier) - } - } - } - } - - private def handleAliasedAccess(IdentifiableElement element, QualifiedName originalName, String importedName, - ImportedElementsMap invalidImports, IEODesc2ISpec originatorMap, ImportSpecifier specifier) { - val invalidAccess = new PlainAccessOfAliasedImportDescription(EObjectDescription.create(originalName, element), - importedName) - invalidImports.put(originalName, invalidAccess) - // TODO IDEBUG-702 originatorMap.putWithOrigin(invalidAccess, specifier) - } - - private def handleNamespacedAccess(IdentifiableElement importedType, QualifiedName originalName, QualifiedName qn, - ImportedElementsMap invalidImports, IEODesc2ISpec originatorMap, ImportSpecifier specifier) { - val invalidAccess = new PlainAccessOfNamespacedImportDescription( - EObjectDescription.create(originalName, importedType), qn) - invalidImports.put(originalName, invalidAccess) - // TODO IDEBUG-702 originatorMap.putWithOrigin(invalidAccess, specifier) - } - - private def handleInvisible(IdentifiableElement importedElement, ImportedElementsMap invalidImports, QualifiedName qn, - String visibilitySuggestion, IEODesc2ISpec originatorMap, ImportSpecifier specifier) { - // TODO IDEBUG-702 val invalidAccess = new InvisibleTypeOrVariableDescription(EObjectDescription.create(qn, importedElement)) - val invalidAccess = invalidImports.putOrError(importedElement, qn, null) - invalidAccess.addAccessModifierSuggestion(visibilitySuggestion) - originatorMap.putWithOrigin(invalidAccess, specifier) - } - - /** Add the description to the orginatorMap and include trace to the specifier in special Error-Aware IEObjectDesciptoins - * like AmbigousImportDescriptions. - */ - private def putWithOrigin(HashMap originiatorMap, - IEObjectDescription description, ImportSpecifier specifier) { - originiatorMap.put(description, specifier); - switch (description) { - AmbiguousImportDescription: { - description.originatingImports.add(specifier); - // Handling of wrapped delegatee, since this information will not be available in other cases: - val firstPlaceSpec = originiatorMap.get(description.delegate) - // add only if not there yet: - if (firstPlaceSpec !== null && ! description.originatingImports.contains(firstPlaceSpec)) { - description.originatingImports.add(firstPlaceSpec) - } - } - } - } - - def private boolean isValueOnlyFrom(IdentifiableElement element, ImportDeclaration imp) { - if (imp?.module === null) { - return false; - } - if (imp.module.functions.contains(element)) { - return true - } - if (imp.module.exportedVariables.contains(element)) { - return true - } - return false; - } - - private def AbstractTypeVisibilityChecker.TypeVisibility isVisible(Resource contextResource, - IdentifiableElement element) { - if (element instanceof TMember && ResourceType.getResourceType(element) == ResourceType.DTS) - new AbstractTypeVisibilityChecker.TypeVisibility(true) - else if (element instanceof Type) - typeVisibilityChecker.isVisible(contextResource, element) - else if (element instanceof TVariable) - variableVisibilityChecker.isVisible(contextResource, element) - else if (element instanceof TDynamicElement) - return new AbstractTypeVisibilityChecker.TypeVisibility(true) - else - return new AbstractTypeVisibilityChecker.TypeVisibility(false); - } - - /** - * Returns {@code true} if an import of the given {@link IEObjectDescription} should be - * regarded as ambiguous with the given {@link IdentifiableElement}. - */ - protected def boolean isAmbiguous(IEObjectDescription existing, IdentifiableElement element) { - // make sure ambiguity is only detected in case of the same imported version of a type - return true; - } - - private def IEObjectDescription putOrError(ImportedElementsMap result, - IdentifiableElement element, QualifiedName importedName, String issueCode) { - // TODO IDEBUG-702 refactor InvisibleTypeOrVariableDescription / AmbiguousImportDescription relation - var IEObjectDescription ret = null; - val existing = result.getElements(importedName) - - if (!existing.empty && existing.get(0) !== null) { - if (issueCode !== null) { - switch existing { - AmbiguousImportDescription: { - existing.elements += element; - ret = existing - } - default: { - val error = new AmbiguousImportDescription(existing.head, issueCode, element) - result.put(importedName, error) - error.elements += element; - ret = error - } - } - } - } else if (issueCode === null) { - ret = createDescription(importedName, element) - ret = new InvisibleTypeOrVariableDescription(ret) - result.put(importedName, ret) - } else { - ret = createDescription(importedName, element) - result.put(importedName, ret) - } - return ret; - } - - private def IEObjectDescription createDescription(QualifiedName name, IdentifiableElement element) { - if (name.lastSegment != element.name) { - var qn = qualifiedNameProvider.getFullyQualifiedName(element); - if (qn === null) { - // non-directly-exported variable / function / type alias that is exported under an alias via a separate export declaration: - qn = qualifiedNameProvider.getFullyQualifiedName(element.containingModule)?.append(element.name); - } - return new AliasedEObjectDescription(name, EObjectDescription.create(qn, element)) - } else { - return EObjectDescription.create(name, element) - } - } - - /** - * global object scope indirectly cached, as this method is only called by getImportedIdentifiables (which is cached) - */ - private def IScope getGlobalObjectProperties(IScope parent, EObject context) { - val globalObject = GlobalObjectScope.get(context.eResource.resourceSet).getGlobalObject - memberScopeFactory.create(parent, globalObject, context, false, false, false) - } - - private def void addAccessModifierSuggestion(IEObjectDescription description, String suggestion) { - if (description instanceof InvisibleTypeOrVariableDescription) { - description.accessModifierSuggestion = suggestion; - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/SingleImportedElementsMap.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/SingleImportedElementsMap.java new file mode 100644 index 0000000000..6186d61f2b --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/SingleImportedElementsMap.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2017 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.scoping.imports; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +import org.eclipse.xtext.naming.QualifiedName; +import org.eclipse.xtext.resource.IEObjectDescription; + +/** + * HashMap-based implementation of {@link ImportedElementsMap}. + * + * This map can only hold a single {@link IEObjectDescription} per qualified name. + */ +public class SingleImportedElementsMap implements ImportedElementsMap { + private final HashMap elementsMap = new HashMap<>(); + + @Override + public boolean containsElement(QualifiedName name) { + return this.elementsMap.containsKey(name); + } + + @Override + public Iterable getElements(QualifiedName name) { + IEObjectDescription result = this.elementsMap.get(name); + if (null != result) { + return List.of(result); + } else { + return Collections.emptyList(); + } + } + + @Override + public void put(QualifiedName name, IEObjectDescription element) { + this.elementsMap.put(name, element); + } + + @Override + public Iterable values() { + return this.elementsMap.values(); + } + +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/SingleImportedElementsMap.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/SingleImportedElementsMap.xtend deleted file mode 100644 index 3a8bb8c8a9..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/imports/SingleImportedElementsMap.xtend +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (c) 2017 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.scoping.imports - -import java.util.HashMap -import org.eclipse.xtext.naming.QualifiedName -import org.eclipse.xtext.resource.IEObjectDescription - -/** - * HashMap-based implementation of {@link ImportedElementsMap}. - * - * This map can only hold a single {@link IEObjectDescription} per qualified name. - */ -public class SingleImportedElementsMap implements ImportedElementsMap { - private HashMap elementsMap; - - new() { - this.elementsMap = newHashMap(); - } - - override containsElement(QualifiedName name) { - return this.elementsMap.containsKey(name); - } - - override getElements(QualifiedName name) { - val result = this.elementsMap.get(name); - if (null !== result) { - return #[result]; - } else { - return emptyList; - } - } - - override put(QualifiedName name, IEObjectDescription element) { - this.elementsMap.put(name, element); - } - - override values() { - this.elementsMap.values; - } - -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/MemberScopingHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/MemberScopingHelper.java new file mode 100644 index 0000000000..1a475cd725 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/MemberScopingHelper.java @@ -0,0 +1,565 @@ +/** + * 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.scoping.members; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.booleanTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.newRuleEnvironment; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.numberTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.stringTypeRef; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filterNull; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.n4js.n4JS.MemberAccess; +import org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression; +import org.eclipse.n4js.scoping.accessModifiers.MemberVisibilityChecker; +import org.eclipse.n4js.scoping.accessModifiers.StaticWriteAccessFilterScope; +import org.eclipse.n4js.scoping.accessModifiers.VisibilityAwareMemberScope; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.scoping.builtin.N4Scheme; +import org.eclipse.n4js.scoping.utils.CompositeScope; +import org.eclipse.n4js.scoping.utils.DynamicPseudoScope; +import org.eclipse.n4js.scoping.utils.UberParentScope; +import org.eclipse.n4js.ts.typeRefs.BooleanLiteralTypeRef; +import org.eclipse.n4js.ts.typeRefs.EnumLiteralTypeRef; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeRef; +import org.eclipse.n4js.ts.typeRefs.IntersectionTypeExpression; +import org.eclipse.n4js.ts.typeRefs.LiteralTypeRef; +import org.eclipse.n4js.ts.typeRefs.NumericLiteralTypeRef; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRefStructural; +import org.eclipse.n4js.ts.typeRefs.StringLiteralTypeRef; +import org.eclipse.n4js.ts.typeRefs.ThisTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeTypeRef; +import org.eclipse.n4js.ts.typeRefs.UnionTypeExpression; +import org.eclipse.n4js.ts.typeRefs.UnknownTypeRef; +import org.eclipse.n4js.ts.types.ContainerType; +import org.eclipse.n4js.ts.types.PrimitiveType; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TEnum; +import org.eclipse.n4js.ts.types.TStructuralType; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.ts.types.TypingStrategy; +import org.eclipse.n4js.ts.types.UndefinedType; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.n4js.utils.EcoreUtilN4; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind; +import org.eclipse.n4js.validation.JavaScriptVariantHelper; +import org.eclipse.n4js.xtext.scoping.FilterWithErrorMarkerScope; +import org.eclipse.n4js.xtext.scoping.IEObjectDescriptionWithError; +import org.eclipse.xtext.naming.QualifiedName; +import org.eclipse.xtext.resource.IEObjectDescription; +import org.eclipse.xtext.scoping.IScope; +import org.eclipse.xtext.scoping.Scopes; + +import com.google.inject.Inject; + +/** + */ +public class MemberScopingHelper { + @Inject + N4JSTypeSystem ts; + @Inject + TypeSystemHelper tsh; + @Inject + MemberScope.MemberScopeFactory memberScopeFactory; + @Inject + private MemberVisibilityChecker memberVisibilityChecker; + @Inject + private JavaScriptVariantHelper jsVariantHelper; + + /** + * Create a new member scope that filters using the given criteria (visibility, static access). Members retrieved + * via the scope returned by this method are guaranteed to be contained in a resource. + *

+ * When choosing static scope, the {@code context} is inspected to determine read/write access but only if it's a + * {@link ParameterizedPropertyAccessExpression} or a {@code IndexedAccessExpression}. + * + * @param receiverTypeRef + * TypeRef for the value whose scope is of interest. + * @param context + * AST node used for (a) obtaining context resource, (b) visibility checking, and (c) caching composed + * members. + * @param checkVisibility + * if true, the member scope will be wrapped in a {@link VisibilityAwareMemberScope}. + * @param staticAccess + * true: only static members are relevant; false: only non-static ones. + * @param structFieldInitMode + * see {@link AbstractMemberScope#structFieldInitMode}. + */ + public IScope createMemberScope(TypeRef receiverTypeRef, EObject context, + boolean checkVisibility, boolean staticAccess, boolean structFieldInitMode) { + + MemberScopeRequest request = new MemberScopeRequest(receiverTypeRef, context, true, checkVisibility, + staticAccess, + structFieldInitMode, receiverTypeRef.isDynamic()); + return decoratedMemberScopeFor(receiverTypeRef, request); + } + + /** + * Same as {@link #createMemberScope(TypeRef, EObject, boolean, boolean, boolean)}, but the returned scope + * DOES NOT guarantee that members will be contained in a resource (in particular, composed members + * will not be contained in a resource). In turn, this method does not require a context of type + * {@link MemberAccess}. + *

+ * This method can be used if members are only used temporarily for a purpose that does not require proper + * containment of the member, e.g. retrieving the type of a field for validation purposes. There are two reasons for + * using this method: + *

    + *
  1. client code is unable to provide a context of type {@link MemberAccess}, + *
  2. client code wants to invoke {@link IScope#getAllElements()} or similar methods on the returned scope and + * wants to avoid unnecessary caching of all those members. + *
+ */ + public IScope createMemberScopeAllowingNonContainedMembers(TypeRef receiverTypeRef, EObject context, + boolean checkVisibility, boolean staticAccess, boolean structFieldInitMode) { + + MemberScopeRequest request = new MemberScopeRequest(receiverTypeRef, context, false, checkVisibility, + staticAccess, + structFieldInitMode, receiverTypeRef.isDynamic()); + return decoratedMemberScopeFor(receiverTypeRef, request); + } + + /** + * Creates member scope via #members and decorates it via #decorate. + */ + private IScope decoratedMemberScopeFor(TypeRef typeRef, MemberScopeRequest memberScopeRequest) { + if (typeRef == null) { + return IScope.NULLSCOPE; + } + var result = members(typeRef, memberScopeRequest); + return result; + } + + /** + * Called only be members functions to decorate returned scope. + */ + private IScope decorate(IScope scope, MemberScopeRequest memberScopeRequest, TypeRef receiverTypeRef) { + if (scope == IScope.NULLSCOPE) { + return scope; + } + IScope decoratedScope = scope; + if (memberScopeRequest.checkVisibility && + !FilterWithErrorMarkerScope.isDecoratedWithFilter(scope, VisibilityAwareMemberScope.class)) { + decoratedScope = new VisibilityAwareMemberScope(decoratedScope, memberVisibilityChecker, receiverTypeRef, + memberScopeRequest.context); + } + if (memberScopeRequest.staticAccess && + !FilterWithErrorMarkerScope.isDecoratedWithFilter(scope, StaticWriteAccessFilterScope.class)) { + decoratedScope = new StaticWriteAccessFilterScope(decoratedScope, memberScopeRequest.context); + } + if (memberScopeRequest.checkVisibility && + !FilterWithErrorMarkerScope.isDecoratedWithFilter(scope, TypingStrategyAwareMemberScope.class)) { + decoratedScope = new TypingStrategyAwareMemberScope(decoratedScope, receiverTypeRef, + memberScopeRequest.context); + } + return decoratedScope; + } + + /** + * For the member given by (name, staticAccess) return the erroneous descriptions from the given scope. + */ + public Iterable getErrorsForMember(IScope scope, String memberName) { + Iterable descriptions = scope.getElements(QualifiedName.create(memberName)); + Iterable errorsOrNulls = map(descriptions, + d -> IEObjectDescriptionWithError.getDescriptionWithError(d)); + return filterNull(errorsOrNulls); + } + + @SuppressWarnings("unused") + private IScope members(UnknownTypeRef type, MemberScopeRequest request) { + return new DynamicPseudoScope(); + } + + @SuppressWarnings("unused") + private IScope members(LiteralTypeRef ltr, MemberScopeRequest request) { + throw new UnsupportedOperationException("missing method for " + ltr.eClass().getName()); + } + + @SuppressWarnings("unused") + private IScope members(BooleanLiteralTypeRef ltr, MemberScopeRequest request) { + RuleEnvironment G = newRuleEnvironment(request.context); + return members(booleanTypeRef(G), request); + } + + @SuppressWarnings("unused") + private IScope members(NumericLiteralTypeRef ltr, MemberScopeRequest request) { + RuleEnvironment G = newRuleEnvironment(request.context); + return members(numberTypeRef(G), request); // no need to distinguish between number and int + } + + @SuppressWarnings("unused") + private IScope members(StringLiteralTypeRef ltr, MemberScopeRequest request) { + RuleEnvironment G = newRuleEnvironment(request.context); + return members(stringTypeRef(G), request); + } + + private IScope members(EnumLiteralTypeRef ltr, MemberScopeRequest request) { + RuleEnvironment G = newRuleEnvironment(request.context); + return members(N4JSLanguageUtils.getLiteralTypeBase(G, ltr), request); + } + + private IScope members(ParameterizedTypeRef ptr, MemberScopeRequest request) { + IScope result = membersOfType(ptr.getDeclaredType(), request); + if (ptr.isDynamic() && !(result instanceof DynamicPseudoScope)) { + return new DynamicPseudoScope(decorate(result, request, ptr)); + } + return decorate(result, request, ptr); + } + + private IScope members(ParameterizedTypeRefStructural ptrs, MemberScopeRequest request) { + IScope result = membersOfType(ptrs.getDeclaredType(), request); + if (ptrs.isDynamic() && !(result instanceof DynamicPseudoScope)) { + return new DynamicPseudoScope(decorate(result, request, ptrs)); + } + if (ptrs.getStructuralMembers().isEmpty()) { + return decorate(result, request, ptrs); + } + IScope memberScopeRaw; + if (ptrs.getStructuralType() != null) { + memberScopeRaw = memberScopeFactory.create(result, ptrs.getStructuralType(), request.context, + request.staticAccess, + request.structFieldInitMode, request.isDynamicType); + } else { + // note: these are not the members of the defined type + // however, we only scope locally, so that doesn't matter + memberScopeRaw = memberScopeFactory.create(result, ptrs.getStructuralMembers(), request.context, + request.staticAccess, + request.structFieldInitMode, request.isDynamicType); + } + + return decorate(memberScopeRaw, request, ptrs); + } + + /** + * Note: N4JSScopeProvider already taking the upper bound before using this class (thus resolving ThisTypeRefs + * beforehand), so we will never enter this method from there; still provided to support uses from other code. + */ + private IScope members(ThisTypeRef thisTypeRef, MemberScopeRequest request) { + // taking the upper bound to "resolve" the ThisTypeRef: + // this[C] --> C (ParameterizedTypeRef) + // ~~this[C] with { number prop; } --> ~~C with { number prop; } (ParameterizedTypeRefStructural) + TypeRef ub = ts.upperBoundWithReopen(newRuleEnvironment(request.context), thisTypeRef); + + if (ub != null) { // ThisTypeRef was resolved + return members(ub, request); + } + + // probably an unbound ThisTypeRef or some other error (reported elsewhere) + return IScope.NULLSCOPE; + } + + private IScope members(TypeTypeRef ttr, MemberScopeRequest request) { + MemberScopeRequest staticRequest = request.enforceStatic(); + RuleEnvironment G = newRuleEnvironment(request.context); + Type ctrStaticType = tsh.getStaticType(G, ttr, true); + IScope staticMembers = membersOfType(ctrStaticType, staticRequest); // staticAccess is always true in this case + if (ctrStaticType instanceof TEnum) { + // enums have their literals as static members + staticMembers = decorate(Scopes.scopeFor(((TEnum) ctrStaticType).getLiterals(), staticMembers), request, + ttr); + } + if (ttr.isDynamic() && !(staticMembers instanceof DynamicPseudoScope)) { + staticMembers = new DynamicPseudoScope(decorate(staticMembers, staticRequest, ttr)); + } + // in addition, we need instance members of either Function (in case of constructor{T}) or Object (for type{T}) + // except for @NumberBased/@StringBased enums: + if (ctrStaticType instanceof TEnum && N4JSLanguageUtils.getEnumKind((TEnum) ctrStaticType) != EnumKind.Normal) { + return decorate(staticMembers, staticRequest, ttr); + } + MemberScopeRequest instanceRequest = request.enforceInstance(); + BuiltInTypeScope builtInScope = BuiltInTypeScope.get(getResourceSet(ttr, request.context)); + TClassifier functionType = (ttr.isConstructorRef()) ? builtInScope.getFunctionType() + : builtInScope.getObjectType(); + IScope ftypeScope = membersOfType(functionType, instanceRequest); + IScope result = CompositeScope.create( + // order matters (shadowing!) + decorate(staticMembers, staticRequest, ttr), + decorate(ftypeScope, instanceRequest, ttr)); + return result; + } + + private IScope members(UnionTypeExpression uniontypeexp, MemberScopeRequest request) { + if (jsVariantHelper.activateDynamicPseudoScope(request.context)) { // cf. sec. 13.1 + return new DynamicPseudoScope(); + } + + RuleEnvironment G = RuleEnvironmentExtensions.newRuleEnvironment(request.context); + IScope anyPlusScope = null; + List subScopes = new ArrayList<>(); + for (TypeRef elementTypeRef : uniontypeexp.getTypeRefs()) { + boolean structFieldInitMode = elementTypeRef + .getTypingStrategy() == TypingStrategy.STRUCTURAL_FIELD_INITIALIZER; + IScope scope = members(elementTypeRef, request.setStructFieldInitMode(structFieldInitMode)); + if (RuleEnvironmentExtensions.isAnyDynamic(G, elementTypeRef)) { + anyPlusScope = scope; + } else { + subScopes.add(scope); + } + } + + // only create union scope if really necessary, remember this optimization in test, since union{A} tests scope + // of A only! + IScope subScope = null; + if (subScopes.size() == 1) { + subScope = subScopes.get(0); + } else if (subScopes.size() > 1) { + subScope = new UnionMemberScope(uniontypeexp, request, subScopes, ts); + } + + if (anyPlusScope == null && subScope == null) { + return IScope.NULLSCOPE; + } + if (anyPlusScope == null) { + return subScope; + } + if (subScope == null) { + return anyPlusScope; + } + return new UberParentScope("", subScope, anyPlusScope); + } + + private IScope members(IntersectionTypeExpression intersectiontypeexp, MemberScopeRequest request) { + if (intersectiontypeexp.getTypeRefs().isEmpty()) { + return IScope.NULLSCOPE; + } + + RuleEnvironment G = RuleEnvironmentExtensions.newRuleEnvironment(request.context); + IScope anyPlusScope = null; + List subScopes = new ArrayList<>(); + for (TypeRef elementTypeRef : intersectiontypeexp.getTypeRefs()) { + boolean structFieldInitMode = elementTypeRef + .getTypingStrategy() == TypingStrategy.STRUCTURAL_FIELD_INITIALIZER; + IScope scope = members(elementTypeRef, request.setStructFieldInitMode(structFieldInitMode)); + if (RuleEnvironmentExtensions.isAnyDynamic(G, elementTypeRef)) { + anyPlusScope = scope; + } else { + subScopes.add(scope); + } + } + + // only create union scope if really necessary, remember this optimization in test, since union{A} tests scope + // of A only! + IScope subScope = null; + if (subScopes.size() == 1) { + subScope = subScopes.get(0); + } else if (subScopes.size() > 1) { + subScope = new IntersectionMemberScope(intersectiontypeexp, request, subScopes, ts); + } + + if (anyPlusScope == null && subScope == null) { + return IScope.NULLSCOPE; + } + if (subScope != null) { + return subScope; + } + return anyPlusScope; + } + + private IScope members(FunctionTypeRef ftExpr, MemberScopeRequest request) { + return membersOfFunctionTypeRef(ftExpr, request); + } + + private IScope members(FunctionTypeExpression ftExpr, MemberScopeRequest request) { + return membersOfFunctionTypeRef(ftExpr, request); + } + + /** + * delegated from two methods above, to avoid catch-all of ParameterizedTypeRef for FuntionTypeRefs while + * dispatching + */ + private IScope membersOfFunctionTypeRef(FunctionTypeExprOrRef ftExpr, MemberScopeRequest request) { + BuiltInTypeScope builtInTypeScope = BuiltInTypeScope.get(getResourceSet(ftExpr, request.context)); + TClass fType = builtInTypeScope.getFunctionType(); + IScope ret = membersOfType(fType, request); + return decorate(ret, request, ftExpr); + } + + @SuppressWarnings("unused") + private IScope membersOfType(UndefinedType type, MemberScopeRequest request) { + if (jsVariantHelper.activateDynamicPseudoScope(request.context)) { // cf. sec. 13.1 + return new DynamicPseudoScope(); + } + + return IScope.NULLSCOPE; + } + + @SuppressWarnings("unused") + private IScope membersOfType(Void type, MemberScopeRequest request) { + return new DynamicPseudoScope(); + } + + /** + * Primitive types have no members, but they can be auto-boxed to their corresponding object type which then, + * transparently to the user, provide members. + */ + private IScope membersOfType(PrimitiveType prim, MemberScopeRequest request) { + TClassifier boxedType = prim.getAutoboxedType(); + return (boxedType != null) ? membersOfType(boxedType, request) : IScope.NULLSCOPE; + } + + /** + * Creates member scope with parent containing members of implicit super types. + */ + private IScope membersOfType(ContainerType type, MemberScopeRequest request) { + IScope parentScope = (jsVariantHelper.activateDynamicPseudoScope(request.context)) + // cf. sec. 13.1 + ? new DynamicPseudoScope() + : IScope.NULLSCOPE; + + if (!request.staticAccess && type instanceof TClass && N4Scheme.isFromResourceWithN4Scheme(type)) { + // classifiers defined in builtin_js.n4jsd and builtin_n4.n4jsd are allowed to extend primitive + // types, and the following is required to support auto-boxing in such a case: + Type rootSuperType = getRootSuperType((TClass) type); + if (rootSuperType instanceof PrimitiveType) { + TClassifier boxedType = ((PrimitiveType) rootSuperType).getAutoboxedType(); + if (boxedType != null) { + parentScope = memberScopeFactory.create(parentScope, boxedType, request.context, + request.staticAccess, request.structFieldInitMode, request.isDynamicType); + } + } + } + + return memberScopeFactory.create(parentScope, type, request.context, request.staticAccess, + request.structFieldInitMode, request.isDynamicType); + } + + /** + * Returns a scope of the literals, that is members such as name or value. That is, the instance members of an + * enumeration. The static members are made available in {@link #members(EnumLiteralTypeRef, MemberScopeRequest)} + */ + private IScope membersOfType(TEnum enumeration, MemberScopeRequest request) { + BuiltInTypeScope builtInTypeScope = BuiltInTypeScope.get(getResourceSet(enumeration, request.context)); + // IDE-1221 select built-in type depending on whether this enumeration is tagged number-/string-based + EnumKind enumKind = N4JSLanguageUtils.getEnumKind(enumeration); + TClass specificEnumType = null; + switch (enumKind) { + case Normal: + specificEnumType = builtInTypeScope.getN4EnumType(); + break; + case NumberBased: + specificEnumType = builtInTypeScope.getN4NumberBasedEnumType(); + break; + case StringBased: + specificEnumType = builtInTypeScope.getN4StringBasedEnumType(); + break; + } + return membersOfType(specificEnumType, request); + } + + private IScope membersOfType(TStructuralType structType, MemberScopeRequest request) { + if (structType.getOwnedMembers().isEmpty()) { + return IScope.NULLSCOPE; + } + return memberScopeFactory.create(structType, request.context, request.staticAccess, request.structFieldInitMode, + request.isDynamicType); + } + + private ResourceSet getResourceSet(EObject type, EObject context) { + var result = EcoreUtilN4.getResourceSet(type, context); + if (result == null) { + throw new IllegalStateException("type or context must be contained in a ResourceSet"); + } + return result; + } + + private Type getRootSuperType(TClass type) { + Type curr = type; + Type next; + do { + next = null; + if (curr instanceof TClass) { + TClass tc = (TClass) curr; + next = tc.getSuperClassRef() == null ? null : tc.getSuperClassRef().getDeclaredType(); + } + if (next != null) { + curr = next; + } + } while (next != null); + return curr; + } + + private IScope members(TypeRef ftExpr, MemberScopeRequest request) { + if (ftExpr instanceof FunctionTypeRef) { + return members((FunctionTypeRef) ftExpr, request); + } else if (ftExpr instanceof ParameterizedTypeRefStructural) { + return members((ParameterizedTypeRefStructural) ftExpr, request); + } else if (ftExpr instanceof FunctionTypeExpression) { + return members((FunctionTypeExpression) ftExpr, request); + } else if (ftExpr instanceof IntersectionTypeExpression) { + return members((IntersectionTypeExpression) ftExpr, request); + } else if (ftExpr instanceof ParameterizedTypeRef) { + return members((ParameterizedTypeRef) ftExpr, request); + } else if (ftExpr instanceof ThisTypeRef) { + return members((ThisTypeRef) ftExpr, request); + } else if (ftExpr instanceof TypeTypeRef) { + return members((TypeTypeRef) ftExpr, request); + } else if (ftExpr instanceof UnionTypeExpression) { + return members((UnionTypeExpression) ftExpr, request); + } else if (ftExpr instanceof BooleanLiteralTypeRef) { + return members((BooleanLiteralTypeRef) ftExpr, request); + } else if (ftExpr instanceof EnumLiteralTypeRef) { + return members((EnumLiteralTypeRef) ftExpr, request); + } else if (ftExpr instanceof NumericLiteralTypeRef) { + return members((NumericLiteralTypeRef) ftExpr, request); + } else if (ftExpr instanceof StringLiteralTypeRef) { + return members((StringLiteralTypeRef) ftExpr, request); + } else if (ftExpr instanceof LiteralTypeRef) { + return members((LiteralTypeRef) ftExpr, request); + } else if (ftExpr instanceof UnknownTypeRef) { + return members((UnknownTypeRef) ftExpr, request); + } else if (ftExpr != null) { + return IScope.NULLSCOPE; + } else { + throw new IllegalArgumentException("Unhandled parameter types: " + + Arrays.asList(ftExpr, request).toString()); + } + } + + private IScope membersOfType(Type structType, MemberScopeRequest request) { + if (structType instanceof TStructuralType) { + return membersOfType((TStructuralType) structType, request); + } else if (structType instanceof ContainerType) { + return membersOfType((ContainerType) structType, request); + } else if (structType instanceof PrimitiveType) { + return membersOfType((PrimitiveType) structType, request); + } else if (structType instanceof UndefinedType) { + return membersOfType((UndefinedType) structType, request); + } else if (structType instanceof TEnum) { + return membersOfType((TEnum) structType, request); + } else if (structType != null) { + // TODO member computation should be extracted + if (structType.eIsProxy()) { + return new DynamicPseudoScope(); + } + if (jsVariantHelper.activateDynamicPseudoScope(request.context)) { // cf. sec. 13.1 + return new DynamicPseudoScope(); + } + + return IScope.NULLSCOPE; + } else { + return membersOfType((Void) null, request); + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/MemberScopingHelper.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/MemberScopingHelper.xtend deleted file mode 100644 index 6c3a67d388..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/MemberScopingHelper.xtend +++ /dev/null @@ -1,469 +0,0 @@ -/** - * 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.scoping.members - -import com.google.inject.Inject -import java.util.ArrayList -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.resource.ResourceSet -import org.eclipse.n4js.n4JS.MemberAccess -import org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression -import org.eclipse.n4js.scoping.accessModifiers.MemberVisibilityChecker -import org.eclipse.n4js.scoping.accessModifiers.StaticWriteAccessFilterScope -import org.eclipse.n4js.scoping.accessModifiers.VisibilityAwareMemberScope -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.scoping.builtin.N4Scheme -import org.eclipse.n4js.scoping.utils.CompositeScope -import org.eclipse.n4js.scoping.utils.DynamicPseudoScope -import org.eclipse.n4js.scoping.utils.UberParentScope -import org.eclipse.n4js.ts.typeRefs.BooleanLiteralTypeRef -import org.eclipse.n4js.ts.typeRefs.EnumLiteralTypeRef -import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef -import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression -import org.eclipse.n4js.ts.typeRefs.FunctionTypeRef -import org.eclipse.n4js.ts.typeRefs.IntersectionTypeExpression -import org.eclipse.n4js.ts.typeRefs.LiteralTypeRef -import org.eclipse.n4js.ts.typeRefs.NumericLiteralTypeRef -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRefStructural -import org.eclipse.n4js.ts.typeRefs.StringLiteralTypeRef -import org.eclipse.n4js.ts.typeRefs.ThisTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.typeRefs.TypeTypeRef -import org.eclipse.n4js.ts.typeRefs.UnionTypeExpression -import org.eclipse.n4js.ts.typeRefs.UnknownTypeRef -import org.eclipse.n4js.ts.types.ContainerType -import org.eclipse.n4js.ts.types.PrimitiveType -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.TEnum -import org.eclipse.n4js.ts.types.TStructuralType -import org.eclipse.n4js.ts.types.Type -import org.eclipse.n4js.ts.types.TypingStrategy -import org.eclipse.n4js.ts.types.UndefinedType -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper -import org.eclipse.n4js.utils.EcoreUtilN4 -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind -import org.eclipse.n4js.validation.JavaScriptVariantHelper -import org.eclipse.n4js.xtext.scoping.FilterWithErrorMarkerScope -import org.eclipse.n4js.xtext.scoping.IEObjectDescriptionWithError -import org.eclipse.xtext.naming.QualifiedName -import org.eclipse.xtext.scoping.IScope -import org.eclipse.xtext.scoping.Scopes - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* -import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions - -/** - */ -class MemberScopingHelper { - @Inject N4JSTypeSystem ts; - @Inject TypeSystemHelper tsh; - @Inject MemberScope.MemberScopeFactory memberScopeFactory - @Inject private MemberVisibilityChecker memberVisibilityChecker - @Inject private JavaScriptVariantHelper jsVariantHelper; - - /** - * Create a new member scope that filters using the given criteria (visibility, static access). Members retrieved - * via the scope returned by this method are guaranteed to be contained in a resource. - *

- * When choosing static scope, the {@code context} is inspected to determine read/write access - * but only if it's a {@link ParameterizedPropertyAccessExpression} or a {@code IndexedAccessExpression}. - * - * @param receiverTypeRef - * TypeRef for the value whose scope is of interest. - * @param context - * AST node used for (a) obtaining context resource, (b) visibility checking, and - * (c) caching composed members. - * @param checkVisibility - * if true, the member scope will be wrapped in a {@link VisibilityAwareMemberScope}; if - * false, method {@link getPropertyTypeForNode(IScope,String)} will never return - * {@link #INVISIBLE_MEMBER}. - * @param staticAccess - * true: only static members are relevant; false: only non-static ones. - * @param structFieldInitMode - * see {@link AbstractMemberScope#structFieldInitMode}. - */ - public def IScope createMemberScope(TypeRef receiverTypeRef, EObject context, - boolean checkVisibility, boolean staticAccess, boolean structFieldInitMode) { - - val request = new MemberScopeRequest(receiverTypeRef, context, true, checkVisibility, staticAccess, - structFieldInitMode, receiverTypeRef.isDynamic); - return decoratedMemberScopeFor(receiverTypeRef, request); - } - - /** - * Same as {@link #createMemberScope(TypeRef, MemberAccess, boolean, boolean)}, but the returned scope DOES - * NOT guarantee that members will be contained in a resource (in particular, composed members will not be - * contained in a resource). In turn, this method does not require a context of type {@link MemberAccess}. - *

- * This method can be used if members are only used temporarily for a purpose that does not require proper - * containment of the member, e.g. retrieving the type of a field for validation purposes. There are two reasons - * for using this method: - *

    - *
  1. client code is unable to provide a context of type {@link MemberAccess}, - *
  2. client code wants to invoke {@link IScope#getAllElements()} or similar methods on the returned scope and - * wants to avoid unnecessary caching of all those members. - *
- */ - public def IScope createMemberScopeAllowingNonContainedMembers(TypeRef receiverTypeRef, EObject context, - boolean checkVisibility, boolean staticAccess, boolean structFieldInitMode) { - - val request = new MemberScopeRequest(receiverTypeRef, context, false, checkVisibility, staticAccess, - structFieldInitMode, receiverTypeRef.isDynamic); - return decoratedMemberScopeFor(receiverTypeRef, request); - } - - /** - * Creates member scope via #members and decorates it via #decorate. - */ - private def IScope decoratedMemberScopeFor(TypeRef typeRef, MemberScopeRequest memberScopeRequest) { - if(typeRef === null) - return IScope.NULLSCOPE - var result = members(typeRef, memberScopeRequest); - return result; - } - - /** - * Called only be members functions to decorate returned scope. - */ - private def IScope decorate(IScope scope, MemberScopeRequest memberScopeRequest, TypeRef receiverTypeRef) { - if (scope == IScope.NULLSCOPE) { - return scope; - } - var decoratedScope = scope; - if (memberScopeRequest.checkVisibility && - ! FilterWithErrorMarkerScope.isDecoratedWithFilter(scope, VisibilityAwareMemberScope)) { - decoratedScope = new VisibilityAwareMemberScope(decoratedScope, memberVisibilityChecker, receiverTypeRef, - memberScopeRequest.context); - } - if (memberScopeRequest.staticAccess && - ! FilterWithErrorMarkerScope.isDecoratedWithFilter(scope, StaticWriteAccessFilterScope)) { - decoratedScope = new StaticWriteAccessFilterScope(decoratedScope, memberScopeRequest.context); - } - if (memberScopeRequest.checkVisibility && - ! FilterWithErrorMarkerScope.isDecoratedWithFilter(scope, TypingStrategyAwareMemberScope)) { - decoratedScope = new TypingStrategyAwareMemberScope(decoratedScope, receiverTypeRef, - memberScopeRequest.context); - } - return decoratedScope; - } - - /** - * For the member given by (name, staticAccess) return the erroneous descriptions from the given scope. - *

- * Precondition: {@link #isNonExistentMember} has negative answer. - */ - public def Iterable getErrorsForMember(IScope scope, String memberName, - boolean staticAccess) { - val descriptions = scope.getElements(QualifiedName.create(memberName)) - val errorsOrNulls = descriptions.map[d|IEObjectDescriptionWithError.getDescriptionWithError(d)] - return errorsOrNulls.filterNull - } - - private def dispatch IScope members(TypeRef type, MemberScopeRequest request) { - return IScope.NULLSCOPE - } - - private def dispatch IScope members(UnknownTypeRef type, MemberScopeRequest request) { - return new DynamicPseudoScope() - } - - private def dispatch IScope members(LiteralTypeRef ltr, MemberScopeRequest request) { - throw new UnsupportedOperationException("missing dispatch method for " + ltr.eClass().getName()); - } - - private def dispatch IScope members(BooleanLiteralTypeRef ltr, MemberScopeRequest request) { - val G = request.context.newRuleEnvironment; - return members(G.booleanTypeRef, request); - } - - private def dispatch IScope members(NumericLiteralTypeRef ltr, MemberScopeRequest request) { - val G = request.context.newRuleEnvironment; - return members(G.numberTypeRef, request); // no need to distinguish between number and int - } - - private def dispatch IScope members(StringLiteralTypeRef ltr, MemberScopeRequest request) { - val G = request.context.newRuleEnvironment; - return members(G.stringTypeRef, request); - } - - private def dispatch IScope members(EnumLiteralTypeRef ltr, MemberScopeRequest request) { - val G = request.context.newRuleEnvironment; - return members(N4JSLanguageUtils.getLiteralTypeBase(G, ltr), request); - } - - private def dispatch IScope members(ParameterizedTypeRef ptr, MemberScopeRequest request) { - val IScope result = membersOfType(ptr.declaredType, request); - if (ptr.dynamic && !(result instanceof DynamicPseudoScope)) { - return new DynamicPseudoScope(result.decorate(request, ptr)) - } - return result.decorate(request, ptr) - } - - private def dispatch IScope members(ParameterizedTypeRefStructural ptrs, MemberScopeRequest request) { - val IScope result = membersOfType(ptrs.declaredType, request); - if (ptrs.dynamic && !(result instanceof DynamicPseudoScope)) { - return new DynamicPseudoScope(result.decorate(request, ptrs)) - } - if (ptrs.structuralMembers.empty) { - return result.decorate(request, ptrs) - } - val memberScopeRaw = if (ptrs.structuralType !== null) { - memberScopeFactory.create(result, ptrs.structuralType, request.context, request.staticAccess, - request.structFieldInitMode, request.isDynamicType); - } else { - // note: these are not the members of the defined type - // however, we only scope locally, so that doesn't matter - memberScopeFactory.create(result, ptrs.structuralMembers, request.context, request.staticAccess, - request.structFieldInitMode, request.isDynamicType); - } - - return decorate(memberScopeRaw, request, ptrs); - } - - /** - * Note: N4JSScopeProvider already taking the upper bound before using this class (thus resolving ThisTypeRefs - * beforehand), so we will never enter this method from there; still provided to support uses from other code. - */ - private def dispatch IScope members(ThisTypeRef thisTypeRef, MemberScopeRequest request) { - // taking the upper bound to "resolve" the ThisTypeRef: - // this[C] --> C (ParameterizedTypeRef) - // ~~this[C] with { number prop; } --> ~~C with { number prop; } (ParameterizedTypeRefStructural) - val ub = ts.upperBoundWithReopen(request.context.newRuleEnvironment, thisTypeRef); - - if (ub !== null) { // ThisTypeRef was resolved - return members(ub, request); - } - - // probably an unbound ThisTypeRef or some other error (reported elsewhere) - return IScope.NULLSCOPE; - } - - private def dispatch IScope members(TypeTypeRef ttr, MemberScopeRequest request) { - val MemberScopeRequest staticRequest = request.enforceStatic; - val G = request.context.newRuleEnvironment; - val ctrStaticType = tsh.getStaticType(G, ttr, true); - var IScope staticMembers = membersOfType(ctrStaticType, staticRequest) // staticAccess is always true in this case - if (ctrStaticType instanceof TEnum) { - // enums have their literals as static members - staticMembers = Scopes.scopeFor(ctrStaticType.literals, staticMembers).decorate(request, ttr); - } - if (ttr.dynamic && !(staticMembers instanceof DynamicPseudoScope)) { - staticMembers = new DynamicPseudoScope(staticMembers.decorate(staticRequest, ttr)) - } - // in addition, we need instance members of either Function (in case of constructor{T}) or Object (for type{T}) - // except for @NumberBased/@StringBased enums: - if (ctrStaticType instanceof TEnum && N4JSLanguageUtils.getEnumKind(ctrStaticType as TEnum) !== EnumKind.Normal) { - return staticMembers.decorate(staticRequest, ttr); - } - val MemberScopeRequest instanceRequest = request.enforceInstance; - val builtInScope = BuiltInTypeScope.get(getResourceSet(ttr, request.context)); - val functionType = if (ttr.isConstructorRef) builtInScope.functionType else builtInScope.objectType; - val IScope ftypeScope = membersOfType(functionType, instanceRequest); - val result = CompositeScope.create( - // order matters (shadowing!) - staticMembers.decorate(staticRequest, ttr), - ftypeScope.decorate(instanceRequest, ttr) - ); - return result - } - - private def dispatch IScope members(UnionTypeExpression uniontypeexp, MemberScopeRequest request) { - - if (jsVariantHelper.activateDynamicPseudoScope(request.context)) { // cf. sec. 13.1 - return new DynamicPseudoScope(); - } - - val G = RuleEnvironmentExtensions.newRuleEnvironment(request.context); - var IScope anyPlusScope = null; - val subScopes = new ArrayList(); - for (TypeRef elementTypeRef: uniontypeexp.typeRefs) { - val structFieldInitMode = elementTypeRef.getTypingStrategy() == TypingStrategy.STRUCTURAL_FIELD_INITIALIZER; - val scope = members(elementTypeRef, request.setStructFieldInitMode(structFieldInitMode)); - if (RuleEnvironmentExtensions.isAnyDynamic(G, elementTypeRef)) { - anyPlusScope = scope; - } else { - subScopes.add(scope); - } - } - - val IScope subScope = switch (subScopes.size) { // only create union scope if really necessary, remember this optimization in test, since union{A} tests scope of A only! - case 0: null - case 1: subScopes.get(0) - default: new UnionMemberScope(uniontypeexp, request, subScopes, ts) - } - - if (anyPlusScope === null && subScope === null) { - return IScope.NULLSCOPE; - } - if (anyPlusScope === null) { - return subScope; - } - if (subScope === null) { - return anyPlusScope; - } - return new UberParentScope("", subScope, anyPlusScope); - } - - private def dispatch IScope members(IntersectionTypeExpression intersectiontypeexp, MemberScopeRequest request) { - if (intersectiontypeexp.typeRefs.isEmpty) { - return IScope.NULLSCOPE; - } - - val G = RuleEnvironmentExtensions.newRuleEnvironment(request.context); - var IScope anyPlusScope = null; - val subScopes = new ArrayList(); - for (TypeRef elementTypeRef: intersectiontypeexp.typeRefs) { - val structFieldInitMode = elementTypeRef.getTypingStrategy() == TypingStrategy.STRUCTURAL_FIELD_INITIALIZER; - val scope = members(elementTypeRef, request.setStructFieldInitMode(structFieldInitMode)); - if (RuleEnvironmentExtensions.isAnyDynamic(G, elementTypeRef)) { - anyPlusScope = scope; - } else { - subScopes.add(scope); - } - } - - val IScope subScope = switch (subScopes.size) { // only create union scope if really necessary, remember this optimization in test, since union{A} tests scope of A only! - case 0: null - case 1: subScopes.get(0) - default: new IntersectionMemberScope(intersectiontypeexp, request, subScopes, ts) - } - - if (anyPlusScope === null && subScope === null) { - return IScope.NULLSCOPE; - } - if (subScope !== null) { - return subScope; - } - return anyPlusScope; - } - - private def dispatch IScope members(FunctionTypeRef ftExpr, MemberScopeRequest request) { - return membersOfFunctionTypeRef(ftExpr, request) - } - - private def dispatch IScope members(FunctionTypeExpression ftExpr, MemberScopeRequest request) { - return membersOfFunctionTypeRef(ftExpr, request) - } - - /** delegated from two methods above, to avoid catch-all of ParameterizedTypeRef for FuntionTypeRefs while dispatching */ - def private IScope membersOfFunctionTypeRef(FunctionTypeExprOrRef ftExpr, MemberScopeRequest request) { - val builtInTypeScope = BuiltInTypeScope.get(getResourceSet(ftExpr, request.context)); - val fType = builtInTypeScope.functionType - val ret = membersOfType(fType, request) - return ret.decorate(request, ftExpr); - } - -// TODO member computation should be extracted - private def dispatch IScope membersOfType(Type type, MemberScopeRequest request) { - if (type.eIsProxy) { - return new DynamicPseudoScope() - } - if (jsVariantHelper.activateDynamicPseudoScope(request.context)) { // cf. sec. 13.1 - return new DynamicPseudoScope(); - } - - return IScope.NULLSCOPE - } - - private def dispatch IScope membersOfType(UndefinedType type, MemberScopeRequest request) { - if (jsVariantHelper.activateDynamicPseudoScope(request.context)) { // cf. sec. 13.1 - return new DynamicPseudoScope(); - } - - return IScope.NULLSCOPE - } - - private def dispatch IScope membersOfType(Void type, MemberScopeRequest request) { - return new DynamicPseudoScope() - } - - /** - * Primitive types have no members, but they can be auto-boxed to their - * corresponding object type which then, transparently to the user, provide members. - */ - private def dispatch IScope membersOfType(PrimitiveType prim, MemberScopeRequest request) { - val boxedType = prim.autoboxedType; - return if(boxedType!==null) membersOfType(boxedType, request) else IScope.NULLSCOPE; - } - - /** - * Creates member scope with parent containing members of implicit super types. - */ - private def dispatch IScope membersOfType(ContainerType type, MemberScopeRequest request) { - var parentScope = if (jsVariantHelper.activateDynamicPseudoScope(request.context)) { // cf. sec. 13.1 - new DynamicPseudoScope() - } else { - IScope.NULLSCOPE - }; - - if (!request.staticAccess && type instanceof TClass && N4Scheme.isFromResourceWithN4Scheme(type)) { - // classifiers defined in builtin_js.n4jsd and builtin_n4.n4jsd are allowed to extend primitive - // types, and the following is required to support auto-boxing in such a case: - val rootSuperType = getRootSuperType(type as TClass); - if (rootSuperType instanceof PrimitiveType) { - val boxedType = rootSuperType.autoboxedType; - if(boxedType!==null) { - parentScope = memberScopeFactory.create(parentScope, boxedType, request.context, - request.staticAccess, request.structFieldInitMode, request.isDynamicType); - } - } - } - - return memberScopeFactory.create(parentScope, type, request.context, request.staticAccess, - request.structFieldInitMode, request.isDynamicType); - } - - /** - * Returns a scope of the literals, that is members such as name or value. - * That is, the instance members of an enumeration. The static members are made available - * in {@link #members(EnumTypeRef, EObject, boolean)} - */ - private def dispatch IScope membersOfType(TEnum enumeration, MemberScopeRequest request) { - val builtInTypeScope = BuiltInTypeScope.get(getResourceSet(enumeration, request.context)); - // IDE-1221 select built-in type depending on whether this enumeration is tagged number-/string-based - val enumKind = N4JSLanguageUtils.getEnumKind(enumeration); - val specificEnumType = switch(enumKind) { - case Normal: builtInTypeScope.n4EnumType - case NumberBased: builtInTypeScope.n4NumberBasedEnumType - case StringBased: builtInTypeScope.n4StringBasedEnumType - }; - return membersOfType(specificEnumType, request); - } - - private def dispatch IScope membersOfType(TStructuralType structType, MemberScopeRequest request) { - if (structType.ownedMembers.empty) { - return IScope.NULLSCOPE - } - return memberScopeFactory.create(structType, request.context, request.staticAccess, request.structFieldInitMode, request.isDynamicType); - } - - def private ResourceSet getResourceSet(EObject type, EObject context) { - var result = EcoreUtilN4.getResourceSet(type, context); - if (result === null) - throw new IllegalStateException("type or context must be contained in a ResourceSet") - return result; - } - - def private Type getRootSuperType(TClass type) { - var Type curr = type; - var Type next; - do { - next = if(curr instanceof TClass) curr.superClassRef?.declaredType; - if (next !== null) { - curr = next; - } - } while (next !== null); - return curr; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ExpressionExtensions.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ExpressionExtensions.java new file mode 100644 index 0000000000..c858e94f64 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ExpressionExtensions.java @@ -0,0 +1,135 @@ +/** + * 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.scoping.utils; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.last; + +import java.util.Arrays; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.AssignmentExpression; +import org.eclipse.n4js.n4JS.AssignmentOperator; +import org.eclipse.n4js.n4JS.BinaryLogicalExpression; +import org.eclipse.n4js.n4JS.CommaExpression; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ParenExpression; +import org.eclipse.n4js.n4JS.PostfixExpression; +import org.eclipse.n4js.n4JS.UnaryExpression; +import org.eclipse.n4js.n4JS.UnaryOperator; +import org.eclipse.xtext.EcoreUtil2; + +/** + * General utility methods for expressions. + */ +public class ExpressionExtensions { + + /** + * Returns true if the subExpression actually is the left hand side expression of an assignment expression, that is + * its value could be changed when the assignment is evaluated. I.e. the subExpression could be returned by ancestor + * expression, e.g., if the subExpression is an operand of a binary logical expression. This method returns false, + * if the subExpression is an assignment expression itself! + *

+ * Note that neither assignments nor conditional expression return any of their operands! + */ + public static boolean isLeftHandSide(EObject subExpression) { + if (subExpression == null || subExpression instanceof AssignmentExpression) { + return false; + } + EObject expr = subExpression; + while (expr.eContainer() != null && isPotentialEvalResult(expr.eContainer(), expr)) { + expr = expr.eContainer(); + } + return expr.eContainer() instanceof AssignmentExpression && + ((AssignmentExpression) expr.eContainer()).getLhs() == expr; + } + + /** + * Does the argument occur as operand in a (prefix or postfix) ++ or -- operation? + *

+ * The increment and decrement operators "conceptually" involve both read- and write-access, unlike the LHS of a + * simple assignment. Granted, '+=' and similar compound assignments can be seen as comprising read- and + * write-access. + */ + public static boolean isIncOrDecTarget(EObject subExpression) { + if (subExpression == null || subExpression instanceof AssignmentExpression) { + return false; + } + EObject expr = subExpression; + while (expr.eContainer() != null && isPotentialEvalResult(expr.eContainer(), expr)) { + expr = expr.eContainer(); + } + if (expr.eContainer() instanceof PostfixExpression) { + return true; + } + if (expr.eContainer() instanceof UnaryExpression) { + UnaryExpression ue = (UnaryExpression) expr.eContainer(); + if (ue.getOp() == UnaryOperator.INC || ue.getOp() == UnaryOperator.DEC) { + return true; + } + } + return false; + } + + /***/ + public static boolean isBothReadFromAndWrittenTo(EObject expr) { + if (isLeftHandSide(expr)) { + AssignmentExpression a = EcoreUtil2.getContainerOfType(expr, AssignmentExpression.class); + return a.getOp() != AssignmentOperator.ASSIGN; + } + return isIncOrDecTarget(expr); + } + + /** + * Returns true if the (value of the) subExpression could be returned by container expression, e.g., if the + * subExpression is an operand of a binary logical expression. + *

+ * Most types of expressions return false here. Note that neither assignments nor conditional expression return any + * of their operands, thus, both type of expressions always return false as well. + *

+ * Example: the unparenthesized {@code arr[0]} below {@link #isLeftHandSide} although its direct container isn't an + * assignment but a {@link ParenExpression} + * + *

+	 * {@code
+	 * var arr = [1];
+	 * (arr[0]) = 6;
+	 * console.log(arr[0])
+	 * }
+	 * 
+ */ + private static boolean isPotentialEvalResult(final EObject container, final EObject childExpression) { + if (container instanceof ParenExpression && childExpression instanceof Expression) { + return isPotentialEvalResult((ParenExpression) container, (Expression) childExpression); + } else if (container instanceof BinaryLogicalExpression && childExpression instanceof Expression) { + return isPotentialEvalResult((BinaryLogicalExpression) container, (Expression) childExpression); + } else if (container instanceof CommaExpression && childExpression instanceof Expression) { + return isPotentialEvalResult((CommaExpression) container, (Expression) childExpression); + } else if (container != null && childExpression != null) { + return false; + } else { + throw new IllegalArgumentException("Unhandled parameter types: " + + Arrays.asList(container, childExpression).toString()); + } + } + + private static boolean isPotentialEvalResult(ParenExpression container, Expression childExpression) { + return childExpression != null && childExpression.eContainer() == container; + } + + private static boolean isPotentialEvalResult(BinaryLogicalExpression container, Expression childExpression) { + return childExpression != null && childExpression.eContainer() == container; + } + + private static boolean isPotentialEvalResult(CommaExpression container, Expression childExpression) { + return container != null && last(container.getExprs()) == childExpression; + } + +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ExpressionExtensions.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ExpressionExtensions.xtend deleted file mode 100644 index 15b5bb7917..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ExpressionExtensions.xtend +++ /dev/null @@ -1,118 +0,0 @@ -/** - * 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.scoping.utils - -import org.eclipse.n4js.n4JS.AssignmentExpression -import org.eclipse.n4js.n4JS.BinaryLogicalExpression -import org.eclipse.n4js.n4JS.CommaExpression -import org.eclipse.n4js.n4JS.Expression -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.ParenExpression -import org.eclipse.n4js.n4JS.PostfixExpression -import org.eclipse.n4js.n4JS.UnaryExpression -import org.eclipse.n4js.n4JS.UnaryOperator -import org.eclipse.n4js.n4JS.AssignmentOperator -import org.eclipse.xtext.EcoreUtil2 - -/** - * General utitility methods for expressions. - */ -class ExpressionExtensions { - - /** - * Returns true if the subExpression actually is the left hand side expression of an assignment expression, that is - * its value could be changed when the assignment is evaluated. I.e. the subExpression - * could be returned by ancestor expression, e.g., if the subExpression is - * an operand of a binary logical expression. - * This method returns false, if the subExpression is an assignment expression itself! - *

- * Note that neither assignments nor conditional expression return any of their operands! - */ - static def boolean isLeftHandSide(EObject subExpression) { - if (subExpression === null || subExpression instanceof AssignmentExpression) { - return false; - } - var EObject expr = subExpression; - while (expr.eContainer!==null && isPotentialEvalResult(expr.eContainer, expr)) { - expr = expr.eContainer; - } - return expr !== null && expr.eContainer instanceof AssignmentExpression && - (expr.eContainer as AssignmentExpression).lhs == expr - } - - - /** - * Does the argument occur as operand in a (prefix or postfix) ++ or -- operation? - *

- * The increment and decrement operators "conceptually" involve both read- and write-access, - * unlike the LHS of a simple assignment. Granted, '+=' and similar compound assignments can be seen - * as comprising read- and write-access. - */ - static def boolean isIncOrDecTarget(EObject subExpression) { - if (subExpression === null || subExpression instanceof AssignmentExpression) { - return false; - } - var EObject expr = subExpression; - while (expr.eContainer!==null && isPotentialEvalResult(expr.eContainer, expr)) { - expr = expr.eContainer; - } - if (expr.eContainer instanceof PostfixExpression) { - return true - } - if (expr.eContainer instanceof UnaryExpression) { - val ue = expr.eContainer as UnaryExpression; - if (ue.op == UnaryOperator.INC || ue.op === UnaryOperator.DEC) { - return true - } - } - return false - } - - static def boolean isBothReadFromAndWrittenTo(EObject expr) { - if (isLeftHandSide(expr)) { - val a = EcoreUtil2.getContainerOfType(expr, AssignmentExpression) - return a.op !== AssignmentOperator.ASSIGN - } - return isIncOrDecTarget(expr) - } - - /** - * Returns true if the (value of the) subExpression could be returned by container expression, e.g., if the subExpression is - * an operand of a binary logical expression. - *

- * Most types of expressions return false here. Note that neither assignments nor conditional expression return any of their operands, thus, both type of expressions - * always return false as well. - *

- * Example: the unparenthesized {@code arr[0]} below {@link #isLeftHandSide} although its direct container isn't an assignment but a {@link ParenExpression} - *

-	 * {@code
-	 * var arr = [1];
-	 * (arr[0]) = 6;
-	 * console.log(arr[0])
-	 * }
-	 * 
- */ - private static def dispatch boolean isPotentialEvalResult(EObject container, EObject childExpression) { - return false; - } - - private static def dispatch boolean isPotentialEvalResult(ParenExpression container, Expression childExpression) { - return childExpression !== null && childExpression.eContainer === container; - } - - private static def dispatch boolean isPotentialEvalResult(BinaryLogicalExpression container, Expression childExpression) { - return childExpression !== null && childExpression.eContainer === container; - } - - private static def dispatch boolean isPotentialEvalResult(CommaExpression container, Expression childExpression) { - return container !== null && container.exprs.last === childExpression; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/LocallyKnownTypesScopingHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/LocallyKnownTypesScopingHelper.java new file mode 100644 index 0000000000..50447bcca7 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/LocallyKnownTypesScopingHelper.java @@ -0,0 +1,187 @@ +/** + * 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.scoping.utils; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; + +import java.util.function.Function; +import java.util.function.Supplier; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.N4NamespaceDeclaration; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.resource.N4JSCache; +import org.eclipse.n4js.scoping.N4JSScopeProvider; +import org.eclipse.n4js.scoping.imports.ImportedElementsScopingHelper; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TEnum; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.TStructMember; +import org.eclipse.n4js.ts.types.TStructMethod; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.xtext.resource.EObjectDescription; +import org.eclipse.xtext.resource.IEObjectDescription; +import org.eclipse.xtext.scoping.IScope; +import org.eclipse.xtext.scoping.impl.SingletonScope; + +import com.google.common.collect.Iterables; +import com.google.inject.Inject; + +/** + * Helper for {@link N4JSScopeProvider N4JSScopeProvider} using {@link ImportedElementsScopingHelper + * ImportedElementsScopingHelper} for providing scope for types provider. + */ +public class LocallyKnownTypesScopingHelper { + + @Inject + N4JSCache cache; + + @Inject + ImportedElementsScopingHelper importedElementsScopingHelper; + + @Inject + ScopeSnapshotHelper scopeSnapshotHelper; + + /** Returns the type itself and type variables in case the type is generic. */ + public IScope scopeWithTypeAndItsTypeVariables(IScope parent, Type type, boolean staticAccess) { + IScope result = parent; + if (type != null) { + + // add the type itself + if (type.getName() != null && type instanceof TClassifier) { + // note that functions cannot be used as type references + result = new SingletonScope(EObjectDescription.create(type.getName(), type), result); + } + + // add the type variables + if (type.isGeneric()) { + if (type instanceof TClassifier && staticAccess) { + // error case: type variables of a classifier cannot be accessed from static members + // e.g. class C { static x: T; } + // --> return same scope as in success case, but wrap descriptions with a + // WrongStaticAccessorDescription + Function wrapEODs = dscr -> new WrongStaticAccessDescription( + dscr, staticAccess); + result = scopeSnapshotHelper.scopeForEObjects("scopeWithTypeAndItsTypeVariables-1", + type, result, type.getTypeVars(), wrapEODs); + } else { + // success case: simply add type variables to scope + result = scopeSnapshotHelper.scopeForEObjects("scopeWithTypeAndItsTypeVariables-2", type, result, + type.getTypeVars()); + } + } + } + + return result; + } + + /** Returns the type variables if the TStructMethod is generic. */ + public IScope scopeWithTypeVarsOfTStructMethod(IScope parent, TStructMethod m) { + TStructMember mDef = m.getDefinedMember(); + if (mDef instanceof TStructMethod) { + if (((TStructMethod) mDef).isGeneric()) { + return scopeSnapshotHelper.scopeForEObjects("scopeWithTypeVarsOfTStructMethod", mDef, parent, + ((TStructMethod) mDef).getTypeVars()); + } + } + return parent; + } + + /** Returns the type variables if the function type expression is generic. */ + public IScope scopeWithTypeVarsOfFunctionTypeExpression(IScope parent, FunctionTypeExpression funTypeExpr) { + if (funTypeExpr != null && funTypeExpr.isGeneric()) { + return scopeSnapshotHelper.scopeForEObjects("scopeWithTypeVarsOfFunctionTypeExpression", funTypeExpr, + parent, funTypeExpr.getTypeVars()); + } + return parent; + } + + /** Returns scope with locally known types and (as parent) import scope; the result is cached. */ + public IScope scopeWithLocallyDeclaredElems(Script script, Supplier parentSupplier, + boolean onlyNamespacelikes) { + return cache.get(script.eResource(), () -> { + // all types in the index: + IScope parent = parentSupplier.get(); + // but imported types are preferred (or maybe renamed with aliases): + IScope importScope = importedElementsScopingHelper.getImportedTypes(parent, script); + // finally, add locally declared types as the outer scope + IScope localTypes = scopeWithLocallyDeclaredElems(script, importScope, onlyNamespacelikes); + + return localTypes; + }, script, "locallyKnownTypes_" + String.valueOf(onlyNamespacelikes)); + } + + /** Returns scope with locally declared types (without import scope). */ + public IScope scopeWithLocallyDeclaredElems(Script script, IScope parent, boolean onlyNamespacelikes) { + return scopeWithLocallyDeclaredElems(script.getModule(), script, parent, onlyNamespacelikes); + } + + /** Returns scope with locally declared types (without import scope). */ + public IScope scopeWithLocallyDeclaredElems(N4NamespaceDeclaration namespace, IScope parent, + boolean onlyNamespacelikes) { + return cache.get(namespace.eResource(), + () -> scopeWithLocallyDeclaredElems((AbstractNamespace) namespace.getDefinedType(), namespace, parent, + onlyNamespacelikes), + namespace, "scopeWithLocallyDeclaredElems_" + String.valueOf(onlyNamespacelikes)); + } + + /** Returns scope with locally declared types (without import scope). */ + public IScope scopeWithLocallyDeclaredElems(AbstractNamespace namespace, IScope parent, + boolean onlyNamespacelikes) { + return scopeWithLocallyDeclaredElems(namespace, namespace, parent, onlyNamespacelikes); + } + + /** Returns scope with locally declared types (without import scope). */ + private IScope scopeWithLocallyDeclaredElems(AbstractNamespace ans, EObject context, IScope parent, + boolean onlyNamespacelikes) { + if (ans == null || ans.eIsProxy()) { + return parent; + } + Iterable tlElems = onlyNamespacelikes + ? Iterables.concat(ans.getNamespaces(), filter(ans.getTypes(), TEnum.class)) + : filter(ans.getTypes(), t -> !t.isPolyfill()); + Iterable eoDescrs = map(tlElems, + topLevelType -> EObjectDescription.create(topLevelType.getName(), topLevelType)); + return scopeSnapshotHelper.scopeFor("scopeWithLocallyDeclaredTypes", context, parent, eoDescrs); + } + + /** + * Returns scope with locally known types specially configured for super reference in case of polyfill definitions. + * It does not add the polyfillType itself. Instead, only its type variables are added, which are otherwise hidden + * in case of polyfills. The result is not cached as this scope is needed only one time. + */ + public IScope scopeWithLocallyKnownTypesForPolyfillSuperRef(Script script, IScope parent, Type polyfillType) { + + // imported and locally defined types are preferred (or maybe renamed with aliases): + IScope importScope = importedElementsScopingHelper.getImportedTypes(parent, script); + + // locally defined types except polyfillType itself + TModule local = script.getModule(); + Iterable eoDescrs = map(filter(local.getTypes(), t -> t != polyfillType), + t -> EObjectDescription.create(t.getName(), t)); + IScope localTypesScope = scopeSnapshotHelper.scopeFor("scopeWithLocallyKnownTypesForPolyfillSuperRef", script, + importScope, eoDescrs); + + // type variables of polyfill + if (polyfillType != null && polyfillType.isGeneric()) { + return scopeSnapshotHelper.scopeForEObjects("scopeWithLocallyKnownTypesForPolyfillSuperRef-polyfillType", + polyfillType, localTypesScope, polyfillType.getTypeVars()); + } + + // non generic: + return localTypesScope; + + } + +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/LocallyKnownTypesScopingHelper.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/LocallyKnownTypesScopingHelper.xtend deleted file mode 100644 index df9692346a..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/LocallyKnownTypesScopingHelper.xtend +++ /dev/null @@ -1,170 +0,0 @@ -/** - * 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.scoping.utils - -import com.google.common.collect.Iterables -import com.google.inject.Inject -import java.util.function.Supplier -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.N4NamespaceDeclaration -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.resource.N4JSCache -import org.eclipse.n4js.scoping.N4JSScopeProvider -import org.eclipse.n4js.scoping.imports.ImportedElementsScopingHelper -import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TEnum -import org.eclipse.n4js.ts.types.TStructMethod -import org.eclipse.n4js.ts.types.Type -import org.eclipse.xtext.resource.EObjectDescription -import org.eclipse.xtext.scoping.IScope -import org.eclipse.xtext.scoping.impl.SingletonScope - -/** - * Helper for {@link N4JSScopeProvider N4JSScopeProvider} using - * {@link ImportedElementsScopingHelper ImportedElementsScopingHelper} - * for providing scope for types provider. - */ -class LocallyKnownTypesScopingHelper { - - @Inject - N4JSCache cache - - @Inject - ImportedElementsScopingHelper importedElementsScopingHelper - - @Inject - ScopeSnapshotHelper scopeSnapshotHelper - - /** Returns the type itself and type variables in case the type is generic. */ - def IScope scopeWithTypeAndItsTypeVariables(IScope parent, Type type, boolean staticAccess) { - var IScope result = parent; - if (type !== null) { - - // add the type itself - if (type.name !== null && type instanceof TClassifier) { - // note that functions cannot be used as type references - result = new SingletonScope(EObjectDescription.create(type.name, type), result) - } - - // add the type variables - if (type.generic) { - if (type instanceof TClassifier && staticAccess) { - // error case: type variables of a classifier cannot be accessed from static members - // e.g. class C { static x: T; } - // --> return same scope as in success case, but wrap descriptions with a WrongStaticAccessorDescription - val wrapEODs = [new WrongStaticAccessDescription(it, staticAccess)]; - result = scopeSnapshotHelper.scopeForEObjects("scopeWithTypeAndItsTypeVariables-1", type, result, type.typeVars, wrapEODs); - } else { - // success case: simply add type variables to scope - result = scopeSnapshotHelper.scopeForEObjects("scopeWithTypeAndItsTypeVariables-2", type, result, type.typeVars); - } - } - } - - return result; - } - - /** Returns the type variables if the TStructMethod is generic. */ - def IScope scopeWithTypeVarsOfTStructMethod(IScope parent, TStructMethod m) { - val mDef = m.definedMember - if (mDef instanceof TStructMethod) { - if (mDef.generic) { - return scopeSnapshotHelper.scopeForEObjects("scopeWithTypeVarsOfTStructMethod", mDef, parent, mDef.typeVars); - } - } - return parent; - } - - /** Returns the type variables if the function type expression is generic. */ - def IScope scopeWithTypeVarsOfFunctionTypeExpression(IScope parent, FunctionTypeExpression funTypeExpr) { - if (funTypeExpr !== null && funTypeExpr.generic) { - return scopeSnapshotHelper.scopeForEObjects("scopeWithTypeVarsOfFunctionTypeExpression", funTypeExpr, parent, funTypeExpr.typeVars); - } - return parent; - } - - /** Returns scope with locally known types and (as parent) import scope; the result is cached. */ - def IScope scopeWithLocallyDeclaredElems(Script script, Supplier parentSupplier, boolean onlyNamespacelikes) { - return cache.get(script.eResource, [| - // all types in the index: - val parent = parentSupplier.get(); - // but imported types are preferred (or maybe renamed with aliases): - val IScope importScope = importedElementsScopingHelper.getImportedTypes(parent, script); - // finally, add locally declared types as the outer scope - val localTypes = scopeWithLocallyDeclaredElems(script, importScope, onlyNamespacelikes); - - return localTypes; - ], script, 'locallyKnownTypes_'+String.valueOf(onlyNamespacelikes)); - } - - /** Returns scope with locally declared types (without import scope). */ - def IScope scopeWithLocallyDeclaredElems(Script script, IScope parent, boolean onlyNamespacelikes) { - return scopeWithLocallyDeclaredElems(script.module, script, parent, onlyNamespacelikes); - } - - /** Returns scope with locally declared types (without import scope). */ - def IScope scopeWithLocallyDeclaredElems(N4NamespaceDeclaration namespace, IScope parent, boolean onlyNamespacelikes) { - return cache.get(namespace.eResource, [| - return scopeWithLocallyDeclaredElems(namespace.definedType as AbstractNamespace, namespace, parent, onlyNamespacelikes); - ], namespace, 'scopeWithLocallyDeclaredElems_'+String.valueOf(onlyNamespacelikes)); - } - - /** Returns scope with locally declared types (without import scope). */ - def IScope scopeWithLocallyDeclaredElems(AbstractNamespace namespace, IScope parent, boolean onlyNamespacelikes) { - return scopeWithLocallyDeclaredElems(namespace, namespace, parent, onlyNamespacelikes); - } - - /** Returns scope with locally declared types (without import scope). */ - def private IScope scopeWithLocallyDeclaredElems(AbstractNamespace ans, EObject context, IScope parent, boolean onlyNamespacelikes) { - if (ans === null || ans.eIsProxy) { - return parent; - } - val tlElems = if (onlyNamespacelikes) { - Iterables.concat(ans.namespaces, ans.types.filter[t | t instanceof TEnum ]) - } else { - ans.types.filter[t | !t.polyfill ]; - }; - val eoDescrs = tlElems.map[ topLevelType | - return EObjectDescription.create(topLevelType.name, topLevelType); - ]; - return scopeSnapshotHelper.scopeFor("scopeWithLocallyDeclaredTypes", context, parent, eoDescrs); - } - - /** - * Returns scope with locally known types specially configured for super reference in case of polyfill definitions. - * It is comparable to {@link #getLocallyKnownTypes(Script, EReference, IScopeProvider), but it does not - * add the polyfillType itself. Instead, only its type variables are added, which are otherwise hidden in case of polyfills. - * The result is not cached as this scope is needed only one time. - */ - def IScope scopeWithLocallyKnownTypesForPolyfillSuperRef(Script script, - IScope parent, Type polyfillType) { - - // imported and locally defined types are preferred (or maybe renamed with aliases): - val IScope importScope = importedElementsScopingHelper.getImportedTypes(parent, script) - - // locally defined types except polyfillType itself - val local = script.module - val eoDescrs = local.types.filter[it !== polyfillType].map[EObjectDescription.create(name, it)]; - val IScope localTypesScope = scopeSnapshotHelper.scopeFor("scopeWithLocallyKnownTypesForPolyfillSuperRef", script, importScope, eoDescrs); - - // type variables of polyfill - if (polyfillType !== null && polyfillType.generic) { - return scopeSnapshotHelper.scopeForEObjects("scopeWithLocallyKnownTypesForPolyfillSuperRef-polyfillType", polyfillType, localTypesScope, polyfillType.typeVars); - } - - // non generic: - return localTypesScope; - - } - -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ScopesHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ScopesHelper.java new file mode 100644 index 0000000000..16cc6b8992 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ScopesHelper.java @@ -0,0 +1,94 @@ +/** + * 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.scoping.utils; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.validation.JavaScriptVariantHelper; +import org.eclipse.xtext.naming.QualifiedName; +import org.eclipse.xtext.resource.IEObjectDescription; +import org.eclipse.xtext.scoping.IScope; +import org.eclipse.xtext.scoping.Scopes; +import org.eclipse.xtext.scoping.impl.MapBasedScope; +import org.eclipse.xtext.scoping.impl.MultimapBasedScope; +import org.eclipse.xtext.scoping.impl.SimpleScope; +import org.eclipse.xtext.util.SimpleAttributeResolver; + +import com.google.common.base.Function; +import com.google.common.collect.Iterables; +import com.google.inject.Inject; + +/** + * Some utility methods, similar to xtext's {@link Scopes}. + */ +public class ScopesHelper { + + @Inject + private JavaScriptVariantHelper javaScriptVariantHelper; + + /** + * Creates a map based scope for the given iterable of descriptions. + * + * @param context + * The context of the scope + * @param descriptions + * The descriptions + */ + public IScope mapBasedScopeFor(EObject context, Iterable descriptions) { + return mapBasedScopeFor(context, IScope.NULLSCOPE, descriptions); + } + + /** + * Creates a map based scope for the given iterable of descriptions. + * + * @param context + * The context of the scope + * @param parent + * The parent scope + * @param descriptions + * The descriptions + */ + public IScope mapBasedScopeFor(EObject context, IScope parent, Iterable descriptions) { + if (javaScriptVariantHelper.isMultiQNScope(context)) { + return MultimapBasedScope.createScope(parent, descriptions, false); + } else { + return MapBasedScope.createScope(parent, descriptions); + } + } + + /** + * Convenience method for {@link #scopeFor(Iterable,Function,Function,IScope)}. + */ + public IScope scopeFor(Iterable elements, + Function wrapper) { + return scopeFor(elements, wrapper, IScope.NULLSCOPE); + } + + /** + * Convenience method for {@link #scopeFor(Iterable,Function,Function,IScope)}. + */ + public IScope scopeFor(Iterable elements, + Function wrapper, IScope outer) { + return scopeFor(elements, QualifiedName.wrapper(SimpleAttributeResolver.NAME_RESOLVER), wrapper, outer); + } + + /** + * Similar to {@link Scopes#scopeFor(Iterable,Function,IScope)} but supports custom wrapping of the + * IEObjectDescriptions, for example to wrap them with error message providing subclasses such as + * {@link WrongStaticAccessDescription}. The wrapper can return the object description unchanged, create and return + * a new one or may return null to remove the corresponding object from the scope. + */ + public IScope scopeFor(Iterable elements, + Function nameComputation, + Function wrapper, IScope outer) { + return new SimpleScope(outer, + Iterables.transform(Scopes.scopedElementsFor(elements, nameComputation), wrapper)); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ScopesHelper.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ScopesHelper.xtend deleted file mode 100644 index 3975a05c70..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/utils/ScopesHelper.xtend +++ /dev/null @@ -1,89 +0,0 @@ -/** - * 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.scoping.utils - -import com.google.common.base.Function -import com.google.common.collect.Iterables -import org.eclipse.emf.ecore.EObject -import org.eclipse.xtext.naming.QualifiedName -import org.eclipse.xtext.resource.IEObjectDescription -import org.eclipse.xtext.scoping.IScope -import org.eclipse.xtext.scoping.Scopes -import org.eclipse.xtext.scoping.impl.SimpleScope -import org.eclipse.xtext.util.SimpleAttributeResolver -import com.google.inject.Inject -import org.eclipse.n4js.validation.JavaScriptVariantHelper -import org.eclipse.xtext.scoping.impl.MapBasedScope -import org.eclipse.xtext.scoping.impl.MultimapBasedScope - -/** - * Some utility methods, similar to xtext's {@link Scopes}. - */ -public class ScopesHelper { - - @Inject - private JavaScriptVariantHelper javaScriptVariantHelper; - - /** - * Creates a map based scope for the given iterable of descriptions. - * - * @param context The context of the scope - * @param descriptions The descriptions - */ - def public IScope mapBasedScopeFor(EObject context, Iterable descriptions) { - return mapBasedScopeFor(context, IScope.NULLSCOPE, descriptions); - } - - /** - * Creates a map based scope for the given iterable of descriptions. - * - * @param context The context of the scope - * @param parent The parent scope - * @param descriptions The descriptions - */ - def public IScope mapBasedScopeFor(EObject context, IScope parent, Iterable descriptions) { - if (javaScriptVariantHelper.isMultiQNScope(context)) { - return MultimapBasedScope.createScope(parent, descriptions, false); - } else { - return MapBasedScope.createScope(parent, descriptions); - } - } - - /** - * Convenience method for {@link #scopeFor(Iterable,Function,Function,IScope)}. - */ - def public IScope scopeFor(Iterable elements, - Function wrapper) { - return scopeFor(elements, wrapper, IScope.NULLSCOPE); - } - - /** - * Convenience method for {@link #scopeFor(Iterable,Function,Function,IScope)}. - */ - def public IScope scopeFor(Iterable elements, - Function wrapper, IScope outer) { - return scopeFor(elements, QualifiedName.wrapper(SimpleAttributeResolver.NAME_RESOLVER), wrapper, outer); - } - - /** - * Similar to {@link Scopes#scopeFor(Iterable,Function,IScope)} but supports custom wrapping - * of the IEObjectDescriptions, for example to wrap them with error message providing subclasses - * such as {@link WrongStaticAccessDescription}. The wrapper can return the object description - * unchanged, create and return a new one or may return null to remove the corresponding object - * from the scope. - */ - def public IScope scopeFor(Iterable elements, - Function nameComputation, - Function wrapper, IScope outer) { - return new SimpleScope(outer, - Iterables.transform(Scopes.scopedElementsFor(elements, nameComputation), wrapper)); - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/DIUtility.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/DIUtility.java new file mode 100644 index 0000000000..f91adc4332 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/DIUtility.java @@ -0,0 +1,189 @@ +/** + * 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.tooling.organizeImports; + +import static org.eclipse.n4js.AnnotationDefinition.BINDER; +import static org.eclipse.n4js.AnnotationDefinition.GENERATE_INJECTOR; +import static org.eclipse.n4js.AnnotationDefinition.INJECT; +import static org.eclipse.n4js.AnnotationDefinition.USE_BINDER; +import static org.eclipse.n4js.AnnotationDefinition.WITH_PARENT_INJECTOR; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.n4ProviderType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.newRuleEnvironment; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.TAnnotation; +import org.eclipse.n4js.ts.types.TAnnotationArgument; +import org.eclipse.n4js.ts.types.TAnnotationTypeRefArgument; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.typesystem.utils.AllSuperTypesCollector; +import org.eclipse.n4js.utils.DeclMergingHelper; + +/** + * Collection of utility methods for working with N4JS DI. + */ +public class DIUtility { + + /***/ + public static boolean isSingleton(Type type) { + return exists(type.getAnnotations(), a -> AnnotationDefinition.SINGLETON.name.equals(a.getName())); + } + + /***/ + public static boolean hasSuperType(Type type) { + if (type instanceof TClass) { + TClass tc = (TClass) type; + if (tc.getSuperClassRef() != null) { + return tc.getSuperClassRef().getDeclaredType() instanceof TClass; + } + } + return false; + } + + /** + * Returns true if provided type is instanceof {@link TClass} and at least owned member is annotated with + * {@link AnnotationDefinition#INJECT}. + */ + public static boolean hasInjectedMembers(Type type, DeclMergingHelper declMergingHelper) { + if (type instanceof TClass) { + return exists(AllSuperTypesCollector.collect((TClass) type, declMergingHelper), + t -> exists(t.getOwnedMembers(), m -> INJECT.hasAnnotation(m))); + } + return false; + } + + /** + * Generate DI meta info for classes that have injected members, or are can be injected and have DI relevant + * information, e.g. scope annotation. Also if type has a super type (injection of inherited members) + */ + public static boolean isInjectedClass(Type type, DeclMergingHelper declMergingHelper) { + return isSingleton(type) || hasInjectedMembers(type, declMergingHelper) || hasSuperType(type); + } + + /***/ + public static boolean isBinder(Type type) { + return BINDER.hasAnnotation(type); + } + + /***/ + public static boolean isDIComponent(Type type) { + return GENERATE_INJECTOR.hasAnnotation(type); + } + + /** + * Checks if diComponent has parent component, that is one specified by the superclass or by the inheritance. + */ + public static boolean hasParentInjector(Type type) { + if (WITH_PARENT_INJECTOR.hasAnnotation(type)) { + return true; + } + + if (type instanceof TClass) { + return ((TClass) type).getSuperClassRef() != null; + } else + return false; + } + + /** + * @returns {@link Type} of the parent DIComponent. Throws {@link RuntimeException} if no parent on provided type. + */ + public static Type findParentDIC(Type type) { + TypeRef parent = null; + if (WITH_PARENT_INJECTOR.hasAnnotation(type)) { + TAnnotation ann = WITH_PARENT_INJECTOR.getOwnedAnnotation(type); + if (ann != null) { + parent = ((TAnnotationTypeRefArgument) ann.getArgs().get(0)).getTypeRef(); + } + + } else if (type instanceof TClass) { + parent = ((TClass) type).getSuperClassRef(); + } + + if (parent != null) { + return parent.getDeclaredType(); + } + + throw new RuntimeException("no parent on " + type.getName()); + } + + /** + * returns list of types that are parameters of {@link AnnotationDefinition#USE_BINDER} annotations attached to a + * given type or empty list + */ + public static List resolveBinders(Type type) { + List argTypes = new ArrayList<>(); + for (TAnnotation ann : USE_BINDER.getAllOwnedAnnotations(type)) { + for (TAnnotationArgument annArg : ann.getArgs()) { + Type argType = ((TAnnotationTypeRefArgument) annArg).getTypeRef().getDeclaredType(); + if (argType != null) { + argTypes.add(argType); + } + } + } + + return argTypes; + } + + /** + * Returns with {@code true} if one or more members of the given type are annotated with {@code @Inject} annotation. + */ + public static boolean requiresInjection(Type type, DeclMergingHelper declMergingHelper) { + if (type instanceof TClass) { + return exists(AllSuperTypesCollector.collect((TClass) type, declMergingHelper), + tc -> exists(tc.getOwnedMembers(), m -> INJECT.hasAnnotation(m))); + } + return false; + } + + /** + * Returns with {@code true} if the type reference argument requires injection. Either the declared type requires + * injection, or the type reference represents an N4 provider, and the dependency of the provider requires + * injection. Otherwise returns with {@code false}. + */ + public static boolean requiresInjection(TypeRef tr, DeclMergingHelper declMergingHelper) { + return requiresInjection(tr.getDeclaredType(), declMergingHelper) + || isProviderType(tr) && requiresInjection(getProvidedType(tr), declMergingHelper); + } + + /** + * Returns with {@code true} if the type reference argument is an N4 provider. Otherwise returns with {@code false}. + * Also returns with {@code false} if the type reference is sub interface of N4 provider or a class which implements + * the N4 provider interface. + */ + public static boolean isProviderType(TypeRef tr) { + return null != tr && tr.getDeclaredType() == n4ProviderType(newRuleEnvironment(tr)); + } + + /** + * Returns with the type most nested dependency if the type reference argument represents and N4 provider. Otherwise + * returns with {@code null}. + */ + public static Type getProvidedType(TypeRef tr) { + if (!isProviderType(tr)) { + return null; + } + TypeRef nestedTypeRef = tr; + while (isProviderType(nestedTypeRef) && nestedTypeRef instanceof ParameterizedTypeRef) { + List typeArgs = toList( + filter(((ParameterizedTypeRef) nestedTypeRef).getDeclaredTypeArgs(), TypeRef.class)); + nestedTypeRef = (typeArgs.isEmpty()) ? null : typeArgs.get(0); + } + return nestedTypeRef == null ? null : nestedTypeRef.getDeclaredType(); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/DIUtility.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/DIUtility.xtend deleted file mode 100644 index 72376157a3..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/DIUtility.xtend +++ /dev/null @@ -1,151 +0,0 @@ -/** - * 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.tooling.organizeImports - -import java.util.List -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.TAnnotationTypeRefArgument -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.Type -import org.eclipse.n4js.typesystem.utils.AllSuperTypesCollector -import org.eclipse.n4js.utils.DeclMergingHelper - -import static org.eclipse.n4js.AnnotationDefinition.* - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * Collection of utility methods for working with N4JS DI. - */ -class DIUtility { - - def public static boolean isSingleton(Type type) { - type.annotations.exists[name == AnnotationDefinition.SINGLETON.name] - } - - def public static boolean hasSuperType(Type type) { - if(type instanceof TClass){ - type.superClassRef?.declaredType instanceof TClass - }else{ - false - } - } - - /** - * Returns true if provided type is instanceof {@link TClass} - * and at least owned member is annotated with {@link AnnotationDefinition#INJECT}. - */ - def public static boolean hasInjectedMembers(Type type, DeclMergingHelper declMergingHelper) { - if (type instanceof TClass) - AllSuperTypesCollector.collect(type, declMergingHelper).exists[ownedMembers.exists[INJECT.hasAnnotation(it)]] - else - false; - } - - /** - * Generate DI meta info for classes that have injected members, - * or are can be injected and have DI relevant information, e.g. scope annotation. - * Also if type has a super type (injection of inherited members) - */ - def public static boolean isInjectedClass(Type it, DeclMergingHelper declMergingHelper){ - isSingleton || hasInjectedMembers(declMergingHelper) || hasSuperType - } - - def public static boolean isBinder(Type type) { - BINDER.hasAnnotation(type) - } - - def public static boolean isDIComponent(Type type) { - GENERATE_INJECTOR.hasAnnotation(type) - } - - /** - * Checks if diComponent has parent component, that is one specified by the superclass - * or by the inheritance. - */ - def public static boolean hasParentInjector(Type type) { - return WITH_PARENT_INJECTOR.hasAnnotation(type) || - if (type instanceof TClass) { - type.superClassRef !== null; - } else - false; - } - - /** - * @returns {@link Type} of the parent DIComponent. - * @throws {@link RuntimeException} if no parent on provided type. - */ - def public static Type findParentDIC(Type type) { - var TypeRef parent = if (WITH_PARENT_INJECTOR.hasAnnotation(type)) { - (WITH_PARENT_INJECTOR.getOwnedAnnotation(type)?.args.head as TAnnotationTypeRefArgument).typeRef; - } else if (type instanceof TClass) { - type.superClassRef; - } else - null; - - if (parent !== null) { - return parent.declaredType - } - - throw new RuntimeException("no parent on " + type.name); - } - - /** - * returns list of types that are parameters of {@link AnnotationDefinition#USE_BINDER} annotations - * attached to a given type or empty list - */ - def public static List resolveBinders(Type type) { - return USE_BINDER.getAllOwnedAnnotations(type) - .map[args].flatten - .map[(it as TAnnotationTypeRefArgument).typeRef.declaredType].filterNull.toList - } - - /** Returns with {@code true} if one or more members of the given type are annotated with {@code @Inject} annotation. */ - def public static boolean requiresInjection(Type type, DeclMergingHelper declMergingHelper) { - return if (type instanceof TClass) AllSuperTypesCollector.collect(type, declMergingHelper).exists[ownedMembers.exists[INJECT.hasAnnotation(it)]] else false; - } - - /** - * Returns with {@code true} if the type reference argument requires injection. Either the declared type requires injection, - * or the type reference represents an N4 provider, and the dependency of the provider requires injection. Otherwise - * returns with {@code false}. - */ - def public static boolean requiresInjection(TypeRef it, DeclMergingHelper declMergingHelper) { - return declaredType.requiresInjection(declMergingHelper) || (providerType && providedType.requiresInjection(declMergingHelper)) - } - - /** - * Returns with {@code true} if the type reference argument is an N4 provider. Otherwise returns with {@code false}. - * Also returns with {@code false} if the type reference is sub interface of N4 provider or a class which implements - * the N4 provider interface. - */ - def public static boolean isProviderType(TypeRef it) { - null !== it && declaredType === newRuleEnvironment.n4ProviderType; - } - - /** - * Returns with the type most nested dependency if the type reference argument represents and N4 provider. - * Otherwise returns with {@code null}. - */ - def public static getProvidedType(TypeRef it) { - if (!providerType) { - return null; - } - var nestedTypeRef = it; - while (nestedTypeRef.providerType && nestedTypeRef instanceof ParameterizedTypeRef) { - val typeArgs = (nestedTypeRef as ParameterizedTypeRef).declaredTypeArgs.filter(TypeRef); - nestedTypeRef = if (typeArgs.nullOrEmpty) null else typeArgs.head; - } - return nestedTypeRef?.declaredType; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportSpecifiersUtil.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportSpecifiersUtil.java new file mode 100644 index 0000000000..f516e206e5 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportSpecifiersUtil.java @@ -0,0 +1,209 @@ +/** + * Copyright (c) 2017 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.tooling.organizeImports; + +import static com.google.common.base.Strings.isNullOrEmpty; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; + +import org.eclipse.n4js.N4JSLanguageConstants; +import org.eclipse.n4js.n4JS.DefaultImportSpecifier; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.ElementExportDefinition; +import org.eclipse.n4js.ts.types.ExportDefinition; +import org.eclipse.n4js.ts.types.ModuleExportDefinition; +import org.eclipse.n4js.ts.types.TExportableElement; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.RecursionGuard; + +import com.google.common.collect.Lists; + +/** + * Utilities for ImportSpecifiers + */ +public class ImportSpecifiersUtil { + + /** + * @return {@link List} of {@link ImportProvidedElement}s describing imported elements + */ + public static List mapToImportProvidedElements( + Collection importSpecifiers) { + + List result = new ArrayList<>(); + for (ImportSpecifier specifier : importSpecifiers) { + if (specifier instanceof NamespaceImportSpecifier) { + result.addAll(namespaceToProvidedElements((NamespaceImportSpecifier) specifier)); + } else if (specifier instanceof NamedImportSpecifier) { + NamedImportSpecifier nis = (NamedImportSpecifier) specifier; + result.add(new ImportProvidedElement(usedName(nis), importedElementName(nis), + nis, N4JSLanguageUtils.isHollowElement(nis.getImportedElement()))); + } + } + + return result; + } + + /** Map all exported elements from namespace target module to the import provided elements. */ + private static List namespaceToProvidedElements(NamespaceImportSpecifier specifier) { + TModule importedModule = importedModule(specifier); + if (importedModule == null || importedModule.eIsProxy()) { + return Collections.emptyList(); + } + + List importProvidedElements = new ArrayList<>(); + // add import provided element for a namespace itself + importProvidedElements.add(new ImportProvidedElement(specifier.getAlias(), + computeNamespaceActualName(specifier), specifier, false)); + + Set localNamesAdded = new HashSet<>(); + collectProvidedElements(importedModule, new RecursionGuard<>(), exportDef -> { + String localName = importedElementName(specifier, exportDef); + // function overloading and declaration merging in .d.ts can lead to multiple elements of same name + // being imported via a single namespace import -> to avoid showing bogus "duplicate import" errors + // in those cases we need to avoid adding more than one ImportProvidedElement in those cases: + // TODO IDE-3604 no longer required for function overloading; should probably be removed once declaration + // merging is supported + if (localNamesAdded.add(localName)) { + importProvidedElements.add( + new ImportProvidedElement(localName, exportDef.getExportedName(), + specifier, N4JSLanguageUtils.isHollowElement(exportDef.getExportedElement()))); + } + }); + + return importProvidedElements; + } + + private static void collectProvidedElements(AbstractNamespace namespace, RecursionGuard guard, + Consumer consumer) { + for (ExportDefinition exportDef : Lists.reverse(namespace.getExportDefinitions())) { + if (exportDef instanceof ElementExportDefinition) { + consumer.accept((ElementExportDefinition) exportDef); + } else if (exportDef instanceof ModuleExportDefinition) { + TModule exportedModule = ((ModuleExportDefinition) exportDef).getExportedModule(); + if (exportedModule != null && !exportedModule.eIsProxy()) { + if (guard.tryNext(exportedModule)) { + collectProvidedElements(exportedModule, guard, consumer); + } + } + } + } + } + + /** + * Computes 'actual' name of the namespace for {@link ImportProvidedElement} entry. If processed namespace refers to + * unresolved module, will return dummy name, otherwise returns artificial name composed of prefix and target module + * qualified name + * + */ + public static String computeNamespaceActualName(NamespaceImportSpecifier specifier) { + if (importedModule(specifier).eIsProxy()) + return ImportProvidedElement.NAMESPACE_PREFIX + specifier.hashCode(); + else + return ImportProvidedElement.NAMESPACE_PREFIX + importedModule(specifier).getQualifiedName().toString(); + } + + /** + * Computes exported name of the element imported by this specifier. + */ + public static String importedElementName(NamedImportSpecifier specifier) { + if (specifier instanceof DefaultImportSpecifier) { + return N4JSLanguageConstants.EXPORT_DEFAULT_NAME; + } + + TExportableElement element = specifier.getImportedElement(); + if (element == null) + return "<" + specifier.getImportedElementAsText() + ">(null)"; + + if (element.eIsProxy()) { + if (specifier.isDeclaredDynamic()) { + return specifier.getImportedElementAsText(); + } + return "<" + specifier.getImportedElementAsText() + ">(proxy)"; + } + + return specifier.getImportedElementAsText(); + } + + /** returns locally used name of element imported via {@link NamedImportSpecifier} */ + public static String usedName(NamedImportSpecifier nis) { + return (nis.getAlias() == null) ? importedElementName(nis) : nis.getAlias(); + } + + /** returns locally used name of element imported via {@link NamespaceImportSpecifier} */ + public static String importedElementName(NamespaceImportSpecifier is, ElementExportDefinition exportDef) { + return is.getAlias() + "." + exportDef.getExportedName(); + } + + /***/ + public static TModule importedModule(ImportSpecifier is) { + return ((ImportDeclaration) is.eContainer()).getModule(); + } + + /** + * Returns true if the module that is target of the import declaration containing provided import specifier is + * invalid (null, proxy, no name). Additionally for {@link NamedImportSpecifier} instances checks if linker failed + * to resolve target (is null, proxy, or has no name) + * + * @param spec + * - the ImportSpecifier to investigate + * @return true import looks broken + */ + public static boolean isBrokenImport(ImportSpecifier spec) { + return isBrokenImport((ImportDeclaration) spec.eContainer(), spec); + } + + /** + * Returns true iff the target module of the given import declaration is invalid (null, proxy, no name). Import + * specifiers are not checked. + */ + public static boolean isBrokenImport(ImportDeclaration decl) { + return isBrokenImport(decl, null); + } + + private static boolean isBrokenImport(ImportDeclaration decl, ImportSpecifier spec) { + TModule module = decl.getModule(); + + // check target module + if (module == null || module.eIsProxy() || isNullOrEmpty(module.getQualifiedName())) { + return true; + } + + // check import specifier + if (spec instanceof NamedImportSpecifier && !spec.isDeclaredDynamic()) { + NamedImportSpecifier nis = (NamedImportSpecifier) spec; + if (nis.eIsProxy() || isNullOrEmpty(nis.getImportedElementAsText())) { + return true; + } + + // check what object that is linked + TExportableElement imported = nis.getImportedElement(); + if (imported == null) { + return true; + } + if (imported.eIsProxy()) { + return true; + } + } + + return false; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportSpecifiersUtil.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportSpecifiersUtil.xtend deleted file mode 100644 index 1fcdef565f..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportSpecifiersUtil.xtend +++ /dev/null @@ -1,191 +0,0 @@ -/** - * Copyright (c) 2017 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.tooling.organizeImports - -import com.google.common.collect.Lists -import java.util.List -import java.util.function.Consumer -import org.eclipse.n4js.N4JSLanguageConstants -import org.eclipse.n4js.n4JS.DefaultImportSpecifier -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.ImportSpecifier -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.ElementExportDefinition -import org.eclipse.n4js.ts.types.ModuleExportDefinition -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.RecursionGuard -import org.eclipse.n4js.validation.JavaScriptVariantHelper - -/** - * Utilities for ImportSpecifiers - */ -class ImportSpecifiersUtil { - - /** - * @return {@link List} of {@link ImportProvidedElement}s describing imported elements - */ - public static def List mapToImportProvidedElements( - List importSpecifiers, JavaScriptVariantHelper jsVariantHelper - ) { - return importSpecifiers.map( - specifier | - switch (specifier) { - NamespaceImportSpecifier: - return namespaceToProvidedElements(jsVariantHelper, specifier) - NamedImportSpecifier: - return newArrayList( - new ImportProvidedElement(specifier.usedName, specifier.importedElementName, - specifier as ImportSpecifier, - N4JSLanguageUtils.isHollowElement(specifier.importedElement))) - default: - return emptyList - } - ).flatten.toList - } - - /** Map all exported elements from namespace target module to the import provided elements. */ - private static def List namespaceToProvidedElements(JavaScriptVariantHelper jsVariantHelper, NamespaceImportSpecifier specifier) { - val importedModule = specifier.importedModule; - if (importedModule === null || importedModule.eIsProxy) - return emptyList - - val importProvidedElements = newArrayList - // add import provided element for a namespace itself - importProvidedElements.add(new ImportProvidedElement(specifier.alias, - computeNamespaceActualName(specifier), specifier, false)); - - val localNamesAdded = newHashSet; - collectProvidedElements(importedModule, new RecursionGuard(), [ exportDef | - val localName = specifier.importedElementName(exportDef); - // function overloading and declaration merging in .d.ts can lead to multiple elements of same name - // being imported via a single namespace import -> to avoid showing bogus "duplicate import" errors - // in those cases we need to avoid adding more than one ImportProvidedElement in those cases: - // TODO IDE-3604 no longer required for function overloading; should probably be removed once declaration merging is supported - if (localNamesAdded.add(localName)) { - importProvidedElements.add( - new ImportProvidedElement(localName, exportDef.exportedName, - specifier, N4JSLanguageUtils.isHollowElement(exportDef.exportedElement))); - } - ]); - - return importProvidedElements - } - - private static def void collectProvidedElements(AbstractNamespace namespace, RecursionGuard guard, Consumer consumer) { - for (exportDef : Lists.reverse(namespace.exportDefinitions)) { - if (exportDef instanceof ElementExportDefinition) { - consumer.accept(exportDef); - } else if (exportDef instanceof ModuleExportDefinition) { - val exportedModule = exportDef.exportedModule; - if (exportedModule !== null && !exportedModule.eIsProxy) { - if (guard.tryNext(exportedModule)) { - collectProvidedElements(exportedModule, guard, consumer); - } - } - } - } - } - - /** - * Computes 'actual' name of the namespace for {@link ImportProvidedElement} entry. - * If processed namespace refers to unresolved module, will return dummy name, - * otherwise returns artificial name composed of prefix and target module qualified name - * - */ - public static def String computeNamespaceActualName(NamespaceImportSpecifier specifier) { - if (specifier.importedModule.eIsProxy) - ImportProvidedElement.NAMESPACE_PREFIX + specifier.hashCode - else - ImportProvidedElement.NAMESPACE_PREFIX + specifier.importedModule.qualifiedName.toString - } - - /** - * Computes exported name of the element imported by this specifier. - */ - public static def String importedElementName(NamedImportSpecifier specifier) { - if (specifier instanceof DefaultImportSpecifier) { - return N4JSLanguageConstants.EXPORT_DEFAULT_NAME; - } - - val element = specifier.importedElement - if (element === null) - return "<" + specifier.importedElementAsText + ">(null)" - - if (element.eIsProxy) { - if (specifier.declaredDynamic) { - return specifier.importedElementAsText; - } - return "<" + specifier.importedElementAsText + ">(proxy)" - } - - return specifier.importedElementAsText; - } - - /** returns locally used name of element imported via {@link NamedImportSpecifier} */ - public static def String usedName(NamedImportSpecifier it) { - if (alias === null) importedElementName else alias - } - - /** returns locally used name of element imported via {@link NamespaceImportSpecifier} */ - public static def String importedElementName(NamespaceImportSpecifier is, ElementExportDefinition exportDef) { - is.alias + "." + exportDef.exportedName - } - - public static def TModule importedModule(ImportSpecifier it) { - (eContainer as ImportDeclaration).module - } - - /** - * Returns true if the module that is target of the import declaration containing provided import specifier is invalid (null, proxy, no name). - * Additionally for {@link NamedImportSpecifier} instances checks if linker failed to resolve target (is null, proxy, or has no name) - * - * @param spec - the ImportSpecifier to investigate - * @return true import looks broken - * */ - public static def boolean isBrokenImport(ImportSpecifier spec) { - return isBrokenImport(spec.eContainer as ImportDeclaration, spec); - } - - /** - * Returns true iff the target module of the given import declaration is invalid (null, proxy, no name). - * Import specifiers are not checked. - */ - public static def boolean isBrokenImport(ImportDeclaration decl) { - return isBrokenImport(decl, null); - } - - private static def boolean isBrokenImport(ImportDeclaration decl, ImportSpecifier spec) { - val module = decl.module; - - // check target module - if (module === null || module.eIsProxy || module.qualifiedName.isNullOrEmpty) - return true - - // check import specifier - if (spec instanceof NamedImportSpecifier && !spec.declaredDynamic) { - val nis = spec as NamedImportSpecifier; - if (nis === null || nis.eIsProxy || nis.importedElementAsText.isNullOrEmpty) - return true - - // check what object that is linked - val imported = nis.importedElement - if (imported === null) - return true - if (imported.eIsProxy) - return true - } - - return false - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportStateCalculator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportStateCalculator.java new file mode 100644 index 0000000000..d88111b6fa --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportStateCalculator.java @@ -0,0 +1,318 @@ +/** + * 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.tooling.organizeImports; + +import static org.eclipse.n4js.tooling.organizeImports.ImportSpecifiersUtil.computeNamespaceActualName; +import static org.eclipse.n4js.tooling.organizeImports.ImportSpecifiersUtil.isBrokenImport; +import static org.eclipse.n4js.tooling.organizeImports.ImportSpecifiersUtil.mapToImportProvidedElements; +import static org.eclipse.n4js.tooling.organizeImports.ScriptDependencyResolver.usedDependenciesTypeRefs; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.flatten; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.forEach; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.head; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.tail; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; + +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.postprocessing.ASTMetaInfoCache; +import org.eclipse.n4js.resource.N4JSResource; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.validation.IssueCodes; +import org.eclipse.xtext.xbase.lib.Pair; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; + +/** + * Analyzes all imports in a script. Builds up a data structure of {@link RecordingImportState} to capture the findings. + */ +public class ImportStateCalculator { + + /** + * Algorithm to check the Model for Issues with Imports. + * + * @returns {@link RecordingImportState} + */ + public RecordingImportState calculateImportstate(Script script) { + RecordingImportState reg = new RecordingImportState(); + + ASTMetaInfoCache astMetaInfoCache = ((N4JSResource) script.eResource()).getASTMetaInfoCacheVerifyContext(); + + // Calculate Available + Iterable importDeclarationsALL = filter(script.getScriptElements(), ImportDeclaration.class); + + registerDuplicatedImoprtDeclarationsFrom(reg, importDeclarationsALL); + + List importSpecifiersUnAnalyzed = toList( + flatten(map(filter(importDeclarationsALL, it -> !reg.isDuplicatingImportDeclaration(it)), + decl -> decl.getImportSpecifiers()))); + + // markDuplicatingSpecifiersAsUnused(importSpecifiersUnAnalyzed) + + // collect all unused if stable + registerUnusedAndBrokenImports(reg, importSpecifiersUnAnalyzed, astMetaInfoCache); + + List importProvidedElements = mapToImportProvidedElements( + toList(filter(importSpecifiersUnAnalyzed, it -> !(reg.brokenImports.contains(it))))); + + // refactor into specific types, those are essentially Maps holding elements in insertion order (keys and + // values) + List>> lN2IPE = new ArrayList<>(); + List>> lM2IPE = new ArrayList<>(); + + // TODO refactor this, those composed collections should be encapsulated as specific types with proper get/set + // methods + for (ImportProvidedElement ipe : importProvidedElements) { + Pair> pN2IPE = findFirst(lN2IPE, + p -> Objects.equals(p.getKey(), ipe.getCollisionUniqueName())); + + if (pN2IPE != null) { + pN2IPE.getValue().add(ipe); + } else { + List al = new ArrayList<>(); + al.add(ipe); + lN2IPE.add(Pair.of(ipe.getCollisionUniqueName(), al)); + } + Pair> pM2IPE = findFirst(lM2IPE, + p -> Objects.equals(p.getKey(), ipe.getImportedModule())); + if (pM2IPE != null) { + pM2IPE.getValue().add(ipe); + } else { + List al = new ArrayList<>(); + al.add(ipe); + lM2IPE.add(Pair.of(ipe.getImportedModule(), al)); + } + } + + registerUsedImportsLocalNamesCollisions(reg, lN2IPE); + + registerUsedImportsDuplicatedImportedElements(reg, lM2IPE); + + reg.registerAllUsedTypeNameToSpecifierTuples(importProvidedElements); + + // usages in script: + List externalDep = usedDependenciesTypeRefs(script); + + // mark used imports as seen in externalDep: + for (ScriptDependency scriptDep : externalDep) { + TModule mod = scriptDep.dependencyModule; + Pair> pM2IPE = findFirst(lM2IPE, p -> p.getKey() == mod); + if (pM2IPE != null) { + forEach(filter(pM2IPE.getValue(), ipe -> Objects.equals(ipe.getExportedName(), scriptDep.actualName) + && Objects.equals(ipe.getLocalName(), scriptDep.localName)), it -> it.markUsed()); + } + } + + /* + * TODO review ambiguous imports looks like reference to type that is ambiguously imported can happen only if + * there are errors in the import declaratiosn, so should ignore those references and resolve issues in the + * imports only? Or can this information be used to resolve those issues in smarter way? + */ + // localname2importprovider.markAmbigousImports(script) + + return reg; + } + + /** + * Registers conflicting or duplicate (based on imported elements) imports in the provided + * {@link RecordingImportState} + */ + private void registerUsedImportsDuplicatedImportedElements(RecordingImportState reg, + List>> module2imported) { + + for (Pair> pair : module2imported) { + List fromMod = pair.getValue(); + + // find duplicates in actual name, report them as duplicateImport + ArrayListMultimap name2Import = ArrayListMultimap.create(); + for (ImportProvidedElement ipe : fromMod) { + name2Import.put(ipe.getDuplicateImportUniqueName(), ipe); + } + + for (String name : name2Import.keySet()) { + List v = name2Import.get(name); + String actName = v.get(0).getExportedName(); + List x = toList(filter(v, internalIPE -> { + // filter out ImportProvidedElements that reflect Namespace element itself + ImportSpecifier specifier = internalIPE.getImportSpecifier(); + if (specifier instanceof NamespaceImportSpecifier) { + return !Objects.equals(internalIPE.getExportedName(), + computeNamespaceActualName((NamespaceImportSpecifier) specifier)); + } else { + return true; + } + })); + if (x.size() > 1) { + reg.registerDuplicateImportsOfSameElement(actName, pair.getKey(), x); + } + } + } + } + + /** + * Registers conflicting or duplicate (based on local name checks) imports in the provided + * {@link RecordingImportState} + */ + private void registerUsedImportsLocalNamesCollisions(RecordingImportState reg, + List>> localname2importprovider) { + for (Pair> pair : localname2importprovider) { + if (pair.getValue().size() > 1) { + reg.registerLocalNameCollision(pair.getKey(), pair.getValue()); + } + } + } + + /** + * analyzes provided {@link ImportDeclaration}s, if it finds *exact* duplicates, adds them to the + * {@link RecordingImportState#duplicatedImportDeclarations} + */ + private void registerDuplicatedImoprtDeclarationsFrom(RecordingImportState reg, + Iterable importDeclarations) { + Multimap nsisImports = LinkedHashMultimap.create(); + Multimap nisImports = LinkedHashMultimap.create(); + for (ImportDeclaration id : importDeclarations) { + if (findFirst(id.getImportSpecifiers(), is -> is instanceof NamespaceImportSpecifier) != null) { + nsisImports.put(id.getModule(), id); + } + if (findFirst(id.getImportSpecifiers(), is -> is instanceof NamedImportSpecifier) != null) { + nisImports.put(id.getModule(), id); + } + } + + for (TModule module : nsisImports.keySet()) { + registerImportDeclarationsWithNamespaceImportsForModule(nsisImports.get(module), reg); + } + + for (TModule module : nisImports.keySet()) { + registerImportDeclarationsWithNamedImportsForModule(nisImports.get(module), reg); + } + + // importDeclarations + // .filter[id| id.importSpecifiers.findFirst[is| is instanceof NamespaceImportSpecifier] !== null] + // .groupBy[module] + // .forEach[module, impDecls| + // registerImportDeclarationsWithNamespaceImportsForModule(impDecls, reg) + // ] + // + // for (ImportDeclaration id: importDeclarations ) { + // + // } + // importDeclarations + // .filter[id| id.importSpecifiers.findFirst[is| is instanceof NamedImportSpecifier] !== null] + // .groupBy[module] + // .forEach[module, impDecls| + // registerImportDeclarationsWithNamedImportsForModule(impDecls, reg) + // ] + } + + private void registerImportDeclarationsWithNamespaceImportsForModule( + Collection importDeclarations, + RecordingImportState reg) { + if (importDeclarations.size() < 2) { + return; + } + + List duplicates = new ArrayList<>(); + ImportDeclaration firstDeclaration = importDeclarations.iterator().next(); + String firstNamespaceName = head(filter(firstDeclaration.getImportSpecifiers(), NamespaceImportSpecifier.class)) + .getAlias(); + for (ImportDeclaration importDeclaration : tail(importDeclarations)) { + String followingNamespaceName = head( + filter(importDeclaration.getImportSpecifiers(), NamespaceImportSpecifier.class)).getAlias(); + if (Objects.equals(firstNamespaceName, followingNamespaceName)) { + duplicates.add(importDeclaration); + } + } + + if (!duplicates.isEmpty()) { + reg.registerDuplicatesOfImportDeclaration(firstDeclaration, duplicates); + } + } + + private void registerImportDeclarationsWithNamedImportsForModule(Collection importDeclarations, + RecordingImportState reg) { + if (importDeclarations.size() < 2) { + return; + } + + List duplicates = new ArrayList<>(); + ImportDeclaration firstDeclaration = importDeclarations.iterator().next(); + List firstDeclarationSpecifiers = toList( + filter(firstDeclaration.getImportSpecifiers(), NamedImportSpecifier.class)); + for (ImportDeclaration importDeclaration : tail(importDeclarations)) { + List followingDeclarationSpecifiers = toList( + filter(importDeclaration.getImportSpecifiers(), NamedImportSpecifier.class)); + if ((!firstDeclarationSpecifiers.isEmpty()) + && firstDeclarationSpecifiers.size() == followingDeclarationSpecifiers.size()) { + if (allFollowingMatchByNameAndAlias(firstDeclarationSpecifiers, followingDeclarationSpecifiers)) { + duplicates.add(importDeclaration); + } + } + } + + if (!duplicates.isEmpty()) { + reg.registerDuplicatesOfImportDeclaration(firstDeclaration, duplicates); + } + } + + private boolean allFollowingMatchByNameAndAlias(Iterable firstDeclarationSpecifiers, + Iterable followingDeclarationSpecifiers) { + + for (NamedImportSpecifier namedImportSpecifier : firstDeclarationSpecifiers) { + if (!exists(followingDeclarationSpecifiers, + otherNamedImportSpecifier -> Objects.equals(namedImportSpecifier.getAlias(), + otherNamedImportSpecifier.getAlias()) + && Objects.equals(namedImportSpecifier.getImportedElement().getName(), + otherNamedImportSpecifier.getImportedElement().getName()))) { + return false; + } + } + return true; + } + + /** + * Registers unused or broken (missing or unresolved imported module) import specifiers in the provided + * {@link RecordingImportState} + */ + private void registerUnusedAndBrokenImports(RecordingImportState reg, List importSpecifiers, + ASTMetaInfoCache astMetaInfoCache) { + for (ImportSpecifier is : importSpecifiers) { + // avoid duplicate error messages + if (!isNamedImportOfNonExportedElement(is, astMetaInfoCache) && !is.isFlaggedUsedInCode()) { + reg.registerUnusedImport(is); + if (isBrokenImport(is)) { + reg.registerBrokenImport(is); + } + } + } + } + + private static boolean isNamedImportOfNonExportedElement(ImportSpecifier importSpec, + ASTMetaInfoCache astMetaInfoCache) { + return astMetaInfoCache + .getLinkingIssueCodes(importSpec, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER__IMPORTED_ELEMENT) + .contains(IssueCodes.IMP_NOT_EXPORTED.name()); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportStateCalculator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportStateCalculator.xtend deleted file mode 100644 index 85aa1e7a16..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ImportStateCalculator.xtend +++ /dev/null @@ -1,243 +0,0 @@ -/** - * 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.tooling.organizeImports - -import com.google.common.collect.ArrayListMultimap -import com.google.inject.Inject -import java.util.List -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.ImportSpecifier -import org.eclipse.n4js.n4JS.N4JSPackage -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.postprocessing.ASTMetaInfoCache -import org.eclipse.n4js.resource.N4JSResource -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.utils.Log -import org.eclipse.n4js.validation.IssueCodes -import org.eclipse.n4js.validation.JavaScriptVariantHelper - -import static extension org.eclipse.n4js.tooling.organizeImports.ImportSpecifiersUtil.* -import static extension org.eclipse.n4js.tooling.organizeImports.ScriptDependencyResolver.* - -/** - * Analyzes all imports in a script. Builds up a data structure of {@link RecordingImportState} to capture the findings. - */ -@Log -class ImportStateCalculator { - - @Inject - private JavaScriptVariantHelper jsVariantHelper; - - /** - * Algorithm to check the Model for Issues with Imports. - * @returns {@link RecordingImportState} - */ - public def RecordingImportState calculateImportstate(Script script) { - val reg = new RecordingImportState(); - - val astMetaInfoCache = (script.eResource as N4JSResource).getASTMetaInfoCacheVerifyContext(); - - // Calculate Available - val importDeclarationsALL = script.scriptElements.filter(ImportDeclaration) - - reg.registerDuplicatedImoprtDeclarationsFrom(importDeclarationsALL) - - val importSpecifiersUnAnalyzed = importDeclarationsALL.filter[!reg.isDuplicatingImportDeclaration(it)].map[importSpecifiers].flatten.toList - -// markDuplicatingSpecifiersAsUnused(importSpecifiersUnAnalyzed) - - // collect all unused if stable - reg.registerUnusedAndBrokenImports(importSpecifiersUnAnalyzed, astMetaInfoCache) - - val List importProvidedElements = importSpecifiersUnAnalyzed.filter[!(reg.brokenImports.contains(it))].toList.mapToImportProvidedElements(jsVariantHelper) - - //refactor into specific types, those are essentially Maps holding elements in insertion order (keys and values) - val List>> lN2IPE = newArrayList() - val List>> lM2IPE = newArrayList() - - //TODO refactor this, those composed collections should be encapsulated as specific types with proper get/set methods - for (ipe : importProvidedElements) { - val pN2IPE = lN2IPE.findFirst[it.key == ipe.getCollisionUniqueName()]; - if(pN2IPE !== null){ - pN2IPE.value.add(ipe) - }else{ - lN2IPE.add(ipe.getCollisionUniqueName() -> newArrayList(ipe)) - } - val pM2IPE = lM2IPE.findFirst[it.key == ipe.importedModule]; - if(pM2IPE !== null){ - pM2IPE.value.add(ipe) - }else{ - lM2IPE.add(ipe.importedModule -> newArrayList(ipe)) - } - } - - reg.registerUsedImportsLocalNamesCollisions(lN2IPE) - - reg.registerUsedImportsDuplicatedImportedElements(lM2IPE) - - reg.registerAllUsedTypeNameToSpecifierTuples(importProvidedElements) - - - // usages in script: - val externalDep = script.usedDependenciesTypeRefs - - // mark used imports as seen in externalDep: - for( scriptDep : externalDep ) { - val mod = scriptDep.dependencyModule - val pM2IPE = lM2IPE.findFirst[it.key == mod] - if(pM2IPE !== null){ - pM2IPE.value.filter[it.exportedName == scriptDep.actualName && it.getLocalName() == scriptDep.localName ].forEach[ it.markUsed]; - } - } - -/*TODO review ambiguous imports - * looks like reference to type that is ambiguously imported can happen only if there are errors in the import declaratiosn, - * so should ignore those references and resolve issues in the imports only? - * Or can this information be used to resolve those issues in smarter way? - */ -// localname2importprovider.markAmbigousImports(script) - - - return reg; - } - - /** - * Registers conflicting or duplicate (based on imported elements) imports in the provided {@link RecordingImportState} - */ - private def registerUsedImportsDuplicatedImportedElements(RecordingImportState reg, List>> module2imported) { - for (pair : module2imported) { - val fromMod = pair.value - - // find duplicates in actual name, report them as duplicateImport - val name2Import = ArrayListMultimap.create - for (ipe : fromMod) - name2Import.put(ipe.getDuplicateImportUniqueName, ipe) - - for (name : name2Import.keySet) { - val v = name2Import.get(name).toList - val actName = v.head.exportedName; - val x = v.filter[internalIPE| - // filter out ImportProvidedElements that reflect Namespace element itself - val specifier = internalIPE.importSpecifier; - if(specifier instanceof NamespaceImportSpecifier){ - internalIPE.exportedName != computeNamespaceActualName(specifier) - }else{ - true - } - ].toList - if (x.size > 1) - reg.registerDuplicateImportsOfSameElement(actName, pair.key, x) - } - } - } - - /** - * Registers conflicting or duplicate (based on local name checks) imports in the provided {@link RecordingImportState} - */ - private def registerUsedImportsLocalNamesCollisions(RecordingImportState reg, List>> localname2importprovider) { - for(pair : localname2importprovider){ - if(pair.value.size>1){ - reg.registerLocalNameCollision(pair.key, pair.value) - } - } - } - - /** - * analyzes provided {@link ImportDeclaration}s, if it finds *exact* duplicates, adds them to the {@link RecordingImportState#duplicatedImportDeclarations} - */ - private def void registerDuplicatedImoprtDeclarationsFrom(RecordingImportState reg, Iterable importDeclarations) { - - importDeclarations - .filter[id| id.importSpecifiers.findFirst[is| is instanceof NamespaceImportSpecifier] !== null] - .groupBy[module] - .forEach[module, impDecls| - registerImportDeclarationsWithNamespaceImportsForModule(impDecls, reg) - ] - - importDeclarations - .filter[id| id.importSpecifiers.findFirst[is| is instanceof NamedImportSpecifier] !== null] - .groupBy[module] - .forEach[module, impDecls| - registerImportDeclarationsWithNamedImportsForModule(impDecls, reg) - ] - } - - private def void registerImportDeclarationsWithNamespaceImportsForModule(List importDeclarations, - RecordingImportState reg) { - if (importDeclarations.size < 2) - return; - - val duplicates = newArrayList - val firstDeclaration = importDeclarations.head - val firstNamespaceName = (firstDeclaration.importSpecifiers.filter(NamespaceImportSpecifier).head).alias - importDeclarations.tail.forEach [ importDeclaration | - val followingNamespaceName = importDeclaration.importSpecifiers.filter(NamespaceImportSpecifier).head.alias - if (firstNamespaceName == followingNamespaceName) - duplicates.add(importDeclaration) - ] - - if (!duplicates.empty) - reg.registerDuplicatesOfImportDeclaration(firstDeclaration, duplicates); - } - - private def void registerImportDeclarationsWithNamedImportsForModule(List importDeclarations, - RecordingImportState reg) { - if (importDeclarations.size < 2) - return; - - val duplicates = newArrayList - val firstDeclaration = importDeclarations.head - val firstDeclarationSpecifiers = firstDeclaration.importSpecifiers.filter(NamedImportSpecifier) - importDeclarations.tail.forEach [ importDeclaration | - val followingDeclarationSpecifiers = importDeclaration.importSpecifiers.filter(NamedImportSpecifier) - if ((!firstDeclarationSpecifiers.empty) && - firstDeclarationSpecifiers.size === followingDeclarationSpecifiers.size) { - if (firstDeclarationSpecifiers.allFollowingMatchByNameAndAlias(followingDeclarationSpecifiers)) - duplicates.add(importDeclaration) - } - ] - - if (!duplicates.empty) - reg.registerDuplicatesOfImportDeclaration(firstDeclaration, duplicates); - } - - private def boolean allFollowingMatchByNameAndAlias(Iterable firstDeclarationSpecifiers, - Iterable followingDeclarationSpecifiers) { - - firstDeclarationSpecifiers.forall [ namedImportSpecifier | - followingDeclarationSpecifiers.exists [ otherNamedImportSpecifier | - namedImportSpecifier.alias == otherNamedImportSpecifier.alias && - namedImportSpecifier.importedElement.name == otherNamedImportSpecifier.importedElement.name - ] - ] - } - - /** - * Registers unused or broken (missing or unresolved imported module) import specifiers in the provided {@link RecordingImportState} - */ - private def void registerUnusedAndBrokenImports(RecordingImportState reg, List importSpecifiers, ASTMetaInfoCache astMetaInfoCache) { - for (is : importSpecifiers) { - if (!isNamedImportOfNonExportedElement(is, astMetaInfoCache) // avoid duplicate error messages - && !is.isFlaggedUsedInCode) { - reg.registerUnusedImport(is); - if (is.isBrokenImport) - reg.registerBrokenImport(is); - } - } - } - - private static def boolean isNamedImportOfNonExportedElement(ImportSpecifier importSpec, ASTMetaInfoCache astMetaInfoCache) { - return astMetaInfoCache.getLinkingIssueCodes(importSpec, N4JSPackage.Literals.NAMED_IMPORT_SPECIFIER__IMPORTED_ELEMENT) - .contains(IssueCodes.IMP_NOT_EXPORTED.name()); - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/InjectedTypesResolverUtility.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/InjectedTypesResolverUtility.java new file mode 100644 index 0000000000..45c5e46f3a --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/InjectedTypesResolverUtility.java @@ -0,0 +1,146 @@ +/** + * 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.tooling.organizeImports; + +import static org.eclipse.n4js.AnnotationDefinition.BIND; +import static org.eclipse.n4js.AnnotationDefinition.BINDER; +import static org.eclipse.n4js.AnnotationDefinition.GENERATE_INJECTOR; +import static org.eclipse.n4js.AnnotationDefinition.INJECT; +import static org.eclipse.n4js.AnnotationDefinition.PROVIDES; +import static org.eclipse.n4js.AnnotationDefinition.USE_BINDER; +import static org.eclipse.n4js.AnnotationDefinition.WITH_PARENT_INJECTOR; +import static org.eclipse.n4js.tooling.organizeImports.DIUtility.getProvidedType; +import static org.eclipse.n4js.tooling.organizeImports.DIUtility.isProviderType; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filterNull; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.last; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.toIterable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.n4js.n4JS.Annotation; +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.n4JS.N4ClassifierDefinition; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4MethodDeclaration; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.n4JS.TypeRefAnnotationArgument; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.Type; + +/** + * Utility for computing dependencies for N4JS DI mechanisms. + */ +public class InjectedTypesResolverUtility { + + /** + * Search through {@link Script} to find all {@link N4ClassifierDefinition}s. From found entries builds collection + * of {@link Type}s used with DI annotations. + */ + public static List findAllInjected(Script script) { + List injections = new ArrayList<>(); + + for (N4ClassifierDefinition cl : toIterable(filter(script.eAllContents(), N4ClassifierDefinition.class))) { + + // If has owned injected ctor with formal params, then use params types + for (TFormalParameter fp : getOwnedInjectedCtorParams(cl)) { + injections.add(getDeclaredTypeFromTypeRef(fp.getTypeRef())); + } + + // Injected fields. + for (N4FieldDeclaration fd : cl.getOwnedFields()) { + if (INJECT.hasAnnotation(fd)) { + injections.add(getDeclaredTypeFromTypeRef(fd.getDeclaredTypeRef())); + } + } + + // Binder specific + if (BINDER.hasOwnedAnnotation(cl)) { + // Binder's @Bind dependencies. + for (Annotation an : BIND.getAllOwnedAnnotations(cl)) { + // Since bind has only two arguments, both are TypeRefs. + injections.add(getDeclaredTypeFromTypeRef((TypeRef) an.getArgs().get(0).value())); + injections.add(getDeclaredTypeFromTypeRef((TypeRef) last(an.getArgs()).value())); + } + + // Binder's @Provides dependencies. + for (N4MethodDeclaration m : cl.getOwnedMethods()) { + if (PROVIDES.hasAnnotation(m)) { + injections.add(getDeclaredTypeFromTypeRef(m.getDeclaredReturnTypeRef())); + + for (FormalParameter fp : m.getFpars()) { + injections.add(getDeclaredTypeFromTypeRef(fp.getDeclaredTypeRef())); + } + } + } + } + + // DIComponent specific + if (GENERATE_INJECTOR.hasOwnedAnnotation(cl)) { + if (WITH_PARENT_INJECTOR.hasOwnedAnnotation(cl)) { + var ann = WITH_PARENT_INJECTOR.getOwnedAnnotation(cl); + if (ann != null) { + injections + .add(((TypeRefAnnotationArgument) ann.getArgs().get(0)).getTypeRef().getDeclaredType()); + } + } + + if (USE_BINDER.hasOwnedAnnotation(cl)) { + Iterable anns = USE_BINDER.getAllOwnedAnnotations(cl); + if (anns != null) { + var argsTypes = map( + filterNull(map(anns, a -> ((TypeRefAnnotationArgument) a.getArgs().get(0)))), + arg -> arg.getTypeRef().getDeclaredType()); + + for (Type at : argsTypes) { + injections.add(at); + } + } + } + } + } + return toList(filterNull(injections)); + } + + private static List getOwnedInjectedCtorParams(N4ClassifierDefinition cd) { + if (cd != null && cd.getDefinedType() instanceof TClass) { + TMethod ctor = ((TClass) cd.getDefinedType()).getOwnedCtor(); + if (null != ctor) { + if (INJECT.hasAnnotation(ctor)) + return ctor.getFpars(); + } + } + return Collections.emptyList(); + } + + /** + * resolves declared type from type ref. If declared type is N4Provider (can be nested) resolves to (nested) + * provided type. + */ + private static Type getDeclaredTypeFromTypeRef(TypeRef typeRef) { + if (isProviderType(typeRef)) { + Type providedType = getProvidedType(typeRef); + if (null != providedType) { + return providedType; + } + } else { + return typeRef.getDeclaredType(); + } + return null; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/InjectedTypesResolverUtility.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/InjectedTypesResolverUtility.xtend deleted file mode 100644 index 974eb29826..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/InjectedTypesResolverUtility.xtend +++ /dev/null @@ -1,114 +0,0 @@ -/** - * 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.tooling.organizeImports - -import java.util.Collection -import org.eclipse.n4js.n4JS.N4ClassifierDefinition -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.n4JS.TypeRefAnnotationArgument -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.Type - -import static org.eclipse.n4js.AnnotationDefinition.* - -import static extension org.eclipse.n4js.tooling.organizeImports.DIUtility.* - -/** - * Utility for computing dependencies for N4JS DI mechanisms. - */ -class InjectedTypesResolverUtility { - - /** - * Search through {@link Script} to find all {@link N4ClassifierDefinition}s. - * From found entries builds collection of {@link Type}s used with DI annotations. - */ - public static def Collection findAllInjected(Script script) { - val injections = newArrayList; - - script.eAllContents.filter(N4ClassifierDefinition).forEach [ cl | - - // If has owned injected ctor with formal params, then use params types - cl.getOwnedInjectedCtorParams.forEach[ - injections.add(getDeclaredTypeFromTypeRef(it.typeRef)) - ]; - // Injected fields. - cl.ownedFields.forEach [ f | - if (INJECT.hasAnnotation(f)) { - injections.add(getDeclaredTypeFromTypeRef(f.declaredTypeRef)); - } - ] - - //Binder specific - if(BINDER.hasOwnedAnnotation(cl)){ - // Binder's @Bind dependencies. - BIND.getAllOwnedAnnotations(cl).forEach [ an | - // Since bind has only two arguments, both are TypeRefs. - injections.add(getDeclaredTypeFromTypeRef(an.args.head.value as TypeRef)); - injections.add(getDeclaredTypeFromTypeRef(an.args.last.value as TypeRef)); - ] - - // Binder's @Provides dependencies. - cl.ownedMethods.forEach [ m | - if (PROVIDES.hasAnnotation(m)) { - injections.add(getDeclaredTypeFromTypeRef(m.declaredReturnTypeRef)); - m.fpars.forEach[injections.add(getDeclaredTypeFromTypeRef(it.declaredTypeRef))]; - } - ]; - } - - //DIComponent specific - if(GENERATE_INJECTOR.hasOwnedAnnotation(cl)){ - if(WITH_PARENT_INJECTOR.hasOwnedAnnotation(cl)){ - var ann = WITH_PARENT_INJECTOR.getOwnedAnnotation(cl) - if(ann !== null){ - injections.add((ann.args.head as TypeRefAnnotationArgument).typeRef.declaredType) - } - } - - if(USE_BINDER.hasOwnedAnnotation(cl)){ - var anns = USE_BINDER.getAllOwnedAnnotations(cl) - if(anns !== null){ - var argsTypes = anns.map[(args.head as TypeRefAnnotationArgument)].filterNull.map[typeRef.declaredType]; - argsTypes.forEach[injections.add(it)]; - } - } - } - - ]; - return injections.filterNull.toList; - } - - private static def getOwnedInjectedCtorParams(N4ClassifierDefinition it) { - if (it?.definedType instanceof TClass) { - val ctor = (definedType as TClass).ownedCtor; - if (null !== ctor) { - if (INJECT.hasAnnotation(ctor)) return ctor.fpars; - } - } - return emptyList; - } - - /** - * resolves declared type from type ref. If declared type is - * N4Provider (can be nested) resolves to (nested) provided type. - */ - private static def getDeclaredTypeFromTypeRef(TypeRef typeRef) { - if (typeRef.providerType) { - val providedType = typeRef.providedType; - if (null !== providedType) { - return providedType; - } - } else { - typeRef.declaredType; - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RecordingImportState.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RecordingImportState.java new file mode 100644 index 0000000000..765c95191b --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RecordingImportState.java @@ -0,0 +1,176 @@ +/** + * 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.tooling.organizeImports; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.xtext.xbase.lib.Pair; + +/** + * Register holding results of analyzing {@link ImportDeclaration}s and contained {@link ImportSpecifier}s. + */ +@SuppressWarnings("javadoc") +public class RecordingImportState { + + public List>> duplicatedImportDeclarations = new ArrayList<>(); + + public List unusedImports = new ArrayList<>(); + public List brokenImports = new ArrayList<>(); + + /* TODO refactor nested collections into specialized types */ + public List, List>> duplicateImportsOfSameElement = new ArrayList<>(); + public List>> localNameCollision = new ArrayList<>(); + + public List allUsedTypeNameToSpecifierTuples = new ArrayList<>(); + + public void registerDuplicatesOfImportDeclaration(ImportDeclaration declaration, + List duplicates) { + duplicatedImportDeclarations.add(Pair.of(declaration, duplicates)); + } + + public boolean isDuplicatingImportDeclaration(ImportDeclaration importDeclaration) { + return exists(duplicatedImportDeclarations, + dupePair -> dupePair.getKey().getModule() == importDeclaration.getModule() && + dupePair.getValue().contains(importDeclaration)); + } + + public void registerUnusedImport(ImportSpecifier specifier) { + unusedImports.add(specifier); + } + + public void registerBrokenImport(ImportSpecifier specifier) { + brokenImports.add(specifier); + } + + /** + * Removes any information stored in the register. + */ + public void cleanup() { + // clean own + unusedImports.clear(); + brokenImports.clear(); + allUsedTypeNameToSpecifierTuples.clear(); + + localNameCollision.clear(); + duplicatedImportDeclarations.clear(); + duplicateImportsOfSameElement.clear(); + + // cut ref: + allUsedTypeNameToSpecifierTuples = null; + } + + public void registerAllUsedTypeNameToSpecifierTuples(List pairs) { + allUsedTypeNameToSpecifierTuples = pairs; + } + + // remove all known unused imports from the passed in list. + public void removeDuplicatedImportsOfSameelement(List declarations, Adapter nodelessMarker) { + for (Pair, List> e : duplicateImportsOfSameElement) { + for (ImportProvidedElement e2 : e.getValue()) { + List l = new ArrayList<>(); + l.add(e2.getImportSpecifier()); + removeFrom(l, declarations, nodelessMarker); + } + } + } + + public void removeLocalNameCollisions(List declarations, Adapter nodelessMarker) { + for (Pair> e : localNameCollision) { + for (ImportProvidedElement e2 : e.getValue()) { + List l = new ArrayList<>(); + l.add(e2.getImportSpecifier()); + removeFrom(l, declarations, nodelessMarker); + } + } + } + + public void removeDuplicatedImportDeclarations(List declarations) { + for (Pair> decl2dupes : duplicatedImportDeclarations) { + declarations.removeAll(decl2dupes.getValue()); + } + } + + public void removeUnusedImports(List declarations, Adapter nodelessMarker) { + removeFrom(unusedImports, declarations, nodelessMarker); + } + + public void removeBrokenImports(List declarations, Adapter nodelessMarker) { + removeFrom(brokenImports, declarations, nodelessMarker); + } + + private void removeFrom(List tobeRemoved, List declarations, + Adapter nodelessMarker) { + + // remove from declarations + for (ImportSpecifier it : tobeRemoved) { + if (it instanceof NamespaceImportSpecifier) { + declarations.remove(it.eContainer()); + + } else if (it instanceof NamedImportSpecifier) { + ImportDeclaration imp = (ImportDeclaration) it.eContainer(); + if (imp != null) { + if (imp.getImportSpecifiers() != null) { + imp.getImportSpecifiers().remove(it); + // mark as modified to rebuild whole node. + imp.eAdapters().add(nodelessMarker); + } + if (imp.getImportSpecifiers() == null || imp.getImportSpecifiers().isEmpty()) { + declarations.remove(imp); + } + } + } + } + } + + /** + * Returns set of names, for which there are broken import specifiers. Happens after broken imports are removed, + * which makes name (usually IdRef/TypeRef) refer to ImportSpecifier, which is being removed from document. + * Providing list of broken names, allows organize imports to fix those. + */ + public Set calcRemovedImportedNames() { + Set ret = new HashSet<>(); + for (ImportProvidedElement e : allUsedTypeNameToSpecifierTuples) { + if (e.isUsed() && e.getImportSpecifier().eContainer() == null) { + ret.add(e.getLocalName()); + } + } + return ret; + } + + public void registerDuplicateImportsOfSameElement(String name, TModule module, + List elements) { + duplicateImportsOfSameElement.add(Pair.of(Pair.of(name, module), elements)); + } + + public void registerLocalNameCollision(String string, List elements) { + Pair> key = findFirst(localNameCollision, + it -> Objects.equals(it.getKey(), string)); + if (key != null) { + key.getValue().addAll(elements); + } else { + localNameCollision.add(Pair.of(string, elements)); + } + } + +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RecordingImportState.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RecordingImportState.xtend deleted file mode 100644 index 7a5334426a..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RecordingImportState.xtend +++ /dev/null @@ -1,161 +0,0 @@ -/** - * 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.tooling.organizeImports - -import java.util.List -import java.util.Set -import org.eclipse.emf.common.notify.Adapter -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.ImportSpecifier -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.ts.types.TModule - -/** - * Register holding results of analyzing {@link ImportDeclaration}s - * and contained {@link ImportSpecifier}s. - */ -class RecordingImportState { - - public List>> duplicatedImportDeclarations = newArrayList(); - - public List unusedImports = newArrayList(); - public List brokenImports = newArrayList(); - - /*TODO refactor nested collections into specialized types */ - public List, List>> duplicateImportsOfSameElement = newArrayList(); - public List>> localNameCollision = newArrayList(); - - public List allUsedTypeNameToSpecifierTuples = newArrayList(); - - def registerDuplicatesOfImportDeclaration(ImportDeclaration declaration, List duplicates) { - duplicatedImportDeclarations.add(declaration -> duplicates); - } - - def boolean isDuplicatingImportDeclaration(ImportDeclaration importDeclaration){ - duplicatedImportDeclarations.exists[dupePair| - dupePair.key.module === importDeclaration.module && - dupePair.value.contains(importDeclaration) - ] - } - - def registerUnusedImport(ImportSpecifier specifier) { - unusedImports.add(specifier); - } - - def registerBrokenImport(ImportSpecifier specifier) { - brokenImports.add(specifier); - } - - /** - * Removes any information stored in the register. - */ - def cleanup() { - - // clean own - #[unusedImports, brokenImports, allUsedTypeNameToSpecifierTuples].forEach[clear] - - localNameCollision.clear - duplicatedImportDeclarations.clear - duplicateImportsOfSameElement.clear - - // cut ref: - allUsedTypeNameToSpecifierTuples = null; - } - - def registerAllUsedTypeNameToSpecifierTuples(List pairs) { - allUsedTypeNameToSpecifierTuples = pairs - } - - // remove all known unused imports from the passed in list. - def removeDuplicatedImportsOfSameelement(List declarations, Adapter nodelessMarker ) { - duplicateImportsOfSameElement.forEach[e| - e.value.forEach[e2| - newArrayList(e2.importSpecifier).removeFrom(declarations, nodelessMarker) - ] - ] - } - - def removeLocalNameCollisions(List declarations, Adapter nodelessMarker ) { - localNameCollision.forEach[e| - e.value.forEach[e2| - newArrayList(e2.importSpecifier).removeFrom(declarations, nodelessMarker) - ] - ] - return - } - - def removeDuplicatedImportDeclarations(List declarations) { - duplicatedImportDeclarations.forEach[decl2dupes| - declarations.removeAll(decl2dupes.value) - ] - } - - def removeUnusedImports(List declarations, Adapter nodelessMarker ) { - unusedImports.removeFrom(declarations, nodelessMarker) - } - - def removeBrokenImports(List declarations, Adapter nodelessMarker ) { - brokenImports.removeFrom(declarations, nodelessMarker ) - } - - private def removeFrom(List tobeRemoved, List declarations, Adapter nodelessMarker ) { - //remove from declarations - tobeRemoved.forEach [ - switch (it) { - NamespaceImportSpecifier: - declarations.remove(it.eContainer) - NamedImportSpecifier: { - val imp = it.eContainer as ImportDeclaration - if (imp !== null) { - if (imp.importSpecifiers !== null) { - imp.importSpecifiers.remove(it); - // mark as modified to rebuild whole node. - imp.eAdapters.add(nodelessMarker) - } - if (imp.importSpecifiers === null || imp.importSpecifiers.empty) { - declarations.remove(imp) - } - } - } - } - ] - } - - /** - * Returns set of names, for which there are broken import specifiers. Happens after broken - * imports are removed, which makes name (usually IdRef/TypeRef) refer to ImportSpecifier, which - * is being removed from document. Providing list of broken names, allows organize imports to fix those. - */ - def Set calcRemovedImportedNames() { - var ret = newHashSet() - for (e : allUsedTypeNameToSpecifierTuples) { - if (e.used && e.importSpecifier.eContainer === null) { - ret.add(e.getLocalName()) - } - } - return ret - } - - def registerDuplicateImportsOfSameElement(String name, TModule module, List elements) { - duplicateImportsOfSameElement.add((name->module)->elements); - } - - def registerLocalNameCollision(String string, List elements) { - val key = localNameCollision.findFirst[it.key == string]; - if(key !== null){ - key.value.addAll(elements) - }else{ - localNameCollision.add(string -> elements.toList) - } - } - -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RefNameUtil.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RefNameUtil.java new file mode 100644 index 0000000000..5c47b39bfd --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RefNameUtil.java @@ -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.tooling.organizeImports; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.join; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; + +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.types.TypingStrategy; +import org.eclipse.xtext.nodemodel.ICompositeNode; +import org.eclipse.xtext.nodemodel.util.NodeModelUtils; + +/** + * Utility to find actual name that was used for given reference. + */ +class RefNameUtil { + + /** + * Finds name that is used as identifier. + */ + public static String findIdentifierName(IdentifierRef ref) { + return join(map(filter(NodeModelUtils.findActualNodeFor(ref).getLeafNodes(), n -> !n.isHidden()), + n -> n.getText())); + } + + /** + * Finds the name in the ParameterizedTypeRef. + * + * @return null if no connection to AST + */ + public static String findTypeName(ParameterizedTypeRef ref) { + ICompositeNode astNode = NodeModelUtils.findActualNodeFor(ref); + if (astNode != null) { + int prefixLen = 0; + int suffixLen = 0; + String nodeText = join(map(filter(astNode.getLeafNodes(), n -> !n.isHidden()), n -> n.getText())); + + if (!ref.getDefinedTypingStrategy().equals(TypingStrategy.NOMINAL)) { + String typingLiteral = ref.getDefinedTypingStrategy().getLiteral(); + if (nodeText.startsWith(typingLiteral)) { + // handle things like + // foo2 : ~r~ /* ~r~ */ A + // nodeText does not contain whitespace or comments, so it is like + // ~r~A + // drop typing strategy literal value and return just + // A + prefixLen = ref.getDefinedTypingStrategy().getLiteral().length(); + } + } + + // handle A? + if (ref.isFollowedByQuestionMark() && nodeText.endsWith("?")) { + suffixLen = 1; + } + + // handle A+ + if (ref.isDynamic() && nodeText.endsWith("+")) { + suffixLen = 1; + } + + return nodeText.substring(prefixLen, nodeText.length() - suffixLen); + } else { + return null; + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RefNameUtil.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RefNameUtil.xtend deleted file mode 100644 index 0d7de932a5..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/RefNameUtil.xtend +++ /dev/null @@ -1,68 +0,0 @@ -/** - * 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.tooling.organizeImports - -import org.eclipse.n4js.n4JS.IdentifierRef -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.types.TypingStrategy -import org.eclipse.xtext.nodemodel.util.NodeModelUtils - -/** - * Utility to find actual name that was used for given reference. - */ -class RefNameUtil { - /** - * Finds name that is used as identifier. - */ - def public static String findIdentifierName(IdentifierRef ref) { - NodeModelUtils.findActualNodeFor(ref).leafNodes.filter[!hidden].map[text].join - } - - /** - * Finds the name in the ParameterizedTypeRef. - * @return null if no connection to AST - */ - def public static String findTypeName(ParameterizedTypeRef ref) { - val astNode = NodeModelUtils.findActualNodeFor(ref) - if (astNode !== null) { - var prefixLen = 0 - var suffixLen = 0 - val nodeText = astNode.leafNodes.filter[!hidden].map[text].join - - if(!ref.definedTypingStrategy.equals(TypingStrategy.NOMINAL)){ - val typingLiteral = ref.definedTypingStrategy.literal - if(nodeText.startsWith(typingLiteral)){ - // handle things like - // foo2 : ~r~ /* ~r~ */ A - // nodeText does not contain whitespace or comments, so it is like - // ~r~A - // drop typing strategy literal value and return just - // A - prefixLen = ref.definedTypingStrategy.literal.length - } - } - - // handle A? - if(ref.isFollowedByQuestionMark && nodeText.endsWith('?')) { - suffixLen = 1; - } - - //handle A+ - if(ref.dynamic && nodeText.endsWith('+')) { - suffixLen = 1; - } - - return nodeText.substring(prefixLen, nodeText.length - suffixLen) - } else { - null - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ScriptDependencyResolver.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ScriptDependencyResolver.java new file mode 100644 index 0000000000..100e9c0f06 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ScriptDependencyResolver.java @@ -0,0 +1,423 @@ +/** + * 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.tooling.organizeImports; + +import static org.eclipse.n4js.tooling.organizeImports.InjectedTypesResolverUtility.findAllInjected; +import static org.eclipse.n4js.tooling.organizeImports.RefNameUtil.findTypeName; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filterNull; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.isNullOrEmpty; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toMap; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.toInvertedMap; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.toList; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.function.Function; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.n4JS.AnnotableElement; +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration; +import org.eclipse.n4js.n4JS.N4TypeDeclaration; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType; +import org.eclipse.n4js.ts.types.TAnnotableElement; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TDynamicElement; +import org.eclipse.n4js.ts.types.TExportableElement; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TInterface; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.TVariable; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.utils.ResourceType; +import org.eclipse.xtext.EcoreUtil2; + +/** + * Static analysis for {@link Script} dependencies. Analyzes all identifiers in the {@link Script}, and on (on demand) + * {@link Type}s or {@link TypeRef}s. During analysis identifiers from {@link NamedImportSpecifier} and + * {@link NamespaceImportSpecifier} are taken into account. Note that if result analysis does not contain descriptions + * matching some of the imports, it means those imports are not used, and can be removed from script, or ignored during + * compilation. + * + * Result of analysis is list of {@link ScriptDependency} instances describing what {@link EObject}s should be imported. + *
    + * Note: + *
  • declarations marked with "@ProvidedByRuntime" are ignored (they are never in the result)
  • + *
  • declarations marked with "@Global" are not ignored (can show up in the result)
  • + *
+ */ +@SuppressWarnings("unused") +public class ScriptDependencyResolver { + + /** + * Resolves dependencies only from {@link IdentifierRef}s, no {@link Type}s or {@link TypeRef}s are taken into + * account. + */ + public static List usedDependencies(Script script) { + if (null == script) { + return Collections.emptyList(); + } + return allRequiredExternalDeclaration(script, Collections.emptySet(), Collections.emptySet()); + } + + /** + * Resolves dependencies from {@link IdentifierRef}s and {@link Type}s that are injected into local type + * declarations. + */ + public static List usedDependenciesWithInejctedTypes(Script script) { + if (null == script) { + return Collections.emptyList(); + } + return allRequiredExternalDeclaration(script, findAllInjected(script), Collections.emptySet()); + } + + /** + * Resolves dependencies from {@link IdentifierRef}s and all {@link TypeRef}s. + */ + public static List usedDependenciesTypeRefs(Script script) { + if (null == script) { + return Collections.emptyList(); + } + return allRequiredExternalDeclaration(script, Collections.emptySet(), + toList(filter(script.eAllContents(), TypeRef.class))); + } + + /** + * Looks through all {@link IdentifierRef} for external dependencies (from different module than currently analyzed + * script containing module). Additionally looks through all types used as super types and implemented interfaces. + * Not used types (see {@link #shouldBeImported}) are removed from external dependencies. + * + * @param script + * to be analyzed + * @param typesToBeIncluded + * force specific collection of {@link Type}s to be considered for as dependencies + * @param typeRefsToBeIncluded + * force specific collection of {@link TypeRef}s to be considered for as dependencies + */ + private static List allRequiredExternalDeclaration(Script script, + Collection typesToBeIncluded, + Collection typeRefsToBeIncluded) { + + List indirectlyImported = toList(filter(script.eAllContents(), N4TypeDeclaration.class)); + List identifierRefs = toList(filter(script.eAllContents(), IdentifierRef.class)); + + List potentialDependencies = new ArrayList<>(); + potentialDependencies.addAll(indirectlyImported); + potentialDependencies.addAll(identifierRefs); + potentialDependencies.addAll(typesToBeIncluded); + potentialDependencies.addAll(typeRefsToBeIncluded); + + List namedImportSpecifiers = toList( + filter(filter(script.eAllContents(), NamedImportSpecifier.class), + nis -> nis.getImportedElement() != null)); + Map usedNamespaceSpecifiers = toInvertedMap( + filter(script.eAllContents(), NamespaceImportSpecifier.class), x -> false); + + TModule baseModule = script.getModule(); + + Set sortedDeps = new TreeSet<>(Comparator.comparing(dep -> dep.localName)); + for (EObject eo : potentialDependencies) { + Map nisByName = toMap(namedImportSpecifiers, + nis -> nis.getImportedElement().getName()); + + Iterable deps = handle(eo, nisByName, usedNamespaceSpecifiers, + eo2 -> shouldBeImported(baseModule, eo2)); + + for (ScriptDependency dep : deps) { + if (dep != null) { + sortedDeps.add(dep); + } + } + } + + return new ArrayList<>(sortedDeps); + } + + /** + * Checks if a given EObject should be imported. + * + *
    + * Evaluates to true if: + *
  • provided EO is not from the module provided at creation time (that module is assumed to be one for which we + * analyze dependencies)
  • + *
  • provided EO is not from built in types
  • + *
  • (in case of AST elements) is not annotated with {@link AnnotationDefinition#PROVIDED_BY_RUNTIME}
  • + *
  • (in case of TS elements) providedByRuntime evaluates to false
  • + *
+ * + * @returns true if given EO should be imported + */ + public static boolean shouldBeImported(TModule baseModule, EObject eo) { + if (eo instanceof ModuleNamespaceVirtualType + || eo instanceof TDynamicElement) { + return true; + } + + EObject containingModule = EcoreUtil.getRootContainer(eo); + if (containingModule instanceof TModule) { + if (AnnotationDefinition.PROVIDED_BY_RUNTIME.hasAnnotation((TModule) containingModule) + || (ResourceType.getResourceType(containingModule) == ResourceType.DTS + && AnnotationDefinition.GLOBAL.hasAnnotation((TModule) containingModule))) { + return false; + } + } + + if (eo instanceof AnnotableElement) { + if (AnnotationDefinition.PROVIDED_BY_RUNTIME.hasAnnotation((AnnotableElement) eo)) { + return false; + } + } else if (eo instanceof TAnnotableElement) { + if (AnnotationDefinition.PROVIDED_BY_RUNTIME.hasAnnotation((TAnnotableElement) eo)) { + return false; + } else if (eo instanceof Type) { + // TODO is this dead code + if (((Type) eo).isProvidedByRuntime()) { + return false; + } + } else if (eo instanceof TVariable) { + // TODO is this dead code + if (((TVariable) eo).isProvidedByRuntime()) { + return false; + } + } + } + + // ignore built-in things as n4scheme:/console.n4jsd: + // in non platform realm check if URI describes file, + // in eclipse platform realm check if URI describes platform resource + Resource res = eo.eResource(); + return res != null && res.getURI() != null // + && ((res.getURI().isFile() || res.getURI().isPlatformResource())) // + // and check if modules/files are different + && (!res.getURI().toString().equals(baseModule.eResource().getURI().toString())); + } + + private static boolean isNamespaceDependencyHandlingNeeded( + Map usedNamespaceSpecifiers, TModule targMod) { + + return exists(usedNamespaceSpecifiers.keySet(), + is -> ((ImportDeclaration) is.eContainer()).getModule() == targMod); + } + + private static ScriptDependency createScriptDependency(Type type, + Map nameToNamedImportSpecifiers, + Map usedNamespaceSpecifiers) { + if (nameToNamedImportSpecifiers.containsKey(type.getName())) { + NamedImportSpecifier nis = nameToNamedImportSpecifiers.get(type.getName()); + TExportableElement identifiableElement = nis.getImportedElement(); + TModule module = EcoreUtil2.getContainerOfType(identifiableElement, TModule.class); + return new ScriptDependency(nis.getAlias() != null ? nis.getAlias() : identifiableElement.getName(), + identifiableElement.getName(), identifiableElement, module); + } else if (isNamespaceDependencyHandlingNeeded(usedNamespaceSpecifiers, type.getContainingModule())) { + return createDependencyOnNamespace(usedNamespaceSpecifiers, type.getContainingModule()); + } else { + // add dependency, looks like something that is @Global but not @ProvidedByRuntime + return new ScriptDependency(type.getName(), type.getName(), type, type.getContainingModule()); + } + } + + private static ScriptDependency createDependencyOnNamespace( + Map usedNamespaceSpecifiers, TModule targMod) { + NamespaceImportSpecifier is = findFirst(usedNamespaceSpecifiers.keySet(), + nis -> ((ImportDeclaration) nis.eContainer()).getModule() == targMod); + boolean used = usedNamespaceSpecifiers.get(is); + if (!used) { + // add dependency on the namespace + usedNamespaceSpecifiers.put(is, true); + return new ScriptDependency(is.getAlias(), + // For namespace imports, the actual name is intentionally null. + null, + // For namespace imports, this is ModuleNamespaceVirtualType, but intentionally null + null, + targMod); + } else { + // namespace was already used + return null; + } + } + + private static Iterable handle(EObject tClass, + Map nameToNamedImportSpecifiers, + Map usedNamespaceSpecifiers, Function compare) { + if (tClass instanceof TClass + && compare != null) { + return handle((TClass) tClass, nameToNamedImportSpecifiers, usedNamespaceSpecifiers, compare); + } else if (tClass instanceof TInterface + && compare != null) { + return handle((TInterface) tClass, nameToNamedImportSpecifiers, usedNamespaceSpecifiers, compare); + } else if (tClass instanceof N4ClassDeclaration + && compare != null) { + return handle((N4ClassDeclaration) tClass, nameToNamedImportSpecifiers, usedNamespaceSpecifiers, compare); + } else if (tClass instanceof N4InterfaceDeclaration + && compare != null) { + return handle((N4InterfaceDeclaration) tClass, nameToNamedImportSpecifiers, usedNamespaceSpecifiers, + compare); + } else if (tClass instanceof TFunction + && compare != null) { + return handle((TFunction) tClass, nameToNamedImportSpecifiers, usedNamespaceSpecifiers, compare); + } else if (tClass instanceof ParameterizedTypeRef + && compare != null) { + return handle((ParameterizedTypeRef) tClass, nameToNamedImportSpecifiers, usedNamespaceSpecifiers, compare); + } else if (tClass instanceof IdentifierRef + && compare != null) { + return handle((IdentifierRef) tClass, nameToNamedImportSpecifiers, usedNamespaceSpecifiers, compare); + } else if (tClass instanceof TypeRef + && compare != null) { + return handle((TypeRef) tClass, nameToNamedImportSpecifiers, usedNamespaceSpecifiers, compare); + } + return new ArrayList<>(); + } + + private static Iterable handle(TypeRef eo, + Map nameToNamedImportSpecifiers, + Map usedNamespaceSpecifiers, Function compare) { + + return new ArrayList<>(); + } + + private static Iterable handle(Void eo, + Map nameToNamedImportSpecifiers, + Map usedNamespaceSpecifiers, Function compare) { + + return new ArrayList<>(); + } + + private static Iterable handle(TFunction tFunction, + Map nameToNamedImportSpecifiers, + Map usedNamespaceSpecifiers, Function compare) { + // TODO is there nothing to do? + + return new ArrayList<>(); + } + + private static Iterable handle(N4ClassDeclaration eo, + Map nameToNamedImportSpecifiers, + Map usedNamespaceSpecifiers, Function compare) { + + EObject tClass = eo.getDefinedType(); + return handle(tClass, nameToNamedImportSpecifiers, usedNamespaceSpecifiers, compare); + } + + private static Iterable handle(N4InterfaceDeclaration eo, + Map nameToNamedImportSpecifiers, + Map usedNamespaceSpecifiers, Function compare) { + + EObject tInterface = eo.getDefinedType(); + return handle(tInterface, nameToNamedImportSpecifiers, usedNamespaceSpecifiers, compare); + } + + private static Iterable handle(ParameterizedTypeRef eo, + Map nameToNamedImportSpecifiers, + Map usedNamespaceSpecifiers, Function compare) { + + // added check for container instance, as polyfill tests were crashing when + // eo.declared type was TVariable and its container TClass + if (eo.getDeclaredType() != null && eo.getDeclaredType().eContainer() instanceof TModule && + compare.apply(eo.getDeclaredType())) { + String typeName = findTypeName(eo); + if (typeName != null) { // null means not typed in script (e.g. TypesComputer)-> no import necessary + TModule module = EcoreUtil2.getContainerOfType(eo.getDeclaredType(), TModule.class); + return List.of( + new ScriptDependency(typeName, eo.getDeclaredType().getName(), eo.getDeclaredType(), module)); + } + } + return new ArrayList<>(); + } + + /** + * Resolves dependency from identifier reference. + */ + private static Iterable handle(IdentifierRef idRef, + Map nameToNamedImportSpecifiers, + Map usedNamespaceSpecifiers, Function compare) { + + IdentifiableElement targetElem = idRef.getId(); + if (targetElem == null) { + // broken identifier ref? smoke tests? + return new ArrayList<>(); + } + + if (compare.apply(targetElem)) { + TModule containingModule = EcoreUtil2.getContainerOfType(targetElem, TModule.class); + return List.of( + new ScriptDependency(RefNameUtil.findIdentifierName(idRef), targetElem.getName(), targetElem, + containingModule)); + } else if (targetElem instanceof ModuleNamespaceVirtualType) { + TModule targMod = ((ModuleNamespaceVirtualType) targetElem).getModule(); + + if (isNamespaceDependencyHandlingNeeded(usedNamespaceSpecifiers, targMod)) { + return List.of(createDependencyOnNamespace(usedNamespaceSpecifiers, targMod)); + } + } + return new ArrayList<>(); + } + + private static Iterable handle(TClass tClass, + Map nameToNamedImportSpecifiers, + Map usedNamespaceSpecifiers, Function compare) { + + List deps = new ArrayList<>(); + + deps.add(tClass); + + EList interfaces = tClass.getImplementedInterfaceRefs(); + if (!isNullOrEmpty(interfaces)) + deps.addAll(toList(filterNull(map(interfaces, i -> i.getDeclaredType())))); + + ParameterizedTypeRef superClass = tClass.getSuperClassRef(); + if (superClass != null) + deps.add(superClass.getDeclaredType()); + + return map(filter(deps, it -> compare.apply(it)), + it -> createScriptDependency(it, nameToNamedImportSpecifiers, usedNamespaceSpecifiers)); + } + + private static Iterable handle(TInterface tInterface, + Map nameToNamedImportSpecifiers, + Map usedNamespaceSpecifiers, Function compare) { + + List deps = new ArrayList<>(); + + deps.add(tInterface); + + EList rs = tInterface.getSuperInterfaceRefs(); + if (!isNullOrEmpty(rs)) + deps.addAll(toList(filterNull(map(rs, it -> it.getDeclaredType())))); + + return map(filter(deps, d -> compare.apply(d)), + it -> createScriptDependency(it, nameToNamedImportSpecifiers, usedNamespaceSpecifiers)); + } + +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ScriptDependencyResolver.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ScriptDependencyResolver.xtend deleted file mode 100644 index 2117f81e99..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/organizeImports/ScriptDependencyResolver.xtend +++ /dev/null @@ -1,339 +0,0 @@ -/** - * 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.tooling.organizeImports - -import java.util.ArrayList -import java.util.Collection -import java.util.Collections -import java.util.List -import java.util.Map -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.util.EcoreUtil -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.AnnotableElement -import org.eclipse.n4js.n4JS.IdentifierRef -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.n4JS.N4InterfaceDeclaration -import org.eclipse.n4js.n4JS.N4TypeDeclaration -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType -import org.eclipse.n4js.ts.types.TAnnotableElement -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.TDynamicElement -import org.eclipse.n4js.ts.types.TFunction -import org.eclipse.n4js.ts.types.TInterface -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.ts.types.TVariable -import org.eclipse.n4js.ts.types.Type -import org.eclipse.n4js.utils.ResourceType -import org.eclipse.xtext.EcoreUtil2 - -import static extension org.eclipse.n4js.tooling.organizeImports.InjectedTypesResolverUtility.* -import static extension org.eclipse.n4js.tooling.organizeImports.RefNameUtil.* - -/** - * Static analysis for {@link Script} dependencies. Analyzes all identifiers in the {@link Script}, - * and on (on demand) {@link Type}s or {@link TypeRef}s. During analysis identifiers from {@link NamedImportSpecifier} - * and {@link NamespaceImportSpecifier} are taken into account. Note that if result analysis does not contain descriptions matching - * some of the imports, it means those imports are not used, and can be removed from script, or ignored during compilation. - * - * Result of analysis is list of {@link ScriptDependency} instances describing what {@link EObject}s should be imported. - *
    - * Note: - *
  • declarations marked with "@ProvidedByRuntime" are ignored (they are never in the result)
  • - *
  • declarations marked with "@Global" are not ignored (can show up in the result)
  • - *
- */ -class ScriptDependencyResolver { - - /** - * Resolves dependencies only from {@link IdentifierRef}s, no {@link Type}s or {@link TypeRef}s - * are taken into account. - */ - def public static List usedDependencies(Script script) { - if (null === script) return emptyList - allRequiredExternalDeclaration(script, Collections.EMPTY_SET, Collections.EMPTY_SET) - } - - /** - * Resolves dependencies from {@link IdentifierRef}s and {@link Type}s that are - * injected into local type declarations. - */ - def public static List usedDependenciesWithInejctedTypes(Script script) { - if (null === script) return emptyList - allRequiredExternalDeclaration(script, script.findAllInjected, Collections.EMPTY_SET) - } - - /** - * Resolves dependencies from {@link IdentifierRef}s and all {@link TypeRef}s. - */ - def public static List usedDependenciesTypeRefs(Script script) { - if (null === script) return emptyList - allRequiredExternalDeclaration(script, Collections.EMPTY_SET, script.eAllContents.filter(TypeRef).toList) - } - - /** - * Looks through all {@link IdentifierRef} for external dependencies - * (from different module than currently analyzed script containing module). - * Additionally looks through all types used as super types and implemented interfaces. - * Not used types (see {@link #shouldBeImported}) are removed from external dependencies. - * - * @param script to be analyzed - * @param typesToBeIncluded force specific collection of {@link Type}s to be considered for as dependencies - * @param typeRefsToBeIncluded force specific collection of {@link TypeRef}s to be considered for as dependencies - */ - def private static List allRequiredExternalDeclaration(Script script, Collection typesToBeIncluded, - Collection typeRefsToBeIncluded) { - - val indirectlyImported = script.eAllContents.filter(N4TypeDeclaration).toList - val identifierRefs = script.eAllContents.filter(IdentifierRef).toList - - val potentialDependencies = newArrayList - potentialDependencies += indirectlyImported - potentialDependencies += identifierRefs - potentialDependencies += typesToBeIncluded - potentialDependencies += typeRefsToBeIncluded - - val namedImportSpecifiers = script.eAllContents.filter(NamedImportSpecifier). - filter[it.importedElement !== null].toList - val usedNamespaceSpecifiers = script.eAllContents.filter(NamespaceImportSpecifier).toInvertedMap[false] - - val baseModule = script.module; - var depsImportedWithName = potentialDependencies.map [ - handle(namedImportSpecifiers.toMap[importedElement.name], usedNamespaceSpecifiers, - [ EObject eo | shouldBeImported(baseModule, eo) ]) - ].flatten.filterNull.toSet.toList.sortBy[localName] - - return depsImportedWithName - } - - /** - * Checks if a given EObject should be imported. - * - *
    - * Evaluates to true if: - *
  • provided EO is not from the module provided at creation time (that module is assumed to be one for which we analyze dependencies)
  • - *
  • provided EO is not from built in types
  • - *
  • (in case of AST elements) is not annotated with {@link AnnotationDefinition.PROVIDED_BY_RUNTIME)
  • - *
  • (in case of TS elements) providedByRuntime evaluates to false
  • - *
- * - * @returns true if given EO should be imported - */ - def public static boolean shouldBeImported(TModule baseModule, EObject eo) { - if (eo instanceof ModuleNamespaceVirtualType - || eo instanceof TDynamicElement) { - return true; - } - - val containingModule = EcoreUtil.getRootContainer(eo); - if (containingModule instanceof TModule) { - if (AnnotationDefinition.PROVIDED_BY_RUNTIME.hasAnnotation(containingModule) - || (ResourceType.getResourceType(containingModule) === ResourceType.DTS && AnnotationDefinition.GLOBAL.hasAnnotation(containingModule))) { - return false; - } - } - - if (eo instanceof AnnotableElement) { - if (AnnotationDefinition.PROVIDED_BY_RUNTIME.hasAnnotation(eo)) { - return false; - } - } else if (eo instanceof TAnnotableElement) { - if (AnnotationDefinition.PROVIDED_BY_RUNTIME.hasAnnotation(eo)) { - return false; - } else if (eo instanceof Type) { - // TODO is this dead code - if (eo.providedByRuntime) { - return false; - } - } else if (eo instanceof TVariable) { - // TODO is this dead code - if (eo.providedByRuntime) { - return false; - } - } - } - - // ignore built-in things as n4scheme:/console.n4jsd: - // in non platform realm check if URI describes file, - // in eclipse platform realm check if URI describes platform resource - return eo.eResource?.getURI !== null // - && ((eo.eResource.getURI.file || eo.eResource.getURI.platformResource)) // - // and check if modules/files are different - && (! eo.eResource.getURI.toString.equals(baseModule.eResource.getURI.toString)) - } - - def private static boolean isNamespaceDependencyHandlingNeeded( - Map usedNamespaceSpecifiers, TModule targMod) { - - return usedNamespaceSpecifiers.keySet.exists[is|(is.eContainer as ImportDeclaration).module === targMod] - } - - def private static createScriptDependency(Type type, Map nameToNamedImportSpecifiers, - Map usedNamespaceSpecifiers) { - if (nameToNamedImportSpecifiers.containsKey(type.name)) { - val nis = nameToNamedImportSpecifiers.get(type.name); - val identifiableElement = nis.importedElement; - val module = EcoreUtil2.getContainerOfType(identifiableElement, TModule); - new ScriptDependency(nis.alias ?: identifiableElement.name, identifiableElement.name, identifiableElement, module); - } else if (isNamespaceDependencyHandlingNeeded(usedNamespaceSpecifiers, type.containingModule)) { - createDependencyOnNamespace(usedNamespaceSpecifiers, type.containingModule) - } else { - // add dependency, looks like something that is @Global but not @ProvidedByRuntime - new ScriptDependency(type.name, type.name, type, type.containingModule) - } - } - - def private static ScriptDependency createDependencyOnNamespace( - Map usedNamespaceSpecifiers, TModule targMod) { - val is = usedNamespaceSpecifiers.keySet.findFirst [ is | - (is.eContainer as ImportDeclaration).module === targMod - ] - val used = usedNamespaceSpecifiers.get(is) - if (!used) { - // add dependency on the namespace - usedNamespaceSpecifiers.put(is, true) - new ScriptDependency(is.alias, null, // For namespace imports, the actual name is intentionally null. - null, // For namespace imports, this is ModuleNamespaceVirtualType, but intentionally null - targMod) - } else { - // namespace was already used - null - } - } - - def private static dispatch Iterable handle(EObject eo, - Map nameToNamedImportSpecifiers, - Map usedNamespaceSpecifiers, (EObject)=>boolean compare) { - - return newArrayList() - } - - def private static dispatch Iterable handle(TypeRef eo, - Map nameToNamedImportSpecifiers, - Map usedNamespaceSpecifiers, (EObject)=>boolean compare) { - - return newArrayList() - } - - def private static dispatch Iterable handle(Void eo, - Map nameToNamedImportSpecifiers, - Map usedNamespaceSpecifiers, (EObject)=>boolean compare) { - - return newArrayList() - } - - def private static dispatch Iterable handle(TFunction tFunction, - Map nameToNamedImportSpecifiers, - Map usedNamespaceSpecifiers, (EObject)=>boolean compare) { - // TODO is there nothing to do? - - return newArrayList() - } - - def private static dispatch Iterable handle(N4ClassDeclaration eo, - Map nameToNamedImportSpecifiers, - Map usedNamespaceSpecifiers, (EObject)=>boolean compare) { - - val tClass = eo.definedType as TClass - handle(tClass, nameToNamedImportSpecifiers, usedNamespaceSpecifiers, compare) - } - - def private static dispatch Iterable handle(N4InterfaceDeclaration eo, - Map nameToNamedImportSpecifiers, - Map usedNamespaceSpecifiers, (EObject)=>boolean compare) { - - val tInterface = eo.definedType as TInterface - handle(tInterface, nameToNamedImportSpecifiers, usedNamespaceSpecifiers, compare) - } - - def private static dispatch Iterable handle(ParameterizedTypeRef eo, - Map nameToNamedImportSpecifiers, - Map usedNamespaceSpecifiers, (EObject)=>boolean compare) { - - // added check for container instance, as polyfill tests were crashing when - // eo.declared type was TVariable and its container TClass - if (eo.declaredType !== null && eo.declaredType.eContainer instanceof TModule && - compare.apply(eo.declaredType)) { - val typeName = eo.findTypeName - if (typeName !== null) { // null means not typed in script (e.g. TypesComputer)-> no import necessary - val module = EcoreUtil2.getContainerOfType(eo.declaredType, TModule); - return newArrayList( - new ScriptDependency(typeName, eo.declaredType.name, eo.declaredType, module)) - } - } - return newArrayList() - } - - /** - * Resolves dependency from identifier reference. - */ - def private static dispatch Iterable handle(IdentifierRef idRef, - Map nameToNamedImportSpecifiers, - Map usedNamespaceSpecifiers, (EObject)=>boolean compare) { - - val targetElem = idRef.id; - if(targetElem === null){ - //broken identifier ref? smoke tests? - return newArrayList() - } - - if (compare.apply(targetElem)) { - val containingModule = EcoreUtil2.getContainerOfType(targetElem, TModule); - return newArrayList( - new ScriptDependency(idRef.findIdentifierName, targetElem.name, targetElem, containingModule)) - } else if (targetElem instanceof ModuleNamespaceVirtualType) { - val targMod = targetElem.module - - if (isNamespaceDependencyHandlingNeeded(usedNamespaceSpecifiers, targMod)) { - return newArrayList(createDependencyOnNamespace(usedNamespaceSpecifiers, targMod)) - } - } - return newArrayList() - } - - def private static dispatch Iterable handle(TClass tClass, - Map nameToNamedImportSpecifiers, - Map usedNamespaceSpecifiers, (EObject)=>boolean compare) { - - val deps = new ArrayList() - - deps.add(tClass) - - val interfaces = tClass.implementedInterfaceRefs - if (!interfaces.nullOrEmpty) deps.addAll(interfaces.map[declaredType].filterNull) - - val superClass = tClass.superClassRef - if (superClass !== null) deps.add(superClass.declaredType) - - deps.filter[compare.apply(it)].map[createScriptDependency(nameToNamedImportSpecifiers, usedNamespaceSpecifiers)] - } - - def private static dispatch Iterable handle(TInterface tInterface, - Map nameToNamedImportSpecifiers, - Map usedNamespaceSpecifiers, (EObject)=>boolean compare) { - - val deps = new ArrayList() - - deps.add(tInterface) - - val rs = tInterface.superInterfaceRefs - if (!rs.nullOrEmpty) deps.addAll(rs.map[declaredType].filterNull) - - deps.filter[compare.apply(it)].map[createScriptDependency(nameToNamedImportSpecifiers, usedNamespaceSpecifiers)] - } - -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.java new file mode 100644 index 0000000000..bd8d130f36 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.java @@ -0,0 +1,396 @@ +/** + * 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.tooling.react; + +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.anyTypeRef; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.newRuleEnvironment; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.JSXElement; +import org.eclipse.n4js.resource.N4JSCache; +import org.eclipse.n4js.resource.N4JSResource; +import org.eclipse.n4js.scoping.N4JSScopeProvider; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeTypeRef; +import org.eclipse.n4js.ts.types.ElementExportDefinition; +import org.eclipse.n4js.ts.types.ExportDefinition; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TInterface; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.TNamespace; +import org.eclipse.n4js.ts.types.TVariable; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.ts.types.TypeVariable; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; +import org.eclipse.xtext.naming.QualifiedName; +import org.eclipse.xtext.resource.IEObjectDescription; +import org.eclipse.xtext.scoping.IScope; +import org.eclipse.xtext.scoping.IScopeProvider; +import org.eclipse.xtext.xbase.lib.StringExtensions; + +import com.google.inject.Inject; + +/** + * This helper provides utilities for looking up React definitions such as React.Component or React.ReactElement or for + * calculating types related to React (e.g. of props property) etc. + */ +public class ReactHelper { + @Inject + private N4JSTypeSystem ts; + @Inject + private TypeSystemHelper tsh; + @Inject + private N4JSCache cache; + @Inject + private IScopeProvider scopeProvider; + + /***/ + public final static String REACT_PROJECT_ID = "react"; + /***/ + public final static String REACT_COMPONENT = "Component"; + /***/ + public final static String REACT_ELEMENT = "ReactElement"; + /***/ + public final static String REACT_FRAGMENT_NAME = "Fragment"; + + /***/ + public final static String REACT_NAMESPACE_NAME = StringExtensions.toFirstUpper(REACT_PROJECT_ID); + /***/ + public final static String REACT_JSX_TRANSFORM_NAME = "jsx"; + /***/ + public final static String REACT_JSXS_TRANSFORM_NAME = "jsxs"; + /***/ + public final static String REACT_ELEMENT_FACTORY_FUNCTION_NAME = "createElement"; + /***/ + public final static String REACT_ELEMENT_PROPERTY_KEY_NAME = "key"; + /***/ + public final static String REACT_ELEMENT_PROPERTY_CHILDREN_NAME = "children"; + /***/ + public final static String REACT_JSX_RUNTIME_NAME = "react/jsx-runtime"; + + private final static String REACT_KEY = "KEY__" + REACT_PROJECT_ID; + + /** + * Returns the {@link TModule} which contains the definitions of the React JSX backend (e.g. {@code Component}, + * {@code createElement}). + * + * Returns {@code null} if no valid React implementation can be found in the index. + */ + public TModule getJsxBackendModule(Resource resource) { + String key = REACT_KEY + "." + "TMODULE"; + return cache.get(resource, () -> { + IScope scope = ((N4JSScopeProvider) scopeProvider).getScopeForImplicitImports((N4JSResource) resource); + Iterable matchingDescriptions = scope + .getElements(QualifiedName.create(REACT_PROJECT_ID)); + // resolve all found 'react.js' files, until a valid react implementation is found + for (IEObjectDescription desc : matchingDescriptions) { + if (desc != null) { + // filter for valid react modules only + TModule module = (TModule) EcoreUtil.resolve(desc.getEObjectOrProxy(), resource); + if (isValidReactModule(module)) { + return module; + } + } + } + return null; + }, key); + } + + /** + * Returns the preferred name of the namespace used to import the JSX backend. + */ + public String getJsxBackendNamespaceName() { + return REACT_NAMESPACE_NAME; + } + + /** + * Returns the name of the element factory function to use with React as JSX backend. + */ + public String getJsxBackendElementFactoryFunctionName() { + return REACT_ELEMENT_FACTORY_FUNCTION_NAME; + } + + /** + * Calculate the type that an JSX element is binding to, usually class/function type + * + * @param jsxElem + * the input JSX element + * @return the {@link TypeRef} that the JSX element is binding to and null if not found + */ + public TypeRef getJsxElementBindingType(JSXElement jsxElem) { + Expression expr = jsxElem.getJsxElementName().getExpression(); + RuleEnvironment G = newRuleEnvironment(expr); + TypeRef exprResult = ts.type(G, expr); + return exprResult; + } + + /** + * Returns the element factory function for JSX elements which can be extracted from the given {@link Resource}. + */ + public TFunction getJsxBackendElementFactoryFunction(Resource resource) { + TModule module = this.getJsxBackendModule(resource); + if (module != null) { + return lookUpReactElementFactoryFunction(module); + } + return null; + } + + /** + * Returns the fragment factory function for JSX elements which can be extracted from the given {@link Resource}. + */ + public IdentifiableElement getJsxBackendFragmentComponent(Resource resource) { + TModule module = this.getJsxBackendModule(resource); + if (module != null) { + return lookUpReactFragmentComponent(module); + } + return null; + } + + /** + * Look up React.Element in the index. + * + * @param context + * the EObject serving the context to look for React.Element. + */ + public TClassifier lookUpReactElement(EObject context) { + // val reactElement = lookUpReactClassifier(context, REACT_ELEMENT, TInterface) + // if (reactElement !== null) { + // return reactElement; + // } + return lookUpReactClassifier_OLD(context, REACT_ELEMENT, TInterface.class); + } + + /** + * Look up React.Component in the index. + * + * @param context + * the EObject serving the context to look for React.Component. + */ + public TClass lookUpReactComponent(EObject context) { + // val reactComponent = lookUpReactClassifier(context, REACT_COMPONENT, TClass); + // if (reactComponent !== null) { + // return reactComponent; + // } + return lookUpReactClassifier_OLD(context, REACT_COMPONENT, TClass.class); + } + + /** + * Calculate the "props" type of an JSX element. It is either the first type parameter of React.Component class or + * the type of the first parameter of a functional React component + * + * @param jsxElem + * the input JSX element + * @return the {@link TypeRef} if exists and null otherwise + */ + public TypeRef getPropsType(JSXElement jsxElem) { + TypeRef exprTypeRef = getJsxElementBindingType(jsxElem); + if (exprTypeRef == null) { + return null; + } + + RuleEnvironment G = newRuleEnvironment(jsxElem); + if (exprTypeRef instanceof TypeTypeRef && ((TypeTypeRef) exprTypeRef).isConstructorRef()) { + // The JSX element refers to a class + Type tclass = tsh.getStaticType(G, (TypeTypeRef) exprTypeRef); + TClass tComponentClass = lookUpReactComponent(jsxElem); + if (tComponentClass == null || tComponentClass.getTypeVars().isEmpty()) { + return null; + } + TypeVariable reactComponentProps = tComponentClass.getTypeVars().get(0); + // Add type variable -> type argument mappings from the current and all super types + tsh.addSubstitutions(G, TypeUtils.createTypeRef(tclass)); + // Substitute type variables in the 'props' and return the result + // Note: after substTypeVariablesInTypeRef is called, the rule environment G is unchanged so do not ask G + // for result as this caused bug IDE-2540 + TypeRef reactComponentPropsTypeRef = ts.substTypeVariables(G, + TypeUtils.createTypeRef(reactComponentProps)); + return reactComponentPropsTypeRef; + + } else if (exprTypeRef instanceof FunctionTypeExprOrRef) { + FunctionTypeExprOrRef fteor = (FunctionTypeExprOrRef) exprTypeRef; + // The JSX elements refers to a function, assume that the first parameter is props + if (fteor.getFpars().size() > 0) { + TFormalParameter tPropsParam = fteor.getFpars().get(0); + return tPropsParam.getTypeRef(); + } + } + return null; + } + + /***/ + public TypeRef getConstructorFunctionType(JSXElement jsxElem) { + RuleEnvironment G = newRuleEnvironment(jsxElem); + TypeRef returnTypeRef = getJsxElementBindingType(jsxElem); + if (returnTypeRef instanceof TypeTypeRef && ((TypeTypeRef) returnTypeRef).getTypeArg() instanceof TypeRef) { + returnTypeRef = (TypeRef) ((TypeTypeRef) returnTypeRef).getTypeArg(); + } + List args = Collections.singletonList(anyTypeRef(G)); + return TypeUtils.createFunctionTypeExpression(args, returnTypeRef); + } + + /** + * Return the type of a field or return type of a getter. + * + * @param member + * MUST be either a field or getter (otherwise an exception is thrown). + */ + public TypeRef typeRefOfFieldOrGetter(TMember member, TypeRef context) { + if (member instanceof TField || member instanceof TGetter) + return ts.tau(member, context); + + throw new IllegalArgumentException(member + " must be either a TField or TGetter"); + } + + /** + * Lookup React component/element type. For increased efficiency, the found results are cached. + * + * @param context + * the EObject serving the context to look for React classifiers. + * @param reactClassifierName + * the name of React classifier. + */ + // TODO: continue work on use of TypeScript type definitions of React + @SuppressWarnings("unchecked") + private T lookUpReactClassifier(EObject context, String reactClassifierName, + Class clazz) { + Resource resource = context.eResource(); + TModule tModule = getJsxBackendModule(resource); + if (tModule == null || tModule.eResource() == null) { + return null; + } + + String key = REACT_KEY + "." + reactClassifierName; + return cache.get(tModule.eResource(), () -> { + // used for @types/react + for (ExportDefinition expDef : tModule.getExportDefinitions()) { + if (expDef instanceof ElementExportDefinition) { + ElementExportDefinition eed = (ElementExportDefinition) expDef; + if ("React".equals(eed.getExportedName()) && eed.getExportedElement() instanceof TNamespace) { + for (Type type : ((TNamespace) eed.getExportedElement()).getTypes()) { + if (clazz.isAssignableFrom(type.getClass()) && reactClassifierName.equals(type.getName())) { + return (T) type; + } + } + } + } + } + return null; + }, key); + } + + private T lookUpReactClassifier_OLD(EObject context, String reactClassifierName, + Class clazz) { + Resource resource = context.eResource(); + TModule tModule = getJsxBackendModule(resource); + if (tModule == null || tModule.eResource() == null) { + return null; + } + + String key = REACT_KEY + "_OLD." + reactClassifierName; + return cache.get(tModule.eResource(), () -> { + // used for @n4jsd/react + T tClassifier = findFirst(filter(tModule.getTypes(), clazz), + c -> Objects.equals(c.getName(), reactClassifierName)); + return tClassifier; + }, key); + } + + private IdentifiableElement lookUpReactFragmentComponent(TModule module) { + if (module != null) { + // used for @types/react + for (ExportDefinition expDef : module.getExportDefinitions()) { + if (expDef instanceof ElementExportDefinition) { + ElementExportDefinition eed = (ElementExportDefinition) expDef; + if ("React".equals(eed.getExportedName()) && eed.getExportedElement() instanceof TNamespace) { + for (TVariable currTopLevelVar : ((TNamespace) eed.getExportedElement()) + .getExportedVariables()) { + if (REACT_FRAGMENT_NAME.equals(currTopLevelVar.getName())) { + return currTopLevelVar; + } + } + } + } + } + // used for @n4jsd/react + for (Type currTopLevelType : module.getTypes()) { + if (currTopLevelType instanceof TClass + && REACT_FRAGMENT_NAME.equals(currTopLevelType.getName())) { + return currTopLevelType; + } + } + } + return null; + } + + /** + * Looks up the element factory function to use, assuming the react implementation in use is to be found in the + * given {@code module}. + * + * Returns {@code null} if no factory function can be found in the given module. + */ + private TFunction lookUpReactElementFactoryFunction(TModule module) { + if (module != null) { + // used for @types/react + for (ExportDefinition expDef : module.getExportDefinitions()) { + if (expDef instanceof ElementExportDefinition) { + ElementExportDefinition eed = (ElementExportDefinition) expDef; + if ("React".equals(eed.getExportedName()) && eed.getExportedElement() instanceof TNamespace) { + for (TFunction currTopLevelType : ((TNamespace) eed.getExportedElement()).getFunctions()) { + if (REACT_ELEMENT_FACTORY_FUNCTION_NAME.equals(currTopLevelType.getName())) { + return currTopLevelType; + } + } + } + } + } + // used for @n4jsd/react + for (TFunction currTopLevelType : module.getFunctions()) { + if (REACT_ELEMENT_FACTORY_FUNCTION_NAME.equals(currTopLevelType.getName())) { + return currTopLevelType; + } + } + } + return null; + } + + /** + * Returns {@code true} if the given {@code module} is a {@link TModule} that represents a valid implementation of + * React. + * + * Returns {@code false} otherwise. + * + * Note that this requires type definitions to be available for the given {@link TModule}. + */ + private boolean isValidReactModule(TModule module) { + // check for existence of the element factory function + return lookUpReactElementFactoryFunction(module) != null; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend deleted file mode 100644 index 23f11003e8..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/react/ReactHelper.xtend +++ /dev/null @@ -1,344 +0,0 @@ -/** - * 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.tooling.react - -import com.google.inject.Inject -import java.util.Collections -import java.util.List -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.resource.Resource -import org.eclipse.n4js.n4JS.JSXElement -import org.eclipse.n4js.resource.N4JSCache -import org.eclipse.n4js.resource.N4JSResource -import org.eclipse.n4js.scoping.N4JSScopeProvider -import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.typeRefs.TypeTypeRef -import org.eclipse.n4js.ts.types.ElementExportDefinition -import org.eclipse.n4js.ts.types.ExportDefinition -import org.eclipse.n4js.ts.types.IdentifiableElement -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TField -import org.eclipse.n4js.ts.types.TFunction -import org.eclipse.n4js.ts.types.TGetter -import org.eclipse.n4js.ts.types.TInterface -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.ts.types.TNamespace -import org.eclipse.n4js.ts.types.TVariable -import org.eclipse.n4js.ts.types.Type -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.N4JSTypeSystem -import org.eclipse.n4js.typesystem.utils.TypeSystemHelper -import org.eclipse.xtext.EcoreUtil2 -import org.eclipse.xtext.naming.QualifiedName -import org.eclipse.xtext.scoping.IScopeProvider - -import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* - -/** - * This helper provides utilities for looking up React definitions such as React.Component or React.ReactElement or - * for calculating types related to React (e.g. of props property) etc. - */ -class ReactHelper { - @Inject private N4JSTypeSystem ts - @Inject private TypeSystemHelper tsh - @Inject private N4JSCache cache - @Inject private IScopeProvider scopeProvider; - - public final static String REACT_PROJECT_ID = "react" - public final static String REACT_COMPONENT = "Component" - public final static String REACT_ELEMENT = "ReactElement" - public final static String REACT_FRAGMENT_NAME = "Fragment"; - - public final static String REACT_NAMESPACE_NAME = REACT_PROJECT_ID.toFirstUpper; - public final static String REACT_JSX_TRANSFORM_NAME = "jsx"; - public final static String REACT_JSXS_TRANSFORM_NAME = "jsxs"; - public final static String REACT_ELEMENT_FACTORY_FUNCTION_NAME = "createElement"; - public final static String REACT_ELEMENT_PROPERTY_KEY_NAME = "key"; - public final static String REACT_ELEMENT_PROPERTY_CHILDREN_NAME = "children"; - public final static String REACT_JSX_RUNTIME_NAME = "react/jsx-runtime"; - - - private final static String REACT_KEY = "KEY__" + REACT_PROJECT_ID - - /** - * Returns the {@link TModule} which contains the definitions of the React - * JSX backend (e.g. {@code Component}, {@code createElement}). - * - * Returns {@code null} if no valid React implementation can be found in the index. - */ - def public TModule getJsxBackendModule(Resource resource) { - val String key = REACT_KEY + "." + "TMODULE"; - return cache.get(resource, [ - val scope = (scopeProvider as N4JSScopeProvider).getScopeForImplicitImports(resource as N4JSResource); - val matchingDescriptions = scope.getElements(QualifiedName.create(REACT_PROJECT_ID)); - // resolve all found 'react.js' files, until a valid react implementation is found - return matchingDescriptions.map[desc | - if(desc === null) - return null - return EcoreUtil2.resolve(desc.EObjectOrProxy, resource) as TModule - ] - // filter for valid react modules only - .filter[module | module.isValidReactModule].head; - ], key); - } - - /** - * Returns the preferred name of the namespace used to import the JSX backend. - */ - def public String getJsxBackendNamespaceName() { - return REACT_NAMESPACE_NAME; - } - - /** - * Returns the name of the element factory function to use with React as JSX backend. - */ - def getJsxBackendElementFactoryFunctionName() { - return REACT_ELEMENT_FACTORY_FUNCTION_NAME; - } - - /** - * Calculate the type that an JSX element is binding to, usually class/function type - * - * @param jsxElem the input JSX element - * @return the typeref that the JSX element is binding to and null if not found - */ - def public TypeRef getJsxElementBindingType(JSXElement jsxElem) { - val expr = jsxElem.jsxElementName.expression; - val G = expr.newRuleEnvironment; - val exprResult = ts.type(G, expr); - return exprResult; - } - - /** - * Returns the element factory function for JSX elements which can be extracted - * from the given {@link Resource}. - */ - def public TFunction getJsxBackendElementFactoryFunction(Resource resource) { - val module = this.getJsxBackendModule(resource); - if (module !== null) { - return lookUpReactElementFactoryFunction(module); - } - return null; - } - - /** - * Returns the fragment factory function for JSX elements which can be extracted - * from the given {@link Resource}. - */ - def public IdentifiableElement getJsxBackendFragmentComponent(Resource resource) { - val module = this.getJsxBackendModule(resource); - if (module !== null) { - return lookUpReactFragmentComponent(module); - } - return null; - } - - /** - * Look up React.Element in the index. - * - * @param context the EObject serving the context to look for React.Element. - */ - def public TClassifier lookUpReactElement(EObject context) { -// val reactElement = lookUpReactClassifier(context, REACT_ELEMENT, TInterface) -// if (reactElement !== null) { -// return reactElement; -// } - return lookUpReactClassifier_OLD(context, REACT_ELEMENT, TInterface); - } - - /** - * Look up React.Component in the index. - * - * @param context the EObject serving the context to look for React.Component. - */ - def public TClass lookUpReactComponent(EObject context) { -// val reactComponent = lookUpReactClassifier(context, REACT_COMPONENT, TClass); -// if (reactComponent !== null) { -// return reactComponent; -// } - return lookUpReactClassifier_OLD(context, REACT_COMPONENT, TClass); - } - - /** - * Calculate the "props" type of an JSX element. It is either the first type parameter of React.Component class or - * the type of the first parameter of a functional React component - * - * @param jsxElement the input JSX element - * @return the typeref if exists and null otherwise - */ - def public TypeRef getPropsType(JSXElement jsxElem) { - val TypeRef exprTypeRef = jsxElem.jsxElementBindingType - if (exprTypeRef === null) - return null; - - val G = jsxElem.newRuleEnvironment; - if (exprTypeRef instanceof TypeTypeRef && (exprTypeRef as TypeTypeRef).constructorRef) { - // The JSX element refers to a class - val tclass = tsh.getStaticType(G, exprTypeRef as TypeTypeRef); - val tComponentClass = lookUpReactComponent(jsxElem); - if (tComponentClass === null || tComponentClass.typeVars.isEmpty) { - return null; - } - val reactComponentProps = tComponentClass.typeVars.get(0); - // Add type variable -> type argument mappings from the current and all super types - tsh.addSubstitutions(G, TypeUtils.createTypeRef(tclass)); - // Substitute type variables in the 'props' and return the result - // Note: after substTypeVariablesInTypeRef is called, the rule environment G is unchanged so do not ask G for result as this caused bug IDE-2540 - val reactComponentPropsTypeRef = ts.substTypeVariables(G, - TypeUtils.createTypeRef(reactComponentProps)); - return reactComponentPropsTypeRef; - - } else if (exprTypeRef instanceof FunctionTypeExprOrRef) { - // The JSX elements refers to a function, assume that the first parameter is props - if (exprTypeRef.fpars.length > 0) { - val tPropsParam = exprTypeRef.fpars.get(0); - return tPropsParam.typeRef - } - } - return null; - } - - def public TypeRef getConstructorFunctionType(JSXElement jsxElem) { - val G = newRuleEnvironment(jsxElem); - var TypeRef returnTypeRef = getJsxElementBindingType(jsxElem); - if (returnTypeRef instanceof TypeTypeRef && (returnTypeRef as TypeTypeRef).typeArg instanceof TypeRef) { - returnTypeRef = (returnTypeRef as TypeTypeRef).typeArg as TypeRef; - } - val List args = Collections.singletonList(anyTypeRef(G)); - return TypeUtils.createFunctionTypeExpression(args, returnTypeRef); - } - - /** - * Return the type of a field or return type of a getter. - * - * @param member MUST be either a field or getter (otherwise an exception is thrown). - */ - def public TypeRef typeRefOfFieldOrGetter(TMember member, TypeRef context) { - if (member instanceof TField || member instanceof TGetter) - return ts.tau(member, context); - - throw new IllegalArgumentException(member + " must be either a TField or TGetter"); - } - - /** - * Lookup React component/element type. For increased efficiency, the found results are cached. - * - * @param context the EObject serving the context to look for React classifiers. - * @param reactClassifierName the name of React classifier. - */ - // TODO: continue work on use of TypeScript type definitions of React - def private T lookUpReactClassifier(EObject context, String reactClassifierName, Class clazz) { - val resource = context.eResource; - val tModule = getJsxBackendModule(resource); - if (tModule === null || tModule.eResource === null) - return null; - - val String key = REACT_KEY + "." + reactClassifierName; - return cache.get(tModule.eResource, [ - // used for @types/react - for (ExportDefinition expDef : tModule.exportDefinitions) { - if (expDef instanceof ElementExportDefinition) { - if (expDef.exportedName == "React" && expDef.exportedElement instanceof TNamespace) { - for (Type type : (expDef.exportedElement as TNamespace).types) { - if (clazz.isAssignableFrom(type.class) && reactClassifierName.equals(type.getName())) { - return type as T; - } - } - } - } - } - return null; - ], key); - } - def private T lookUpReactClassifier_OLD(EObject context, String reactClassifierName, Class clazz) { - val resource = context.eResource; - val tModule = getJsxBackendModule(resource); - if (tModule === null || tModule.eResource === null) - return null; - - val String key = REACT_KEY + "_OLD." + reactClassifierName; - return cache.get(tModule.eResource, [ - // used for @n4jsd/react - val tClassifier = tModule.types.filter(clazz).findFirst[name == reactClassifierName]; - return tClassifier; - ], key); - } - - def private IdentifiableElement lookUpReactFragmentComponent(TModule module) { - if (module !== null) { - // used for @types/react - for (ExportDefinition expDef : module.exportDefinitions) { - if (expDef instanceof ElementExportDefinition) { - if (expDef.exportedName == "React" && expDef.exportedElement instanceof TNamespace) { - for (TVariable currTopLevelVar : (expDef.exportedElement as TNamespace).exportedVariables) { - if (REACT_FRAGMENT_NAME.equals(currTopLevelVar.getName())) { - return currTopLevelVar; - } - } - } - } - } - // used for @n4jsd/react - for (Type currTopLevelType : module.getTypes()) { - if (currTopLevelType instanceof TClass - && REACT_FRAGMENT_NAME.equals(currTopLevelType.getName())) { - return currTopLevelType as TClass; - } - } - } - return null; - } - /** - * Looks up the element factory function to use, assuming the react implementation in use - * is to be found in the given {@code module}. - * - * Returns {@code null} if no factory function can be found in the given module. - */ - def private TFunction lookUpReactElementFactoryFunction(TModule module) { - if (module !== null) { - // used for @types/react - for (ExportDefinition expDef : module.exportDefinitions) { - if (expDef instanceof ElementExportDefinition) { - if (expDef.exportedName == "React" && expDef.exportedElement instanceof TNamespace) { - for (TFunction currTopLevelType : (expDef.exportedElement as TNamespace).getFunctions()) { - if (REACT_ELEMENT_FACTORY_FUNCTION_NAME.equals(currTopLevelType.getName())) { - return currTopLevelType; - } - } - } - } - } - // used for @n4jsd/react - for (TFunction currTopLevelType : module.getFunctions()) { - if (REACT_ELEMENT_FACTORY_FUNCTION_NAME.equals(currTopLevelType.getName())) { - return currTopLevelType; - } - } - } - return null; - } - - /** - * Returns {@code true} if the given {@code module} is a {@link TModule} - * that represents a valid implementation of React. - * - * Returns {@code false} otherwise. - * - * Note that this requires type definitions to be available for the given {@link TModule}. - */ - def private boolean isValidReactModule(TModule module) { - // check for existence of the element factory function - return lookUpReactElementFactoryFunction(module) !== null; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/LambdaUtils.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/LambdaUtils.java new file mode 100644 index 0000000000..e72cae6ac9 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/LambdaUtils.java @@ -0,0 +1,96 @@ +/** + * 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.types.utils; + +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.filter; + +import java.util.Iterator; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.ArrowFunction; +import org.eclipse.n4js.n4JS.Block; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4JSASTUtils; +import org.eclipse.n4js.n4JS.ThisArgProvider; +import org.eclipse.n4js.n4JS.ThisLiteral; +import org.eclipse.n4js.n4JS.ThisTarget; +import org.eclipse.n4js.utils.EcoreUtilN4; +import org.eclipse.xtext.EcoreUtil2; + +/** + * Utility methods added to support ES6 arrow functions, aka lambdas. + */ +public class LambdaUtils { + + /** + * All {@link ThisLiteral}s occurring in body that refer to the same this-value; ie without delving + * into functions (unless arrow functions) or into a declaration that introduces a this context, ie any + * {@link ThisTarget} in general. + */ + public static Iterator thisLiterals(Block body) { + return filter(EcoreUtilN4.getAllContentsFiltered(body, elem -> !introducesThisContext(elem)), + ThisLiteral.class); + } + + private static boolean introducesThisContext(EObject node) { + if (node instanceof FunctionExpression) { + return !((FunctionExpression) node).isArrowFunction(); + } + if (node instanceof FunctionDefinition) { + return true; + } + if (node instanceof FunctionDefinition) { + return true; + } + return false; + } + + /** Returns true iff the given element is instance of {@link ArrowFunction} */ + public static boolean isLambda(EObject funDef) { + return funDef instanceof ArrowFunction; + } + + /** + * A this-binder is a non-lambda {@link FunctionDefinition}. This method looks up the nearest such construct that + * encloses the argument. In case the argument itself is a this-binder, it is returned. In case no this-binder + * exists (for example, the argument is enclosed in a top-level arrow-function) then null is returned. + *

+ * Note: unlike {@link N4JSASTUtils#getContainingFunctionOrAccessor(EObject)} this method regards + * {@link N4FieldDeclaration} as valid answer (ie, a "nearest enclosing this-binder"). + */ + public static ThisArgProvider nearestEnclosingThisBinder(EObject expr) { + if (expr == null) { + return null; + } + ThisArgProvider enclosingThisBinder = EcoreUtil2.getContainerOfType(expr, ThisArgProvider.class); + if (enclosingThisBinder == null) { + return null; + } + if (isLambda(enclosingThisBinder)) { + // lambda functions provide no binding for 'this', keep searching + return nearestEnclosingThisBinder(enclosingThisBinder.eContainer()); + } + // non-lambda functions do bind 'this'; we've found it + return enclosingThisBinder; + } + + /** + * A top-level lambda has no enclosing lexical context that provides bindings for 'this' and 'arguments'. + */ + public static boolean isTopLevelLambda(FunctionExpression funExpr) { + EObject enclosing = funExpr.eContainer(); + return isLambda(funExpr) && null == nearestEnclosingThisBinder(enclosing); + + } + +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/LambdaUtils.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/LambdaUtils.xtend deleted file mode 100644 index dd00dab2ed..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/LambdaUtils.xtend +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 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.types.utils; - -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.ArrowFunction -import org.eclipse.n4js.n4JS.Block -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.FunctionExpression -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.N4JSASTUtils -import org.eclipse.n4js.n4JS.ThisArgProvider -import org.eclipse.n4js.n4JS.ThisLiteral -import org.eclipse.n4js.n4JS.ThisTarget -import org.eclipse.n4js.utils.EcoreUtilN4 -import org.eclipse.xtext.EcoreUtil2 - -/** - * Utility methods added to support ES6 arrow functions, aka lambdas. - */ -public class LambdaUtils { - - /** - * All {@link ThisLiteral}s occurring in body that refer to the same this-value; - * ie without delving into functions (unless arrow functions) or into a declaration that introduces - * a this context, ie any {@link ThisTarget} in general. - */ - public static def thisLiterals(Block body) { - EcoreUtilN4.getAllContentsFiltered(body, [!introducesThisContext(it)]).filter(it| it instanceof ThisLiteral) - } - - private static def boolean introducesThisContext(EObject node) { - switch node { - FunctionExpression: !node.isArrowFunction - FunctionDefinition: true - ThisArgProvider: true - default: false - } - } - - public static def boolean isLambda(EObject funDef) { - funDef instanceof ArrowFunction - } - - /** - * A this-binder is a non-lambda {@link FunctionDefinition}. - * This method looks up the nearest such construct that encloses the argument. - * In case the argument itself is a this-binder, it is returned. - * In case no this-binder exists (for example, the argument is enclosed in a top-level arrow-function) then null is returned. - *

- * Note: unlike {@link N4JSASTUtils#getContainingFunctionOrAccessor(EObject)} this method - * regards {@link N4FieldDeclaration} as valid answer (ie, a "nearest enclosing this-binder"). - */ - public static def ThisArgProvider nearestEnclosingThisBinder(EObject expr) { - if (expr === null) { - return null; - } - val enclosingThisBinder = EcoreUtil2.getContainerOfType(expr, ThisArgProvider); - if (enclosingThisBinder === null) { - return null; - } - if (isLambda(enclosingThisBinder)) { - // lambda functions provide no binding for 'this', keep searching - return nearestEnclosingThisBinder(enclosingThisBinder.eContainer); - } - // non-lambda functions do bind 'this'; we've found it - return enclosingThisBinder; - } - - /** - * A top-level lambda has no enclosing lexical context that provides bindings for 'this' and 'arguments'. - */ - public static def isTopLevelLambda(FunctionExpression funExpr) { - isLambda(funExpr) && { - val enclosing = funExpr.eContainer; - null === nearestEnclosingThisBinder(enclosing); - } - } - -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/TypeHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/TypeHelper.java new file mode 100644 index 0000000000..549177f00f --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/TypeHelper.java @@ -0,0 +1,211 @@ +/** + * 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.types.utils; + +import static org.eclipse.n4js.types.utils.SuperTypesList.newSuperTypesList; +import static org.eclipse.n4js.types.utils.TypeUtils.declaredSuperTypes; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.PrimitiveType; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.xtext.xbase.lib.IterableExtensions; + +import com.google.inject.Inject; + +/** + * Helper providing utility methods for type and type ref handling, needs to be injected. Static utility methods can be + * found in {@link TypeUtils}. + */ +public class TypeHelper { + + @Inject + TypeCompareHelper tch; + + /** + * Collects all declared super types of a type referenced by a type references, recognizing cyclic dependencies in + * case of invalid type hierarchies. Type arguments are not considered during comparison, thus G and G will + * result in a single reference in the result. + * + * @param reflexive + * if true, type itself is also added to the list of super types + * + * @return ordered list of super types, using a depth first search, starting with classes, then roles, and + * eventually interfaces. + */ + // TODO functions and other type expressions are not supported yet! + public SuperTypesList collectAllDeclaredSuperTypesTypeargsIgnored(TypeRef ref, boolean reflexive) { + SuperTypesList allDeclaredSuperTypes = newSuperTypesList(tch.getTypeRefComparator()); + + allDeclaredSuperTypes.add(ref); + collectAllDeclaredSuperTypesTypeargsIgnored(ref, allDeclaredSuperTypes); + + // in case of cycles, we do not want the current type to be contained in the super types list + // if reflexive is false + if (!reflexive) { + allDeclaredSuperTypes.remove(ref); + } + return allDeclaredSuperTypes; + } + + /** + * Collects all declared super types of a type referenced by a type references, recognizing cyclic dependencies in + * case of invalid type hierarchies. Type arguments are considered during comparison, thus G and G will both + * be part of the result. + * + * @param reflexive + * if true, type itself is also added to the list of super types + * + * @return ordered list of super types, using a depth first search, starting with classes, then roles, and + * eventually interfaces. + */ + // TODO functions and other type expressions are not supported yet! + public SuperTypesList collectAllDeclaredSuperTypesWithTypeargs(TypeRef ref, boolean reflexive) { + SuperTypesList allDeclaredSuperTypes = newSuperTypesList(tch.getTypeRefComparator()); + + allDeclaredSuperTypes.add(ref); + collectAllDeclaredSuperTypesTypeargsIgnored(ref, allDeclaredSuperTypes); + + // in case of cycles, we do not want the current type to be contained in the super types list + // if reflexive is false + if (!reflexive) { + allDeclaredSuperTypes.remove(ref); + } + return allDeclaredSuperTypes; + } + + /***/ + public SuperTypesList collectAllDeclaredSuperTypes(Type type, boolean reflexive) { + SuperTypesList allDeclaredSuperTypes = newSuperTypesList(tch.getTypeComparator()); + + allDeclaredSuperTypes.add(type); + collectAllDeclaredSuperTypes(type, allDeclaredSuperTypes); + + // in case of cycles, we do not want the current type to be contained in the super types list + // if reflexive is false + if (!reflexive) { + allDeclaredSuperTypes.remove(type); + } + return allDeclaredSuperTypes; + } + + /** + * Collects all type references of given type reference and add these types to both given collections. This method + * requires the tree set to use the {@link TypeCompareHelper#getTypeRefComparator()}. In most cases, you probably + * will call {@link #collectAllDeclaredSuperTypes(Type, boolean)} instead of calling this method directly. However, + * for some optimized methods, it may be useful to call this method directly. + * + * @param allDeclaredSuperTypes + * needs to be instantiated with correct comparator, that is the types are ordered by their qualified + * name + */ + public void collectAllDeclaredSuperTypesTypeargsIgnored(TypeRef ref, + SuperTypesList allDeclaredSuperTypes) { + + if (ref != null && ref.getDeclaredType() != null) { + for (ParameterizedTypeRef superTypeRef : declaredSuperTypes(ref.getDeclaredType())) { + if (allDeclaredSuperTypes.add(superTypeRef)) { + collectAllDeclaredSuperTypesTypeargsIgnored(superTypeRef, allDeclaredSuperTypes); + } + } + } + } + + /***/ + public void collectAllDeclaredSuperTypes(Type type, SuperTypesList allDeclaredSuperTypes) { + if (type != null) { + for (Type superType : map(declaredSuperTypes(type), t -> t.getDeclaredType())) { + if (allDeclaredSuperTypes.add(superType)) { + collectAllDeclaredSuperTypes(superType, allDeclaredSuperTypes); + } + } + } + } + + /** + * Removes the first occurrence of the given type from the iterable, whereby the type is found by name using the + * {@link TypeCompareHelper#getTypeRefComparator()}. The iterator of the iterable needs to support the + * {@link Iterator#remove()} operation. + * + * @return true if type has been found, false otherwise + */ + public boolean removeTypeRef(Iterable typeRefs, TypeRef toBeRemoved) { + Iterator iter = typeRefs.iterator(); + while (iter.hasNext()) { + if (tch.compare(toBeRemoved, iter.next()) == 0) { + iter.remove(); + return true; + } + } + return false; + } + + /** + * Retains all types from list of refs. + *

+ * This method is optimized for leastCommonSuperType and assumes that all types in orderedRefs are ordered as + * returned by collecAllDeclaredSuperTypes(). The iterator returned by typeRefs must support the + * {@link Iterator#remove()} operation. + */ + public void retainAllTypeRefs(Iterable typeRefs, SuperTypesList typesToBeRetained) { + Iterator iter = typeRefs.iterator(); + while (iter.hasNext()) { + if (!typesToBeRetained.contains(iter.next())) { + iter.remove(); + } + } + } + + /** + * Returns true if given iterable contains the type ref, using the {@link TypeCompareHelper#getTypeRefComparator()} + * for finding the type ref. + */ + public boolean containsByType(Iterable typeRefs, TypeRef typeRef) { + return IterableExtensions.exists(typeRefs, tr -> tch.compare(typeRef, tr) == 0); + } + + /** + * Returns the index of the type ref contained in the typeRefs collections, which either equals the given type ref + * by means of the {@link TypeCompareHelper#getTypeRefComparator()}, or which is assignment compatible in case of + * primitive types. + * + * @return index or -1, if type ref has not been found + */ + public int findTypeRefOrAssignmentCompatible(List typeRefs, TypeRef typeRef) { + PrimitiveType assignmentCompatible = (typeRef.getDeclaredType() instanceof PrimitiveType) + ? ((PrimitiveType) typeRef.getDeclaredType()).getAssignmentCompatible() + : null; + int i = 0; + while (i < typeRefs.size()) { + TypeRef t = typeRefs.get(i); + + if (tch.compare(typeRef, t) == 0) { + return i; + } + if (assignmentCompatible != null) { + Type type = t.getDeclaredType(); + if (type instanceof PrimitiveType) { + if (tch.getTypeComparator().compare(assignmentCompatible, type) == 0 || + tch.getTypeComparator().compare(typeRef.getDeclaredType(), + ((PrimitiveType) type).getAssignmentCompatible()) == 0) { + return i; + } + } + } + i = i + 1; + } + return -1; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/TypeHelper.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/TypeHelper.xtend deleted file mode 100644 index 829182fb0b..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/TypeHelper.xtend +++ /dev/null @@ -1,194 +0,0 @@ -/** - * 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.types.utils - -import com.google.inject.Inject -import java.util.Iterator -import java.util.List -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.PrimitiveType -import org.eclipse.n4js.ts.types.Type - -import static org.eclipse.n4js.types.utils.SuperTypesList.* - -import static extension org.eclipse.n4js.types.utils.TypeUtils.* - -/** - * Helper providing utility methods for type and type ref handling, needs to be injected. Static utility methods - * can be found in {@link TypeUtils}. - */ -public class TypeHelper { - - @Inject - extension TypeCompareHelper - - /* - * Collects all declared super types of a type referenced by a type references, recognizing cyclic dependencies in - * case of invalid type hierarchies. Type arguments are not considered during comparison, thus G and G - * will result in a single reference in the result. - * - * @param reflexive if true, type itself is also added to the list of super types - * @return ordered list of super types, using a depth first search, starting with classes, then roles, and eventually interfaces. - */ - // TODO functions and other type expressions are not supported yet! - public def SuperTypesList collectAllDeclaredSuperTypesTypeargsIgnored(TypeRef ref, boolean reflexive) { - val allDeclaredSuperTypes = newSuperTypesList(typeRefComparator); - - allDeclaredSuperTypes.add(ref) - ref.collectAllDeclaredSuperTypesTypeargsIgnored(allDeclaredSuperTypes) - - // in case of cycles, we do not want the current type to be contained in the super types list - // if reflexive is false - if (!reflexive) { - allDeclaredSuperTypes.remove(ref); - } - return allDeclaredSuperTypes; - } - - /* - * Collects all declared super types of a type referenced by a type references, recognizing cyclic dependencies in - * case of invalid type hierarchies. Type arguments are considered during comparison, thus G and G - * will both be part of the result. - * - * @param reflexive if true, type itself is also added to the list of super types - * @return ordered list of super types, using a depth first search, starting with classes, then roles, and eventually interfaces. - */ - // TODO functions and other type expressions are not supported yet! - public def SuperTypesList collectAllDeclaredSuperTypesWithTypeargs(TypeRef ref, boolean reflexive) { - val allDeclaredSuperTypes = newSuperTypesList(typeRefComparator); - - allDeclaredSuperTypes.add(ref) - ref.collectAllDeclaredSuperTypesTypeargsIgnored(allDeclaredSuperTypes) - - // in case of cycles, we do not want the current type to be contained in the super types list - // if reflexive is false - if (!reflexive) { - allDeclaredSuperTypes.remove(ref); - } - return allDeclaredSuperTypes; - } - - public def SuperTypesList collectAllDeclaredSuperTypes(Type type, boolean reflexive) { - val allDeclaredSuperTypes = newSuperTypesList(typeComparator); - - allDeclaredSuperTypes.add(type) - type.collectAllDeclaredSuperTypes(allDeclaredSuperTypes) - - // in case of cycles, we do not want the current type to be contained in the super types list - // if reflexive is false - if (!reflexive) { - allDeclaredSuperTypes.remove(type); - } - return allDeclaredSuperTypes; - } - - /** - * Collects all type references of given type reference and add these types to both given collections. This method requires the tree set to use the - * {@link TypeCompareHelper#getTypeRefComparator()}. In most cases, you probably will call {@link #collectAllDeclaredSuperTypes(TypeRef, boolean)} instead of calling this method - * directly. However, for some optimized methods, it may be usefull to call this method directly. - * - * @param allDeclaredSuperTypes - * needs to be instantiated with correct comparator, see {@link collectAllDeclaredSuperTypes(TypeRef)}, that is the types are ordered by their - * qualified name - * @param allDeclaredSuperTypesOrdered ordered list of super types, using a depth first search, starting with classes, then roles, and eventually interfaces. - */ - public def void collectAllDeclaredSuperTypesTypeargsIgnored(TypeRef ref, SuperTypesList allDeclaredSuperTypes) { - if (ref !== null && ref.declaredType !== null) { - for (superTypeRef : ref.declaredType.declaredSuperTypes) { - if (allDeclaredSuperTypes.add(superTypeRef)) { - collectAllDeclaredSuperTypesTypeargsIgnored(superTypeRef, allDeclaredSuperTypes) - } - } - } - } - - public def void collectAllDeclaredSuperTypes(Type type, SuperTypesList allDeclaredSuperTypes) { - if (type !== null) { - for (superType : type.declaredSuperTypes.map[declaredType]) { - if (allDeclaredSuperTypes.add(superType)) { - collectAllDeclaredSuperTypes(superType, allDeclaredSuperTypes) - } - } - } - } - - /** - * Removes the first occurrence of the given type from the iterable, whereby the type is found by name using the - * {@link TypeCompareHelper#getTypeRefComparator()}. The iterator of the iterable needs to support the {@link Iterator#remove()} operation. - * @return true if type has been found, false otherwise - */ - public def boolean removeTypeRef(Iterable typeRefs, TypeRef toBeRemoved) { - val Iterator iter = typeRefs.iterator; - while (iter.hasNext()) { - if (compare(toBeRemoved, iter.next()) === 0) { - iter.remove(); - return true; - } - } - return false; - } - - /** - * Retains all types from list of refs. - *

- * This method is optimized for leastCommonSuperType and - * assumes that all types in orderedRefs are ordered as returned by collecAllDeclaredSuperTypes(). - * The iterator returned by typeRefs must support the {@link Iterator#remove()} operation. - */ - public def void retainAllTypeRefs(Iterable typeRefs, SuperTypesList typesToBeRetained) { - val iter = typeRefs.iterator - while (iter.hasNext) { - if (! typesToBeRetained.contains(iter.next())) { - iter.remove() - } - } - } - - /** - * Returns true if given iterable contains the type ref, using the {@link TypeCompareHelper#getTypeRefComparator()} for finding the type ref. - */ - public def boolean containsByType(Iterable typeRefs, TypeRef typeRef) { - typeRefs.exists[compare(typeRef, it) == 0] - } - - /** - * Returns the index of the type ref contained in the typeRefs collections, which either equals the given type ref - * by means of the {@link TypeCompareHelper#getTypeRefComparator()}, or which is assignment compatible in case of primitive types. - * - * @return index or -1, if type ref has not been found - */ - public def int findTypeRefOrAssignmentCompatible(List typeRefs, TypeRef typeRef) { - val assignmentCompatible = if (typeRef.declaredType instanceof PrimitiveType) { - (typeRef.declaredType as PrimitiveType).assignmentCompatible; - } else { - null; - } - var i = 0; - while (i { + if (formalParameterTypesBuilder.relinkFormalParameter(fpar, functionType, builtInTypeScope, preLinkingPhase, + idx)) { + return idx + 1; + } + return idx; + }); + } + + protected void addFormalParameters(TFunction functionType, FunctionDefinition functionDef, + BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + functionType.getFpars().addAll( + toList(filterNull(map(functionDef.getFpars(), + fp -> formalParameterTypesBuilder.createFormalParameter(fp, builtInTypeScope, + preLinkingPhase))))); + } + + protected void setReturnType(TGetter getterType, N4GetterDeclaration getterDef, + BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + if (!preLinkingPhase) { + TypeRef inferredReturnTypeRef = null; + if (getterDef.getDeclaredTypeRefInAST() == null) { + if (!preLinkingPhase) { + if (getterType.isAbstract()) { + inferredReturnTypeRef = builtInTypeScope.getAnyTypeRef(); + } else { + inferredReturnTypeRef = inferReturnTypeFromReturnStatements(getterDef, builtInTypeScope); + } + } + } else { + inferredReturnTypeRef = getterDef.getDeclaredTypeRefInAST(); + } + getterType.setTypeRef(TypeUtils.copyWithProxies(inferredReturnTypeRef)); + } + } + + protected void setReturnType(TFunction functionType, FunctionDefinition functionDef, + BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + if (!preLinkingPhase) { + TypeRef inferredReturnTypeRef = null; + if (functionDef.getDeclaredReturnTypeRefInAST() == null) { + if (!preLinkingPhase) { + inferredReturnTypeRef = inferReturnTypeFromReturnStatements(functionDef, builtInTypeScope); + } + } else { + inferredReturnTypeRef = functionDef.getDeclaredReturnTypeRefInAST(); + } + functionType.setReturnTypeRef(TypeUtils.copyWithProxies(inferredReturnTypeRef)); + // note: handling of the return type of async functions not done here, see + // TypeProcessor#handleAsyncFunctionDeclaration() + } + } + + /** + * Poor man's return type inferencer + */ + // TODO improve that + protected ParameterizedTypeRef inferReturnTypeFromReturnStatements(FunctionDefinition definition, + BuiltInTypeScope builtInTypeScope) { + boolean hasNonVoidReturn = definition.getBody() != null && definition.getBody().hasNonVoidReturn(); + if (hasNonVoidReturn) { + return builtInTypeScope.getAnyTypeRef(); + } else { + /* + * No Return statements usually implies void as result type for the FunctionDefinition, except for those + * representing arrow functions of the single-expression variety, whose result type is heuristically + * approximated as 'any'. + * + * FIXME that single-expr in an arrow function may well be an invocation to a void-method, in which case the + * 'any' choice is wrong. + */ + if (isSingleExprArrowFunction(definition)) { + return builtInTypeScope.getAnyTypeRef(); + } else { + return builtInTypeScope.getVoidTypeRef(); + } + } + } + + private boolean isSingleExprArrowFunction(FunctionDefinition definition) { + if (definition instanceof ArrowFunction) { + return ((ArrowFunction) definition).isSingleExprImplicitReturn(); + } + return false; + } + + /** + * Poor man's return type inferencer + */ + // TODO improve that + protected ParameterizedTypeRef inferReturnTypeFromReturnStatements(N4GetterDeclaration definition, + BuiltInTypeScope builtInTypeScope) { + boolean hasNonVoidReturn = definition.getBody() != null && definition.getBody().hasNonVoidReturn(); + if (hasNonVoidReturn) { + return builtInTypeScope.getAnyTypeRef(); + } else { + return builtInTypeScope.getVoidTypeRef(); + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/AbstractFunctionDefinitionTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/AbstractFunctionDefinitionTypesBuilder.xtend deleted file mode 100644 index fb35a576e4..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/AbstractFunctionDefinitionTypesBuilder.xtend +++ /dev/null @@ -1,125 +0,0 @@ -/** - * 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.typesbuilder - -import com.google.inject.Inject -import org.eclipse.n4js.n4JS.ArrowFunction -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.N4GetterDeclaration -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.types.TFunction -import org.eclipse.n4js.ts.types.TGetter -import org.eclipse.n4js.types.utils.TypeUtils - -/** - * Base class for functions and methods - */ -package abstract class AbstractFunctionDefinitionTypesBuilder { - - @Inject extension N4JSFormalParameterTypesBuilder - - def protected void relinkFormalParameters(TFunction functionType, FunctionDefinition functionDef, boolean preLinkingPhase) { - val builtInTypeScope = BuiltInTypeScope.get(functionDef.eResource.resourceSet) - functionDef.fpars.fold(0) [ idx, fpar | - if (relinkFormalParameter(fpar, functionType, builtInTypeScope, preLinkingPhase, idx)) { - return idx + 1; - } - return idx; - ] - } - - def protected void addFormalParameters(TFunction functionType, FunctionDefinition functionDef, - BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - functionType.fpars.addAll( - functionDef.fpars.map[createFormalParameter(builtInTypeScope, preLinkingPhase)].filterNull); - } - - def protected void setReturnType(TGetter getterType, N4GetterDeclaration getterDef, - BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - if (!preLinkingPhase) { - val inferredReturnTypeRef = - if (getterDef.declaredTypeRefInAST === null) { - if (!preLinkingPhase) { - if(getterType.isAbstract) { - builtInTypeScope.anyTypeRef - } else { - inferReturnTypeFromReturnStatements(getterDef, builtInTypeScope) - } - } - } else { - getterDef.declaredTypeRefInAST - }; - getterType.typeRef = TypeUtils.copyWithProxies(inferredReturnTypeRef); - } - } - - def protected void setReturnType(TFunction functionType, FunctionDefinition functionDef, - BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - if (!preLinkingPhase) { - val inferredReturnTypeRef = - if (functionDef.declaredReturnTypeRefInAST === null) { - if (!preLinkingPhase) { - inferReturnTypeFromReturnStatements(functionDef, builtInTypeScope) - } - } else { - functionDef.declaredReturnTypeRefInAST - }; - functionType.returnTypeRef = TypeUtils.copyWithProxies(inferredReturnTypeRef); - // note: handling of the return type of async functions not done here, see TypeProcessor#handleAsyncFunctionDeclaration() - } - } - - /** - * Poor man's return type inferencer - */ - // TODO improve that - def protected ParameterizedTypeRef inferReturnTypeFromReturnStatements(FunctionDefinition definition, BuiltInTypeScope builtInTypeScope) { - val hasNonVoidReturn = definition.body!==null && definition.body.hasNonVoidReturn; - if (hasNonVoidReturn) { - return builtInTypeScope.anyTypeRef - } else { - /* - * No Return statements usually implies void as result type for the FunctionDefinition, - * except for those representing arrow functions of the single-expression variety, - * whose result type is heuristically approximated as 'any'. - * - * FIXME that single-expr in an arrow function may well be an invocation to - * a void-method, in which case the 'any' choice is wrong. - */ - if (isSingleExprArrowFunction(definition)) { - return builtInTypeScope.anyTypeRef - } else { - return builtInTypeScope.voidTypeRef - } - } - } - - private def boolean isSingleExprArrowFunction(FunctionDefinition definition) { - switch definition { - ArrowFunction: definition.isSingleExprImplicitReturn - default: false - } - } - - /** - * Poor man's return type inferencer - */ - // TODO improve that - def protected ParameterizedTypeRef inferReturnTypeFromReturnStatements(N4GetterDeclaration definition, BuiltInTypeScope builtInTypeScope) { - val hasNonVoidReturn = definition.body!==null && definition.body.hasNonVoidReturn; - if (hasNonVoidReturn) { - builtInTypeScope.anyTypeRef - } else { - builtInTypeScope.voidTypeRef - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassDeclarationTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassDeclarationTypesBuilder.java new file mode 100644 index 0000000000..596d72f5c6 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassDeclarationTypesBuilder.java @@ -0,0 +1,135 @@ +/** + * 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.typesbuilder; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4ClassDefinition; +import org.eclipse.n4js.n4JS.N4ClassExpression; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.utils.N4JSLanguageUtils; + +/***/ +public class N4JSClassDeclarationTypesBuilder extends N4JSClassifierDeclarationTypesBuilder { + + /***/ + protected boolean relinkTClass(N4ClassDeclaration n4Class, AbstractNamespace target, boolean preLinkingPhase, + int idx) { + if (n4Class.getName() == null) { // may be null due to syntax errors + return false; + } + + TClass tclass = (TClass) target.getTypes().get(idx); + + relinkClassifierAndMembers(tclass, n4Class, preLinkingPhase); + return true; + } + + /***/ + protected TClass createTClass(N4ClassDeclaration n4Class, AbstractNamespace target, boolean preLinkingPhase) { + if (n4Class.getName() == null) { // may be null due to syntax errors + return null; + } + + TClass tclass = createTClass(n4Class); + // modifiers + _n4JSTypesBuilderHelper.setTypeAccessModifier(tclass, n4Class); + _n4JSTypesBuilderHelper.setProvidedByRuntime(tclass, n4Class, preLinkingPhase); + tclass.setDeclaredNonStaticPolyfill(N4JSLanguageUtils.isNonStaticPolyfill(n4Class)); + tclass.setDeclaredStaticPolyfill(N4JSLanguageUtils.isStaticPolyfill(n4Class)); + tclass.setDeclaredCovariantConstructor(_n4JSTypesBuilderHelper.isDeclaredCovariantConstructor(n4Class)); + _n4JSTypeVariableTypesBuilder.addTypeParameters(tclass, n4Class, preLinkingPhase); + + // super types etc + setSuperType(tclass, n4Class, preLinkingPhase); + addImplementedInterfaces(tclass, n4Class, preLinkingPhase); + + // members + addFields(tclass, n4Class, preLinkingPhase); + addMethods(tclass, n4Class, target, preLinkingPhase); + + addGetters(tclass, n4Class, target, preLinkingPhase); + addSetters(tclass, n4Class, target, preLinkingPhase); + + _n4JSTypesBuilderHelper.copyAnnotations(tclass, n4Class, preLinkingPhase); + + // + set "bindings" (derived refs from ast to types and vice versa) + tclass.setAstElement(n4Class); + n4Class.setDefinedType(tclass); + + target.getTypes().add(tclass); + + return tclass; + } + + void createTClass(N4ClassExpression n4Class, AbstractNamespace target, boolean preLinkingPhase) { + TClass tclass = createTClass(n4Class); + + // super types etc + setSuperType(tclass, n4Class, preLinkingPhase); + addImplementedInterfaces(tclass, n4Class, preLinkingPhase); + + // members + addFields(tclass, n4Class, preLinkingPhase); + addMethods(tclass, n4Class, target, preLinkingPhase); + + addGetters(tclass, n4Class, target, preLinkingPhase); + addSetters(tclass, n4Class, target, preLinkingPhase); + + _n4JSTypesBuilderHelper.copyAnnotations(tclass, n4Class, preLinkingPhase); + + // + set "bindings" (derived refs from ast to types and vice versa) + tclass.setAstElement(n4Class); + n4Class.setDefinedType(tclass); + + target.getContainingModule().getInternalTypes().add(tclass); + } + + private TClass createTClass(N4ClassDeclaration classDecl) { + TClass tclass = TypesFactory.eINSTANCE.createTClass(); + tclass.setName(classDecl.getName()); + tclass.setExternal(classDecl.isExternal()); + tclass.setDeclaredAbstract(classDecl.isAbstract()); + tclass.setDeclaredFinal(AnnotationDefinition.FINAL.hasAnnotation(classDecl)); + tclass.setObservable(AnnotationDefinition.OBSERVABLE.hasAnnotation(classDecl)); + tclass.setDeclaredEcmaScript(AnnotationDefinition.ECMASCRIPT.hasAnnotation(classDecl)); + + return tclass; + } + + private TClass createTClass(N4ClassExpression classExpr) { + TClass tclass = TypesFactory.eINSTANCE.createTClass(); + tclass.setName(classExpr.getName()); + return tclass; + } + + private void setSuperType(TClass tclass, N4ClassDefinition classDecl, boolean preLinkingPhase) { + if (!preLinkingPhase) { + TypeReferenceNode scr = classDecl.getSuperClassRef(); + tclass.setSuperClassRef(TypeUtils.copyWithProxies(scr == null ? null : scr.getTypeRefInAST())); + } + } + + private void addImplementedInterfaces(TClass tclass, N4ClassDefinition classDecl, boolean preLinkingPhase) { + if (!preLinkingPhase) { + _n4JSTypesBuilderHelper.addCopyOfReferences(tclass.getImplementedInterfaceRefs(), + toList(map(classDecl.getImplementedInterfaceRefs(), ir -> ir.getTypeRefInAST()))); + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassDeclarationTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassDeclarationTypesBuilder.xtend deleted file mode 100644 index f99f316f83..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassDeclarationTypesBuilder.xtend +++ /dev/null @@ -1,122 +0,0 @@ -/** - * 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.typesbuilder - -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.n4JS.N4ClassDefinition -import org.eclipse.n4js.n4JS.N4ClassExpression -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.utils.N4JSLanguageUtils - -public class N4JSClassDeclarationTypesBuilder extends N4JSClassifierDeclarationTypesBuilder { - - def protected boolean relinkTClass(N4ClassDeclaration n4Class, AbstractNamespace target, boolean preLinkingPhase, int idx) { - if (n4Class.name === null) { // may be null due to syntax errors - return false; - } - - val TClass tclass = target.types.get(idx) as TClass - - tclass.relinkClassifierAndMembers(n4Class, preLinkingPhase); - return true; - } - - def protected TClass createTClass(N4ClassDeclaration n4Class, AbstractNamespace target, boolean preLinkingPhase) { - if (n4Class.name === null) { // may be null due to syntax errors - return null; - } - - val TClass tclass = n4Class.createTClass; - // modifiers - tclass.setTypeAccessModifier(n4Class); - tclass.setProvidedByRuntime(n4Class, preLinkingPhase); - tclass.declaredNonStaticPolyfill = N4JSLanguageUtils.isNonStaticPolyfill(n4Class); - tclass.declaredStaticPolyfill = N4JSLanguageUtils.isStaticPolyfill(n4Class); - tclass.declaredCovariantConstructor = n4Class.isDeclaredCovariantConstructor; - tclass.addTypeParameters(n4Class, preLinkingPhase); - - // super types etc - tclass.setSuperType(n4Class, preLinkingPhase); - tclass.addImplementedInterfaces(n4Class, preLinkingPhase); - - // members - tclass.addFields(n4Class, preLinkingPhase); - tclass.addMethods(n4Class, target, preLinkingPhase); - - tclass.addGetters(n4Class, target, preLinkingPhase); - tclass.addSetters(n4Class, target, preLinkingPhase); - - tclass.copyAnnotations(n4Class, preLinkingPhase); - - // + set "bindings" (derived refs from ast to types and vice versa) - tclass.astElement = n4Class; - n4Class.definedType = tclass; - - target.types += tclass; - - return tclass; - } - - def package createTClass(N4ClassExpression n4Class, AbstractNamespace target, boolean preLinkingPhase) { - val tclass = n4Class.createTClass; - - // super types etc - tclass.setSuperType(n4Class, preLinkingPhase); - tclass.addImplementedInterfaces(n4Class, preLinkingPhase); - - // members - tclass.addFields(n4Class, preLinkingPhase); - tclass.addMethods(n4Class, target, preLinkingPhase); - - tclass.addGetters(n4Class, target, preLinkingPhase); - tclass.addSetters(n4Class, target, preLinkingPhase); - - tclass.copyAnnotations(n4Class, preLinkingPhase); - - // + set "bindings" (derived refs from ast to types and vice versa) - tclass.astElement = n4Class; - n4Class.definedType = tclass; - - target.containingModule.internalTypes += tclass; - } - - def private createTClass(N4ClassDeclaration classDecl) { - val tclass = TypesFactory::eINSTANCE.createTClass(); - tclass.name = classDecl.name; - tclass.external = classDecl.external; - tclass.declaredAbstract = classDecl.abstract; - tclass.declaredFinal = AnnotationDefinition.FINAL.hasAnnotation(classDecl); - tclass.observable = AnnotationDefinition.OBSERVABLE.hasAnnotation(classDecl); - tclass.declaredEcmaScript = AnnotationDefinition.ECMASCRIPT.hasAnnotation(classDecl); - - return tclass; - } - - def private createTClass(N4ClassExpression classExpr) { - val tclass = TypesFactory::eINSTANCE.createTClass(); - tclass.name = classExpr.name; - return tclass; - } - - def private setSuperType(TClass tclass, N4ClassDefinition classDecl, boolean preLinkingPhase) { - if (!preLinkingPhase) - tclass.superClassRef = TypeUtils.copyWithProxies(classDecl.superClassRef?.typeRefInAST); - } - - def private addImplementedInterfaces(TClass tclass, N4ClassDefinition classDecl, boolean preLinkingPhase) { - if (!preLinkingPhase) - addCopyOfReferences(tclass.implementedInterfaceRefs, classDecl.implementedInterfaceRefs.map[typeRefInAST]); - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassifierDeclarationTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassifierDeclarationTypesBuilder.java new file mode 100644 index 0000000000..66d6e38c4a --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassifierDeclarationTypesBuilder.java @@ -0,0 +1,167 @@ +/** + * Copyright (c) 2017 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.typesbuilder; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filterNull; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.n4js.compileTime.CompileTimeEvaluator; +import org.eclipse.n4js.compileTime.CompileTimeValue; +import org.eclipse.n4js.compileTime.CompileTimeValue.ValueValid; +import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; +import org.eclipse.n4js.n4JS.N4ClassifierDefinition; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.n4JS.N4GetterDeclaration; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.N4MethodDeclaration; +import org.eclipse.n4js.n4JS.N4SetterDeclaration; +import org.eclipse.n4js.n4JS.PropertyNameOwner; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.TSetter; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; +import org.eclipse.n4js.utils.N4JSLanguageUtils; + +import com.google.inject.Inject; + +/** + * Abstract base class for N4JSClassDeclarationTypesBuilder and N4JSInterfaceDeclarationTypesBuilder to provide reusable + * bits and pieces. + */ +abstract class N4JSClassifierDeclarationTypesBuilder { + + @Inject + protected N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + @Inject + protected N4JSTypeVariableTypesBuilder _n4JSTypeVariableTypesBuilder; + @Inject + protected N4JSFieldTypesBuilder _n4JSFieldTypesBuilder; + @Inject + protected N4JSMethodTypesBuilder _n4JSMethodTypesBuilder; + @Inject + protected N4JSGetterTypesBuilder _n4JSGetterTypesBuilder; + @Inject + protected N4JSSetterTypesBuilder _n4JSSetterTypesBuilder; + @Inject + protected CompileTimeEvaluator compileTimeEvaluator; + + protected void addFields(TClassifier classifier, N4ClassifierDefinition definition, boolean preLinkingPhase) { + Iterable n4Fields = filter(definition.getOwnedMembers(), N4FieldDeclaration.class); + List fields = toList( + filterNull(map(n4Fields, f -> _n4JSFieldTypesBuilder.createField(f, classifier, preLinkingPhase)))); + classifier.getOwnedMembers().addAll(fields); + } + + protected void addMethods(TClassifier classifier, N4ClassifierDefinition definition, AbstractNamespace target, + boolean preLinkingPhase) { + // note: won't include call/construct signatures + Iterable n4Methods = filter(definition.getOwnedMembers(), N4MethodDeclaration.class); + List methods = toList( + filterNull(map(n4Methods, m -> _n4JSMethodTypesBuilder.createMethod(m, target, preLinkingPhase)))); + classifier.getOwnedMembers().addAll(methods); + + N4MethodDeclaration cs = definition.getOwnedCallSignature(); + N4MethodDeclaration css = definition.getOwnedConstructSignature(); + classifier.setCallSignature( + cs == null ? null : _n4JSMethodTypesBuilder.createMethod(cs, target, preLinkingPhase)); + classifier.setConstructSignature( + css == null ? null : _n4JSMethodTypesBuilder.createMethod(css, target, preLinkingPhase)); + } + + protected void addGetters(TClassifier classifier, N4ClassifierDefinition definition, AbstractNamespace target, + boolean preLinkingPhase) { + // create also getters for all non private fields without explicit getter + Iterable n4Getters = filter(definition.getOwnedMembers(), N4GetterDeclaration.class); + List getters = toList(filterNull( + map(n4Getters, g -> _n4JSGetterTypesBuilder.createGetter(g, classifier, target, preLinkingPhase)))); + classifier.getOwnedMembers().addAll(getters); + } + + protected void addSetters(TClassifier classifier, N4ClassifierDefinition definition, AbstractNamespace target, + boolean preLinkingPhase) { + // create also getters for all non private fields without explicit getter + Iterable n4Setters = filter(definition.getOwnedMembers(), N4SetterDeclaration.class); + List setters = toList(filterNull( + map(n4Setters, s -> _n4JSSetterTypesBuilder.createSetter(s, classifier, target, preLinkingPhase)))); + classifier.getOwnedMembers().addAll(setters); + } + + void relinkClassifierAndMembers(TClassifier classifier, N4ClassifierDeclaration declaration, + boolean preLinkingPhase) { + _n4JSTypesBuilderHelper.ensureEqualName(declaration, classifier); + + // members + N4MethodDeclaration astCallSig = declaration.getOwnedCallSignature(); + if (astCallSig != null) { + _n4JSMethodTypesBuilder.relinkMethod(astCallSig, classifier.getCallSignature(), preLinkingPhase); + } + N4MethodDeclaration astConstructSig = declaration.getOwnedConstructSignature(); + if (astConstructSig != null) { + _n4JSMethodTypesBuilder.relinkMethod(astConstructSig, classifier.getConstructSignature(), preLinkingPhase); + } + + // OWNED members + Map memberByName = new HashMap<>(); + for (N4MemberDeclaration member : declaration.getOwnedMembersRaw()) { + PropertyNameOwner pno = (PropertyNameOwner) member; + if (member.getName() != null) { + memberByName.put(member.getName(), member); + } else if (pno.hasComputedPropertyName()) { + Expression expr = pno.getDeclaredName().getExpression(); + if (N4JSLanguageUtils.isProcessedAsCompileTimeExpression(expr)) { + RuleEnvironment G = RuleEnvironmentExtensions.newRuleEnvironment(pno); + CompileTimeValue ctv = compileTimeEvaluator.evaluateCompileTimeExpression(G, expr); + if (ctv.isValid()) { + String ctvName = ((ValueValid) ctv).getValue().toString(); + memberByName.put(ctvName, member); + } + } + } + } + + for (TMember tMember : classifier.getOwnedMembers()) { + N4MemberDeclaration member = memberByName.get(tMember.getName()); + if (tMember instanceof TField && member instanceof N4FieldDeclaration) { + _n4JSFieldTypesBuilder.relinkField((N4FieldDeclaration) member, (TField) tMember, preLinkingPhase); + } + if (tMember instanceof TMethod && member instanceof N4MethodDeclaration) { + N4MethodDeclaration method = (N4MethodDeclaration) member; + if (!method.isConstructSignature() && !method.isCallSignature()) { + _n4JSMethodTypesBuilder.relinkMethod(method, (TMethod) tMember, preLinkingPhase); + } + } + if (tMember instanceof TGetter && member instanceof N4GetterDeclaration) { + _n4JSGetterTypesBuilder.relinkGetter((N4GetterDeclaration) member, (TGetter) tMember, preLinkingPhase); + } + if (tMember instanceof TSetter && member instanceof N4SetterDeclaration) { + _n4JSSetterTypesBuilder.relinkSetter((N4SetterDeclaration) member, (TSetter) tMember, preLinkingPhase); + } + } + + // TODO proxy resolve vs setter invocation? + classifier.setAstElement(declaration); + // setter is ok here + declaration.setDefinedType(classifier); + } + +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassifierDeclarationTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassifierDeclarationTypesBuilder.xtend deleted file mode 100644 index 1deeadd0a1..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSClassifierDeclarationTypesBuilder.xtend +++ /dev/null @@ -1,136 +0,0 @@ -/** - * Copyright (c) 2017 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.typesbuilder - -import com.google.inject.Inject -import java.util.HashMap -import java.util.Map -import org.eclipse.n4js.compileTime.CompileTimeEvaluator -import org.eclipse.n4js.compileTime.CompileTimeValue.ValueValid -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.n4JS.N4ClassifierDefinition -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.n4JS.N4GetterDeclaration -import org.eclipse.n4js.n4JS.N4MemberDeclaration -import org.eclipse.n4js.n4JS.N4MethodDeclaration -import org.eclipse.n4js.n4JS.N4SetterDeclaration -import org.eclipse.n4js.n4JS.PropertyNameOwner -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TField -import org.eclipse.n4js.ts.types.TGetter -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.ts.types.TSetter -import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions -import org.eclipse.n4js.utils.N4JSLanguageUtils - -/** - * Abstract base class for N4JSClassDeclarationTypesBuilder and N4JSInterfaceDeclarationTypesBuilder - * to provide reusable bits and pieces. - */ -package abstract class N4JSClassifierDeclarationTypesBuilder { - - @Inject protected extension N4JSTypesBuilderHelper - @Inject protected extension N4JSTypeVariableTypesBuilder - @Inject protected extension N4JSFieldTypesBuilder - @Inject protected extension N4JSMethodTypesBuilder - @Inject protected extension N4JSGetterTypesBuilder - @Inject protected extension N4JSSetterTypesBuilder - @Inject protected CompileTimeEvaluator compileTimeEvaluator; - - def protected void addFields(TClassifier classifier, N4ClassifierDefinition definition, boolean preLinkingPhase) { - val n4Fields = definition.ownedMembers.filter(N4FieldDeclaration); - val fields = n4Fields.map[createField(classifier, preLinkingPhase)].filterNull - classifier.ownedMembers.addAll(fields); - } - - def protected void addMethods(TClassifier classifier, N4ClassifierDefinition definition, AbstractNamespace target, boolean preLinkingPhase) { - val n4Methods = definition.ownedMembers.filter(N4MethodDeclaration); // note: won't include call/construct signatures - val methods = n4Methods.map[createMethod(target, preLinkingPhase)].filterNull; - classifier.ownedMembers.addAll(methods); - classifier.callSignature = definition.ownedCallSignature?.createMethod(target, preLinkingPhase); - classifier.constructSignature = definition.ownedConstructSignature?.createMethod(target, preLinkingPhase); - } - - def protected void addGetters(TClassifier classifier, N4ClassifierDefinition definition, AbstractNamespace target, boolean preLinkingPhase) { - // create also getters for all non private fields without explicit getter - val n4Getters = definition.ownedMembers.filter(N4GetterDeclaration) - val getters = n4Getters.map[createGetter(classifier, target, preLinkingPhase)].filterNull - classifier.ownedMembers.addAll(getters); - } - - def protected void addSetters(TClassifier classifier, N4ClassifierDefinition definition, AbstractNamespace target, boolean preLinkingPhase) { - // create also getters for all non private fields without explicit getter - val n4Setters = definition.ownedMembers.filter(N4SetterDeclaration) - val setters = n4Setters.map[createSetter(classifier, target, preLinkingPhase)].filterNull - classifier.ownedMembers.addAll(setters); - } - - def package void relinkClassifierAndMembers(TClassifier classifier, N4ClassifierDeclaration declaration, boolean preLinkingPhase) { - ensureEqualName(declaration, classifier); - - // members - val astCallSig = declaration.ownedCallSignature; - if (astCallSig !== null ) { - relinkMethod(astCallSig, classifier.callSignature, preLinkingPhase) - } - val astConstructSig = declaration.ownedConstructSignature; - if (astConstructSig !== null) { - relinkMethod(astConstructSig, classifier.constructSignature, preLinkingPhase) - } - - // OWNED members - val Map memberByName = new HashMap(); - for (member : declaration.ownedMembersRaw) { - val pno = member as PropertyNameOwner; - if (member.name !== null) { - memberByName.put(member.name, member); - } else if (pno.hasComputedPropertyName) { - val expr = pno.declaredName.expression; - if (N4JSLanguageUtils.isProcessedAsCompileTimeExpression(expr)) { - val G = RuleEnvironmentExtensions.newRuleEnvironment(pno); - val ctv = compileTimeEvaluator.evaluateCompileTimeExpression(G, expr); - if (ctv.valid) { - val ctvName = (ctv as ValueValid).value.toString; - memberByName.put(ctvName, member); - } - } - } - } - - var idx = 0; - for (tMember : classifier.ownedMembers) { - val member = memberByName.get(tMember.name); - if (tMember instanceof TField && member instanceof N4FieldDeclaration) { - relinkField(member as N4FieldDeclaration, tMember as TField, preLinkingPhase); - } - if (tMember instanceof TMethod && member instanceof N4MethodDeclaration) { - val method = member as N4MethodDeclaration; - if (!method.isConstructSignature && !method.isCallSignature) { - relinkMethod(method, tMember as TMethod, preLinkingPhase); - } - } - if (tMember instanceof TGetter && member instanceof N4GetterDeclaration) { - relinkGetter(member as N4GetterDeclaration, tMember as TGetter, preLinkingPhase); - } - if (tMember instanceof TSetter && member instanceof N4SetterDeclaration) { - relinkSetter(member as N4SetterDeclaration, tMember as TSetter, preLinkingPhase); - } - idx++; - } - - // TODO proxy resolve vs setter invocation? - classifier.astElement = declaration; - // setter is ok here - declaration.definedType = classifier; - } - -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSEnumDeclarationTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSEnumDeclarationTypesBuilder.java new file mode 100644 index 0000000000..cacba812ee --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSEnumDeclarationTypesBuilder.java @@ -0,0 +1,145 @@ +/** + * 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.typesbuilder; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filterNull; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.fold; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toSet; + +import java.math.BigDecimal; +import java.util.Set; + +import org.eclipse.n4js.n4JS.N4EnumDeclaration; +import org.eclipse.n4js.n4JS.N4EnumLiteral; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TEnum; +import org.eclipse.n4js.ts.types.TEnumLiteral; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind; + +import com.google.inject.Inject; + +@SuppressWarnings("javadoc") +public class N4JSEnumDeclarationTypesBuilder { + + @Inject + N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + + boolean relinkTEnum(N4EnumDeclaration n4Enum, AbstractNamespace target, + @SuppressWarnings("unused") boolean preLinkingPhase, int idx) { + + if (n4Enum.getName() == null) { + return false; + } + + TEnum enumType = (TEnum) target.getTypes().get(idx); + _n4JSTypesBuilderHelper.ensureEqualName(n4Enum, enumType); + + relinkTEnumLiterals(n4Enum, enumType); + + enumType.setAstElement(n4Enum); + n4Enum.setDefinedType(enumType); + return true; + } + + private int relinkTEnumLiterals(N4EnumDeclaration n4Enum, TEnum tEnum) { + return fold(n4Enum.getLiterals(), 0, (idx, n4EnumLit) -> { + if (relinkTEnumLiteral(n4EnumLit, tEnum, idx)) { + return idx + 1; + } + return idx; + }); + } + + private boolean relinkTEnumLiteral(N4EnumLiteral n4EnumLit, TEnum tEnum, int idx) { + TEnumLiteral tEnumLit = tEnum.getLiterals().get(idx); + _n4JSTypesBuilderHelper.ensureEqualName(n4EnumLit, tEnumLit); + tEnumLit.setAstElement(n4EnumLit); + n4EnumLit.setDefinedLiteral(tEnumLit); + return true; + } + + protected TEnum createTEnum(N4EnumDeclaration n4Enum, AbstractNamespace target, boolean preLinkingPhase) { + if (n4Enum.getName() == null) { + return null; + } + + TEnum enumType = createTEnum(n4Enum); + _n4JSTypesBuilderHelper.setTypeAccessModifier(enumType, n4Enum); + _n4JSTypesBuilderHelper.setProvidedByRuntime(enumType, n4Enum, preLinkingPhase); + addLiterals(enumType, n4Enum); + _n4JSTypesBuilderHelper.copyAnnotations(enumType, n4Enum, preLinkingPhase); + + computeDefaultValues(enumType, n4Enum); + + enumType.setAstElement(n4Enum); + n4Enum.setDefinedType(enumType); + + target.getTypes().add(enumType); + + return enumType; + } + + private TEnum createTEnum(N4EnumDeclaration n4Enum) { + TEnum enumType = TypesFactory.eINSTANCE.createTEnum(); + enumType.setName(n4Enum.getName()); + enumType.setExternal(n4Enum.isExternal()); + return enumType; + } + + private void addLiterals(TEnum enumType, N4EnumDeclaration n4Enum) { + enumType.getLiterals().addAll(toList( + map(filter(n4Enum.getLiterals(), N4EnumLiteral.class), el -> createEnumLiteral(el)))); + } + + private TEnumLiteral createEnumLiteral(N4EnumLiteral n4Literal) { + Object value = N4JSLanguageUtils.getEnumLiteralValue(n4Literal); + + TEnumLiteral tLiteral = TypesFactory.eINSTANCE.createTEnumLiteral(); + tLiteral.setName(n4Literal.getName()); + tLiteral.setValueString((value instanceof String) ? (String) value : null); + tLiteral.setValueNumber((value instanceof BigDecimal) ? (BigDecimal) value : null); + tLiteral.setAstElement(n4Literal); + n4Literal.setDefinedLiteral(tLiteral); + return tLiteral; + } + + private void computeDefaultValues(TEnum enumType, N4EnumDeclaration n4Enum) { + EnumKind enumKind = N4JSLanguageUtils.getEnumKind(n4Enum); + if (enumKind == EnumKind.NumberBased) { + // @NumberBased enums + Set usedNumbers = toSet(filterNull(map(enumType.getLiterals(), l -> l.getValueNumber()))); + BigDecimal next = BigDecimal.ONE.negate(); + for (TEnumLiteral tLiteral : enumType.getLiterals()) { + if (tLiteral.getValueNumber() != null) { + next = tLiteral.getValueNumber(); + } else { + do { + next = next.add(BigDecimal.ONE); + } while (usedNumbers.contains(next)); + tLiteral.setValueNumber(next); + usedNumbers.add(next); + } + } + } else { + // ordinary and @StringBased enums + for (TEnumLiteral lit : enumType.getLiterals()) { + if (lit.getValueString() == null) { + lit.setValueString(lit.getName()); + } + } + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSEnumDeclarationTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSEnumDeclarationTypesBuilder.xtend deleted file mode 100644 index 0f1fbfaeb1..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSEnumDeclarationTypesBuilder.xtend +++ /dev/null @@ -1,126 +0,0 @@ -/** - * 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.typesbuilder - -import com.google.inject.Inject -import java.math.BigDecimal -import org.eclipse.n4js.n4JS.N4EnumDeclaration -import org.eclipse.n4js.n4JS.N4EnumLiteral -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.TEnum -import org.eclipse.n4js.ts.types.TEnumLiteral -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.utils.N4JSLanguageUtils.EnumKind - -public class N4JSEnumDeclarationTypesBuilder { - - @Inject extension N4JSTypesBuilderHelper - - def package boolean relinkTEnum(N4EnumDeclaration n4Enum, AbstractNamespace target, boolean preLinkingPhase, int idx) { - if (n4Enum.name === null) { - return false; - } - - val TEnum enumType = target.types.get(idx) as TEnum - ensureEqualName(n4Enum, enumType); - - relinkTEnumLiterals(n4Enum, enumType, preLinkingPhase); - - enumType.astElement = n4Enum - n4Enum.definedType = enumType - return true; - } - - def private int relinkTEnumLiterals(N4EnumDeclaration n4Enum, TEnum tEnum, boolean preLinkingPhase) { - return n4Enum.literals.fold(0) [ idx, n4EnumLit | - if (relinkTEnumLiteral(n4EnumLit, tEnum, preLinkingPhase, idx)) { - return idx + 1; - } - return idx; - ] - } - - def private boolean relinkTEnumLiteral(N4EnumLiteral n4EnumLit, TEnum tEnum, boolean preLinkingPhase, int idx) { - val tEnumLit = tEnum.literals.get(idx); - ensureEqualName(n4EnumLit, tEnumLit); - tEnumLit.astElement = n4EnumLit; - n4EnumLit.definedLiteral = tEnumLit; - return true; - } - - def protected TEnum createTEnum(N4EnumDeclaration n4Enum, AbstractNamespace target, boolean preLinkingPhase) { - if (n4Enum.name === null) { - return null; - } - - val enumType = n4Enum.createTEnum - enumType.setTypeAccessModifier(n4Enum) - enumType.setProvidedByRuntime(n4Enum, preLinkingPhase) - enumType.addLiterals(n4Enum, preLinkingPhase) - enumType.copyAnnotations(n4Enum, preLinkingPhase) - - computeDefaultValues(enumType, n4Enum); - - enumType.astElement = n4Enum - n4Enum.definedType = enumType - - target.types += enumType - - return enumType; - } - - def private TEnum createTEnum(N4EnumDeclaration n4Enum) { - val enumType = TypesFactory::eINSTANCE.createTEnum(); - enumType.name = n4Enum.name; - enumType.external = n4Enum.external; - enumType - } - - def private void addLiterals(TEnum enumType, N4EnumDeclaration n4Enum, boolean preLinkingPhase) { - enumType.literals.addAll(n4Enum.literals.filter(N4EnumLiteral).map[createEnumLiteral(preLinkingPhase)]); - } - - def private TEnumLiteral createEnumLiteral(N4EnumLiteral n4Literal, boolean preLinkingPhase) { - val value = N4JSLanguageUtils.getEnumLiteralValue(n4Literal); - - val tLiteral = TypesFactory::eINSTANCE.createTEnumLiteral(); - tLiteral.name = n4Literal.name; - tLiteral.valueString = if (value instanceof String) value; - tLiteral.valueNumber = if (value instanceof BigDecimal) value; - tLiteral.astElement = n4Literal; - n4Literal.definedLiteral = tLiteral - return tLiteral; - } - - def private void computeDefaultValues(TEnum enumType, N4EnumDeclaration n4Enum) { - val enumKind = N4JSLanguageUtils.getEnumKind(n4Enum); - if (enumKind === EnumKind.NumberBased) { - // @NumberBased enums - val usedNumbers = enumType.literals.map[valueNumber].filterNull.toSet; - var next = BigDecimal.ONE.negate(); - for (tLiteral : enumType.literals) { - if (tLiteral.valueNumber !== null) { - next = tLiteral.valueNumber; - } else { - do { - next = next.add(BigDecimal.ONE); - } while(usedNumbers.contains(next)); - tLiteral.valueNumber = next; - usedNumbers += next; - } - } - } else { - // ordinary and @StringBased enums - enumType.literals.filter[valueString === null].forEach[valueString = name]; - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSExportDefinitionTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSExportDefinitionTypesBuilder.java new file mode 100644 index 0000000000..a9ae6a4659 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSExportDefinitionTypesBuilder.java @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2022 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.typesbuilder; + +import java.util.Objects; + +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.n4js.N4JSLanguageConstants; +import org.eclipse.n4js.n4JS.ExportDeclaration; +import org.eclipse.n4js.n4JS.ExportableElement; +import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.NamedExportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceExportSpecifier; +import org.eclipse.n4js.n4JS.TypeDefiningElement; +import org.eclipse.n4js.n4JS.VariableStatement; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.ElementExportDefinition; +import org.eclipse.n4js.ts.types.ExportDefinition; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.ModuleExportDefinition; +import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType; +import org.eclipse.n4js.ts.types.TExportableElement; +import org.eclipse.n4js.ts.types.TExportingElement; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.xtext.EcoreUtil2; + +import com.google.inject.Inject; + +/** + * Does not create new types but instead creates {@link ExportDefinition}s for {@link ExportDeclaration}s. + */ +class N4JSExportDefinitionTypesBuilder { + + @Inject + N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + + // relinking export definitions not required + // (see N4JSTypesBuilder#relinkTypes(EObject, AbstractNamespace, boolean, RelinkIndices) for details) + + void createExportDefinition(ExportDeclaration exportDecl, AbstractNamespace target, boolean preLinkingPhase) { + ExportableElement directlyExportedElem = exportDecl.getExportedElement(); + if (directlyExportedElem != null) { + createExportDefinitionForDirectlyExportedElement(directlyExportedElem, target, preLinkingPhase); + } else if (exportDecl.getNamespaceExport() != null) { + NamespaceExportSpecifier exportSpec = exportDecl.getNamespaceExport(); + TModule exportedModuleProxy = (TModule) exportDecl.eGet(N4JSPackage.eINSTANCE.getModuleRef_Module(), false); + if (exportedModuleProxy != null) { + TModule exportedModuleProxyCopy = EcoreUtil2.cloneWithProxies(exportedModuleProxy); + String alias = exportSpec.getAlias(); + if (alias != null) { + ModuleNamespaceVirtualType mnvt = _n4JSTypesBuilderHelper.addNewModuleNamespaceVirtualType( + target.getContainingModule(), alias, exportedModuleProxy, false, exportSpec); + addElementExportDefinition(target, alias, mnvt); + } else { + addModuleExportDefinition(target, exportedModuleProxyCopy); + } + } + } else { + for (NamedExportSpecifier exportSpec : exportDecl.getNamedExports()) { + IdentifierRef idRef = exportSpec.getExportedElement(); + if (idRef != null) { + IdentifiableElement expElemProxy = (IdentifiableElement) idRef + .eGet(N4JSPackage.eINSTANCE.getIdentifierRef_Id(), false); + if (expElemProxy != null) { + TExportableElement expElemProxyCpy = TypesFactory.eINSTANCE.createTExportableElement(); + ((InternalEObject) expElemProxyCpy).eSetProxyURI(((InternalEObject) expElemProxy).eProxyURI()); + var expName = exportSpec.getAlias(); + if (expName == null) { + // we do not use the name of the actually exported element here, because ... + // 1) we only have a proxy to the exported element (i.e. expElemProxy) anyway and are not + // allowed + // to trigger proxy resolution in the types builder, so we cannot retrieve its name; + // 2) the exported element might have been imported from another file under an alias and in + // that + // case the import specifier's alias will be the default exported name, not the element's + // name. + expName = idRef.getIdAsText(); + } + addElementExportDefinition(target, expName, expElemProxyCpy); + } + } + } + } + } + + void createExportDefinitionForDirectlyExportedElement(ExportableElement directlyExportedElem, + AbstractNamespace target, boolean preLinkingPhase) { + if (directlyExportedElem instanceof VariableStatement) { + // variable statements inherit from ExportableElement, but they do not actually represent + // the element being exported (instead, the variable declarations represent those elements) + // --> ignore them here + return; + } + TExportableElement tDirectlyExportedElem = getExportedTypesModelElement(directlyExportedElem); + if (tDirectlyExportedElem == null) { + return; // broken AST (e.g. class declaration with missing name) + } + createExportDefinitionForDirectlyExportedElement(tDirectlyExportedElem, + directlyExportedElem.getDirectlyExportedName(), target, preLinkingPhase); + } + + void createExportDefinitionForDirectlyExportedElement(TExportableElement tDirectlyExportedElem, String exportedName, + AbstractNamespace target, @SuppressWarnings("unused") boolean preLinkingPhase) { + tDirectlyExportedElem.setDirectlyExported(true); + tDirectlyExportedElem + .setDirectlyExportedAsDefault(N4JSLanguageConstants.EXPORT_DEFAULT_NAME.equals(exportedName)); + addElementExportDefinition(target, exportedName, tDirectlyExportedElem); + } + + private void addModuleExportDefinition(TExportingElement exportingElem, TModule exportedModule) { + ModuleExportDefinition expDef = TypesFactory.eINSTANCE.createModuleExportDefinition(); + expDef.setExportedModule(exportedModule); + exportingElem.getExportDefinitions().add(expDef); + } + + private ExportDefinition addElementExportDefinition(TExportingElement exportingElem, String exportedName, + TExportableElement exportedElem) { + Objects.requireNonNull(exportingElem); + Objects.requireNonNull(exportedName); + Objects.requireNonNull(exportedElem); + ElementExportDefinition expDef = TypesFactory.eINSTANCE.createElementExportDefinition(); + expDef.setExportedName(exportedName); + expDef.setExportedElement(exportedElem); + exportingElem.getExportDefinitions().add(expDef); + return expDef; + } + + private TExportableElement getExportedTypesModelElement(ExportableElement n4ExportableElem) { + if (n4ExportableElem instanceof TypeDefiningElement) { + return ((TypeDefiningElement) n4ExportableElem).getDefinedType(); + } + return null; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSExportDefinitionTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSExportDefinitionTypesBuilder.xtend deleted file mode 100644 index 08ea295a51..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSExportDefinitionTypesBuilder.xtend +++ /dev/null @@ -1,125 +0,0 @@ -/** - * Copyright (c) 2022 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.typesbuilder - -import com.google.inject.Inject -import java.util.Objects -import org.eclipse.emf.ecore.InternalEObject -import org.eclipse.n4js.N4JSLanguageConstants -import org.eclipse.n4js.n4JS.ExportDeclaration -import org.eclipse.n4js.n4JS.ExportableElement -import org.eclipse.n4js.n4JS.N4JSPackage -import org.eclipse.n4js.n4JS.NamedExportSpecifier -import org.eclipse.n4js.n4JS.TypeDefiningElement -import org.eclipse.n4js.n4JS.VariableStatement -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.ExportDefinition -import org.eclipse.n4js.ts.types.IdentifiableElement -import org.eclipse.n4js.ts.types.TExportableElement -import org.eclipse.n4js.ts.types.TExportingElement -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.xtext.EcoreUtil2 - -/** - * Does not create new types but instead creates {@link ExportDefinition}s for {@link ExportDeclaration}s. - */ -class N4JSExportDefinitionTypesBuilder { - - @Inject extension N4JSTypesBuilderHelper - - // relinking export definitions not required - // (see N4JSTypesBuilder#relinkTypes(EObject, AbstractNamespace, boolean, RelinkIndices) for details) - - def package void createExportDefinition(ExportDeclaration exportDecl, AbstractNamespace target, boolean preLinkingPhase) { - val directlyExportedElem = exportDecl.exportedElement; - if (directlyExportedElem !== null) { - createExportDefinitionForDirectlyExportedElement(directlyExportedElem, target, preLinkingPhase); - } else if (exportDecl.namespaceExport !== null) { - val exportSpec = exportDecl.namespaceExport; - val exportedModuleProxy = exportDecl.eGet(N4JSPackage.eINSTANCE.moduleRef_Module, false) as TModule; - if (exportedModuleProxy !== null) { - val exportedModuleProxyCopy = EcoreUtil2.cloneWithProxies(exportedModuleProxy); - val alias = exportSpec.alias; - if (alias !== null) { - val mnvt = target.containingModule.addNewModuleNamespaceVirtualType(alias, exportedModuleProxy, false, exportSpec); - addElementExportDefinition(target, alias, mnvt); - } else { - addModuleExportDefinition(target, exportedModuleProxyCopy); - } - } - } else { - for (NamedExportSpecifier exportSpec : exportDecl.namedExports) { - val idRef = exportSpec.exportedElement; - if (idRef !== null) { - val expElemProxy = idRef.eGet(N4JSPackage.eINSTANCE.identifierRef_Id, false) as IdentifiableElement; - if (expElemProxy !== null) { - val expElemProxyCpy = TypesFactory.eINSTANCE.createTExportableElement(); - (expElemProxyCpy as InternalEObject).eSetProxyURI((expElemProxy as InternalEObject).eProxyURI()); - var expName = exportSpec.alias; - if (expName === null) { - // we do not use the name of the actually exported element here, because ... - // 1) we only have a proxy to the exported element (i.e. expElemProxy) anyway and are not allowed - // to trigger proxy resolution in the types builder, so we cannot retrieve its name; - // 2) the exported element might have been imported from another file under an alias and in that - // case the import specifier's alias will be the default exported name, not the element's name. - expName = idRef.idAsText; - } - addElementExportDefinition(target, expName, expElemProxyCpy); - } - } - } - } - } - - def package void createExportDefinitionForDirectlyExportedElement(ExportableElement directlyExportedElem, AbstractNamespace target, boolean preLinkingPhase) { - if (directlyExportedElem instanceof VariableStatement) { - // variable statements inherit from ExportableElement, but they do not actually represent - // the element being exported (instead, the variable declarations represent those elements) - // --> ignore them here - return; - } - val tDirectlyExportedElem = getExportedTypesModelElement(directlyExportedElem); - if (tDirectlyExportedElem === null) { - return; // broken AST (e.g. class declaration with missing name) - } - createExportDefinitionForDirectlyExportedElement(tDirectlyExportedElem, directlyExportedElem.directlyExportedName, target, preLinkingPhase); - } - - def package void createExportDefinitionForDirectlyExportedElement(TExportableElement tDirectlyExportedElem, String exportedName, AbstractNamespace target, boolean preLinkingPhase) { - tDirectlyExportedElem.directlyExported = true; - tDirectlyExportedElem.directlyExportedAsDefault = exportedName == N4JSLanguageConstants.EXPORT_DEFAULT_NAME; - addElementExportDefinition(target, exportedName, tDirectlyExportedElem); - } - - def private void addModuleExportDefinition(TExportingElement exportingElem, TModule exportedModule) { - val expDef = TypesFactory.eINSTANCE.createModuleExportDefinition(); - expDef.exportedModule = exportedModule; - exportingElem.exportDefinitions += expDef; - } - - def private ExportDefinition addElementExportDefinition(TExportingElement exportingElem, String exportedName, TExportableElement exportedElem) { - Objects.requireNonNull(exportingElem); - Objects.requireNonNull(exportedName); - Objects.requireNonNull(exportedElem); - val expDef = TypesFactory.eINSTANCE.createElementExportDefinition(); - expDef.exportedName = exportedName; - expDef.exportedElement = exportedElem; - exportingElem.exportDefinitions += expDef; - return expDef; - } - - def private TExportableElement getExportedTypesModelElement(ExportableElement n4ExportableElem) { - return switch n4ExportableElem { - TypeDefiningElement: n4ExportableElem.definedType - }; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFieldTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFieldTypesBuilder.java new file mode 100644 index 0000000000..d4755b5dac --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFieldTypesBuilder.java @@ -0,0 +1,90 @@ +/** + * 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.typesbuilder; + +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.n4JS.N4FieldDeclaration; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TField; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.types.utils.TypeUtils; + +import com.google.inject.Inject; + +class N4JSFieldTypesBuilder { + + @Inject + N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + + boolean canCreate(N4FieldDeclaration n4Field) { + return n4Field.getName() != null || n4Field.hasComputedPropertyName(); + } + + boolean relinkField(N4FieldDeclaration n4Field, TField tField, + @SuppressWarnings("unused") boolean preLinkingPhase) { + if (!canCreate(n4Field)) { + return false; + } + + _n4JSTypesBuilderHelper.ensureEqualName(n4Field, tField); + tField.setAstElement(n4Field); + n4Field.setDefinedField(tField); + + return true; + } + + TField createField(N4FieldDeclaration n4Field, @SuppressWarnings("unused") TClassifier classifierType, + boolean preLinkingPhase) { + if (!canCreate(n4Field)) { + return null; + } + + TField field = TypesFactory.eINSTANCE.createTField(); + _n4JSTypesBuilderHelper.setMemberName(field, n4Field); + field.setConst(n4Field.isConst()); + field.setDeclaredStatic(n4Field.isDeclaredStatic()); + field.setDeclaredFinal(n4Field.isDeclaredFinal()); + field.setOptional(n4Field.isDeclaredOptional()); + field.setDeclaredOverride(AnnotationDefinition.OVERRIDE.hasAnnotation(n4Field)); + + boolean providesInitializer = AnnotationDefinition.PROVIDES_INITIALZER.hasAnnotation(n4Field); + field.setHasExpression(n4Field.getExpression() != null || providesInitializer); + + _n4JSTypesBuilderHelper.copyAnnotations(field, n4Field, preLinkingPhase); + + setMemberAccessModifier(field, n4Field); + setFieldType(field, n4Field, preLinkingPhase); + + field.setAstElement(n4Field); + n4Field.setDefinedField(field); + + return field; + } + + private void setFieldType(TField field, N4FieldDeclaration n4Field, boolean preLinkingPhase) { + if (!preLinkingPhase) { + if (n4Field.getDeclaredTypeRefInAST() != null) { + // type of field was declared explicitly + field.setTypeRef(TypeUtils.copyWithProxies(n4Field.getDeclaredTypeRefInAST())); + } else { + // in all other cases: + // leave it to the TypingASTWalker to infer the type (e.g. from the initializer expression, if given) + field.setTypeRef(TypeUtils.createDeferredTypeRef()); + } + } + } + + private void setMemberAccessModifier(TField fieldType, N4FieldDeclaration n4Field) { + _n4JSTypesBuilderHelper.setMemberAccessModifier( + (modifier) -> fieldType.setDeclaredMemberAccessModifier(modifier), + n4Field.getDeclaredModifiers(), n4Field.getAnnotations()); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFieldTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFieldTypesBuilder.xtend deleted file mode 100644 index fd4f0dbc0e..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFieldTypesBuilder.xtend +++ /dev/null @@ -1,87 +0,0 @@ -/** - * 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.typesbuilder - -import com.google.inject.Inject -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.N4FieldDeclaration -import org.eclipse.n4js.ts.types.MemberAccessModifier -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TField -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.types.utils.TypeUtils - -package class N4JSFieldTypesBuilder { - - @Inject extension N4JSTypesBuilderHelper - - def boolean canCreate(N4FieldDeclaration n4Field) { - return n4Field.name !== null || n4Field.hasComputedPropertyName; - } - - def package boolean relinkField(N4FieldDeclaration n4Field, TField tField, boolean preLinkingPhase) { - if (!canCreate(n4Field)) { - return false - } - - ensureEqualName(n4Field, tField); - tField.astElement = n4Field; - n4Field.definedField = tField - - return true; - } - - def package TField createField(N4FieldDeclaration n4Field, TClassifier classifierType, boolean preLinkingPhase) { - if (!canCreate(n4Field)) { - return null; - } - - val field = TypesFactory::eINSTANCE.createTField(); - field.setMemberName(n4Field); - field.const = n4Field.const - field.declaredStatic = n4Field.declaredStatic; - field.declaredFinal = n4Field.declaredFinal; - field.optional = n4Field.declaredOptional; - field.declaredOverride = AnnotationDefinition.OVERRIDE.hasAnnotation(n4Field); - - val providesInitializer = AnnotationDefinition.PROVIDES_INITIALZER.hasAnnotation(n4Field); - field.hasExpression = n4Field.expression!==null || providesInitializer; - - field.copyAnnotations(n4Field, preLinkingPhase) - - field.setMemberAccessModifier(n4Field) - field.setFieldType(n4Field, preLinkingPhase) - - field.astElement = n4Field; - n4Field.definedField = field - - return field; - } - - def private void setFieldType(TField field, N4FieldDeclaration n4Field, boolean preLinkingPhase) { - if (!preLinkingPhase) { - if(n4Field.declaredTypeRefInAST!==null) { - // type of field was declared explicitly - field.typeRef = TypeUtils.copyWithProxies(n4Field.declaredTypeRefInAST) - } - else { - // in all other cases: - // leave it to the TypingASTWalker to infer the type (e.g. from the initializer expression, if given) - field.typeRef = TypeUtils.createDeferredTypeRef; - } - } - } - - def private void setMemberAccessModifier(TField fieldType, N4FieldDeclaration n4Field) { - setMemberAccessModifier([MemberAccessModifier modifier | fieldType.declaredMemberAccessModifier = modifier], - n4Field.declaredModifiers, n4Field.annotations) - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.java new file mode 100644 index 0000000000..04f90594d5 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.java @@ -0,0 +1,97 @@ +/** + * 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.typesbuilder; + +import org.eclipse.n4js.n4JS.FormalParameter; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.types.utils.TypeUtils; + +import com.google.inject.Inject; + +class N4JSFormalParameterTypesBuilder { + + @Inject + N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + + boolean relinkFormalParameter(FormalParameter astFormalParameter, TFunction functionType, + BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase, int idx) { + TFormalParameter formalParameterType = functionType.getFpars().get(idx); + _n4JSTypesBuilderHelper.ensureEqualName(astFormalParameter, formalParameterType); + + formalParameterType.setAstElement(astFormalParameter); + astFormalParameter.setDefinedVariable(formalParameterType); + setFormalParameterType(formalParameterType, astFormalParameter, null, builtInTypeScope, preLinkingPhase); + + return true; + } + + TFormalParameter createFormalParameter(FormalParameter n4FormalParameter, BuiltInTypeScope builtInTypeScope, + boolean preLinkingPhase) { + return createFormalParameter(n4FormalParameter, null, builtInTypeScope, preLinkingPhase); + } + + /** + * Creates a TFormalParameter for the given FormalParameter from the AST. + * + * @param defaultTypeRef + * will be used in case there is no declared type for the formal parameter; this may be null + * and in this case any will be the formal parameter's actual type. + */ + TFormalParameter createFormalParameter(FormalParameter astFormalParameter, TypeRef defaultTypeRef, + BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + // note: we also build an fpar if astFormalParameter.name===null (otherwise the AST and types model + // would have different number of formal parameters in case of a broken AST, messing up indices, etc.) + TFormalParameter formalParameterType = TypesFactory.eINSTANCE.createTFormalParameter(); + formalParameterType.setName(astFormalParameter.getName()); + formalParameterType.setVariadic(astFormalParameter.isVariadic()); + formalParameterType.setAstInitializer(null); + formalParameterType.setHasInitializerAssignment(astFormalParameter.isHasInitializerAssignment()); + setFormalParameterType(formalParameterType, astFormalParameter, defaultTypeRef, builtInTypeScope, + preLinkingPhase); + + _n4JSTypesBuilderHelper.copyAnnotations(formalParameterType, astFormalParameter, preLinkingPhase); + + formalParameterType.setAstElement(astFormalParameter); + astFormalParameter.setDefinedVariable(formalParameterType); + + return formalParameterType; + } + + /** + * @param formalParameterType + * the type system related parameter type to be set + * @param astFormalParameter + * the AST related parameter which is to be copied to the former + */ + private void setFormalParameterType(TFormalParameter formalParameterType, FormalParameter astFormalParameter, + TypeRef defaultTypeRef, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + if (!preLinkingPhase) { + TypeRef copy = TypeUtils.copyWithProxies(astFormalParameter.getDeclaredTypeRefInAST()); + formalParameterType.setTypeRef(copy != null ? copy + : getDefaultParameterType(defaultTypeRef, astFormalParameter, builtInTypeScope)); + } + } + + private TypeRef getDefaultParameterType(TypeRef defaultTypeRef, + FormalParameter astFormalParameter, BuiltInTypeScope builtInTypeScope) { + if (astFormalParameter.getInitializer() != null) { + return TypeUtils.createDeferredTypeRef(); + } else if (defaultTypeRef == null) { + return builtInTypeScope.getAnyTypeRef(); + } else { + return TypeUtils.copy(defaultTypeRef); + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.xtend deleted file mode 100644 index 939b88c359..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.xtend +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 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.typesbuilder - -import com.google.inject.Inject -import org.eclipse.n4js.n4JS.FormalParameter -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.TFormalParameter -import org.eclipse.n4js.ts.types.TFunction -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.types.utils.TypeUtils - -package class N4JSFormalParameterTypesBuilder { - - @Inject extension N4JSTypesBuilderHelper - - def package boolean relinkFormalParameter(FormalParameter astFormalParameter, TFunction functionType, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase, int idx) { - val formalParameterType = functionType.fpars.get(idx); - ensureEqualName(astFormalParameter, formalParameterType); - - formalParameterType.astElement = astFormalParameter; - astFormalParameter.definedVariable = formalParameterType; - setFormalParameterType(formalParameterType, astFormalParameter, null, builtInTypeScope, preLinkingPhase); - - return true; - } - - def package TFormalParameter createFormalParameter(FormalParameter n4FormalParameter, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - return createFormalParameter(n4FormalParameter, null, builtInTypeScope, preLinkingPhase); - } - - /** - * Creates a TFormalParameter for the given FormalParameter from the AST. - * - * @param defaultTypeRef will be used in case there is no declared type for the formal parameter; - * this may be null and in this case any will be - * the formal parameter's actual type. - */ - def package TFormalParameter createFormalParameter(FormalParameter astFormalParameter, TypeRef defaultTypeRef, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - // note: we also build an fpar if astFormalParameter.name===null (otherwise the AST and types model - // would have different number of formal parameters in case of a broken AST, messing up indices, etc.) - val formalParameterType = TypesFactory::eINSTANCE.createTFormalParameter(); - formalParameterType.name = astFormalParameter.name; - formalParameterType.variadic = astFormalParameter.variadic; - formalParameterType.astInitializer = null; - formalParameterType.hasInitializerAssignment = astFormalParameter.hasInitializerAssignment; - setFormalParameterType(formalParameterType, astFormalParameter, defaultTypeRef, builtInTypeScope, preLinkingPhase) - - copyAnnotations(formalParameterType, astFormalParameter, preLinkingPhase) - - formalParameterType.astElement = astFormalParameter; - astFormalParameter.definedVariable = formalParameterType; - - return formalParameterType; - } - - /** - * @param formalParameterType the type system related parameter type to be set - * @param astFormalParameter the AST related parameter which is to be copied to the former - */ - def private void setFormalParameterType(TFormalParameter formalParameterType, FormalParameter astFormalParameter, - TypeRef defaultTypeRef, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase - ) { - if (!preLinkingPhase) - formalParameterType.typeRef = TypeUtils.copyWithProxies(astFormalParameter.declaredTypeRefInAST) ?: getDefaultParameterType(defaultTypeRef, astFormalParameter, builtInTypeScope) - } - - def private TypeRef getDefaultParameterType(TypeRef defaultTypeRef, - FormalParameter astFormalParameter, BuiltInTypeScope builtInTypeScope - ) { - if (astFormalParameter.initializer !== null) { - TypeUtils.createDeferredTypeRef - } else if (defaultTypeRef === null) { - builtInTypeScope.anyTypeRef - } else { - TypeUtils.copy(defaultTypeRef) - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFunctionDefinitionTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFunctionDefinitionTypesBuilder.java new file mode 100644 index 0000000000..f80f6dc767 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFunctionDefinitionTypesBuilder.java @@ -0,0 +1,213 @@ +/** + * 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.typesbuilder; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filterNull; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.FunctionDeclaration; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.types.utils.TypeUtils; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +/** + * Type builder for function declaration or expression builder. + */ +// TODO we temporarily create a BuiltInTypeScope in order to get primitive types. This may be changed by passing in this +// scope, one this method is called by the type system +@Singleton +public class N4JSFunctionDefinitionTypesBuilder extends AbstractFunctionDefinitionTypesBuilder { + + @Inject + N4JSFormalParameterTypesBuilder _n4JSFormalParameterTypesBuilder; + @Inject + N4JSTypeVariableTypesBuilder _n4JSTypeVariableTypesBuilder; + @Inject + N4JSVariableStatementTypesBuilder _n4JSVariableStatementTypesBuilder; + @Inject + N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + + boolean relinkTFunction(FunctionDeclaration functionDecl, AbstractNamespace target, boolean preLinkingPhase, + int idx) { + EObject functionDefinedType = (EObject) functionDecl + .eGet(N4JSPackage.eINSTANCE.getTypeDefiningElement_DefinedType(), false); + if (functionDefinedType != null && !functionDefinedType.eIsProxy()) { + throw new IllegalStateException("TFunction already created for FunctionDeclaration"); + } + + if (functionDecl.getName() == null) { + return false; + } + + TFunction functionType = target.getFunctions().get(idx); + _n4JSTypesBuilderHelper.ensureEqualName(functionDecl, functionType); + + relinkFormalParameters(functionType, functionDecl, preLinkingPhase); + functionType.setAstElement(functionDecl); + functionDecl.setDefinedType(functionType); + + return true; + } + + /** + * Creates TFunction for the given function declaration and adds it to the modules top level types (as function + * declarations are only allowed on top level). + * + * @param functionDecl + * declaration for which the TFunction is created, must not be linked to a TFunction yet (i.e. its + * defined type must be null). + * @param target + * the module to which the newly created TFunction is added + */ + void createTFunction(FunctionDeclaration functionDecl, AbstractNamespace target, boolean preLinkingPhase) { + EObject functionDefinedType = (EObject) functionDecl + .eGet(N4JSPackage.eINSTANCE.getTypeDefiningElement_DefinedType(), false); + if (functionDefinedType != null && !functionDefinedType.eIsProxy()) { + throw new IllegalStateException("TFunction already created for FunctionDeclaration"); + } + + if (functionDecl.getName() == null) { + return; + } + + BuiltInTypeScope builtInTypeScope = BuiltInTypeScope.get(functionDecl.eResource().getResourceSet()); + TFunction functionType = createAndLinkTFunction(functionDecl); + _n4JSVariableStatementTypesBuilder.createImplicitArgumentsVariable(functionDecl, target, builtInTypeScope, + preLinkingPhase); + + addFormalParameters(functionType, functionDecl, builtInTypeScope, preLinkingPhase); + _n4JSTypesBuilderHelper.setTypeAccessModifier(functionType, functionDecl); + _n4JSTypesBuilderHelper.setProvidedByRuntime(functionType, functionDecl, preLinkingPhase); + setReturnType(functionType, functionDecl, builtInTypeScope, preLinkingPhase); + _n4JSTypeVariableTypesBuilder.addTypeParameters(functionType, functionDecl, preLinkingPhase); + _n4JSTypesBuilderHelper.setDeclaredThisTypeFromAnnotation(functionType, functionDecl, preLinkingPhase); + _n4JSTypesBuilderHelper.copyAnnotations(functionType, functionDecl, preLinkingPhase); + functionType.setDeclaredAsync(functionDecl.isAsync());// TODO change to declaredAsync once the annotation is + // gone + functionType.setDeclaredGenerator(functionDecl.isGenerator()); + + // set container + target.getFunctions().add(functionType); + } + + /** + * Creates TFunction for the given function expression and adds it to the module. Note that this method applies only + * to expressions that define a function, not to function type expressions that merely define a function type (the + * latter are represented in the AST and TModule by a node of type FunctionTypeExpression from + * Types.xcore). + *

+ * Creating a TFunction for a function expression becomes a bit tricky when type inference has to be used to infer + * the types of one or more formal parameters and/or the return value. These are the steps involved: + *

    + *
  1. method {@link #createTFunction(FunctionExpression,AbstractNamespace,boolean)} creates an initial TFunction in + * which the type of every fpar may(!) be a ComputedTypeRef and the return type may(!) be a ComputedTypeRef. + * ComputedTypeRefs are only used if there is no declared type available. + *
  2. when the first(!) of these ComputedTypeRefs is resolved (and only for the first!), then method + * resolveTFunction(ComputedTypeRef,TFunction,FunctionExpression,BuiltInTypeScope) is invoked. This method will + * handle the resolution of all ComputedTypeRefs of the given TFunction in one step (to avoid unnecessary repeated + * inference of the expected type; note: caching does not help here, because we call judgment 'expectedTypeIn' and + * not 'type'). + *
+ */ + void createTFunction(FunctionExpression functionExpr, AbstractNamespace target, boolean preLinkingPhase) { + EObject functionDefinedType = (EObject) functionExpr + .eGet(N4JSPackage.eINSTANCE.getTypeDefiningElement_DefinedType(), false); + if (functionDefinedType != null && !functionDefinedType.eIsProxy()) { + throw new IllegalStateException("TFunction already created for FunctionExpression"); + } + + BuiltInTypeScope builtInTypeScope = BuiltInTypeScope.get(functionExpr.eResource().getResourceSet()); + TFunction functionType = createAndLinkTFunction(functionExpr); + _n4JSVariableStatementTypesBuilder.createImplicitArgumentsVariable(functionExpr, target, builtInTypeScope, + preLinkingPhase); + + addFormalParametersWithInferredType(functionType, functionExpr, builtInTypeScope, preLinkingPhase); + setReturnTypeWithInferredType(functionType, functionExpr, preLinkingPhase); + _n4JSTypeVariableTypesBuilder.addTypeParameters(functionType, functionExpr, preLinkingPhase); + _n4JSTypesBuilderHelper.setDeclaredThisTypeFromAnnotation(functionType, functionExpr, preLinkingPhase); + + _n4JSTypesBuilderHelper.copyAnnotations(functionType, functionExpr, preLinkingPhase); + + // set container + target.getContainingModule().getInternalTypes().add(functionType); + } + + /** + * Same as + * {@link AbstractFunctionDefinitionTypesBuilder#addFormalParameters(TFunction,FunctionDefinition,BuiltInTypeScope,boolean)}, + * but uses a ComputedTypeRef as the fpar's type if the type has to be inferred. + */ + private void addFormalParametersWithInferredType(TFunction functionType, FunctionExpression functionExpr, + BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + + functionType.getFpars().addAll( + toList(filterNull(map(functionExpr.getFpars(), + fpar -> _n4JSFormalParameterTypesBuilder.createFormalParameter(fpar, + TypeUtils.createDeferredTypeRef(), + // TypeUtils.createComputedTypeRef([resolveAllComputedTypeRefsInTFunction(functionType,functionExpr,builtInTypeScope)]), + builtInTypeScope, + preLinkingPhase))))); + } + + /** + * Same as + * {@link AbstractFunctionDefinitionTypesBuilder#setReturnType(TFunction,FunctionDefinition,BuiltInTypeScope,boolean)}, + * but uses a ComputedTypeRef as the return type if the type has to be inferred. + */ + private void setReturnTypeWithInferredType(TFunction functionType, FunctionExpression functionExpr, + boolean preLinkingPhase) { + if (!preLinkingPhase) { + /* + * TODO IDE-1579 this branch skips makePromiseIfAsync. Question: could this result in 'void' as inferred + * return type (for an async method)? + */ + TypeRef copy = TypeUtils.copyWithProxies(functionExpr.getDeclaredReturnTypeRefInAST()); + functionType.setReturnTypeRef(copy != null ? copy : TypeUtils.createDeferredTypeRef()); + // note: handling of the return type of async functions not done here, see + // TypeProcessor#handleAsyncFunctionDeclaration() + } + } + + private TFunction createAndLinkTFunction(FunctionDefinition functionDef) { + TFunction functionType = this.createTFunction(); + if (functionDef instanceof FunctionDeclaration) { + functionType.setExternal(((FunctionDeclaration) functionDef).isExternal()); + } + functionType.setName(functionDef.getName()); // maybe null in case of function expression + functionType.setDeclaredAsync(functionDef.isAsync()); // TODO change to declaredAsync when annotation is removed + functionType.setDeclaredGenerator(functionDef.isGenerator());// TODO change to declaredAsync when annotation is + // removed + + // link + functionType.setAstElement(functionDef); + functionDef.setDefinedType(functionType); + + return functionType; + } + + /** + * Creates a new plain instance of {@link TFunction}. + */ + private TFunction createTFunction() { + return TypesFactory.eINSTANCE.createTFunction(); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFunctionDefinitionTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFunctionDefinitionTypesBuilder.xtend deleted file mode 100644 index a6462a9606..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFunctionDefinitionTypesBuilder.xtend +++ /dev/null @@ -1,184 +0,0 @@ -/** - * 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.typesbuilder - -import com.google.inject.Inject -import com.google.inject.Singleton -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.FunctionDeclaration -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.FunctionExpression -import org.eclipse.n4js.n4JS.N4JSPackage -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.TFunction -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.types.utils.TypeUtils - -/** - * Type builder for function declaration or expression builder. - */ -// TODO we temporarily create a BuiltInTypeScope in order to get primitive types. This may be changed by passing in this scope, one this method is called by the typesystem -@Singleton -public class N4JSFunctionDefinitionTypesBuilder extends AbstractFunctionDefinitionTypesBuilder { - - @Inject extension N4JSFormalParameterTypesBuilder - @Inject extension N4JSTypeVariableTypesBuilder - @Inject extension N4JSVariableStatementTypesBuilder - @Inject extension N4JSTypesBuilderHelper - - def package boolean relinkTFunction(FunctionDeclaration functionDecl, AbstractNamespace target, boolean preLinkingPhase, int idx) { - val functionDefinedType = functionDecl.eGet(N4JSPackage.eINSTANCE.typeDefiningElement_DefinedType, false) as EObject; - if (functionDefinedType !== null && ! functionDefinedType.eIsProxy) { - throw new IllegalStateException("TFunction already created for FunctionDeclaration"); - } - - if (functionDecl.name === null) { - return false; - } - - val TFunction functionType = target.functions.get(idx) - ensureEqualName(functionDecl, functionType); - - functionType.relinkFormalParameters(functionDecl, preLinkingPhase) - functionType.astElement = functionDecl - functionDecl.definedType = functionType - - return true; - } - - /** - * Creates TFunction for the given function declaration and adds it to the modules top level types - * (as function declarations are only allowed on top level). - * - * @param functionDecl declaration for which the TFunction is created, must not be linked to a TFunction yet (i.e. its defined type must be null). - * @param target the module to which the newly created TFunction is added - */ - def package void createTFunction(FunctionDeclaration functionDecl, AbstractNamespace target, boolean preLinkingPhase) { - val functionDefinedType = functionDecl.eGet(N4JSPackage.eINSTANCE.typeDefiningElement_DefinedType, false) as EObject; - if (functionDefinedType !== null && ! functionDefinedType.eIsProxy) { - throw new IllegalStateException("TFunction already created for FunctionDeclaration"); - } - - if (functionDecl.name === null) { - return; - } - - val builtInTypeScope = BuiltInTypeScope.get(functionDecl.eResource.resourceSet) - val functionType = functionDecl.createAndLinkTFunction(preLinkingPhase) - functionDecl.createImplicitArgumentsVariable(target, builtInTypeScope, preLinkingPhase); - - functionType.addFormalParameters(functionDecl, builtInTypeScope, preLinkingPhase) - functionType.setTypeAccessModifier(functionDecl) - functionType.setProvidedByRuntime(functionDecl, preLinkingPhase) - functionType.setReturnType(functionDecl, builtInTypeScope, preLinkingPhase) - functionType.addTypeParameters(functionDecl, preLinkingPhase) - functionType.setDeclaredThisTypeFromAnnotation(functionDecl, preLinkingPhase) - functionType.copyAnnotations(functionDecl, preLinkingPhase) - functionType.declaredAsync = functionDecl.async // TODO change to declaredAsync once the annotation is gone - functionType.declaredGenerator = functionDecl.generator - - // set container - target.functions += functionType - } - - /** - * Creates TFunction for the given function expression and adds it to the module. Note that this method applies - * only to expressions that define a function, not to function type expressions that merely define a function - * type (the latter are represented in the AST and TModule by a node of type FunctionTypeExpression - * from Types.xcore). - *

- * Creating a TFunction for a function expression becomes a bit tricky when type inference has to be used to - * infer the types of one or more formal parameters and/or the return value. These are the steps involved: - *

    - *
  1. method {@link #createTFunction(FunctionExpression,TModule,boolean)} creates an initial TFunction in - * which the type of every fpar may(!) be a ComputedTypeRef and the return type may(!) be a ComputedTypeRef. - * ComputedTypeRefs are only used if there is no declared type available. - *
  2. when the first(!) of these ComputedTypeRefs is resolved (and only for the first!), then method - * {@link #resolveTFunction(ComputedTypeRef,TFunction,FunctionExpression,BuiltInTypeScope)} - * is invoked. This method will handle the resolution of all ComputedTypeRefs of the given TFunction in - * one step (to avoid unnecessary repeated inference of the expected type; note: caching does not help - * here, because we call judgment 'expectedTypeIn' and not 'type'). - *
- */ - def package void createTFunction(FunctionExpression functionExpr, AbstractNamespace target, boolean preLinkingPhase) { - val functionDefinedType = functionExpr.eGet(N4JSPackage.eINSTANCE.typeDefiningElement_DefinedType, false) as EObject; - if (functionDefinedType !== null && ! functionDefinedType.eIsProxy) { - throw new IllegalStateException("TFunction already created for FunctionExpression"); - } - - val builtInTypeScope = BuiltInTypeScope.get(functionExpr.eResource.resourceSet) - val functionType = functionExpr.createAndLinkTFunction(preLinkingPhase) - functionExpr.createImplicitArgumentsVariable(target, builtInTypeScope, preLinkingPhase); - - functionType.addFormalParametersWithInferredType(functionExpr, builtInTypeScope, preLinkingPhase) - functionType.setReturnTypeWithInferredType(functionExpr, builtInTypeScope, preLinkingPhase) - functionType.addTypeParameters(functionExpr, preLinkingPhase) - functionType.setDeclaredThisTypeFromAnnotation(functionExpr, preLinkingPhase) - - functionType.copyAnnotations(functionExpr, preLinkingPhase) - - // set container - target.containingModule.internalTypes += functionType - } - - /** - * Same as {@link AbstractFunctionDefinitionTypesBuilder#addFormalParameters(TFunction,FunctionDefinition,BuiltInTypeScope,boolean)}, - * but uses a ComputedTypeRef as the fpar's type if the type has to be inferred. - */ - def private void addFormalParametersWithInferredType(TFunction functionType, FunctionExpression functionExpr, - BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - functionType.fpars.addAll( - functionExpr.fpars.map[it.createFormalParameter( - TypeUtils.createDeferredTypeRef, //TypeUtils.createComputedTypeRef([resolveAllComputedTypeRefsInTFunction(functionType,functionExpr,builtInTypeScope)]), - builtInTypeScope, - preLinkingPhase - )].filterNull); - } - - /** - * Same as {@link AbstractFunctionDefinitionTypesBuilder#setReturnType(TFunction,FunctionDefinition,BuiltInTypeScope,boolean)}, - * but uses a ComputedTypeRef as the return type if the type has to be inferred. - */ - def private void setReturnTypeWithInferredType(TFunction functionType, FunctionExpression functionExpr, - BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - if (!preLinkingPhase) - /* - * TODO IDE-1579 this branch skips makePromiseIfAsync. - * Question: could this result in 'void' as inferred return type (for an async method)? - */ - functionType.returnTypeRef = TypeUtils.copyWithProxies(functionExpr.declaredReturnTypeRefInAST) ?: TypeUtils.createDeferredTypeRef - // note: handling of the return type of async functions not done here, see TypeProcessor#handleAsyncFunctionDeclaration() - } - - def private TFunction createAndLinkTFunction(FunctionDefinition functionDef, boolean preLinkingPhase) { - val functionType = this.createTFunction(functionDef); - if(functionDef instanceof FunctionDeclaration) { - functionType.external = functionDef.external; - } - functionType.name = functionDef.name; // maybe null in case of function expression - functionType.declaredAsync = functionDef.isAsync // TODO change to declaredAsync when annotation is removed - functionType.declaredGenerator = functionDef.generator // TODO change to declaredAsync when annotation is removed - - // link - functionType.astElement = functionDef - functionDef.definedType = functionType - - return functionType - } - - /** - * Creates a new plain instance of {@link TFunction}. - */ - def private TFunction createTFunction(FunctionDefinition functionDef) { - return TypesFactory::eINSTANCE.createTFunction(); - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSGetterTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSGetterTypesBuilder.java new file mode 100644 index 0000000000..6946c2f43b --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSGetterTypesBuilder.java @@ -0,0 +1,106 @@ +/** + * 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.typesbuilder; + +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.n4JS.N4GetterDeclaration; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.ts.typeRefs.ThisTypeRef; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TGetter; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.types.utils.TypeUtils; + +import com.google.inject.Inject; + +/** + */ +class N4JSGetterTypesBuilder extends AbstractFunctionDefinitionTypesBuilder { + + @Inject + N4JSVariableStatementTypesBuilder _n4JSVariableStatementTypesBuilder; + @Inject + N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + + boolean canCreate(N4GetterDeclaration n4Getter) { + return n4Getter.getName() != null || n4Getter.hasComputedPropertyName(); + } + + boolean relinkGetter(N4GetterDeclaration n4Getter, TGetter tGetter, + @SuppressWarnings("unused") boolean preLinkingPhase) { + + if (!canCreate(n4Getter)) { + return false; + } + + _n4JSTypesBuilderHelper.ensureEqualName(n4Getter, tGetter); + tGetter.setAstElement(n4Getter); + n4Getter.setDefinedGetter(tGetter); + return true; + } + + TGetter createGetter(N4GetterDeclaration n4Getter, @SuppressWarnings("unused") TClassifier classifierType, + AbstractNamespace target, boolean preLinkingPhase) { + + if (!canCreate(n4Getter)) { + return null; + } + TGetter getterType = TypesFactory.eINSTANCE.createTGetter(); + _n4JSTypesBuilderHelper.setMemberName(getterType, n4Getter); + + getterType.setDeclaredAbstract(n4Getter.isAbstract()); + getterType.setDeclaredStatic(n4Getter.isDeclaredStatic()); + getterType.setDeclaredFinal(n4Getter.isDeclaredFinal()); + getterType.setOptional(n4Getter.isOptional()); + getterType.setDeclaredOverride(AnnotationDefinition.OVERRIDE.hasAnnotation(n4Getter)); + + getterType.setHasNoBody(n4Getter.getBody() == null + && !AnnotationDefinition.PROVIDES_DEFAULT_IMPLEMENTATION.hasAnnotation(n4Getter)); + + // TODO if possible, remove, see AbstractFunctionDefinitionTypesBuilder + BuiltInTypeScope builtInTypeScope = BuiltInTypeScope.get(n4Getter.eResource().getResourceSet()); + _n4JSVariableStatementTypesBuilder.createImplicitArgumentsVariable(n4Getter, target, builtInTypeScope, + preLinkingPhase); + + setMemberAccessModifier(getterType, n4Getter); + setReturnTypeConsideringThis(getterType, n4Getter, builtInTypeScope, preLinkingPhase); + _n4JSTypesBuilderHelper.setDeclaredThisTypeFromAnnotation(getterType, n4Getter, preLinkingPhase); + + _n4JSTypesBuilderHelper.copyAnnotations(getterType, n4Getter, preLinkingPhase); + + getterType.setAstElement(n4Getter); + n4Getter.setDefinedGetter(getterType); + return getterType; + } + + private void setMemberAccessModifier(TGetter getterType, N4GetterDeclaration n4Getter) { + _n4JSTypesBuilderHelper.setMemberAccessModifier( + modifier -> getterType.setDeclaredMemberAccessModifier(modifier), + n4Getter.getDeclaredModifiers(), n4Getter.getAnnotations()); + } + + /** + * Sets the return type. If the declared return type is 'this', a ComputedTypeRef will be created to generate a + * bound this type. + */ + private void setReturnTypeConsideringThis(TGetter getterType, N4GetterDeclaration getterDecl, + BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + // TODO: explicitly differentiate between declared and inferred type + if (getterDecl.getDeclaredTypeRefInAST() instanceof ThisTypeRef) { + // special case: TypingASTWalker will create a BoundThisTypeRef via Xsemantics judgment 'thisTypeRef' + getterType.setTypeRef(TypeUtils.createDeferredTypeRef()); + } else { + // standard case + setReturnType(getterType, getterDecl, builtInTypeScope, preLinkingPhase); + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSGetterTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSGetterTypesBuilder.xtend deleted file mode 100644 index 75eb1e5aac..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSGetterTypesBuilder.xtend +++ /dev/null @@ -1,99 +0,0 @@ -/** - * 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.typesbuilder - -import com.google.inject.Inject -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.N4GetterDeclaration -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.ts.typeRefs.ThisTypeRef -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.MemberAccessModifier -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TGetter -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.types.utils.TypeUtils - -/** - */ -package class N4JSGetterTypesBuilder extends AbstractFunctionDefinitionTypesBuilder { - - @Inject extension N4JSVariableStatementTypesBuilder - @Inject extension N4JSTypesBuilderHelper - - def boolean canCreate(N4GetterDeclaration n4Getter) { - return n4Getter.name !== null || n4Getter.hasComputedPropertyName; - } - - def package boolean relinkGetter(N4GetterDeclaration n4Getter, TGetter tGetter, boolean preLinkingPhase) { - if (!canCreate(n4Getter)) { - return false - } - - ensureEqualName(n4Getter, tGetter); - tGetter.astElement = n4Getter - n4Getter.definedGetter = tGetter - return true - } - - def package TGetter createGetter(N4GetterDeclaration n4Getter, TClassifier classifierType, AbstractNamespace target, boolean preLinkingPhase) { - if (!canCreate(n4Getter)) { - return null - } - val getterType = TypesFactory::eINSTANCE.createTGetter - getterType.setMemberName(n4Getter); - - getterType.declaredAbstract = n4Getter.abstract - getterType.declaredStatic = n4Getter.declaredStatic - getterType.declaredFinal = n4Getter.declaredFinal - getterType.optional = n4Getter.optional; - getterType.declaredOverride = AnnotationDefinition.OVERRIDE.hasAnnotation(n4Getter); - - getterType.hasNoBody = n4Getter.body ===null&& !AnnotationDefinition.PROVIDES_DEFAULT_IMPLEMENTATION.hasAnnotation(n4Getter); - - // TODO if possible, remove, see AbstractFunctionDefinitionTypesBuilder - val builtInTypeScope = BuiltInTypeScope.get(n4Getter.eResource.resourceSet) - n4Getter.createImplicitArgumentsVariable(target, builtInTypeScope, preLinkingPhase); - - getterType.setMemberAccessModifier(n4Getter) - getterType.setReturnTypeConsideringThis(n4Getter, builtInTypeScope, preLinkingPhase) - getterType.setDeclaredThisTypeFromAnnotation(n4Getter, preLinkingPhase) - - getterType.copyAnnotations(n4Getter, preLinkingPhase) - - getterType.astElement = n4Getter - n4Getter.definedGetter = getterType - getterType; - } - - def private void setMemberAccessModifier(TGetter getterType, N4GetterDeclaration n4Getter) { - setMemberAccessModifier([MemberAccessModifier modifier | - getterType.declaredMemberAccessModifier = modifier - ], n4Getter.declaredModifiers, n4Getter.annotations) - } - - /** - * Sets the return type. If the declared return type is 'this', a ComputedTypeRef will - * be created to generate a bound this type. - */ - def private void setReturnTypeConsideringThis(TGetter getterType, N4GetterDeclaration getterDecl, - BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - // TODO: explicitly differentiate between declared and inferred type - if(getterDecl.declaredTypeRefInAST instanceof ThisTypeRef) { - // special case: TypingASTWalker will create a BoundThisTypeRef via Xsemantics judgment 'thisTypeRef' - getterType.typeRef = TypeUtils.createDeferredTypeRef - } - else { - // standard case - getterType.setReturnType(getterDecl, builtInTypeScope, preLinkingPhase) - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSImportTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSImportTypesBuilder.java new file mode 100644 index 0000000000..26a4a6babe --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSImportTypesBuilder.java @@ -0,0 +1,203 @@ +/** + * Copyright (c) 2018 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.typesbuilder; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.n4js.n4JS.ImportDeclaration; +import org.eclipse.n4js.n4JS.ImportSpecifier; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.NamedImportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType; +import org.eclipse.n4js.ts.types.TDynamicElement; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.ts.types.TypesFactory; + +import com.google.inject.Inject; + +/** + * A types builder that creates/relinks type model elements related to imports, as described + * {@link #createTypeModelElementsForImports(Script, TModule, boolean) here}. + */ +class N4JSImportTypesBuilder { + + @Inject + N4JSTypesBuilderHelper _N4JSTypesBuilderHelper; + + /** + * Relinks the elements created by {@link #createTypeModelElementsForImports(Script, TModule, boolean)}. + *

+ * If for a given {@link NamespaceImportSpecifier} no {@link ModuleNamespaceVirtualType} instance exists yet, a new + * one is created and added to the module's {@link TModule#getInternalTypes()} + */ + void relinkTypeModelElementsForImports(Script script, TModule target, boolean preLinkingPhase) { + if (preLinkingPhase) { + return; + } + Map namespaceTypesByName = getExistingNamespaceTypesByName(target); + Map dynElemsByName = getExistingDynamicElementsByName(target); + List ids = toList(filter(script.getScriptElements(), ImportDeclaration.class)); + + for (ImportDeclaration importDecl : ids) { + NamespaceImportSpecifier namespaceImport = getNamespaceImportSpecifier(importDecl); + if (namespaceImport != null) { + TModule importedModule = (TModule) importDecl.eGet(N4JSPackage.eINSTANCE.getModuleRef_Module(), false); + ModuleNamespaceVirtualType existingNamespaceType = namespaceTypesByName.get(namespaceImport.getAlias()); + + if (existingNamespaceType != null) { + // if a namespace import type exists, relink it to the new AST + relinkNamespaceType(existingNamespaceType, namespaceImport, importedModule); + } else { + // otherwise re-create a new namespace import type and add it to the internal types of the module + _N4JSTypesBuilderHelper.addNewModuleNamespaceVirtualType(target, namespaceImport.getAlias(), + importedModule, namespaceImport.isDeclaredDynamic(), namespaceImport); + } + + } else { + + for (ImportSpecifier importSpec : importDecl.getImportSpecifiers()) { + if (importSpec instanceof NamedImportSpecifier) { // includes DefaultImportSpecifier + NamedImportSpecifier nis = (NamedImportSpecifier) importSpec; + if (importSpec.isDeclaredDynamic()) { + TDynamicElement existingDynElem = dynElemsByName.get(getNameForDynamicElement(nis)); + + if (existingDynElem != null) { + relinkDynamicElement(existingDynElem, nis); + } else { + target.getInternalDynamicElements().add(createDynamicElement(nis)); + } + } + } + } + } + } + } + + /** + * Creates ... + *

    + *
  • {@link ModuleNamespaceVirtualType} instances for namespace imports. + *
  • {@link TDynamicElement} instances for dynamic named and default imports. + *
+ */ + void createTypeModelElementsForImports(Script script, TModule target, boolean preLinkingPhase) { + if (preLinkingPhase) { + return; + } + List ids = toList(filter(script.getScriptElements(), ImportDeclaration.class)); + for (ImportDeclaration importDecl : ids) { + NamespaceImportSpecifier namespaceImport = getNamespaceImportSpecifier(importDecl); + if (namespaceImport != null) { + TModule importedModule = (TModule) importDecl.eGet(N4JSPackage.eINSTANCE.getModuleRef_Module(), + false); + _N4JSTypesBuilderHelper.addNewModuleNamespaceVirtualType(target, namespaceImport.getAlias(), + importedModule, namespaceImport.isDeclaredDynamic(), namespaceImport); + } else { + for (ImportSpecifier importSpec : importDecl.getImportSpecifiers()) { + if (importSpec instanceof NamedImportSpecifier) { // includes DefaultImportSpecifier + if (importSpec.isDeclaredDynamic()) { + target.getInternalDynamicElements() + .add(createDynamicElement((NamedImportSpecifier) importSpec)); + } + } + } + } + } + } + + private TDynamicElement createDynamicElement(NamedImportSpecifier importSpecifier) { + TDynamicElement elem = TypesFactory.eINSTANCE.createTDynamicElement(); + elem.setName(getNameForDynamicElement(importSpecifier)); + elem.setAstElement(importSpecifier); + importSpecifier.setDefinedDynamicElement(elem); + return elem; + } + + private String getNameForDynamicElement(NamedImportSpecifier importSpecifier) { + return importSpecifier.getAlias() != null ? importSpecifier.getAlias() + : importSpecifier.getImportedElementAsText(); + } + + /** + * Obtains the {@link NamespaceImportSpecifier} of the given {@code importDeclaration}. + * + * Returns {@code null}, if the given import declaration does not represent a namespace import. + */ + private NamespaceImportSpecifier getNamespaceImportSpecifier(ImportDeclaration importDeclaration) { + List namespaceImportSpecifiers = toList( + filter(importDeclaration.getImportSpecifiers(), NamespaceImportSpecifier.class)); + if (!namespaceImportSpecifiers.isEmpty()) { + return namespaceImportSpecifiers.get(0); + } else { + return null; + } + } + + /** + * Relinks the given {@link ModuleNamespaceVirtualType} to the given import specifier. + */ + private void relinkNamespaceType(ModuleNamespaceVirtualType namespaceType, + NamespaceImportSpecifier namespaceImportSpecifier, TModule importedModule) { + + namespaceType.setModule(importedModule); + namespaceType.setAstElement(namespaceImportSpecifier); + namespaceImportSpecifier.setDefinedType(namespaceType); + } + + private void relinkDynamicElement(TDynamicElement elem, NamedImportSpecifier namedImportSpecifier) { + elem.setAstElement(namedImportSpecifier); + namedImportSpecifier.setDefinedDynamicElement(elem); + } + + /** + * Returns a map of all existing {@link ModuleNamespaceVirtualType} contained in the given {@link TModule}. + * + * Includes exposed and non-exposed internal types. + */ + private Map getExistingNamespaceTypesByName(TModule module) { + Map namespaceTypesByName = new HashMap<>(); + if (module.getInternalTypes() != null) { + for (Type type : module.getInternalTypes()) { + if (type instanceof ModuleNamespaceVirtualType) { + ModuleNamespaceVirtualType mnvt = (ModuleNamespaceVirtualType) type; + namespaceTypesByName.put(mnvt.getName(), mnvt); + } + } + } + if (module.getExposedInternalTypes() != null) { + for (Type type : module.getExposedInternalTypes()) { + if (type instanceof ModuleNamespaceVirtualType) { + ModuleNamespaceVirtualType mnvt = (ModuleNamespaceVirtualType) type; + namespaceTypesByName.put(mnvt.getName(), mnvt); + } + } + } + return namespaceTypesByName; + } + + private Map getExistingDynamicElementsByName(TModule module) { + HashMap dynElemsByName = new HashMap<>(); + if (module.getInternalDynamicElements() != null) { + for (TDynamicElement elem : module.getInternalDynamicElements()) { + dynElemsByName.put(elem.getName(), elem); + } + } + return dynElemsByName; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSImportTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSImportTypesBuilder.xtend deleted file mode 100644 index 2508d218ab..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSImportTypesBuilder.xtend +++ /dev/null @@ -1,178 +0,0 @@ -/** - * Copyright (c) 2018 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.typesbuilder - -import com.google.inject.Inject -import java.util.HashMap -import java.util.Map -import org.eclipse.n4js.n4JS.ImportDeclaration -import org.eclipse.n4js.n4JS.N4JSPackage -import org.eclipse.n4js.n4JS.NamedImportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType -import org.eclipse.n4js.ts.types.TDynamicElement -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.ts.types.TypesFactory - -/** - * A types builder that creates/relinks type model elements related to imports, as described - * {@link #createTypeModelElementsForImports(Script, TModule, boolean) here}. - */ -class N4JSImportTypesBuilder { - - @Inject extension N4JSTypesBuilderHelper - - /** - * Relinks the elements created by {@link #createTypeModelElementsForImports(Script, TModule, boolean)}. - *

- * If for a given {@link NamespaceImportSpecifier} no {@link ModuleNamespaceVirtualType} - * instance exists yet, a new one is created and added to the module's {@link TModule#internalTypes} - */ - def void relinkTypeModelElementsForImports(Script script, TModule target, boolean preLinkingPhase) { - if (!preLinkingPhase) { - val namespaceTypesByName = getExistingNamespaceTypesByName(target); - val dynElemsByName = getExistingDynamicElementsByName(target); - - for (importDecl : script.scriptElements.filter(ImportDeclaration).toList) { - val namespaceImport = getNamespaceImportSpecifier(importDecl) - if(namespaceImport !== null) { - val importedModule = importDecl.eGet(N4JSPackage.eINSTANCE.moduleRef_Module, false) as TModule - val existingNamespaceType = namespaceTypesByName.get(namespaceImport.alias); - - if (existingNamespaceType !== null) { - // if a namespace import type exists, relink it to the new AST - relinkNamespaceType(existingNamespaceType, namespaceImport, importedModule); - } else { - // otherwise re-create a new namespace import type and add it to the internal types of the module - target.addNewModuleNamespaceVirtualType(namespaceImport.alias, importedModule, namespaceImport.declaredDynamic, namespaceImport); - } - - } else { - - for (importSpec : importDecl.importSpecifiers) { - if (importSpec instanceof NamedImportSpecifier) { // includes DefaultImportSpecifier - if (importSpec.declaredDynamic) { - val existingDynElem = dynElemsByName.get(getNameForDynamicElement(importSpec)); - - if (existingDynElem !== null) { - relinkDynamicElement(existingDynElem, importSpec); - } else { - target.internalDynamicElements += createDynamicElement(importSpec); - } - } - } - } - } - } - } - } - - /** - * Creates ... - *

    - *
  • {@link ModuleNamespaceVirtualType} instances for namespace imports. - *
  • {@link TDynamicElement} instances for dynamic named and default imports. - *
- */ - def void createTypeModelElementsForImports(Script script, TModule target, boolean preLinkingPhase) { - if (!preLinkingPhase) { - for (importDecl : script.scriptElements.filter(ImportDeclaration).toList) { - val namespaceImport = getNamespaceImportSpecifier(importDecl) - if (namespaceImport !== null) { - val importedModule = importDecl.eGet(N4JSPackage.eINSTANCE.moduleRef_Module, - false) as TModule - target.addNewModuleNamespaceVirtualType(namespaceImport.alias, importedModule, namespaceImport.declaredDynamic, namespaceImport); - } else { - for (importSpec : importDecl.importSpecifiers) { - if (importSpec instanceof NamedImportSpecifier) { // includes DefaultImportSpecifier - if (importSpec.declaredDynamic) { - target.internalDynamicElements += createDynamicElement(importSpec); - } - } - } - } - } - } - } - - private def TDynamicElement createDynamicElement(NamedImportSpecifier importSpecifier) { - val elem = TypesFactory.eINSTANCE.createTDynamicElement(); - elem.name = getNameForDynamicElement(importSpecifier); - elem.astElement = importSpecifier; - importSpecifier.definedDynamicElement = elem; - return elem; - } - - private def String getNameForDynamicElement(NamedImportSpecifier importSpecifier) { - return importSpecifier.alias ?: importSpecifier.importedElementAsText; - } - - /** - * Obtains the {@link NamespaceImportSpecifier} of the given {@code importDeclaration}. - * - * Returns {@code null}, if the given import declaration does not represent a namespace import. - */ - private def NamespaceImportSpecifier getNamespaceImportSpecifier(ImportDeclaration importDeclaration) { - val namespaceImportSpecifiers = importDeclaration.importSpecifiers.filter(NamespaceImportSpecifier).toList - if (!namespaceImportSpecifiers.empty) { - return namespaceImportSpecifiers.head - } else { - return null; - } - } - - /** - * Relinks the given {@link ModuleNamespaceVirtualType} to the given import specifier. - */ - private def void relinkNamespaceType(ModuleNamespaceVirtualType namespaceType, - NamespaceImportSpecifier namespaceImportSpecifier, TModule importedModule) { - - namespaceType.module = importedModule; - namespaceType.astElement = namespaceImportSpecifier; - namespaceImportSpecifier.definedType = namespaceType; - } - - private def void relinkDynamicElement(TDynamicElement elem, NamedImportSpecifier namedImportSpecifier) { - elem.astElement = namedImportSpecifier; - namedImportSpecifier.definedDynamicElement = elem; - } - - /** - * Returns a map of all existing {@link ModuleNamespaceVirtualType} contained in the - * given {@link TModule}. - * - * Includes exposed and non-exposed internal types. - */ - private def Map getExistingNamespaceTypesByName(TModule module) { - val namespaceTypesByName = new HashMap(); - if (module.internalTypes !== null) { - module.internalTypes - .filter(ModuleNamespaceVirtualType) - .forEach[type | namespaceTypesByName.put(type.name, type) ] - } - if (module.exposedInternalTypes !== null) { - module.exposedInternalTypes - .filter(ModuleNamespaceVirtualType) - .forEach[type | namespaceTypesByName.put(type.name, type) ] - } - return namespaceTypesByName; - } - - private def Map getExistingDynamicElementsByName(TModule module) { - val dynElemsByName = new HashMap(); - if (module.internalDynamicElements !== null) { - module.internalDynamicElements - .forEach[elem | dynElemsByName.put(elem.name, elem) ] - } - return dynElemsByName; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSInterfaceDeclarationTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSInterfaceDeclarationTypesBuilder.java new file mode 100644 index 0000000000..0c5b5e55ac --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSInterfaceDeclarationTypesBuilder.java @@ -0,0 +1,88 @@ +/** + * 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.typesbuilder; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TInterface; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.ts.types.TypingStrategy; +import org.eclipse.n4js.utils.N4JSLanguageUtils; + +/***/ +public class N4JSInterfaceDeclarationTypesBuilder extends N4JSClassifierDeclarationTypesBuilder { + + boolean relinkTInterface(N4InterfaceDeclaration n4Interface, AbstractNamespace target, boolean preLinkingPhase, + int idx) { + if (n4Interface.getName() == null) { // may be null due to syntax errors + return false; + } + + TInterface interfaceType = (TInterface) target.getTypes().get(idx); + relinkClassifierAndMembers(interfaceType, n4Interface, preLinkingPhase); + return true; + } + + /***/ + protected TInterface createTInterface(N4InterfaceDeclaration n4Interface, AbstractNamespace target, + boolean preLinkingPhase) { + if (n4Interface.getName() == null) { + return null; + } + + TInterface interfaceType = createTInterface(n4Interface); + _n4JSTypesBuilderHelper.setTypeAccessModifier(interfaceType, n4Interface); + + interfaceType.setTypingStrategy( + (n4Interface.getTypingStrategy() == TypingStrategy.DEFAULT) ? TypingStrategy.DEFAULT + : // STRUCTURAL_FIELD is not allowed on def site, but maybe we got a wrong input + TypingStrategy.STRUCTURAL); + + _n4JSTypesBuilderHelper.setProvidedByRuntime(interfaceType, n4Interface, preLinkingPhase); + interfaceType.setDeclaredNonStaticPolyfill(N4JSLanguageUtils.isNonStaticPolyfill(n4Interface)); + interfaceType + .setDeclaredCovariantConstructor(_n4JSTypesBuilderHelper.isDeclaredCovariantConstructor(n4Interface)); + _n4JSTypeVariableTypesBuilder.addTypeParameters(interfaceType, n4Interface, preLinkingPhase); + addExtendedInterfaces(interfaceType, n4Interface, preLinkingPhase); + + addFields(interfaceType, n4Interface, preLinkingPhase); + addMethods(interfaceType, n4Interface, target, preLinkingPhase); + + addGetters(interfaceType, n4Interface, target, preLinkingPhase); + addSetters(interfaceType, n4Interface, target, preLinkingPhase); + + _n4JSTypesBuilderHelper.copyAnnotations(interfaceType, n4Interface, preLinkingPhase); + + interfaceType.setAstElement(n4Interface); + n4Interface.setDefinedType(interfaceType); + + target.getTypes().add(interfaceType); + return interfaceType; + } + + private TInterface createTInterface(N4InterfaceDeclaration n4Interface) { + TInterface interfaceType = TypesFactory.eINSTANCE.createTInterface(); + interfaceType.setName(n4Interface.getName()); + interfaceType.setExternal(n4Interface.isExternal()); + + return interfaceType; + } + + private void addExtendedInterfaces(TInterface interfaceType, N4InterfaceDeclaration c, boolean preLinkingPhase) { + if (!preLinkingPhase) { + _n4JSTypesBuilderHelper.addCopyOfReferences(interfaceType.getSuperInterfaceRefs(), + toList(map(c.getSuperInterfaceRefs(), sir -> sir.getTypeRefInAST()))); + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSInterfaceDeclarationTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSInterfaceDeclarationTypesBuilder.xtend deleted file mode 100644 index d44dc65229..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSInterfaceDeclarationTypesBuilder.xtend +++ /dev/null @@ -1,80 +0,0 @@ -/** - * 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.typesbuilder - -import org.eclipse.n4js.n4JS.N4InterfaceDeclaration -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.TInterface -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.ts.types.TypingStrategy -import org.eclipse.n4js.utils.N4JSLanguageUtils - -public class N4JSInterfaceDeclarationTypesBuilder extends N4JSClassifierDeclarationTypesBuilder { - - def package boolean relinkTInterface(N4InterfaceDeclaration n4Interface, AbstractNamespace target, boolean preLinkingPhase, int idx) { - if (n4Interface.name === null) { // may be null due to syntax errors - return false; - } - - val TInterface interfaceType = target.types.get(idx) as TInterface - interfaceType.relinkClassifierAndMembers(n4Interface, preLinkingPhase); - return true; - } - - def protected TInterface createTInterface(N4InterfaceDeclaration n4Interface, AbstractNamespace target, boolean preLinkingPhase) { - if (n4Interface.name === null) { - return null; - } - - val interfaceType = createTInterface(n4Interface); - interfaceType.setTypeAccessModifier(n4Interface) - - interfaceType.setTypingStrategy( - if (n4Interface.typingStrategy === TypingStrategy.DEFAULT) { - TypingStrategy.DEFAULT - } else { // STRUCTURAL_FIELD is not allowed on def site, but maybe we got a wrong input - TypingStrategy.STRUCTURAL - }) - - interfaceType.setProvidedByRuntime(n4Interface, preLinkingPhase) - interfaceType.declaredNonStaticPolyfill = N4JSLanguageUtils.isNonStaticPolyfill(n4Interface); - interfaceType.declaredCovariantConstructor = n4Interface.isDeclaredCovariantConstructor; - interfaceType.addTypeParameters(n4Interface, preLinkingPhase) - interfaceType.addExtendedInterfaces(n4Interface, preLinkingPhase) - - interfaceType.addFields(n4Interface, preLinkingPhase) - interfaceType.addMethods(n4Interface, target, preLinkingPhase) - - interfaceType.addGetters(n4Interface, target, preLinkingPhase) - interfaceType.addSetters(n4Interface, target, preLinkingPhase) - - interfaceType.copyAnnotations(n4Interface, preLinkingPhase) - - interfaceType.astElement = n4Interface - n4Interface.definedType = interfaceType - - target.types += interfaceType - return interfaceType; - } - - def private TInterface createTInterface(N4InterfaceDeclaration n4Interface) { - val interfaceType = TypesFactory::eINSTANCE.createTInterface(); - interfaceType.name = n4Interface.name; - interfaceType.external = n4Interface.external; - - return interfaceType - } - - def private void addExtendedInterfaces(TInterface interfaceType, N4InterfaceDeclaration c, boolean preLinkingPhase) { - if (!preLinkingPhase) - addCopyOfReferences(interfaceType.superInterfaceRefs, c.superInterfaceRefs.map[typeRefInAST]) - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSMethodTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSMethodTypesBuilder.java new file mode 100644 index 0000000000..78e40e301c --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSMethodTypesBuilder.java @@ -0,0 +1,173 @@ +/** + * 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.typesbuilder; + +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.exists; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.n4JS.Block; +import org.eclipse.n4js.n4JS.FunctionDeclaration; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.N4JSPackage; +import org.eclipse.n4js.n4JS.N4MethodDeclaration; +import org.eclipse.n4js.n4JS.SuperLiteral; +import org.eclipse.n4js.n4JS.ThisLiteral; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.ts.typeRefs.ThisTypeRef; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TMethod; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.utils.EcoreUtilN4; +import org.eclipse.n4js.utils.N4JSLanguageUtils; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +@Singleton +class N4JSMethodTypesBuilder extends AbstractFunctionDefinitionTypesBuilder { + + @Inject + N4JSTypeVariableTypesBuilder _n4JSTypeVariableTypesBuilder; + @Inject + N4JSVariableStatementTypesBuilder _n4JSVariableStatementTypesBuilder; + @Inject + N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + + boolean canCreate(N4MethodDeclaration methodDecl) { + EObject methodDefinedType = (EObject) methodDecl.eGet( + N4JSPackage.eINSTANCE.getTypeDefiningElement_DefinedType(), + false); + if (methodDefinedType != null && !methodDefinedType.eIsProxy()) { + throw new IllegalStateException("TMethod already created for N4MethodDeclaration"); + } + if (methodDecl.getName() == null && !methodDecl.hasComputedPropertyName() && !methodDecl.isCallSignature()) { + return false; + } + return true; + } + + boolean relinkMethod(N4MethodDeclaration methodDecl, TClassifier classifier, boolean preLinkingPhase, int idx) { + if (!canCreate(methodDecl)) { + return false; + } + return relinkMethod(methodDecl, (TMethod) classifier.getOwnedMembers().get(idx), preLinkingPhase); + } + + boolean relinkMethod(N4MethodDeclaration methodDecl, TMethod tMethod, boolean preLinkingPhase) { + TMethod methodType = tMethod; + _n4JSTypesBuilderHelper.ensureEqualName(methodDecl, methodType); + + relinkFormalParameters(methodType, methodDecl, preLinkingPhase); + + // link + methodType.setAstElement(methodDecl); + methodDecl.setDefinedType(methodType); + + return true; + } + + /** + * Creates TMethod for the given method declaration (and links it to that method). + * + * @param methodDecl + * declaration for which the TMethod is created, must not be linked to a TMethod yet (i.e. its defined + * type must be null). + */ + TMethod createMethod(N4MethodDeclaration methodDecl, AbstractNamespace target, boolean preLinkingPhase) { + if (!canCreate(methodDecl)) { + return null; + } + TMethod methodType = TypesFactory.eINSTANCE.createTMethod(); + if (methodDecl.isCallSignature()) { + methodType.setName(N4JSLanguageUtils.CALL_SIGNATURE_NAME); + } else { + _n4JSTypesBuilderHelper.setMemberName(methodType, methodDecl); + } + methodType.setDeclaredAbstract(methodDecl.isAbstract()); + methodType.setDeclaredStatic(methodDecl.isDeclaredStatic()); + methodType.setDeclaredFinal(methodDecl.isDeclaredFinal()); + methodType.setDeclaredOverride(AnnotationDefinition.OVERRIDE.hasAnnotation(methodDecl)); + methodType.setConstructor(methodDecl.isConstructor()); + methodType.setDeclaredAsync(methodDecl.isAsync()); + methodType.setDeclaredGenerator(methodDecl.isGenerator()); + + boolean providesDefaultImpl = AnnotationDefinition.PROVIDES_DEFAULT_IMPLEMENTATION.hasAnnotation(methodDecl); + methodType.setHasNoBody(methodDecl.getBody() == null && !providesDefaultImpl); + + methodType.setLacksThisOrSuperUsage( + hasNonNullBody(methodDecl.getBody()) && !containsThisOrSuperUsage(methodDecl.getBody())); + + BuiltInTypeScope builtInTypeScope = BuiltInTypeScope.get(methodDecl.eResource().getResourceSet()); + _n4JSVariableStatementTypesBuilder.createImplicitArgumentsVariable(methodDecl, target, builtInTypeScope, + preLinkingPhase); + + setMemberAccessModifier(methodType, methodDecl); + _n4JSTypeVariableTypesBuilder.addTypeParameters(methodType, methodDecl, preLinkingPhase); + addFormalParameters(methodType, methodDecl, builtInTypeScope, preLinkingPhase); + setReturnTypeConsideringThis(methodType, methodDecl, builtInTypeScope, preLinkingPhase); + _n4JSTypesBuilderHelper.setDeclaredThisTypeFromAnnotation(methodType, methodDecl, preLinkingPhase); + + _n4JSTypesBuilderHelper.copyAnnotations(methodType, methodDecl, preLinkingPhase); + + // link + methodType.setAstElement(methodDecl); + methodDecl.setDefinedType(methodType); + + return methodType; + } + + private void setMemberAccessModifier(TMethod methodType, N4MethodDeclaration n4Method) { + _n4JSTypesBuilderHelper.setMemberAccessModifier( + modifier -> methodType.setDeclaredMemberAccessModifier(modifier), + n4Method.getDeclaredModifiers(), n4Method.getAnnotations()); + } + + /** + * Sets the return type. If the declared return type is 'this', a ComputedTypeRef will be created to generate a + * bound this type. + */ + private void setReturnTypeConsideringThis(TMethod methodType, N4MethodDeclaration methodDecl, + BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + if (methodDecl.isConstructor() || methodDecl.getDeclaredReturnTypeRefInAST() instanceof ThisTypeRef) { + // special case: TypeDeferredProcessor will create a BoundThisTypeRef via Xsemantics judgment 'thisTypeRef' + methodType.setReturnTypeRef(TypeUtils.createDeferredTypeRef()); + } else { + // standard case + setReturnType(methodType, methodDecl, builtInTypeScope, preLinkingPhase); + } + } + + private boolean hasNonNullBody(Block body) { + return (null != body) && (null != body.getAllStatements()); + } + + /** + * Checks for the presence of 'this' or 'super' usages in the given body, also including sub-expressions (eg, 'if + * (sub-expr)'), without delving inside function definitions or declarations. + *

+ * Static methods refer to static members via ThisLiteral. + */ + private boolean containsThisOrSuperUsage(Block body) { + return exists(body.getAllStatements(), stmt -> isThisOrSuperUsage(stmt) || + exists(EcoreUtilN4.getAllContentsFiltered(stmt, s -> !isFnDefOrDecl(s)), s -> isThisOrSuperUsage(s))); + } + + private boolean isFnDefOrDecl(EObject ast) { + return ast instanceof FunctionDeclaration || ast instanceof FunctionDefinition; + } + + private boolean isThisOrSuperUsage(EObject expr) { + return expr instanceof SuperLiteral || expr instanceof ThisLiteral; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSMethodTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSMethodTypesBuilder.xtend deleted file mode 100644 index 46eead69b1..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSMethodTypesBuilder.xtend +++ /dev/null @@ -1,166 +0,0 @@ -/** - * 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.typesbuilder - -import com.google.inject.Inject -import com.google.inject.Singleton -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.Block -import org.eclipse.n4js.n4JS.FunctionDeclaration -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.N4JSPackage -import org.eclipse.n4js.n4JS.N4MethodDeclaration -import org.eclipse.n4js.n4JS.SuperLiteral -import org.eclipse.n4js.n4JS.ThisLiteral -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.ts.typeRefs.ThisTypeRef -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.MemberAccessModifier -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TMethod -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.utils.EcoreUtilN4 -import org.eclipse.n4js.utils.N4JSLanguageUtils - -@Singleton -package class N4JSMethodTypesBuilder extends AbstractFunctionDefinitionTypesBuilder { - - @Inject extension N4JSTypeVariableTypesBuilder - @Inject extension N4JSVariableStatementTypesBuilder - @Inject extension N4JSTypesBuilderHelper - - def boolean canCreate(N4MethodDeclaration methodDecl) { - val methodDefinedType = methodDecl.eGet(N4JSPackage.eINSTANCE.typeDefiningElement_DefinedType, false) as EObject; - if (methodDefinedType !== null && !methodDefinedType.eIsProxy) { - throw new IllegalStateException("TMethod already created for N4MethodDeclaration"); - } - if (methodDecl.name === null && !methodDecl.hasComputedPropertyName && !methodDecl.callSignature) { - return false; - } - return true; - } - - def package boolean relinkMethod(N4MethodDeclaration methodDecl, TClassifier classifier, boolean preLinkingPhase, int idx) { - if (!canCreate(methodDecl)) { - return false; - } - relinkMethod(methodDecl, classifier.ownedMembers.get(idx) as TMethod, preLinkingPhase); - } - - def package boolean relinkMethod(N4MethodDeclaration methodDecl, TMethod tMethod, boolean preLinkingPhase) { - val methodType = tMethod; - ensureEqualName(methodDecl, methodType); - - methodType.relinkFormalParameters(methodDecl, preLinkingPhase) - - // link - methodType.astElement = methodDecl - methodDecl.definedType = methodType - - return true; - } - - /** - * Creates TMethod for the given method declaration (and links it to that method). - * - * @param methodDecl declaration for which the TMethod is created, must not be linked to a TMethod yet (i.e. its defined type must be null). - * @param preLinkingPhase - */ - def package TMethod createMethod(N4MethodDeclaration methodDecl, AbstractNamespace target, boolean preLinkingPhase) { - if (!canCreate(methodDecl)) { - return null; - } - val methodType = TypesFactory::eINSTANCE.createTMethod(); - if (methodDecl.isCallSignature) { - methodType.name = N4JSLanguageUtils.CALL_SIGNATURE_NAME; - } else { - methodType.setMemberName(methodDecl); - } - methodType.declaredAbstract = methodDecl.abstract - methodType.declaredStatic = methodDecl.declaredStatic - methodType.declaredFinal = methodDecl.declaredFinal - methodType.declaredOverride = AnnotationDefinition.OVERRIDE.hasAnnotation(methodDecl); - methodType.constructor = methodDecl.constructor - methodType.declaredAsync = methodDecl.async - methodType.declaredGenerator = methodDecl.generator - - val providesDefaultImpl = AnnotationDefinition.PROVIDES_DEFAULT_IMPLEMENTATION.hasAnnotation(methodDecl); - methodType.hasNoBody = methodDecl.body===null && !providesDefaultImpl; - - methodType.lacksThisOrSuperUsage = hasNonNullBody(methodDecl.body) && !containsThisOrSuperUsage(methodDecl.body) - - val builtInTypeScope = BuiltInTypeScope.get(methodDecl.eResource.resourceSet) - methodDecl.createImplicitArgumentsVariable(target, builtInTypeScope, preLinkingPhase); - - methodType.setMemberAccessModifier(methodDecl) - methodType.addTypeParameters(methodDecl, preLinkingPhase) - methodType.addFormalParameters(methodDecl, builtInTypeScope, preLinkingPhase) - methodType.setReturnTypeConsideringThis(methodDecl, builtInTypeScope, preLinkingPhase) - methodType.setDeclaredThisTypeFromAnnotation(methodDecl, preLinkingPhase) - - methodType.copyAnnotations(methodDecl, preLinkingPhase) - - // link - methodType.astElement = methodDecl - methodDecl.definedType = methodType - - return methodType; - } - - def private void setMemberAccessModifier(TMethod methodType, N4MethodDeclaration n4Method) { - setMemberAccessModifier([MemberAccessModifier modifier|methodType.declaredMemberAccessModifier = modifier], - n4Method.declaredModifiers, n4Method.annotations) - } - - /** - * Sets the return type. If the declared return type is 'this', a ComputedTypeRef will - * be created to generate a bound this type. - */ - def private void setReturnTypeConsideringThis(TMethod methodType, N4MethodDeclaration methodDecl, - BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - if (methodDecl.isConstructor || methodDecl.declaredReturnTypeRefInAST instanceof ThisTypeRef) { - // special case: TypeDeferredProcessor will create a BoundThisTypeRef via Xsemantics judgment 'thisTypeRef' - methodType.returnTypeRef = TypeUtils.createDeferredTypeRef - } else { - // standard case - methodType.setReturnType(methodDecl, builtInTypeScope, preLinkingPhase) - } - } - - private def boolean hasNonNullBody(Block body) { - (null !== body) && - (null !== body.allStatements) - } - - /** - * Checks for the presence of 'this' or 'super' usages in the given body, - * also including sub-expressions (eg, 'if (sub-expr)'), - * without delving inside function definitions or declarations. - *

- * Static methods refer to static members via ThisLiteral. - */ - private def boolean containsThisOrSuperUsage(Block body) { - body.allStatements.exists[ stmt | - isThisOrSuperUsage(stmt) || - EcoreUtilN4.getAllContentsFiltered(stmt, [!isFnDefOrDecl(it)]).exists[isThisOrSuperUsage(it)]; - ] - } - - private def boolean isFnDefOrDecl(EObject ast) { - ast instanceof FunctionDeclaration || ast instanceof FunctionDefinition - } - - private def boolean isThisOrSuperUsage(EObject expr) { - expr instanceof SuperLiteral || expr instanceof ThisLiteral - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSNamespaceDeclarationTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSNamespaceDeclarationTypesBuilder.java new file mode 100644 index 0000000000..9564275b42 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSNamespaceDeclarationTypesBuilder.java @@ -0,0 +1,63 @@ +/** + * 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.typesbuilder; + +import org.eclipse.n4js.n4JS.N4NamespaceDeclaration; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TNamespace; +import org.eclipse.n4js.ts.types.TypesFactory; + +@SuppressWarnings("javadoc") +public class N4JSNamespaceDeclarationTypesBuilder extends N4JSClassifierDeclarationTypesBuilder { + + boolean relinkTNamespace(N4NamespaceDeclaration n4Namespace, AbstractNamespace target, + @SuppressWarnings("unused") boolean preLinkingPhase, int idx) { + + if (n4Namespace.getName() == null) { // may be null due to syntax errors + return false; + } + + TNamespace namespaceType = target.getNamespaces().get(idx); + _n4JSTypesBuilderHelper.ensureEqualName(n4Namespace, namespaceType); + + namespaceType.setAstElement(n4Namespace); + n4Namespace.setDefinedType(namespaceType); + + return true; + } + + protected TNamespace createTNamespace(N4NamespaceDeclaration n4Namespace, AbstractNamespace target, + boolean preLinkingPhase) { + if (n4Namespace.getName() == null) { + return null; + } + + TNamespace namespaceType = createTNamespace(n4Namespace); + _n4JSTypesBuilderHelper.setTypeAccessModifier(namespaceType, n4Namespace); + + _n4JSTypesBuilderHelper.setProvidedByRuntime(namespaceType, n4Namespace, preLinkingPhase); + + namespaceType.setAstElement(n4Namespace); + n4Namespace.setDefinedType(namespaceType); + + target.getNamespaces().add(namespaceType); + return namespaceType; + } + + private TNamespace createTNamespace(N4NamespaceDeclaration n4Namespace) { + TNamespace namespaceType = TypesFactory.eINSTANCE.createTNamespace(); + namespaceType.setName(n4Namespace.getName()); + namespaceType.setExternal(n4Namespace.isExternal()); + + return namespaceType; + } + +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSNamespaceDeclarationTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSNamespaceDeclarationTypesBuilder.xtend deleted file mode 100644 index dde09b61a0..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSNamespaceDeclarationTypesBuilder.xtend +++ /dev/null @@ -1,60 +0,0 @@ -/** - * 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.typesbuilder - -import org.eclipse.n4js.n4JS.N4NamespaceDeclaration -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.TNamespace -import org.eclipse.n4js.ts.types.TypesFactory - -public class N4JSNamespaceDeclarationTypesBuilder extends N4JSClassifierDeclarationTypesBuilder { - - def package boolean relinkTNamespace(N4NamespaceDeclaration n4Namespace, AbstractNamespace target, boolean preLinkingPhase, int idx) { - if (n4Namespace.name === null) { // may be null due to syntax errors - return false; - } - - val TNamespace namespaceType = target.namespaces.get(idx) - ensureEqualName(n4Namespace, namespaceType); - - namespaceType.astElement = n4Namespace - n4Namespace.definedType = namespaceType - - return true; - } - - def protected TNamespace createTNamespace(N4NamespaceDeclaration n4Namespace, AbstractNamespace target, boolean preLinkingPhase) { - if (n4Namespace.name === null) { - return null; - } - - val namespaceType = createTNamespace(n4Namespace); - namespaceType.setTypeAccessModifier(n4Namespace) - - - namespaceType.setProvidedByRuntime(n4Namespace, preLinkingPhase) - - namespaceType.astElement = n4Namespace - n4Namespace.definedType = namespaceType - - target.namespaces += namespaceType - return namespaceType; - } - - def private TNamespace createTNamespace(N4NamespaceDeclaration n4Namespace) { - val namespaceType = TypesFactory::eINSTANCE.createTNamespace(); - namespaceType.name = n4Namespace.name; - namespaceType.external = n4Namespace.external; - - return namespaceType - } - -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSObjectLiteralTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSObjectLiteralTypesBuilder.java new file mode 100644 index 0000000000..36e7349342 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSObjectLiteralTypesBuilder.java @@ -0,0 +1,206 @@ +/** + * 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.typesbuilder; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.Arrays; + +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.PropertyAssignment; +import org.eclipse.n4js.n4JS.PropertyGetterDeclaration; +import org.eclipse.n4js.n4JS.PropertyMethodDeclaration; +import org.eclipse.n4js.n4JS.PropertyNameValuePair; +import org.eclipse.n4js.n4JS.PropertySetterDeclaration; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TStructField; +import org.eclipse.n4js.ts.types.TStructGetter; +import org.eclipse.n4js.ts.types.TStructMember; +import org.eclipse.n4js.ts.types.TStructMethod; +import org.eclipse.n4js.ts.types.TStructSetter; +import org.eclipse.n4js.ts.types.TStructuralType; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.types.utils.TypeUtils; + +import com.google.inject.Inject; + +/** + */ +public class N4JSObjectLiteralTypesBuilder { + + @Inject + N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + @Inject + N4JSFormalParameterTypesBuilder _n4JSFormalParameterTypesBuilder; + + void createObjectLiteral(ObjectLiteral objectLiteral, AbstractNamespace target, boolean preLinkingPhase) { + BuiltInTypeScope builtInTypeScope = BuiltInTypeScope.get(objectLiteral.eResource().getResourceSet()); + TStructuralType structType = TypesFactory.eINSTANCE.createTStructuralType(); + + for (PropertyAssignment it : objectLiteral.getPropertyAssignments()) { + if (it.getName() != null || it.hasComputedPropertyName()) { + TStructMember typeModelElement = createTypeModelElement(it, builtInTypeScope, preLinkingPhase); + if (typeModelElement != null) { + typeModelElement.setAstElement(it); + structType.getOwnedMembers().add(typeModelElement); + } + } + } + + structType.setAstElement(objectLiteral); + objectLiteral.setDefinedType(structType); + + target.getContainingModule().getInternalTypes().add(structType); + } + + // TODO GH-1337 add support for spread operator + private TStructMember createTypeModelElement( + PropertyAssignment getterDecl, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + + if (getterDecl instanceof PropertyGetterDeclaration) { + return createTypeModelElement((PropertyGetterDeclaration) getterDecl, + builtInTypeScope, preLinkingPhase); + } else if (getterDecl instanceof PropertyMethodDeclaration) { + return createTypeModelElement((PropertyMethodDeclaration) getterDecl, + builtInTypeScope, preLinkingPhase); + } else if (getterDecl instanceof PropertyNameValuePair) { + return createTypeModelElement((PropertyNameValuePair) getterDecl, + builtInTypeScope, preLinkingPhase); + } else if (getterDecl instanceof PropertySetterDeclaration) { + return createTypeModelElement((PropertySetterDeclaration) getterDecl, + builtInTypeScope, preLinkingPhase); + } else if (getterDecl != null) { + return null; + } else { + throw new IllegalArgumentException("Unhandled parameter types: " + + Arrays.asList(getterDecl, builtInTypeScope, preLinkingPhase).toString()); + } + } + + /** + * Creates a TStructField. + */ + private TStructField createTypeModelElement( + PropertyNameValuePair nameValuePair, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + TStructField field = TypesFactory.eINSTANCE.createTStructField(); + _n4JSTypesBuilderHelper.setMemberName(field, nameValuePair); + field.setOptional(nameValuePair.isDeclaredOptional()); + if (nameValuePair.getDeclaredTypeRefInAST() != null) { + if (!preLinkingPhase) { + field.setTypeRef(TypeUtils.copyWithProxies(nameValuePair.getDeclaredTypeRefInAST())); + } + } else if (nameValuePair.getExpression() != null) { + field.setTypeRef(TypeUtils.createDeferredTypeRef()); + } else { + // FIXME inconsistent with getter/setter case; should use DeferredTypeRef also if expression===null + field.setTypeRef(builtInTypeScope.getAnyTypeRef()); + } + // else { + // // in all other cases: + // // leave it to the corresponding xsemantics rule to infer the type (e.g. from the initializer expression, if + // given) + // if(!preLinkingPhase) { + // field.typeRef = + // TypeUtils.createComputedTypeRef([resolveAllComputedTypeRefsInTStructuralType(structType,objectLiteral,builtInTypeScope)]) + // } + // } + field.setAstElement(nameValuePair); + nameValuePair.setDefinedField(field); + return field; + } + + /** + * Creates a TStructGetter. + */ + private TStructGetter createTypeModelElement(PropertyGetterDeclaration getterDecl, + @SuppressWarnings("unused") BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + + TStructGetter getter = TypesFactory.eINSTANCE.createTStructGetter(); + _n4JSTypesBuilderHelper.setMemberName(getter, getterDecl); + getter.setOptional(getterDecl.isDeclaredOptional()); + if (getterDecl.getDeclaredTypeRefInAST() != null) { + if (!preLinkingPhase) { + getter.setTypeRef(TypeUtils.copyWithProxies(getterDecl.getDeclaredTypeRefInAST())); + } + } else { + getter.setTypeRef(TypeUtils.createDeferredTypeRef()); + } + getter.setAstElement(getterDecl); + getterDecl.setDefinedGetter(getter); + return getter; + } + + /** + * Creates a TStructSetter. + */ + private TStructSetter createTypeModelElement(PropertySetterDeclaration setterDecl, + @SuppressWarnings("unused") BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + + TStructSetter setter = TypesFactory.eINSTANCE.createTStructSetter(); + _n4JSTypesBuilderHelper.setMemberName(setter, setterDecl); + setter.setOptional(setterDecl.isDeclaredOptional()); + // IMPORTANT: do not create the formal parameter with N4JSFormalParameterTypesBuilder#createFormalParameter() + // because we here use improved type inference (the type of a getter/setter in an object literal is inferred + // similarly to that of a name/value pair) + TFormalParameter param = TypesFactory.eINSTANCE.createTFormalParameter(); + if (setterDecl.getFpar() != null) { + param.setName(setterDecl.getFpar().getName()); + TypeRef fparDeclTypeRef = setterDecl.getFpar().getDeclaredTypeRefInAST(); + if (fparDeclTypeRef != null) { + if (!preLinkingPhase) { + param.setTypeRef(TypeUtils.copyWithProxies(fparDeclTypeRef)); + } + } else { + param.setTypeRef(TypeUtils.createDeferredTypeRef()); + } + param.setAstElement(setterDecl.getFpar()); + setterDecl.getFpar().setDefinedVariable(param); + } else { + // broken AST + param.setTypeRef(TypeUtils.createDeferredTypeRef()); + // (note: using UnknownTypeRef would make more sense, but PolyComputer expects this, because + // setterDecl.declaredTypeRef===setterDecl?.fpar.declaredTypeRef===null, so setterDecl will be poly) + } + setter.setFpar(param); + setter.setAstElement(setterDecl); + setterDecl.setDefinedSetter(setter); + return setter; + } + + /** + * Creates a TStructMethod. + */ + private TStructMethod createTypeModelElement( + PropertyMethodDeclaration methodDecl, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + + TStructMethod result = TypesFactory.eINSTANCE.createTStructMethod(); + _n4JSTypesBuilderHelper.setMemberName(result, methodDecl); + // IMPORTANT: do not create the formal parameters as above for the property setters but instead create them with + // method N4JSFormalParameterTypesBuilder#createFormalParameter() (for consistency with methods in classes) + result.getFpars().addAll( + toList(map(methodDecl.getFpars(), fp -> _n4JSFormalParameterTypesBuilder.createFormalParameter(fp, + builtInTypeScope, preLinkingPhase)))); + if (methodDecl.getDeclaredReturnTypeRefInAST() != null) { + if (!preLinkingPhase) { + result.setReturnTypeRef(TypeUtils.copyWithProxies(methodDecl.getDeclaredReturnTypeRefInAST())); + } + } else { + result.setReturnTypeRef(builtInTypeScope.getVoidTypeRef()); + } + result.setAstElement(methodDecl); + methodDecl.setDefinedType(result); + return result; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSObjectLiteralTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSObjectLiteralTypesBuilder.xtend deleted file mode 100644 index dc61e8a117..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSObjectLiteralTypesBuilder.xtend +++ /dev/null @@ -1,164 +0,0 @@ -/** - * 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.typesbuilder; - -import com.google.inject.Inject -import org.eclipse.n4js.n4JS.ObjectLiteral -import org.eclipse.n4js.n4JS.PropertyAssignment -import org.eclipse.n4js.n4JS.PropertyGetterDeclaration -import org.eclipse.n4js.n4JS.PropertyMethodDeclaration -import org.eclipse.n4js.n4JS.PropertyNameValuePair -import org.eclipse.n4js.n4JS.PropertySetterDeclaration -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.TStructField -import org.eclipse.n4js.ts.types.TStructGetter -import org.eclipse.n4js.ts.types.TStructMember -import org.eclipse.n4js.ts.types.TStructMethod -import org.eclipse.n4js.ts.types.TStructSetter -import org.eclipse.n4js.ts.types.TStructuralType -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.types.utils.TypeUtils - -/** - */ -public class N4JSObjectLiteralTypesBuilder { - - @Inject extension N4JSTypesBuilderHelper - @Inject extension N4JSFormalParameterTypesBuilder - - - def package void createObjectLiteral(ObjectLiteral objectLiteral, AbstractNamespace target, boolean preLinkingPhase) { - val builtInTypeScope = BuiltInTypeScope.get(objectLiteral.eResource.resourceSet) - val TStructuralType structType = TypesFactory.eINSTANCE.createTStructuralType - objectLiteral.propertyAssignments.filter[name!==null || hasComputedPropertyName].forEach [ - val TStructMember typeModelElement = createTypeModelElement(structType, objectLiteral, it, builtInTypeScope, preLinkingPhase); - if(typeModelElement!==null) { - typeModelElement.astElement = it; - structType.ownedMembers += typeModelElement - } - ] - - structType.astElement = objectLiteral; - objectLiteral.definedType = structType; - - target.containingModule.internalTypes += structType - } - - // TODO GH-1337 add support for spread operator - private def dispatch TStructMember createTypeModelElement(TStructuralType structType, ObjectLiteral objectLiteral, PropertyAssignment assignment, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - } - - /** - * Creates a TStructField. - */ - private def dispatch TStructField createTypeModelElement(TStructuralType structType, ObjectLiteral objectLiteral, PropertyNameValuePair nameValuePair, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - val TStructField field = TypesFactory.eINSTANCE.createTStructField - field.setMemberName(nameValuePair); - field.optional = nameValuePair.declaredOptional; - if (nameValuePair.declaredTypeRefInAST !== null) { - if (!preLinkingPhase) { - field.typeRef = TypeUtils.copyWithProxies(nameValuePair.declaredTypeRefInAST) - } - } - else if(nameValuePair.expression !== null) { - field.typeRef = TypeUtils.createDeferredTypeRef; - } - else { - field.typeRef = builtInTypeScope.anyTypeRef; // FIXME inconsistent with getter/setter case; should use DeferredTypeRef also if expression===null - } -// else { -// // in all other cases: -// // leave it to the corresponding xsemantics rule to infer the type (e.g. from the initializer expression, if given) -// if(!preLinkingPhase) { -// field.typeRef = TypeUtils.createComputedTypeRef([resolveAllComputedTypeRefsInTStructuralType(structType,objectLiteral,builtInTypeScope)]) -// } -// } - field.astElement = nameValuePair; - nameValuePair.definedField = field; - return field - } - - /** - * Creates a TStructGetter. - */ - private def dispatch TStructGetter createTypeModelElement(TStructuralType structType, ObjectLiteral objectLiteral, PropertyGetterDeclaration getterDecl, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - val TStructGetter getter = TypesFactory.eINSTANCE.createTStructGetter - getter.setMemberName(getterDecl); - getter.optional = getterDecl.declaredOptional; - if (getterDecl.declaredTypeRefInAST !== null) { - if (!preLinkingPhase) { - getter.typeRef = TypeUtils.copyWithProxies(getterDecl.declaredTypeRefInAST) - } - } else { - getter.typeRef = TypeUtils.createDeferredTypeRef; - } - getter.astElement = getterDecl; - getterDecl.definedGetter = getter; - return getter - } - - /** - * Creates a TStructSetter. - */ - private def dispatch TStructSetter createTypeModelElement(TStructuralType structType, ObjectLiteral objectLiteral, PropertySetterDeclaration setterDecl, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - val TStructSetter setter = TypesFactory.eINSTANCE.createTStructSetter - setter.setMemberName(setterDecl); - setter.optional = setterDecl.declaredOptional; - // IMPORTANT: do not create the formal parameter with N4JSFormalParameterTypesBuilder#createFormalParameter() - // because we here use improved type inference (the type of a getter/setter in an object literal is inferred - // similarly to that of a name/value pair) - val param = TypesFactory.eINSTANCE.createTFormalParameter - if (setterDecl.fpar !== null) { - param.name = setterDecl.fpar.name - val fparDeclTypeRef = setterDecl.fpar.declaredTypeRefInAST; - if(fparDeclTypeRef!==null) { - if (!preLinkingPhase) { - param.typeRef = TypeUtils.copyWithProxies(fparDeclTypeRef); - } - } else { - param.typeRef = TypeUtils.createDeferredTypeRef; - } - param.astElement = setterDecl.fpar; - setterDecl.fpar.definedVariable = param; - } else { - // broken AST - param.typeRef = TypeUtils.createDeferredTypeRef; - // (note: using UnknownTypeRef would make more sense, but PolyComputer expects this, because - // setterDecl.declaredTypeRef===setterDecl?.fpar.declaredTypeRef===null, so setterDecl will be poly) - } - setter.fpar = param - setter.astElement = setterDecl; - setterDecl.definedSetter = setter; - return setter - } - - /** - * Creates a TStructMethod. - */ - private def dispatch TStructMethod createTypeModelElement(TStructuralType structType, ObjectLiteral objectLiteral, PropertyMethodDeclaration methodDecl, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - val TStructMethod result = TypesFactory.eINSTANCE.createTStructMethod; - result.setMemberName(methodDecl); - // IMPORTANT: do not create the formal parameters as above for the property setters but instead create them with - // method N4JSFormalParameterTypesBuilder#createFormalParameter() (for consistency with methods in classes) - result.fpars += methodDecl.fpars.map[createFormalParameter(builtInTypeScope, preLinkingPhase)]; - if (methodDecl.declaredReturnTypeRefInAST !== null) { - if (!preLinkingPhase) { - result.returnTypeRef = TypeUtils.copyWithProxies(methodDecl.declaredReturnTypeRefInAST); - } - } else { - result.returnTypeRef = builtInTypeScope.voidTypeRef; - } - result.astElement = methodDecl; - methodDecl.definedType = result; - return result; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSSetterTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSSetterTypesBuilder.java new file mode 100644 index 0000000000..f8724b3843 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSSetterTypesBuilder.java @@ -0,0 +1,112 @@ +/** + * 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.typesbuilder; + +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.n4JS.N4SetterDeclaration; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TSetter; +import org.eclipse.n4js.ts.types.TypesFactory; + +import com.google.inject.Inject; + +/** + */ +class N4JSSetterTypesBuilder { + + @Inject + N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + @Inject + N4JSFormalParameterTypesBuilder _n4JSFormalParameterTypesBuilder; + @Inject + N4JSVariableStatementTypesBuilder _n4JSVariableStatementTypesBuilder; + + boolean canCreate(N4SetterDeclaration n4Setter) { + return n4Setter.getName() != null || n4Setter.hasComputedPropertyName(); + } + + boolean relinkSetter(N4SetterDeclaration n4Setter, TSetter tSetter, + @SuppressWarnings("unused") boolean preLinkingPhase) { + if (!canCreate(n4Setter)) { + return false; + } + + _n4JSTypesBuilderHelper.ensureEqualName(n4Setter, tSetter); + linkFormalParameters(tSetter, n4Setter); + + tSetter.setAstElement(n4Setter); + n4Setter.setDefinedSetter(tSetter); + return true; + } + + TSetter createSetter(N4SetterDeclaration n4Setter, @SuppressWarnings("unused") TClassifier classifierType, + AbstractNamespace target, + boolean preLinkingPhase) { + if (!canCreate(n4Setter)) { + return null; + } + + BuiltInTypeScope builtInTypeScope = BuiltInTypeScope.get(n4Setter.eResource().getResourceSet()); + _n4JSVariableStatementTypesBuilder.createImplicitArgumentsVariable(n4Setter, target, builtInTypeScope, + preLinkingPhase); + + TSetter setterType = TypesFactory.eINSTANCE.createTSetter(); + _n4JSTypesBuilderHelper.setMemberName(setterType, n4Setter); + setterType.setDeclaredAbstract(n4Setter.isAbstract()); + setterType.setDeclaredStatic(n4Setter.isDeclaredStatic()); + setterType.setDeclaredFinal(n4Setter.isDeclaredFinal()); + setterType.setOptional(n4Setter.isOptional()); + setterType.setDeclaredOverride(AnnotationDefinition.OVERRIDE.hasAnnotation(n4Setter)); + + setterType.setHasNoBody(n4Setter.getBody() == null + && !AnnotationDefinition.PROVIDES_DEFAULT_IMPLEMENTATION.hasAnnotation(n4Setter)); + + setMemberAccessModifier(setterType, n4Setter); + addFormalParameters(setterType, n4Setter, builtInTypeScope, preLinkingPhase); + _n4JSTypesBuilderHelper.setDeclaredThisTypeFromAnnotation(setterType, n4Setter, preLinkingPhase); + + _n4JSTypesBuilderHelper.copyAnnotations(setterType, n4Setter, preLinkingPhase); + + setterType.setAstElement(n4Setter); + n4Setter.setDefinedSetter(setterType); + return setterType; + } + + private void setMemberAccessModifier(TSetter setterType, N4SetterDeclaration n4Setter) { + _n4JSTypesBuilderHelper.setMemberAccessModifier( + modifier -> setterType.setDeclaredMemberAccessModifier(modifier), + n4Setter.getDeclaredModifiers(), n4Setter.getAnnotations()); + } + + private void addFormalParameters(TSetter setterType, N4SetterDeclaration n4Setter, + BuiltInTypeScope builtInTypeScope, + boolean preLinkingPhase) { + if (n4Setter.getFpar() != null) { + setterType.setFpar(_n4JSFormalParameterTypesBuilder.createFormalParameter(n4Setter.getFpar(), + builtInTypeScope, preLinkingPhase)); + } + } + + private boolean linkFormalParameters(TSetter setterType, N4SetterDeclaration n4Setter) { + if (n4Setter.getFpar() == null) { + return false; + } + TFormalParameter formalParameterType = setterType.getFpar(); + _n4JSTypesBuilderHelper.ensureEqualName(n4Setter.getFpar(), formalParameterType); + formalParameterType.setAstElement(n4Setter.getFpar()); + n4Setter.getFpar().setDefinedVariable(formalParameterType); + return true; + } + +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSSetterTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSSetterTypesBuilder.xtend deleted file mode 100644 index 5f39050ce7..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSSetterTypesBuilder.xtend +++ /dev/null @@ -1,99 +0,0 @@ -/** - * 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.typesbuilder - -import com.google.inject.Inject -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.n4JS.N4SetterDeclaration -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.MemberAccessModifier -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TSetter -import org.eclipse.n4js.ts.types.TypesFactory - -/** - */ -package class N4JSSetterTypesBuilder { - - @Inject extension N4JSTypesBuilderHelper - @Inject extension N4JSFormalParameterTypesBuilder - @Inject extension N4JSVariableStatementTypesBuilder - - def boolean canCreate(N4SetterDeclaration n4Setter) { - return n4Setter.name !== null || n4Setter.hasComputedPropertyName; - } - - def package boolean relinkSetter(N4SetterDeclaration n4Setter, TSetter tSetter, boolean preLinkingPhase) { - if (!canCreate(n4Setter)) { - return false - } - - ensureEqualName(n4Setter, tSetter); - tSetter.linkFormalParameters(n4Setter, preLinkingPhase) - - tSetter.astElement = n4Setter - n4Setter.definedSetter = tSetter - return true - } - - def package TSetter createSetter(N4SetterDeclaration n4Setter, TClassifier classifierType, AbstractNamespace target, boolean preLinkingPhase) { - if (!canCreate(n4Setter)) { - return null - } - - val builtInTypeScope = BuiltInTypeScope.get(n4Setter.eResource.resourceSet) - n4Setter.createImplicitArgumentsVariable(target, builtInTypeScope, preLinkingPhase); - - val setterType = TypesFactory::eINSTANCE.createTSetter - setterType.setMemberName(n4Setter); - setterType.declaredAbstract = n4Setter.abstract - setterType.declaredStatic = n4Setter.declaredStatic - setterType.declaredFinal = n4Setter.declaredFinal - setterType.optional = n4Setter.optional; - setterType.declaredOverride = AnnotationDefinition.OVERRIDE.hasAnnotation(n4Setter); - - setterType.hasNoBody = n4Setter.body===null && !AnnotationDefinition.PROVIDES_DEFAULT_IMPLEMENTATION.hasAnnotation(n4Setter); - - setterType.setMemberAccessModifier(n4Setter) - setterType.addFormalParameters(n4Setter, builtInTypeScope, preLinkingPhase) - setterType.setDeclaredThisTypeFromAnnotation(n4Setter, preLinkingPhase) - - setterType.copyAnnotations(n4Setter, preLinkingPhase) - - setterType.astElement = n4Setter - n4Setter.definedSetter = setterType - setterType; - } - - def private void setMemberAccessModifier(TSetter setterType, N4SetterDeclaration n4Setter) { - setMemberAccessModifier([MemberAccessModifier modifier|setterType.declaredMemberAccessModifier = modifier], - n4Setter.declaredModifiers, n4Setter.annotations) - } - - def private void addFormalParameters(TSetter setterType, N4SetterDeclaration n4Setter, BuiltInTypeScope builtInTypeScope, - boolean preLinkingPhase) { - if (n4Setter.fpar !== null) - setterType.fpar = n4Setter.fpar.createFormalParameter(builtInTypeScope, preLinkingPhase); - } - - def private boolean linkFormalParameters(TSetter setterType, N4SetterDeclaration n4Setter, boolean preLinkingPhase) { - if (n4Setter.fpar === null) { - return false; - } - val formalParameterType = setterType.fpar; - ensureEqualName(n4Setter.fpar, formalParameterType); - formalParameterType.astElement = n4Setter.fpar; - n4Setter.fpar.definedVariable = formalParameterType; - return true; - } - -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeAliasDeclarationTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeAliasDeclarationTypesBuilder.java new file mode 100644 index 0000000000..227440dc8e --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeAliasDeclarationTypesBuilder.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2021 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.typesbuilder; + +import org.eclipse.n4js.n4JS.N4TypeAliasDeclaration; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TypeAlias; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.types.utils.TypeUtils; + +import com.google.inject.Inject; + +class N4JSTypeAliasDeclarationTypesBuilder { + + @Inject + N4JSTypeVariableTypesBuilder _n4JSTypeVariableTypesBuilder; + @Inject + N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + + protected boolean relinkTypeAlias(N4TypeAliasDeclaration n4TypeAlias, AbstractNamespace target, + @SuppressWarnings("unused") boolean preLinkingPhase, int idx) { + + if (n4TypeAlias.getName() == null) { // may be null due to syntax errors + return false; + } + + TypeAlias typeAlias = (TypeAlias) target.getTypes().get(idx); + + _n4JSTypesBuilderHelper.ensureEqualName(n4TypeAlias, typeAlias); + typeAlias.setAstElement(n4TypeAlias); + n4TypeAlias.setDefinedType(typeAlias); + + return true; + } + + void createTypeAlias(N4TypeAliasDeclaration n4TypeAlias, AbstractNamespace target, boolean preLinkingPhase) { + if (n4TypeAlias.getName() == null) { // may be null due to syntax errors + return; + } + + TypeAlias typeAlias = TypesFactory.eINSTANCE.createTypeAlias(); + typeAlias.setName(n4TypeAlias.getName()); + + _n4JSTypesBuilderHelper.setTypeAccessModifier(typeAlias, n4TypeAlias); + _n4JSTypeVariableTypesBuilder.addTypeParameters(typeAlias, n4TypeAlias, preLinkingPhase); + + _n4JSTypesBuilderHelper.copyAnnotations(typeAlias, n4TypeAlias, preLinkingPhase); + + if (!preLinkingPhase) { + typeAlias.setTypeRef(TypeUtils.copyWithProxies(n4TypeAlias.getDeclaredTypeRefInAST())); + } + + typeAlias.setAstElement(n4TypeAlias); + n4TypeAlias.setDefinedType(typeAlias); + + target.getTypes().add(typeAlias); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeAliasDeclarationTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeAliasDeclarationTypesBuilder.xtend deleted file mode 100644 index 522844ba52..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeAliasDeclarationTypesBuilder.xtend +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright (c) 2021 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.typesbuilder - -import com.google.inject.Inject -import org.eclipse.n4js.n4JS.N4TypeAliasDeclaration -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.TypeAlias -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.types.utils.TypeUtils - -class N4JSTypeAliasDeclarationTypesBuilder { - - @Inject extension N4JSTypeVariableTypesBuilder - @Inject extension N4JSTypesBuilderHelper - - def protected boolean relinkTypeAlias(N4TypeAliasDeclaration n4TypeAlias, AbstractNamespace target, boolean preLinkingPhase, int idx) { - if (n4TypeAlias.name === null) { // may be null due to syntax errors - return false; - } - - val TypeAlias typeAlias = target.types.get(idx) as TypeAlias - - ensureEqualName(n4TypeAlias, typeAlias); - typeAlias.astElement = n4TypeAlias; - n4TypeAlias.definedType = typeAlias; - - return true; - } - - def package void createTypeAlias(N4TypeAliasDeclaration n4TypeAlias, AbstractNamespace target, boolean preLinkingPhase) { - if(n4TypeAlias.name === null) { // may be null due to syntax errors - return; - } - - val typeAlias = TypesFactory.eINSTANCE.createTypeAlias(); - typeAlias.name = n4TypeAlias.name; - - typeAlias.setTypeAccessModifier(n4TypeAlias); - typeAlias.addTypeParameters(n4TypeAlias, preLinkingPhase); - - typeAlias.copyAnnotations(n4TypeAlias, preLinkingPhase); - - if (!preLinkingPhase) { - typeAlias.typeRef = TypeUtils.copyWithProxies(n4TypeAlias.declaredTypeRefInAST); - } - - typeAlias.astElement = n4TypeAlias; - n4TypeAlias.definedType = typeAlias; - - target.types += typeAlias; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeVariableTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeVariableTypesBuilder.java new file mode 100644 index 0000000000..d73c54dec7 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeVariableTypesBuilder.java @@ -0,0 +1,84 @@ +/** + * 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.typesbuilder; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.n4js.n4JS.GenericDeclaration; +import org.eclipse.n4js.n4JS.N4TypeVariable; +import org.eclipse.n4js.n4JS.TypeReferenceNode; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.GenericType; +import org.eclipse.n4js.ts.types.TypeVariable; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; + +import com.google.inject.Inject; + +class N4JSTypeVariableTypesBuilder { + + @Inject + N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + + void relinkTypeParameters(GenericDeclaration decl, GenericType target) { + EList n4TypeVars = decl.getTypeVars(); + EList typeVars = target.getTypeVars(); + int len = Math.min(n4TypeVars.size(), typeVars.size()); + for (var i = 0; i < len; i++) { + relinkTypeParameter(n4TypeVars.get(i), typeVars.get(i)); + } + } + + private void relinkTypeParameter(N4TypeVariable n4TypeVar, TypeVariable typeVar) { + if (n4TypeVar == null || typeVar == null) { + return; + } + _n4JSTypesBuilderHelper.ensureEqualName(n4TypeVar, typeVar); + n4TypeVar.setDefinedTypeVariable(typeVar); + } + + void addTypeParameters(GenericType target, GenericDeclaration decl, boolean preLinkingPhase) { + target.getTypeVars().clear(); + target.getTypeVars().addAll(toList(map(decl.getTypeVars(), tv -> createTypeVariable(tv, preLinkingPhase)))); + } + + private TypeVariable createTypeVariable(N4TypeVariable n4TypeVar, boolean preLinkingPhase) { + TypeVariable typeVar = TypesFactory.eINSTANCE.createTypeVariable(); + typeVar.setName(n4TypeVar.getName()); + typeVar.setDeclaredCovariant(n4TypeVar.isDeclaredCovariant()); + typeVar.setDeclaredContravariant(n4TypeVar.isDeclaredContravariant()); + if (!preLinkingPhase) { + TypeReferenceNode bound = n4TypeVar.getDeclaredUpperBoundNode(); + typeVar.setDeclaredUpperBound(TypeUtils.copyWithProxies(bound == null ? null : bound.getTypeRefInAST())); + if (n4TypeVar.isOptional()) { + TypeReferenceNode argumentNode = n4TypeVar.getDeclaredDefaultArgumentNode(); + TypeRef typeRef = argumentNode == null ? null : argumentNode.getTypeRefInAST(); + if (typeRef == null) { + if (typeVar.getDeclaredUpperBound() == null) { + RuleEnvironment G = RuleEnvironmentExtensions.newRuleEnvironment(n4TypeVar); + typeRef = RuleEnvironmentExtensions.anyTypeRef(G); + } else { + typeRef = typeVar.getDeclaredUpperBound(); + } + } + typeVar.setDefaultArgument(TypeUtils.copyWithProxies(typeRef)); + } + } + + n4TypeVar.setDefinedTypeVariable(typeVar); + + return typeVar; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeVariableTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeVariableTypesBuilder.xtend deleted file mode 100644 index 321ead810f..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypeVariableTypesBuilder.xtend +++ /dev/null @@ -1,74 +0,0 @@ -/** - * 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.typesbuilder - -import com.google.inject.Inject -import org.eclipse.n4js.n4JS.GenericDeclaration -import org.eclipse.n4js.n4JS.N4TypeVariable -import org.eclipse.n4js.ts.types.GenericType -import org.eclipse.n4js.ts.types.TypeVariable -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.types.utils.TypeUtils - -import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions - -package class N4JSTypeVariableTypesBuilder { - - @Inject extension N4JSTypesBuilderHelper - - def package void relinkTypeParameters(GenericDeclaration decl, GenericType target) { - val n4TypeVars = decl.typeVars; - val typeVars = target.typeVars; - val len = Math.min(n4TypeVars.size, typeVars.size); - for (var i = 0; i < len; i++) { - relinkTypeParameter(n4TypeVars.get(i), typeVars.get(i)); - } - } - - def private void relinkTypeParameter(N4TypeVariable n4TypeVar, TypeVariable typeVar) { - if (n4TypeVar === null || typeVar === null) { - return; - } - ensureEqualName(n4TypeVar, typeVar); - n4TypeVar.definedTypeVariable = typeVar; - } - - def package void addTypeParameters(GenericType target, GenericDeclaration decl, boolean preLinkingPhase) { - target.typeVars.clear(); - target.typeVars += decl.typeVars.map[createTypeVariable(it, preLinkingPhase)]; - } - - def private TypeVariable createTypeVariable(N4TypeVariable n4TypeVar, boolean preLinkingPhase) { - val typeVar = TypesFactory.eINSTANCE.createTypeVariable(); - typeVar.name = n4TypeVar.name; - typeVar.declaredCovariant = n4TypeVar.declaredCovariant; - typeVar.declaredContravariant = n4TypeVar.declaredContravariant; - if (!preLinkingPhase) { - typeVar.declaredUpperBound = TypeUtils.copyWithProxies(n4TypeVar.declaredUpperBoundNode?.typeRefInAST); - if (n4TypeVar.isOptional) { - var typeRef = n4TypeVar.getDeclaredDefaultArgumentNode?.typeRefInAST; - if (typeRef === null) { - if (typeVar.declaredUpperBound === null) { - val G = RuleEnvironmentExtensions.newRuleEnvironment(n4TypeVar); - typeRef = RuleEnvironmentExtensions.anyTypeRef(G); - } else { - typeRef = typeVar.declaredUpperBound; - } - } - typeVar.defaultArgument = TypeUtils.copyWithProxies(typeRef); - } - } - - n4TypeVar.definedTypeVariable = typeVar; - - return typeVar; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilder.java new file mode 100644 index 0000000000..3a1ca0f5f4 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilder.java @@ -0,0 +1,685 @@ +/** + * 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.typesbuilder; + +import static org.eclipse.n4js.utils.N4JSLanguageUtils.isContainedInStaticPolyfillAware; +import static org.eclipse.n4js.utils.N4JSLanguageUtils.isContainedInStaticPolyfillModule; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IteratorExtensions.toList; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.n4JS.ExportDeclaration; +import org.eclipse.n4js.n4JS.ExportableElement; +import org.eclipse.n4js.n4JS.FunctionDeclaration; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.MethodDeclaration; +import org.eclipse.n4js.n4JS.ModifiableElement; +import org.eclipse.n4js.n4JS.N4ClassDeclaration; +import org.eclipse.n4js.n4JS.N4ClassExpression; +import org.eclipse.n4js.n4JS.N4EnumDeclaration; +import org.eclipse.n4js.n4JS.N4InterfaceDeclaration; +import org.eclipse.n4js.n4JS.N4JSASTUtils; +import org.eclipse.n4js.n4JS.N4Modifier; +import org.eclipse.n4js.n4JS.N4NamespaceDeclaration; +import org.eclipse.n4js.n4JS.N4TypeAliasDeclaration; +import org.eclipse.n4js.n4JS.NamespaceExportSpecifier; +import org.eclipse.n4js.n4JS.NamespaceImportSpecifier; +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.Script; +import org.eclipse.n4js.n4JS.TryStatement; +import org.eclipse.n4js.n4JS.TypeDefiningElement; +import org.eclipse.n4js.n4JS.VariableDeclarationContainer; +import org.eclipse.n4js.naming.ModuleNameComputer; +import org.eclipse.n4js.naming.SpecifierConverter; +import org.eclipse.n4js.resource.N4JSResource; +import org.eclipse.n4js.smith.Measurement; +import org.eclipse.n4js.smith.N4JSDataCollectors; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.StructuralTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TClass; +import org.eclipse.n4js.ts.types.TInterface; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.TVariable; +import org.eclipse.n4js.ts.types.Type; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.utils.ResourceType; +import org.eclipse.n4js.validation.JavaScriptVariantHelper; +import org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot; +import org.eclipse.n4js.workspace.WorkspaceAccess; +import org.eclipse.xtext.naming.IQualifiedNameConverter; +import org.eclipse.xtext.naming.QualifiedName; +import org.eclipse.xtext.parser.IParseResult; +import org.eclipse.xtext.resource.DerivedStateAwareResource; +import org.eclipse.xtext.xbase.lib.ListExtensions; + +import com.google.inject.Inject; + +/** + * This class with its {@link N4JSTypesBuilder#createTModuleFromSource(DerivedStateAwareResource,boolean) + * createTModuleFromSource()} method is the single entry point for the types builder package. The only exception is the + * public method + * {@link N4JSFunctionDefinitionTypesBuilder#updateTFunction(FunctionExpression, FunctionTypeExprOrRef, TypeRef) + * updateTFunction()} in N4JSFunctionDefinitionTypesBuilder, which is called from Xsemantics. + *

+ * Derives the types model from the AST, i.e. creates a {@link TModule} with its contents from a {@link Script} and its + * children. The types model is stored at the second index of the resource. The types model contains for each exportable + * or type defining element a corresponding entry e.g. for a {@link N4ClassDeclaration} a {@link TClass} is created. + * Later when linking only the types are used in place of the original objects. + *

+ * The types builder must not use type inference because this would lead to a resolution of lazy cross-references at a + * too early stage. Instead, the types builder creates ComputedTypeRefs that will later be resolved either on demand or + * by calling {@link N4JSResource#flattenModule()}. + */ +@SuppressWarnings({ "javadoc", "unused" }) +public class N4JSTypesBuilder { + + @Inject(optional = true) + TypesFactory typesFactory = TypesFactory.eINSTANCE; + @Inject + N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + @Inject + N4JSNamespaceDeclarationTypesBuilder _n4JSNamespaceDeclarationTypesBuilder; + @Inject + N4JSClassDeclarationTypesBuilder _n4JSClassDeclarationTypesBuilder; + @Inject + N4JSInterfaceDeclarationTypesBuilder _n4JSInterfaceDeclarationTypesBuilder; + @Inject + N4JSEnumDeclarationTypesBuilder _n4JSEnumDeclarationTypesBuilder; + @Inject + N4JSTypeAliasDeclarationTypesBuilder _n4JSTypeAliasDeclarationTypesBuilder; + @Inject + N4JSObjectLiteralTypesBuilder _n4JSObjectLiteralTypesBuilder; + @Inject + N4JSFunctionDefinitionTypesBuilder _n4JSFunctionDefinitionTypesBuilder; + @Inject + N4JSVariableStatementTypesBuilder _n4JSVariableStatementTypesBuilder; + @Inject + N4JSTypesFromTypeRefBuilder _n4JSTypesFromTypeRefBuilder; + @Inject + N4JSImportTypesBuilder _n4JSImportTypesBuilder; + @Inject + N4JSExportDefinitionTypesBuilder _n4JSExportDefinitionTypesBuilder; + + @Inject + ModuleNameComputer _moduleNameComputer; + @Inject + private WorkspaceAccess workspaceAccess; + @Inject + private IQualifiedNameConverter qualifiedNameConverter; + @Inject + private SpecifierConverter specifierConverter; + @Inject + protected JavaScriptVariantHelper jsVariantHelper; + + /** Thrown when reconciliation of a TModule fails due to a hash mismatch. */ + public static class RelinkTModuleHashMismatchException extends IllegalStateException { + public RelinkTModuleHashMismatchException(URI resourceURI) { + super("cannot link existing TModule to new AST due to hash mismatch: " + resourceURI); + } + } + + /** + * When demand-loading an AST for a resource that already has a TModule (usually retrieved from the index) by + * calling SyntaxRelatedTElement#getAstElement(), we are facing a challenge: we could simply replace the original + * TModule by a new TModule created in the same way as in the standard case of loading an empty resource from + * source, i.e. with method {@link N4JSTypesBuilder#createTModuleFromSource(DerivedStateAwareResource, boolean) + * #createTModuleFromSource()}. However, this would lead to the issue of all existing references to the original, + * now replaced TModule to now have an invalid target object (not contained in a resource anymore, proxy resolution + * impossible, etc.). + *

+ * As a solution, this method provides a 2nd mode of the types builder in which not a new TModule is created from + * the AST, but an existing TModule is reused, i.e. the types builder does not create anything but simply creates + * the bidirectional links between AST nodes and TModule elements. + *

+ * This method should be called after the AST has been loaded, with the original TModule at second position in the + * resource's contents. If the AST and TModule were created from different versions of the source, checked via an + * MD5 hash, or the rewiring fails for other reasons, an {@link IllegalStateException} is thrown. In that case, the + * state of the AST and TModule are undefined (i.e. linking may have taken place partially). + */ + public void relinkTModuleToSource(DerivedStateAwareResource resource, boolean preLinkingPhase) { + try (Measurement m1 = N4JSDataCollectors.dcTypesBuilder.getMeasurement(); + Measurement m2 = N4JSDataCollectors.dcTypesBuilderRelink.getMeasurement()) { + m1.getClass(); // suppress unused variable warning from Xtend + m2.getClass(); // suppress unused variable warning from Xtend + + doRelinkTModuleToSource(resource, preLinkingPhase); + } + } + + private void doRelinkTModuleToSource(DerivedStateAwareResource resource, boolean preLinkingPhase) { + IParseResult parseResult = resource.getParseResult(); + if (parseResult != null) { + + Script script = (Script) parseResult.getRootASTElement(); + + TModule module = (TModule) resource.getContents().get(1); + + String astMD5New = N4JSASTUtils.md5Hex(resource); + if (!Objects.equals(astMD5New, module.getAstMD5())) { + throw new RelinkTModuleHashMismatchException(resource.getURI()); + } + module.setReconciled(true); + + _n4JSImportTypesBuilder.relinkTypeModelElementsForImports(script, module, preLinkingPhase); + + buildTypesFromTypeRefs(script, module, preLinkingPhase); + + relinkTypes(script, module, preLinkingPhase, new RelinkIndices()); + + module.setAstElement(script); + script.setModule(module); + + } else { + throw new IllegalStateException("resource has no parse result: " + resource.getURI()); + } + } + + /** + * This method is the single entry point for the types builder package. The only exception is the public method + * {@link N4JSFunctionDefinitionTypesBuilder#updateTFunction(FunctionExpression,FunctionTypeExprOrRef,TypeRef) + * updateTFunction()} in N4JSFunctionDefinitionTypesBuilder, which is called from Xsemantics. + *

+ * Creates an {@link TModule} with the module path name (@see {@link ModuleNameComputer#getModulePath(Resource)}) of + * the resource (replacing the dots with slashes). For all {@link ExportableElement} and {@link TypeDefiningElement} + * corresponding types like {@link TClass}, {@link TInterface} are created and assigned as containment references to + * {@link TModule}. Afterwards the so created {@link TModule} tree is browsed for {@link TVariable}s which do not + * have a type reference yet. For these there right hand side expressions is checked for a + * {@link TypeDefiningElement} for this a {@link ParameterizedTypeRef} is created having this element as declared + * type. The parameterized type ref is then assigned as type ref to the {@link TVariable}. + */ + public void createTModuleFromSource(DerivedStateAwareResource resource, boolean preLinkingPhase) { + try (Measurement m1 = N4JSDataCollectors.dcTypesBuilder.getMeasurement(); + Measurement m2 = N4JSDataCollectors.dcTypesBuilderCreate.getMeasurement()) { + m1.getClass(); // suppress unused variable warning from Xtend + m2.getClass(); // suppress unused variable warning from Xtend + + doCreateTModuleFromSource(resource, preLinkingPhase); + } + } + + private void doCreateTModuleFromSource(DerivedStateAwareResource resource, boolean preLinkingPhase) { + IParseResult parseResult = resource.getParseResult(); + if (parseResult != null) { + + // UtilN4.takeSnapshotInGraphView("TB start (preLinking=="+preLinkingPhase+")",resource.resourceSet); + Script script = (Script) parseResult.getRootASTElement(); + + TModule result = typesFactory.createTModule(); + + result.setAstMD5(N4JSASTUtils.md5Hex(resource)); + result.setReconciled(false); + + QualifiedName qualifiedModuleName = _moduleNameComputer.getQualifiedModuleName(resource); + result.setSimpleName(qualifiedModuleName.getLastSegment()); + result.setQualifiedName(qualifiedNameConverter.toString(qualifiedModuleName)); + result.setPreLinkingPhase(preLinkingPhase); + + N4JSProjectConfigSnapshot project = workspaceAccess.findProjectContaining(resource); + if (project != null) { + result.setProjectID(project.getName()); + result.setPackageName(project.getPackageName()); + result.setVendorID(project.getVendorId()); + + // main module + String mainModuleSpec = project.getMainModule(); + if (mainModuleSpec != null) { + result.setMainModule( + Objects.equals(qualifiedModuleName, specifierConverter.toQualifiedName(mainModuleSpec))); + } + } + + _n4JSTypesBuilderHelper.copyAnnotations(result, script, preLinkingPhase); + + _n4JSImportTypesBuilder.createTypeModelElementsForImports(script, result, preLinkingPhase); + + result.setN4jsdModule(jsVariantHelper.isExternalMode(script)); + + // Setting Polyfill property. + result.setStaticPolyfillModule(isContainedInStaticPolyfillModule(result)); + result.setStaticPolyfillAware(isContainedInStaticPolyfillAware(result)); + + buildTypesFromTypeRefs(script, result, preLinkingPhase); + + buildTypes(script, result, preLinkingPhase); + + result.setAstElement(script); + script.setModule(result); + ((N4JSResource) resource).sneakyAddToContent(result); + // UtilN4.takeSnapshotInGraphView("TB end (preLinking=="+preLinkingPhase+")",resource.resourceSet); + } else { + throw new IllegalStateException(resource.getURI() + " has no parse result."); + } + } + + /** + * Create types for those TypeRefs that define a type if they play the role of an AST node. + *

+ * This has to be done up-front, because in the rest of the types builder code we do not know where such a TypeRef + * shows up; to avoid having to check for them at every occurrence of a TypeRef, we do this ahead of the main types + * builder phase. + */ + private void buildTypesFromTypeRefs(Script script, TModule target, boolean preLinkingPhase) { + if (!preLinkingPhase) { + // important to do the following in bottom-up order! + // The structural members of a higher-level StructuralTypeRef STR may contain another StructuralTypeRef + // STR'; + // when the TStructuralType of STR is created, the structural members are copied, including contained + // TypeRefs; + // at that time the lower-level STR' must already have been prepared for copying! + // Example: + // var ~Object with { + // ~Object with { number fieldOfField; } field; + // } x; + List addTypesToTargets = new ArrayList<>(); + for (TypeRef tr : ListExtensions.reverseView(toList(filter(script.eAllContents(), TypeRef.class)))) { + if (tr instanceof StructuralTypeRef) { + StructuralTypeRef str = (StructuralTypeRef) tr; + _n4JSTypesFromTypeRefBuilder.createStructuralType(str); + if (str.getStructuralType() != null) { + addTypesToTargets.add(str.getStructuralType()); + } + } else if (tr instanceof FunctionTypeExpression) { + FunctionTypeExpression ftr = (FunctionTypeExpression) tr; + _n4JSTypesFromTypeRefBuilder.createTFunction(ftr); + if (ftr.getDeclaredType() != null) { + addTypesToTargets.add(ftr.getDeclaredType()); + } + } else if (tr instanceof N4NamespaceDeclaration) { + for (Type type : addTypesToTargets) { + target.getInternalTypes().add(type); + } + addTypesToTargets.clear(); + } + } + + for (Type type : addTypesToTargets) { + target.getInternalTypes().add(type); + } + } + } + + static class RelinkIndices { + int namespacesIdx = 0; + int typesIdx = 0; + int functionIdx = 0; + int variableIdx = 0; + } + + private void relinkTypes(EObject container, AbstractNamespace target, boolean preLinkingPhase, RelinkIndices rlis) { + for (EObject n : container.eContents()) { + // relink types of n (if applicable) + + if (n instanceof N4NamespaceDeclaration) { + rlis.namespacesIdx = relinkNamespace((N4NamespaceDeclaration) n, target, preLinkingPhase, + rlis.namespacesIdx); + } else if (n instanceof FunctionDefinition) { + rlis.functionIdx = relinkFunction(n, target, preLinkingPhase, rlis.functionIdx); + } else if (n instanceof TypeDefiningElement) { + rlis.typesIdx = relinkType(n, target, preLinkingPhase, rlis.typesIdx); + } else if (n instanceof VariableDeclarationContainer) { + rlis.variableIdx = relinkType(n, target, preLinkingPhase, + rlis.variableIdx); + } else if (n instanceof TryStatement) { + rlis.variableIdx = relinkType(n, target, preLinkingPhase, rlis.variableIdx); + } + + // relink types of child nodes + AbstractNamespace nextTarget; + RelinkIndices nextRelinkIndices; + if (n instanceof N4NamespaceDeclaration) { + nextTarget = ((N4NamespaceDeclaration) n).getDefinedNamespace(); + nextRelinkIndices = new RelinkIndices(); + } else { + nextTarget = target; + nextRelinkIndices = rlis; + } + if (nextTarget != null) { // can be null in broken ASTs + relinkTypes(n, nextTarget, preLinkingPhase, nextRelinkIndices); + } + // handle exports + // -> nothing to do + // (AST nodes of type ExportDeclaration are not TypeDefiningElements and + // type model elements of type ExportDefinition are not SyntaxRelatedTElements, + // so we do not have to relink anything between AST and types model here) + } + } + + protected int relinkNamespace(N4NamespaceDeclaration n4Namespace, AbstractNamespace target, boolean preLinkingPhase, + int idx) { + if (_n4JSNamespaceDeclarationTypesBuilder.relinkTNamespace(n4Namespace, target, preLinkingPhase, idx)) { + return idx + 1; + } + return idx; + } + + protected int relinkType(TypeDefiningElement other, AbstractNamespace target, boolean preLinkingPhase, int idx) { + throw new IllegalArgumentException( + "unknown subclass of TypeDefiningElement: " + (other == null ? null : other.eClass().getName())); + } + + protected int relinkType(NamespaceImportSpecifier nsImpSpec, AbstractNamespace target, boolean preLinkingPhase, + int idx) { + // already handled up-front in N4JSNamespaceImportTypesBuilder#relinkNamespaceTypes + return idx; + } + + protected int relinkFunction(MethodDeclaration n4MethodDecl, AbstractNamespace target, boolean preLinkingPhase, + int idx) { + // methods are handled in their containing class/interface -> ignore them here + return idx; + } + + protected int relinkFunction(FunctionDeclaration n4FunctionDecl, AbstractNamespace target, boolean preLinkingPhase, + int idx) { + if (_n4JSFunctionDefinitionTypesBuilder.relinkTFunction(n4FunctionDecl, target, preLinkingPhase, idx)) { + return idx + 1; + } + return idx; + } + + /** + * Function expressions are special, see + * {@link N4JSFunctionDefinitionTypesBuilder#createTFunction(FunctionExpression,TModule,boolean)}. + */ + protected int relinkFunction(FunctionExpression n4FunctionExpr, AbstractNamespace target, boolean preLinkingPhase, + int idx) { + _n4JSFunctionDefinitionTypesBuilder.createTFunction(n4FunctionExpr, target, preLinkingPhase); + return idx; + } + + protected int relinkType(N4ClassDeclaration n4Class, AbstractNamespace target, boolean preLinkingPhase, int idx) { + if (_n4JSClassDeclarationTypesBuilder.relinkTClass(n4Class, target, preLinkingPhase, idx)) { + return idx + 1; + } + return idx; + } + + protected int relinkType(N4ClassExpression n4Class, AbstractNamespace target, boolean preLinkingPhase, int idx) { + _n4JSClassDeclarationTypesBuilder.createTClass(n4Class, target, preLinkingPhase); + // do not increment the index + return idx; + } + + protected int relinkType(N4InterfaceDeclaration n4Interface, AbstractNamespace target, boolean preLinkingPhase, + int idx) { + if (_n4JSInterfaceDeclarationTypesBuilder.relinkTInterface(n4Interface, target, preLinkingPhase, idx)) { + return idx + 1; + } + return idx; + } + + protected int relinkType(N4EnumDeclaration n4Enum, AbstractNamespace target, boolean preLinkingPhase, int idx) { + if (_n4JSEnumDeclarationTypesBuilder.relinkTEnum(n4Enum, target, preLinkingPhase, idx)) { + return idx + 1; + } + return idx; + } + + protected int relinkType(N4TypeAliasDeclaration n4TypeAlias, AbstractNamespace target, boolean preLinkingPhase, + int idx) { + if (_n4JSTypeAliasDeclarationTypesBuilder.relinkTypeAlias(n4TypeAlias, target, preLinkingPhase, idx)) { + return idx + 1; + } + return idx; + } + + protected int relinkType(ObjectLiteral objectLiteral, AbstractNamespace target, boolean preLinkingPhase, int idx) { + _n4JSObjectLiteralTypesBuilder.createObjectLiteral(objectLiteral, target, preLinkingPhase); + return idx; + } + + protected int relinkType(VariableDeclarationContainer n4VarDeclContainer, AbstractNamespace target, + boolean preLinkingPhase, int idx) { + return _n4JSVariableStatementTypesBuilder.relinkVariableTypes(n4VarDeclContainer, target, preLinkingPhase, idx); + } + + protected int relinkType(TryStatement tryStmnt, AbstractNamespace target, boolean preLinkingPhase, int idx) { + return _n4JSVariableStatementTypesBuilder.relinkVariableTypes(tryStmnt, target, preLinkingPhase, idx); + } + + protected int relinkType(NamespaceExportSpecifier n4NamespaceExportSpecifier, AbstractNamespace target, + boolean preLinkingPhase, int idx) { + // namespace export specifiers are handled as part of their containing ExportDeclaration -> ignore them here + return idx; + } + + private void buildTypes(EObject container, AbstractNamespace target, boolean preLinkingPhase) { + for (EObject n : container.eContents()) { + // build type for n (if applicable) + if (n instanceof N4NamespaceDeclaration) { + createNamespace((N4NamespaceDeclaration) n, target, preLinkingPhase); + } else if (n instanceof FunctionDefinition) { + createFunction(n, target, preLinkingPhase); + } else if (n instanceof TypeDefiningElement) { + createType(n, target, preLinkingPhase); + } else if (n instanceof VariableDeclarationContainer) { + // VariableStatement and ForStatement + createType(n, target, preLinkingPhase); + } else if (n instanceof TryStatement) { + createType(n, target, preLinkingPhase); + } + + // build types for child nodes + AbstractNamespace nextTarget = (n instanceof N4NamespaceDeclaration) + ? ((N4NamespaceDeclaration) n).getDefinedNamespace() + : target; + if (nextTarget != null) { // can be null in broken ASTs + buildTypes(n, nextTarget, preLinkingPhase); + } + // handle exports + if (n instanceof ExportDeclaration) { + createType(n, target, preLinkingPhase); + } else if (n instanceof ExportableElement) { + ExportableElement ee = (ExportableElement) n; + if (!ee.isDeclaredExported() && ee.isExportedByNamespace()) { + boolean isDtsExceptionCase = ResourceType.getResourceType(ee) == ResourceType.DTS + && ee instanceof ModifiableElement + && ((ModifiableElement) ee).getDeclaredModifiers().contains(N4Modifier.PRIVATE); + if (!isDtsExceptionCase) { + _n4JSExportDefinitionTypesBuilder.createExportDefinitionForDirectlyExportedElement(ee, target, + preLinkingPhase); + } + } + } + } + } + + protected void createNamespace(N4NamespaceDeclaration n4Namespace, AbstractNamespace target, + boolean preLinkingPhase) { + _n4JSNamespaceDeclarationTypesBuilder.createTNamespace(n4Namespace, target, preLinkingPhase); + } + + protected void createFunction(MethodDeclaration n4MethodDecl, AbstractNamespace target, boolean preLinkingPhase) { + // methods are handled in their containing class/interface -> ignore them here + } + + protected void createFunction(FunctionDeclaration n4FunctionDecl, AbstractNamespace target, + boolean preLinkingPhase) { + _n4JSFunctionDefinitionTypesBuilder.createTFunction(n4FunctionDecl, target, preLinkingPhase); + } + + /** + * Function expressions are special, see + * {@link N4JSFunctionDefinitionTypesBuilder#createTFunction(FunctionExpression,TModule,boolean)}. + */ + protected void createFunction(FunctionExpression n4FunctionExpr, AbstractNamespace target, + boolean preLinkingPhase) { + _n4JSFunctionDefinitionTypesBuilder.createTFunction(n4FunctionExpr, target, preLinkingPhase); + } + + protected void createType(TypeDefiningElement other, AbstractNamespace target, boolean preLinkingPhase) { + throw new IllegalArgumentException( + "unknown subclass of TypeDefiningElement: " + (other == null ? null : other.eClass().getName())); + } + + protected void createType(NamespaceImportSpecifier nsImpSpec, AbstractNamespace target, boolean preLinkingPhase) { + // already handled up-front in #buildNamespacesTypesFromModuleImports() + } + + protected void createType(N4ClassDeclaration n4Class, AbstractNamespace target, boolean preLinkingPhase) { + _n4JSClassDeclarationTypesBuilder.createTClass(n4Class, target, preLinkingPhase); + } + + protected void createType(N4ClassExpression n4Class, AbstractNamespace target, boolean preLinkingPhase) { + _n4JSClassDeclarationTypesBuilder.createTClass(n4Class, target, preLinkingPhase); + } + + protected void createType(N4InterfaceDeclaration n4Interface, AbstractNamespace target, boolean preLinkingPhase) { + _n4JSInterfaceDeclarationTypesBuilder.createTInterface(n4Interface, target, preLinkingPhase); + } + + protected void createType(N4EnumDeclaration n4Enum, AbstractNamespace target, boolean preLinkingPhase) { + _n4JSEnumDeclarationTypesBuilder.createTEnum(n4Enum, target, preLinkingPhase); + } + + protected void createType(N4TypeAliasDeclaration n4TypeAliasDecl, AbstractNamespace target, + boolean preLinkingPhase) { + _n4JSTypeAliasDeclarationTypesBuilder.createTypeAlias(n4TypeAliasDecl, target, preLinkingPhase); + } + + protected void createType(ObjectLiteral objectLiteral, AbstractNamespace target, boolean preLinkingPhase) { + _n4JSObjectLiteralTypesBuilder.createObjectLiteral(objectLiteral, target, preLinkingPhase); + } + + protected void createType(VariableDeclarationContainer n4VarDeclContainer, AbstractNamespace target, + boolean preLinkingPhase) { + _n4JSVariableStatementTypesBuilder.createVariableTypes(n4VarDeclContainer, target, preLinkingPhase); + } + + protected void createType(TryStatement tryStmnt, AbstractNamespace target, boolean preLinkingPhase) { + _n4JSVariableStatementTypesBuilder.createVariableTypes(tryStmnt, target, preLinkingPhase); + } + + protected void createType(ExportDeclaration n4ExportDeclaration, AbstractNamespace target, + boolean preLinkingPhase) { + _n4JSExportDefinitionTypesBuilder.createExportDefinition(n4ExportDeclaration, target, preLinkingPhase); + } + + protected void createType(NamespaceExportSpecifier n4NamespaceExportSpecifier, AbstractNamespace target, + boolean preLinkingPhase) { + // namespace export specifiers are handled as part of their containing ExportDeclaration -> ignore them here + } + + protected int relinkType(final EObject n4Class, final AbstractNamespace target, final boolean preLinkingPhase, + final int idx) { + if (n4Class instanceof N4ClassDeclaration) { + return relinkType((N4ClassDeclaration) n4Class, target, preLinkingPhase, idx); + } else if (n4Class instanceof N4ClassExpression) { + return relinkType((N4ClassExpression) n4Class, target, preLinkingPhase, idx); + } else if (n4Class instanceof N4InterfaceDeclaration) { + return relinkType((N4InterfaceDeclaration) n4Class, target, preLinkingPhase, idx); + } else if (n4Class instanceof N4EnumDeclaration) { + return relinkType((N4EnumDeclaration) n4Class, target, preLinkingPhase, idx); + } else if (n4Class instanceof N4TypeAliasDeclaration) { + return relinkType((N4TypeAliasDeclaration) n4Class, target, preLinkingPhase, idx); + } else if (n4Class instanceof ObjectLiteral) { + return relinkType((ObjectLiteral) n4Class, target, preLinkingPhase, idx); + } else if (n4Class instanceof NamespaceExportSpecifier) { + return relinkType((NamespaceExportSpecifier) n4Class, target, preLinkingPhase, idx); + } else if (n4Class instanceof NamespaceImportSpecifier) { + return relinkType((NamespaceImportSpecifier) n4Class, target, preLinkingPhase, idx); + } else if (n4Class instanceof TryStatement) { + return relinkType((TryStatement) n4Class, target, preLinkingPhase, idx); + } else if (n4Class instanceof TypeDefiningElement) { + return relinkType((TypeDefiningElement) n4Class, target, preLinkingPhase, idx); + } else if (n4Class instanceof VariableDeclarationContainer) { + return relinkType((VariableDeclarationContainer) n4Class, target, preLinkingPhase, idx); + } else { + throw new IllegalArgumentException("Unhandled parameter types: " + + Arrays.asList(n4Class, target, preLinkingPhase, idx).toString()); + } + } + + protected int relinkFunction(final EObject n4FunctionDecl, final AbstractNamespace target, + final boolean preLinkingPhase, final int idx) { + if (n4FunctionDecl instanceof FunctionDeclaration) { + return relinkFunction((FunctionDeclaration) n4FunctionDecl, target, preLinkingPhase, idx); + } else if (n4FunctionDecl instanceof FunctionExpression) { + return relinkFunction((FunctionExpression) n4FunctionDecl, target, preLinkingPhase, idx); + } else if (n4FunctionDecl instanceof MethodDeclaration) { + return relinkFunction((MethodDeclaration) n4FunctionDecl, target, preLinkingPhase, idx); + } else { + throw new IllegalArgumentException("Unhandled parameter types: " + + Arrays.asList(n4FunctionDecl, target, preLinkingPhase, idx).toString()); + } + } + + protected void createFunction(final EObject n4FunctionDecl, final AbstractNamespace target, + final boolean preLinkingPhase) { + if (n4FunctionDecl instanceof FunctionDeclaration) { + createFunction((FunctionDeclaration) n4FunctionDecl, target, preLinkingPhase); + return; + } else if (n4FunctionDecl instanceof FunctionExpression) { + createFunction((FunctionExpression) n4FunctionDecl, target, preLinkingPhase); + return; + } else if (n4FunctionDecl instanceof MethodDeclaration) { + createFunction((MethodDeclaration) n4FunctionDecl, target, preLinkingPhase); + return; + } else { + throw new IllegalArgumentException("Unhandled parameter types: " + + Arrays.asList(n4FunctionDecl, target, preLinkingPhase).toString()); + } + } + + protected void createType(final EObject n4Class, final AbstractNamespace target, final boolean preLinkingPhase) { + if (n4Class instanceof N4ClassDeclaration) { + createType((N4ClassDeclaration) n4Class, target, preLinkingPhase); + return; + } else if (n4Class instanceof N4ClassExpression) { + createType((N4ClassExpression) n4Class, target, preLinkingPhase); + return; + } else if (n4Class instanceof N4InterfaceDeclaration) { + createType((N4InterfaceDeclaration) n4Class, target, preLinkingPhase); + return; + } else if (n4Class instanceof N4EnumDeclaration) { + createType((N4EnumDeclaration) n4Class, target, preLinkingPhase); + return; + } else if (n4Class instanceof N4TypeAliasDeclaration) { + createType((N4TypeAliasDeclaration) n4Class, target, preLinkingPhase); + return; + } else if (n4Class instanceof ObjectLiteral) { + createType((ObjectLiteral) n4Class, target, preLinkingPhase); + return; + } else if (n4Class instanceof ExportDeclaration) { + createType((ExportDeclaration) n4Class, target, preLinkingPhase); + return; + } else if (n4Class instanceof NamespaceExportSpecifier) { + createType((NamespaceExportSpecifier) n4Class, target, preLinkingPhase); + return; + } else if (n4Class instanceof NamespaceImportSpecifier) { + createType((NamespaceImportSpecifier) n4Class, target, preLinkingPhase); + return; + } else if (n4Class instanceof TryStatement) { + createType((TryStatement) n4Class, target, preLinkingPhase); + return; + } else if (n4Class instanceof TypeDefiningElement) { + createType((TypeDefiningElement) n4Class, target, preLinkingPhase); + return; + } else if (n4Class instanceof VariableDeclarationContainer) { + createType((VariableDeclarationContainer) n4Class, target, preLinkingPhase); + return; + } else { + throw new IllegalArgumentException("Unhandled parameter types: " + + Arrays.asList(n4Class, target, preLinkingPhase).toString()); + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilder.xtend deleted file mode 100644 index 96b50b8672..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilder.xtend +++ /dev/null @@ -1,519 +0,0 @@ -/** - * 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.typesbuilder - -import com.google.inject.Inject -import java.util.ArrayList -import java.util.List -import org.eclipse.emf.common.util.URI -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.n4JS.ExportDeclaration -import org.eclipse.n4js.n4JS.ExportableElement -import org.eclipse.n4js.n4JS.FunctionDeclaration -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.FunctionExpression -import org.eclipse.n4js.n4JS.MethodDeclaration -import org.eclipse.n4js.n4JS.ModifiableElement -import org.eclipse.n4js.n4JS.N4ClassDeclaration -import org.eclipse.n4js.n4JS.N4ClassExpression -import org.eclipse.n4js.n4JS.N4EnumDeclaration -import org.eclipse.n4js.n4JS.N4InterfaceDeclaration -import org.eclipse.n4js.n4JS.N4JSASTUtils -import org.eclipse.n4js.n4JS.N4Modifier -import org.eclipse.n4js.n4JS.N4NamespaceDeclaration -import org.eclipse.n4js.n4JS.N4TypeAliasDeclaration -import org.eclipse.n4js.n4JS.NamespaceExportSpecifier -import org.eclipse.n4js.n4JS.NamespaceImportSpecifier -import org.eclipse.n4js.n4JS.ObjectLiteral -import org.eclipse.n4js.n4JS.Script -import org.eclipse.n4js.n4JS.TryStatement -import org.eclipse.n4js.n4JS.TypeDefiningElement -import org.eclipse.n4js.n4JS.VariableDeclarationContainer -import org.eclipse.n4js.naming.ModuleNameComputer -import org.eclipse.n4js.naming.SpecifierConverter -import org.eclipse.n4js.resource.N4JSResource -import org.eclipse.n4js.smith.N4JSDataCollectors -import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.typeRefs.StructuralTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.TClass -import org.eclipse.n4js.ts.types.TInterface -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.ts.types.TVariable -import org.eclipse.n4js.ts.types.Type -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.utils.ResourceType -import org.eclipse.n4js.validation.JavaScriptVariantHelper -import org.eclipse.n4js.workspace.WorkspaceAccess -import org.eclipse.xtext.naming.IQualifiedNameConverter -import org.eclipse.xtext.resource.DerivedStateAwareResource - -import static extension org.eclipse.n4js.utils.N4JSLanguageUtils.* - -/** - * This class with its {@link N4JSTypesBuilder#createTModuleFromSource(DerivedStateAwareResource,boolean) createTModuleFromSource()} - * method is the single entry point for the types builder package. The only exception is the public method - * {@link N4JSFunctionDefinitionTypesBuilder#updateTFunction(FunctionExpression, FunctionTypeExprOrRef, TypeRef) updateTFunction()} - * in N4JSFunctionDefinitionTypesBuilder, which is called from Xsemantics. - *

- * Derives the types model from the AST, i.e. creates a {@link TModule} with its contents - * from a {@link Script} and its children. The types model is stored at the second index of the resource. - * The types model contains for each exportable or type defining element a corresponding entry e.g. - * for a {@link N4ClassDeclaration} a {@link TClass} is created. Later when linking only the types are - * used in place of the original objects. - *

- * The types builder must not use type inference because this would lead to a resolution of lazy - * cross-references at a too early stage. Instead, the types builder creates ComputedTypeRefs that - * will later be resolved either on demand or by calling {@link N4JSResource#flattenModule()}. - */ -public class N4JSTypesBuilder { - - @Inject(optional=true) TypesFactory typesFactory = TypesFactory.eINSTANCE - @Inject extension N4JSTypesBuilderHelper - @Inject extension N4JSNamespaceDeclarationTypesBuilder - @Inject extension N4JSClassDeclarationTypesBuilder - @Inject extension N4JSInterfaceDeclarationTypesBuilder - @Inject extension N4JSEnumDeclarationTypesBuilder - @Inject extension N4JSTypeAliasDeclarationTypesBuilder - @Inject extension N4JSObjectLiteralTypesBuilder - @Inject extension N4JSFunctionDefinitionTypesBuilder - @Inject extension N4JSVariableStatementTypesBuilder - @Inject extension N4JSTypesFromTypeRefBuilder - @Inject extension N4JSImportTypesBuilder - @Inject extension N4JSExportDefinitionTypesBuilder - - @Inject extension ModuleNameComputer - @Inject private WorkspaceAccess workspaceAccess - @Inject private IQualifiedNameConverter qualifiedNameConverter - @Inject private SpecifierConverter specifierConverter - @Inject protected JavaScriptVariantHelper jsVariantHelper; - - /** Thrown when reconciliation of a TModule fails due to a hash mismatch. */ - public static class RelinkTModuleHashMismatchException extends IllegalStateException { - - public new(URI resourceURI) { - super("cannot link existing TModule to new AST due to hash mismatch: " + resourceURI); - } - } - - /** - * When demand-loading an AST for a resource that already has a TModule (usually retrieved from the index) by - * calling SyntaxRelatedTElement#getAstElement(), we are facing a challenge: we could simply replace the original - * TModule by a new TModule created in the same way as in the standard case of loading an empty resource from - * source, i.e. with method {@link N4JSTypesBuilder#createTModuleFromSource(DerivedStateAwareResource, boolean) - * #createTModuleFromSource()}. However, this would lead to the issue of all existing references to the original, - * now replaced TModule to now have an invalid target object (not contained in a resource anymore, proxy resolution - * impossible, etc.). - *

- * As a solution, this method provides a 2nd mode of the types builder in which not a new TModule is created from - * the AST, but an existing TModule is reused, i.e. the types builder does not create anything but simply creates - * the bidirectional links between AST nodes and TModule elements. - *

- * This method should be called after the AST has been loaded, with the original TModule at second position in the - * resource's contents. If the AST and TModule were created from different versions of the source, checked via an - * MD5 hash, or the rewiring fails for other reasons, an {@link IllegalStateException} is thrown. In that case, the - * state of the AST and TModule are undefined (i.e. linking may have taken place partially). - */ - def public void relinkTModuleToSource(DerivedStateAwareResource resource, boolean preLinkingPhase) { - try (val m1 = N4JSDataCollectors.dcTypesBuilder.getMeasurement(); - val m2 = N4JSDataCollectors.dcTypesBuilderRelink.getMeasurement()) { - m1.getClass(); // suppress unused variable warning from Xtend - m2.getClass(); // suppress unused variable warning from Xtend - - doRelinkTModuleToSource(resource, preLinkingPhase); - } - } - - def private void doRelinkTModuleToSource(DerivedStateAwareResource resource, boolean preLinkingPhase) { - val parseResult = resource.getParseResult(); - if (parseResult !== null) { - - val script = parseResult.rootASTElement as Script; - - val TModule module = resource.contents.get(1) as TModule; - - val astMD5New = N4JSASTUtils.md5Hex(resource); - if (astMD5New != module.astMD5) { - throw new RelinkTModuleHashMismatchException(resource.getURI()); - } - module.reconciled = true; - - script.relinkTypeModelElementsForImports(module, preLinkingPhase) - - script.buildTypesFromTypeRefs(module, preLinkingPhase); - - script.relinkTypes(module, preLinkingPhase, new RelinkIndices()); - - module.astElement = script; - script.module = module; - - } else { - throw new IllegalStateException("resource has no parse result: " + resource.URI); - } - } - - /** - * This method is the single entry point for the types builder package. The only exception is the public method - * {@link N4JSFunctionDefinitionTypesBuilder#updateTFunction(FunctionExpression,FunctionTypeExprOrRef,TypeRef) updateTFunction()} - * in N4JSFunctionDefinitionTypesBuilder, which is called from Xsemantics. - *

- * Creates an {@link TModule} with the module path name (@see {@link ModuleNameComputer#getModulePath(Resource)}) - * of the resource (replacing the dots with slashes). For all {@link ExportableElement} and - * {@link TypeDefiningElement} corresponding types like {@link TClass}, {@link TInterface} are created and assigned - * as containment references to {@link TModule}. Afterwards the so created {@link TModule} tree is browsed for - * {@link TVariable}s which do not have a type reference yet. For these there right hand side expressions is - * checked for a {@link TypeDefiningElement} for this a {@link ParameterizedTypeRef} is created having this element - * as declared type. The parameterized type ref is then assigned as type ref to the {@link TVariable}. - */ - def public void createTModuleFromSource(DerivedStateAwareResource resource, boolean preLinkingPhase) { - try (val m1 = N4JSDataCollectors.dcTypesBuilder.getMeasurement(); - val m2 = N4JSDataCollectors.dcTypesBuilderCreate.getMeasurement()) { - m1.getClass(); // suppress unused variable warning from Xtend - m2.getClass(); // suppress unused variable warning from Xtend - - doCreateTModuleFromSource(resource, preLinkingPhase); - } - } - - def private void doCreateTModuleFromSource(DerivedStateAwareResource resource, boolean preLinkingPhase) { - val parseResult = resource.getParseResult(); - if (parseResult !== null) { - -// UtilN4.takeSnapshotInGraphView("TB start (preLinking=="+preLinkingPhase+")",resource.resourceSet); - val script = parseResult.rootASTElement as Script; - - val TModule result = typesFactory.createTModule; - - result.astMD5 = N4JSASTUtils.md5Hex(resource); - result.reconciled = false; - - val qualifiedModuleName = resource.qualifiedModuleName; - result.simpleName = qualifiedModuleName.lastSegment; - result.qualifiedName = qualifiedNameConverter.toString(qualifiedModuleName); - result.preLinkingPhase = preLinkingPhase; - - val project = workspaceAccess.findProjectContaining(resource); - if (project !== null) { - result.projectID = project.name; - result.packageName = project.packageName; - result.vendorID = project.vendorId; - - // main module - val mainModuleSpec = project.mainModule; - if (mainModuleSpec !== null) { - result.mainModule = qualifiedModuleName == - specifierConverter.toQualifiedName(mainModuleSpec); - } - } - - result.copyAnnotations(script, preLinkingPhase); - - script.createTypeModelElementsForImports(result, preLinkingPhase); - - result.n4jsdModule = jsVariantHelper.isExternalMode(script); - - // Setting Polyfill property. - result.staticPolyfillModule = result.isContainedInStaticPolyfillModule; - result.staticPolyfillAware = result.isContainedInStaticPolyfillAware; - - script.buildTypesFromTypeRefs(result, preLinkingPhase); - - script.buildTypes(result, preLinkingPhase); - - result.astElement = script; - script.module = result; - (resource as N4JSResource).sneakyAddToContent(result); -// UtilN4.takeSnapshotInGraphView("TB end (preLinking=="+preLinkingPhase+")",resource.resourceSet); - } else { - throw new IllegalStateException(resource.URI + " has no parse result."); - } - } - - /** - * Create types for those TypeRefs that define a type if they play the role of an AST node. - *

- * This has to be done up-front, because in the rest of the types builder code we do not know where such a TypeRef - * shows up; to avoid having to check for them at every occurrence of a TypeRef, we do this ahead of the main types - * builder phase. - */ - def private void buildTypesFromTypeRefs(Script script, TModule target, boolean preLinkingPhase) { - if (!preLinkingPhase) { - // important to do the following in bottom-up order! - // The structural members of a higher-level StructuralTypeRef STR may contain another StructuralTypeRef STR'; - // when the TStructuralType of STR is created, the structural members are copied, including contained TypeRefs; - // at that time the lower-level STR' must already have been prepared for copying! - // Example: - // var ~Object with { - // ~Object with { number fieldOfField; } field; - // } x; - val List addTypesToTargets = new ArrayList(); - for (tr : script.eAllContents.filter(TypeRef).toList.reverseView) { - switch tr { - StructuralTypeRef: { - tr.createStructuralType() - if (tr.structuralType !== null) { - addTypesToTargets += tr.structuralType; - } - } - FunctionTypeExpression: { - tr.createTFunction() - if (tr.declaredType !== null) { - addTypesToTargets += tr.declaredType; - } - } - N4NamespaceDeclaration: { - for (Type type : addTypesToTargets) { - target.internalTypes += type; - } - addTypesToTargets.clear; - } - } - } - - for (Type type : addTypesToTargets) { - target.internalTypes += type; - } - } - } - - static class RelinkIndices { - package var namespacesIdx = 0; - package var typesIdx = 0; - package var functionIdx = 0; - package var variableIdx = 0; - } - - def private void relinkTypes(EObject container, AbstractNamespace target, boolean preLinkingPhase, RelinkIndices rlis) { - for (n : container.eContents) { - // relink types of n (if applicable) - switch n { - N4NamespaceDeclaration: - rlis.namespacesIdx = n.relinkNamespace(target, preLinkingPhase, rlis.namespacesIdx) - FunctionDefinition: - rlis.functionIdx = n.relinkFunction(target, preLinkingPhase, rlis.functionIdx) - TypeDefiningElement: - rlis.typesIdx = n.relinkType(target, preLinkingPhase, rlis.typesIdx) - VariableDeclarationContainer: - rlis.variableIdx = n.relinkType(target, preLinkingPhase, rlis.variableIdx) - TryStatement: - rlis.variableIdx = n.relinkType(target, preLinkingPhase, rlis.variableIdx) - } - // relink types of child nodes - var AbstractNamespace nextTarget; - var RelinkIndices nextRelinkIndices; - if (n instanceof N4NamespaceDeclaration) { - nextTarget = n.definedNamespace; - nextRelinkIndices = new RelinkIndices(); - } else { - nextTarget = target; - nextRelinkIndices = rlis; - } - if (nextTarget !== null) { // can be null in broken ASTs - relinkTypes(n, nextTarget, preLinkingPhase, nextRelinkIndices) - } - // handle exports - // -> nothing to do - // (AST nodes of type ExportDeclaration are not TypeDefiningElements and - // type model elements of type ExportDefinition are not SyntaxRelatedTElements, - // so we do not have to relink anything between AST and types model here) - } - } - - def protected int relinkNamespace(N4NamespaceDeclaration n4Namespace, AbstractNamespace target, boolean preLinkingPhase, int idx) { - if (n4Namespace.relinkTNamespace(target, preLinkingPhase, idx)) { - return idx + 1; - } - return idx; - } - - def protected dispatch int relinkType(TypeDefiningElement other, AbstractNamespace target, boolean preLinkingPhase, int idx) { - throw new IllegalArgumentException("unknown subclass of TypeDefiningElement: " + other?.eClass.name); - } - - def protected dispatch int relinkType(NamespaceImportSpecifier nsImpSpec, AbstractNamespace target, boolean preLinkingPhase, int idx) { - // already handled up-front in N4JSNamespaceImportTypesBuilder#relinkNamespaceTypes - return idx; - } - - def protected dispatch int relinkFunction(MethodDeclaration n4MethodDecl, AbstractNamespace target, boolean preLinkingPhase, int idx) { - // methods are handled in their containing class/interface -> ignore them here - return idx; - } - - def protected dispatch int relinkFunction(FunctionDeclaration n4FunctionDecl, AbstractNamespace target, boolean preLinkingPhase, int idx) { - if (n4FunctionDecl.relinkTFunction(target, preLinkingPhase, idx)) { - return idx + 1; - } - return idx; - } - - /** Function expressions are special, see {@link N4JSFunctionDefinitionTypesBuilder#createTFunction(FunctionExpression,TModule,boolean)}. */ - def protected dispatch int relinkFunction(FunctionExpression n4FunctionExpr, AbstractNamespace target, boolean preLinkingPhase, int idx) { - n4FunctionExpr.createTFunction(target, preLinkingPhase); - return idx; - } - - def protected dispatch int relinkType(N4ClassDeclaration n4Class, AbstractNamespace target, boolean preLinkingPhase, int idx) { - if (n4Class.relinkTClass(target, preLinkingPhase, idx)) { - return idx + 1; - } - return idx; - } - - def protected dispatch int relinkType(N4ClassExpression n4Class, AbstractNamespace target, boolean preLinkingPhase, int idx) { - n4Class.createTClass(target, preLinkingPhase) - // do not increment the index - return idx - } - - def protected dispatch int relinkType(N4InterfaceDeclaration n4Interface, AbstractNamespace target, boolean preLinkingPhase, int idx) { - if (n4Interface.relinkTInterface(target, preLinkingPhase, idx)) { - return idx + 1; - } - return idx; - } - - def protected dispatch int relinkType(N4EnumDeclaration n4Enum, AbstractNamespace target, boolean preLinkingPhase, int idx) { - if (n4Enum.relinkTEnum(target, preLinkingPhase, idx)) { - return idx + 1; - } - return idx; - } - - def protected dispatch int relinkType(N4TypeAliasDeclaration n4TypeAlias, AbstractNamespace target, boolean preLinkingPhase, int idx) { - if (n4TypeAlias.relinkTypeAlias(target, preLinkingPhase, idx)) { - return idx + 1; - } - return idx; - } - - def protected dispatch int relinkType(ObjectLiteral objectLiteral, AbstractNamespace target, boolean preLinkingPhase, int idx) { - objectLiteral.createObjectLiteral(target, preLinkingPhase) - return idx; - } - - def protected dispatch int relinkType(VariableDeclarationContainer n4VarDeclContainer, AbstractNamespace target, boolean preLinkingPhase, int idx) { - return n4VarDeclContainer.relinkVariableTypes(target, preLinkingPhase, idx) - } - - def protected dispatch int relinkType(TryStatement tryStmnt, AbstractNamespace target, boolean preLinkingPhase, int idx) { - return tryStmnt.relinkVariableTypes(target, preLinkingPhase, idx) - } - - def protected dispatch int relinkType(NamespaceExportSpecifier n4NamespaceExportSpecifier, AbstractNamespace target, boolean preLinkingPhase, int idx) { - // namespace export specifiers are handled as part of their containing ExportDeclaration -> ignore them here - return idx; - } - - - def private void buildTypes(EObject container, AbstractNamespace target, boolean preLinkingPhase) { - for (n : container.eContents) { - // build type for n (if applicable) - switch n { - N4NamespaceDeclaration: - n.createNamespace(target, preLinkingPhase) - FunctionDefinition: - n.createFunction(target, preLinkingPhase) - TypeDefiningElement: - n.createType(target, preLinkingPhase) - VariableDeclarationContainer: // VariableStatement and ForStatement - n.createType(target, preLinkingPhase) - TryStatement: - n.createType(target, preLinkingPhase) - } - // build types for child nodes - val nextTarget = if (n instanceof N4NamespaceDeclaration) n.definedNamespace else target; - if (nextTarget !== null) { // can be null in broken ASTs - buildTypes(n, nextTarget, preLinkingPhase); - } - // handle exports - if (n instanceof ExportDeclaration) { - n.createType(target, preLinkingPhase); - } else if (n instanceof ExportableElement) { - if (!n.isDeclaredExported && n.isExportedByNamespace) { - val isDtsExceptionCase = ResourceType.getResourceType(n) === ResourceType.DTS - && n instanceof ModifiableElement - && (n as ModifiableElement).declaredModifiers.contains(N4Modifier.PRIVATE); - if (!isDtsExceptionCase) { - n.createExportDefinitionForDirectlyExportedElement(target, preLinkingPhase); - } - } - } - } - } - - def protected void createNamespace(N4NamespaceDeclaration n4Namespace, AbstractNamespace target, boolean preLinkingPhase) { - n4Namespace.createTNamespace(target, preLinkingPhase) - } - - def protected dispatch void createFunction(MethodDeclaration n4MethodDecl, AbstractNamespace target, boolean preLinkingPhase) { - // methods are handled in their containing class/interface -> ignore them here - } - - def protected dispatch void createFunction(FunctionDeclaration n4FunctionDecl, AbstractNamespace target, boolean preLinkingPhase) { - n4FunctionDecl.createTFunction(target, preLinkingPhase) - } - - /** Function expressions are special, see {@link N4JSFunctionDefinitionTypesBuilder#createTFunction(FunctionExpression,TModule,boolean)}. */ - def protected dispatch void createFunction(FunctionExpression n4FunctionExpr, AbstractNamespace target, boolean preLinkingPhase) { - n4FunctionExpr.createTFunction(target, preLinkingPhase) - } - - def protected dispatch void createType(TypeDefiningElement other, AbstractNamespace target, boolean preLinkingPhase) { - throw new IllegalArgumentException("unknown subclass of TypeDefiningElement: " + other?.eClass.name); - } - - def protected dispatch void createType(NamespaceImportSpecifier nsImpSpec, AbstractNamespace target, boolean preLinkingPhase) { - // already handled up-front in #buildNamespacesTypesFromModuleImports() - } - - def protected dispatch void createType(N4ClassDeclaration n4Class, AbstractNamespace target, boolean preLinkingPhase) { - n4Class.createTClass(target, preLinkingPhase) - } - - def protected dispatch void createType(N4ClassExpression n4Class, AbstractNamespace target, boolean preLinkingPhase) { - n4Class.createTClass(target, preLinkingPhase) - } - - def protected dispatch void createType(N4InterfaceDeclaration n4Interface, AbstractNamespace target, boolean preLinkingPhase) { - n4Interface.createTInterface(target, preLinkingPhase) - } - - def protected dispatch void createType(N4EnumDeclaration n4Enum, AbstractNamespace target, boolean preLinkingPhase) { - n4Enum.createTEnum(target, preLinkingPhase) - } - - def protected dispatch void createType(N4TypeAliasDeclaration n4TypeAliasDecl, AbstractNamespace target, boolean preLinkingPhase) { - n4TypeAliasDecl.createTypeAlias(target, preLinkingPhase) - } - - def protected dispatch void createType(ObjectLiteral objectLiteral, AbstractNamespace target, boolean preLinkingPhase) { - objectLiteral.createObjectLiteral(target, preLinkingPhase) - } - - def protected dispatch void createType(VariableDeclarationContainer n4VarDeclContainer, AbstractNamespace target, boolean preLinkingPhase) { - n4VarDeclContainer.createVariableTypes(target, preLinkingPhase) - } - - def protected dispatch void createType(TryStatement tryStmnt, AbstractNamespace target, boolean preLinkingPhase) { - tryStmnt.createVariableTypes(target, preLinkingPhase) - } - - def protected dispatch void createType(ExportDeclaration n4ExportDeclaration, AbstractNamespace target, boolean preLinkingPhase) { - n4ExportDeclaration.createExportDefinition(target, preLinkingPhase) - } - - def protected dispatch void createType(NamespaceExportSpecifier n4NamespaceExportSpecifier, AbstractNamespace target, boolean preLinkingPhase) { - // namespace export specifiers are handled as part of their containing ExportDeclaration -> ignore them here - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilderHelper.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilderHelper.java new file mode 100644 index 0000000000..32fa2c6da7 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilderHelper.java @@ -0,0 +1,306 @@ +/** + * 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.typesbuilder; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.exists; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filterNull; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.findFirst; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.head; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.isNullOrEmpty; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.Collection; +import java.util.List; +import java.util.function.Consumer; + +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.compileTime.CompileTimeEvaluator; +import org.eclipse.n4js.compileTime.CompileTimeValue; +import org.eclipse.n4js.n4JS.AnnotableElement; +import org.eclipse.n4js.n4JS.Annotation; +import org.eclipse.n4js.n4JS.AnnotationArgument; +import org.eclipse.n4js.n4JS.FunctionDefinition; +import org.eclipse.n4js.n4JS.LiteralAnnotationArgument; +import org.eclipse.n4js.n4JS.LiteralOrComputedPropertyName; +import org.eclipse.n4js.n4JS.ModifiableElement; +import org.eclipse.n4js.n4JS.ModifierUtils; +import org.eclipse.n4js.n4JS.N4ClassifierDeclaration; +import org.eclipse.n4js.n4JS.N4MemberDeclaration; +import org.eclipse.n4js.n4JS.N4Modifier; +import org.eclipse.n4js.n4JS.NamedElement; +import org.eclipse.n4js.n4JS.PropertyNameKind; +import org.eclipse.n4js.n4JS.PropertyNameOwner; +import org.eclipse.n4js.n4JS.TypeDefiningElement; +import org.eclipse.n4js.n4JS.TypeRefAnnotationArgument; +import org.eclipse.n4js.postprocessing.ComputedNameProcessor; +import org.eclipse.n4js.scoping.N4JSScopeProviderLocalOnly; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.AccessibleTypeElement; +import org.eclipse.n4js.ts.types.FieldAccessor; +import org.eclipse.n4js.ts.types.IdentifiableElement; +import org.eclipse.n4js.ts.types.MemberAccessModifier; +import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType; +import org.eclipse.n4js.ts.types.TAnnotableElement; +import org.eclipse.n4js.ts.types.TAnnotation; +import org.eclipse.n4js.ts.types.TAnnotationStringArgument; +import org.eclipse.n4js.ts.types.TAnnotationTypeRefArgument; +import org.eclipse.n4js.ts.types.TClassifier; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TMember; +import org.eclipse.n4js.ts.types.TModule; +import org.eclipse.n4js.ts.types.TypeAccessModifier; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; +import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.n4js.utils.TameAutoClosable; +import org.eclipse.n4js.validation.JavaScriptVariantHelper; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +@Singleton +class N4JSTypesBuilderHelper { + + @Inject + private JavaScriptVariantHelper jsVariantHelper; + @Inject + private CompileTimeEvaluator compileTimeEvaluator; + @Inject + private N4JSScopeProviderLocalOnly n4jsScopeProviderLocalOnly; + + private static Logger logger = Logger.getLogger(N4JSTypesBuilderHelper.class); + + protected void setTypeAccessModifier( + AccessibleTypeElement classifier, T definition) { + + boolean isPlainJS = jsVariantHelper.isPlainJS(definition); + // IDEBUG-861 assume public visibility if plain JS + if (isPlainJS) { + classifier.setDeclaredTypeAccessModifier(TypeAccessModifier.PUBLIC); + } else { + classifier.setDeclaredTypeAccessModifier(ModifierUtils.convertToTypeAccessModifier( + definition.getDeclaredModifiers(), definition.getAllAnnotations())); + } + } + + void setProvidedByRuntime(AccessibleTypeElement declaredType, AnnotableElement annotableElement, + @SuppressWarnings("unused") boolean preLinkingPhase) { + + declaredType.setDeclaredProvidedByRuntime(AnnotationDefinition.PROVIDED_BY_RUNTIME.hasAnnotation( + annotableElement)); + } + + /** + * Adds references to a feature (via the closure), but copies the references in order to avoid problems with + * containment relations. The references are copied with proxies (see {@link TypeUtils#copyWithProxies(EObject)} in + * order to avoid resolving of proxies here. Null values (usually caused by a syntax error) are omitted, i.e. + * indices are not preserved. + */ + void addCopyOfReferences(List target, List values) { + if (isNullOrEmpty(values)) { + return; + } + if (exists(values, it -> it != null && it.eIsProxy())) { + throw new IllegalStateException("There is a proxy in the list, cannot copy and set references"); + } + target.addAll(toList(map(filterNull(values), it -> TypeUtils.copyWithProxies(it)))); + } + + /** + * Initializes the name of a TMember in the TModule based the member/property declaration in the AST. In case of + * computed property names, this method will keep the name in the TModule set to null and + * {@link ComputedNameProcessor} will later change it to the actual name during post-processing. + */ + void setMemberName(TMember tMember, PropertyNameOwner n4MemberOrPropertyAssignment) { + // this will be 'null' in case of a computed property name + tMember.setName(n4MemberOrPropertyAssignment.getName()); + LiteralOrComputedPropertyName declaredName = n4MemberOrPropertyAssignment.getDeclaredName(); + tMember.setHasComputedName(declaredName != null && declaredName.getKind() == PropertyNameKind.COMPUTED); + } + + /** + * Translates AST related member access modifier (and annotation {@code @Interanl}) to type model related member + * access modifier. + */ + void setMemberAccessModifier(Consumer memberAccessModifierAssignment, + Collection modifiers, List annotations) { + memberAccessModifierAssignment.accept(ModifierUtils.convertToMemberAccessModifier(modifiers, annotations)); + } + + /** Returns newly created reference to built-in type any. */ + ParameterizedTypeRef createAnyTypeRef(EObject object) { + ResourceSet rs = null; + if (object != null && object.eResource() != null) { + rs = object.eResource().getResourceSet(); + } + if (rs != null) { + return BuiltInTypeScope.get(rs).getAnyTypeRef(); + } + return null; + } + + /** + * Copies annotations from AST to Type model. Note that not all annotations are copied, only the ones listed in + * {@link AnnotationDefinition#ANNOTATIONS_IN_TYPEMODEL}. Also annotations contained in containing export + * declaration are copied, as this construct is not present in type model and its annotations are to be defined at + * the type. + *

+ * Since this mechanism is changed anyway, no type check (whether annotation is allowed for given element type) is + * performed. + */ + void copyAnnotations(TAnnotableElement typeTarget, AnnotableElement ast, + @SuppressWarnings("unused") boolean preLinkingPhase) { + + for (Annotation ann : ast.getAllAnnotations()) { + if (AnnotationDefinition.isInTypeModel(ann.getName())) { + TAnnotation ta = TypesFactory.eINSTANCE.createTAnnotation(); + ta.setName(ann.getName()); + + for (AnnotationArgument arg : ann.getArgs()) { + if (arg instanceof LiteralAnnotationArgument) { + TAnnotationStringArgument targ = TypesFactory.eINSTANCE.createTAnnotationStringArgument(); + targ.setValue(((LiteralAnnotationArgument) arg).getLiteral().getValueAsString()); + ta.getArgs().add(targ); + } else if (arg instanceof TypeRefAnnotationArgument) { + TAnnotationTypeRefArgument targ = TypesFactory.eINSTANCE.createTAnnotationTypeRefArgument(); + TypeRefAnnotationArgument traa = (TypeRefAnnotationArgument) arg; + targ.setTypeRef(TypeUtils.copyWithProxies( + traa.getTypeRefNode() == null ? null : traa.getTypeRefNode().getTypeRefInAST())); + ta.getArgs().add(targ); + } + } + typeTarget.getAnnotations().add(ta); + } + } + } + + /** Returns newly created reference to built-in type any. */ + TClassifier getObjectType(EObject object) { + ResourceSet rs = null; + if (object != null && object.eResource() != null) { + rs = object.eResource().getResourceSet(); + } + if (rs != null) { + return BuiltInTypeScope.get(rs).getObjectType(); + } + return null; + } + + /** @see TClassifier#isDeclaredCovariantConstructor() */ + boolean isDeclaredCovariantConstructor(N4ClassifierDeclaration classifierDecl) { + if (AnnotationDefinition.COVARIANT_CONSTRUCTOR.hasAnnotation(classifierDecl)) { + return true; + } + N4MemberDeclaration ctor = findFirst(classifierDecl.getOwnedMembers(), m -> m.isConstructor()); + return ctor != null && AnnotationDefinition.COVARIANT_CONSTRUCTOR.hasAnnotation(ctor); + } + + /** Handle optional "@This" annotation and set its argument as declared this type in types model element. */ + protected void setDeclaredThisTypeFromAnnotation(TFunction functionType, FunctionDefinition functionDef, + boolean preLinkingPhase) { + if (!preLinkingPhase) { + functionType.setDeclaredThisType(TypeUtils.copyWithProxies( + internalGetDeclaredThisTypeFromAnnotation(functionDef))); + } + } + + /** Handle optional "@This" annotation and set its argument as declared this type in types model element. */ + protected void setDeclaredThisTypeFromAnnotation(FieldAccessor accessorType, + org.eclipse.n4js.n4JS.FieldAccessor accessorDecl, boolean preLinkingPhase) { + if (!preLinkingPhase) { + accessorType.setDeclaredThisType(TypeUtils.copyWithProxies( + internalGetDeclaredThisTypeFromAnnotation(accessorDecl))); + } + } + + private TypeRef internalGetDeclaredThisTypeFromAnnotation(AnnotableElement element) { + Annotation annThis = AnnotationDefinition.THIS.getAnnotation(element); + if (annThis != null && annThis.getArgs() != null) { + TypeRefAnnotationArgument traa = head(filter(annThis.getArgs(), TypeRefAnnotationArgument.class)); + if (traa != null && traa.getTypeRefNode() != null) { + return traa.getTypeRefNode().getTypeRefInAST(); + } + } + return null; + } + + /** + * Used during + * {@link N4JSTypesBuilder#relinkTModuleToSource(org.eclipse.xtext.resource.DerivedStateAwareResource, boolean) + * relinking}, to ensure consistency of named elements between newly loaded AST and original TModule. + */ + protected void ensureEqualName(NamedElement astNode, IdentifiableElement moduleElement) { + ensureEqualName(astNode, moduleElement.getName()); + } + + protected void ensureEqualName(NamedElement astNode, String nameInModule) { + String nameInAST = astNode == null ? null : astNode.getName(); + if (astNode != null && nameInAST != null) { + // note: no check if no name available in AST (don't fiddle with computed property names, etc.) + if (!nameInAST.equals(nameInModule)) { + String msg = "inconsistency between newly loaded AST and to-be-linked TModule: " + + "nameInAST=" + nameInAST + ", " + + "nameInModule=" + nameInModule + ", " + + "in: " + (astNode.eResource() == null ? null : astNode.eResource().getURI().toString()); + logger.error(msg); + throw new IllegalStateException(msg); + } + } + } + + ModuleNamespaceVirtualType addNewModuleNamespaceVirtualType(TModule target, String name, TModule wrappedModule, + boolean dynamic, TypeDefiningElement astNode) { + ModuleNamespaceVirtualType type = TypesFactory.eINSTANCE.createModuleNamespaceVirtualType(); + type.setName(name); + type.setModule(wrappedModule); + type.setDeclaredDynamic(dynamic); + + type.setAstElement(astNode); + astNode.setDefinedType(type); + + target.getInternalTypes().add(type); + + return type; + } + + boolean hasValidName(PropertyNameOwner pno) { + if (pno.getName() == null && pno.hasComputedPropertyName()) { + if (N4JSLanguageUtils.isProcessedAsCompileTimeExpression(pno.getDeclaredName().getExpression())) { + return false; + } + + LiteralOrComputedPropertyName litOrComp = pno.getDeclaredName(); + RuleEnvironment G = RuleEnvironmentExtensions.newRuleEnvironment(pno); + try (TameAutoClosable tac = n4jsScopeProviderLocalOnly.newCrossFileResolutionSuppressor()) { + CompileTimeValue value = compileTimeEvaluator.evaluateCompileTimeExpression(G, + litOrComp.getExpression()); + String name = N4JSLanguageUtils.derivePropertyNameFromCompileTimeValue(value); + if (name == null) { + return false; + } + } + } + return true; + } + + boolean validPNO(PropertyNameOwner pno) { + return pno.getName() != null || pno.hasComputedPropertyName(); + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilderHelper.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilderHelper.xtend deleted file mode 100644 index c2f0a15e92..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesBuilderHelper.xtend +++ /dev/null @@ -1,265 +0,0 @@ -/** - * 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.typesbuilder - -import com.google.inject.Inject -import com.google.inject.Singleton -import java.util.Collection -import java.util.List -import org.apache.log4j.Logger -import org.eclipse.emf.ecore.EObject -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.compileTime.CompileTimeEvaluator -import org.eclipse.n4js.n4JS.AnnotableElement -import org.eclipse.n4js.n4JS.Annotation -import org.eclipse.n4js.n4JS.FunctionDefinition -import org.eclipse.n4js.n4JS.LiteralAnnotationArgument -import org.eclipse.n4js.n4JS.ModifiableElement -import org.eclipse.n4js.n4JS.ModifierUtils -import org.eclipse.n4js.n4JS.N4ClassifierDeclaration -import org.eclipse.n4js.n4JS.N4Modifier -import org.eclipse.n4js.n4JS.NamedElement -import org.eclipse.n4js.n4JS.PropertyNameKind -import org.eclipse.n4js.n4JS.PropertyNameOwner -import org.eclipse.n4js.n4JS.TypeDefiningElement -import org.eclipse.n4js.n4JS.TypeRefAnnotationArgument -import org.eclipse.n4js.postprocessing.ComputedNameProcessor -import org.eclipse.n4js.scoping.N4JSScopeProviderLocalOnly -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.types.AccessibleTypeElement -import org.eclipse.n4js.ts.types.FieldAccessor -import org.eclipse.n4js.ts.types.IdentifiableElement -import org.eclipse.n4js.ts.types.MemberAccessModifier -import org.eclipse.n4js.ts.types.ModuleNamespaceVirtualType -import org.eclipse.n4js.ts.types.TAnnotableElement -import org.eclipse.n4js.ts.types.TClassifier -import org.eclipse.n4js.ts.types.TFunction -import org.eclipse.n4js.ts.types.TMember -import org.eclipse.n4js.ts.types.TModule -import org.eclipse.n4js.ts.types.TypeAccessModifier -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions -import org.eclipse.n4js.utils.N4JSLanguageUtils -import org.eclipse.n4js.validation.JavaScriptVariantHelper - -@Singleton -package class N4JSTypesBuilderHelper { - - @Inject private JavaScriptVariantHelper jsVariantHelper; - @Inject private CompileTimeEvaluator compileTimeEvaluator; - @Inject private N4JSScopeProviderLocalOnly n4jsScopeProviderLocalOnly; - - private static Logger logger = Logger.getLogger(N4JSTypesBuilderHelper); - - - def protected void setTypeAccessModifier( - AccessibleTypeElement classifier, T definition) { - - val isPlainJS = jsVariantHelper.isPlainJS(definition); - // IDEBUG-861 assume public visibility if plain JS - if (isPlainJS) { - classifier.declaredTypeAccessModifier = TypeAccessModifier.PUBLIC; - } else { - classifier.declaredTypeAccessModifier = ModifierUtils.convertToTypeAccessModifier( - definition.declaredModifiers, definition.allAnnotations); - } - } - - def package void setProvidedByRuntime(AccessibleTypeElement declaredType, - AnnotableElement annotableElement, boolean preLinkingPhase) { - - declaredType.declaredProvidedByRuntime = AnnotationDefinition.PROVIDED_BY_RUNTIME.hasAnnotation( - annotableElement); - } - - /** - * Adds references to a feature (via the closure), but copies the references in order to avoid problems with containment relations. - * The references are copied with proxies (see {@link TypeUtils#copyWithProxies(EObject)} in order to avoid - * resolving of proxies here. Null values (usually caused by a syntax error) are omitted, i.e. indices are not preserved. - * - * @param typeListAssignment closure, actually adds the processed list - * @param listToAssign the list with references, there must be no proxy in the list - * @param preLinkingPhase if true, references are not set (they are only set in the linking phase) - * @param reference type, e.g., ParameterizedTypeRef - */ - def package void addCopyOfReferences(List target, List values) { - if (values.isNullOrEmpty) { - return - } - if (values.exists[it !== null && eIsProxy]) { - throw new IllegalStateException("There is a proxy in the list, cannot copy and set references"); - } - target += values.filterNull.map[TypeUtils.copyWithProxies(it)] - } - - /** - * Initializes the name of a TMember in the TModule based the member/property declaration in the AST. In case of - * computed property names, this method will keep the name in the TModule set to null and - * {@link ComputedNameProcessor} will later change it to the actual name during post-processing. - */ - def package void setMemberName(TMember tMember, PropertyNameOwner n4MemberOrPropertyAssignment) { - tMember.name = n4MemberOrPropertyAssignment.name; // this will be 'null' in case of a computed property name - tMember.hasComputedName = n4MemberOrPropertyAssignment.declaredName?.kind === PropertyNameKind.COMPUTED; - } - - /** - * Translates AST related member access modifier (and annotation {@code @Interanl}) to type model related member access modifier. - */ - def package void setMemberAccessModifier((MemberAccessModifier)=>void memberAccessModifierAssignment, - Collection modifiers, List annotations) { - memberAccessModifierAssignment.apply(ModifierUtils.convertToMemberAccessModifier(modifiers, annotations)); - } - - /** Returns newly created reference to built-in type any. */ - def package ParameterizedTypeRef createAnyTypeRef(EObject object) { - val rs = object?.eResource?.resourceSet - if (rs !== null) - BuiltInTypeScope.get(rs).anyTypeRef - else - null - } - - /** - * Copies annotations from AST to Type model. Note that not all annotations are copied, only the ones listed in - * {@link #ANNOTATIONS_IN_TYPE_MODEL}. Also annotations contained in containing export declaration are copied, as this - * construct is not present in type model and its annotations are to be defined at the type. - *

- * Since this mechanism is changed anyway, no type check (whether annotation is allowed for given element type) is - * performed. - */ - def package void copyAnnotations(TAnnotableElement typeTarget, AnnotableElement ast, boolean preLinkingPhase) { - typeTarget.annotations += ast.allAnnotations.filter[AnnotationDefinition.isInTypeModel(name)].map [ - val ta = TypesFactory.eINSTANCE.createTAnnotation(); - ta.name = it.name; - ta.args.addAll(args.map [ - switch (it) { - LiteralAnnotationArgument: { - val arg = TypesFactory.eINSTANCE.createTAnnotationStringArgument(); - arg.value = it.literal.valueAsString; - return arg; - } - TypeRefAnnotationArgument: { - val arg = TypesFactory.eINSTANCE.createTAnnotationTypeRefArgument(); - arg.typeRef = TypeUtils.copyWithProxies(typeRefNode?.typeRefInAST); - return arg; - } - } - ]) - return ta - ] - } - - /** Returns newly created reference to built-in type any. */ - def package TClassifier getObjectType(EObject object) { - val rs = object?.eResource?.resourceSet - if (rs !== null) - BuiltInTypeScope.get(rs).objectType - else - null - } - - /** @see TClassifier#isDeclaredCovariantConstructor() */ - def package boolean isDeclaredCovariantConstructor(N4ClassifierDeclaration classifierDecl) { - if (AnnotationDefinition.COVARIANT_CONSTRUCTOR.hasAnnotation(classifierDecl)) { - return true; - } - val ctor = classifierDecl.ownedMembers.findFirst[isConstructor]; - return ctor !== null && AnnotationDefinition.COVARIANT_CONSTRUCTOR.hasAnnotation(ctor); - } - - /** Handle optional "@This" annotation and set its argument as declared this type in types model element. */ - def protected void setDeclaredThisTypeFromAnnotation(TFunction functionType, FunctionDefinition functionDef, - boolean preLinkingPhase) { - if (!preLinkingPhase) - functionType.declaredThisType = TypeUtils.copyWithProxies( - internalGetDeclaredThisTypeFromAnnotation(functionDef)); - } - - /** Handle optional "@This" annotation and set its argument as declared this type in types model element. */ - def protected void setDeclaredThisTypeFromAnnotation(FieldAccessor accessorType, - org.eclipse.n4js.n4JS.FieldAccessor accessorDecl, boolean preLinkingPhase) { - if (!preLinkingPhase) - accessorType.declaredThisType = TypeUtils.copyWithProxies( - internalGetDeclaredThisTypeFromAnnotation(accessorDecl)); - } - - def private TypeRef internalGetDeclaredThisTypeFromAnnotation(AnnotableElement element) { - val annThis = AnnotationDefinition.THIS.getAnnotation(element); - return annThis?.args?.filter(TypeRefAnnotationArgument)?.head?.typeRefNode?.typeRefInAST; - } - - - /** - * Used during {@link N4JSTypesBuilder#relinkTModuleToSource(org.eclipse.xtext.resource.DerivedStateAwareResource, - * boolean) relinking}, to ensure consistency of named elements between newly loaded AST and original TModule. - */ - def protected void ensureEqualName(NamedElement astNode, IdentifiableElement moduleElement) { - ensureEqualName(astNode, moduleElement.name); - } - - def protected void ensureEqualName(NamedElement astNode, String nameInModule) { - val nameInAST = astNode?.name; - if (nameInAST !== null) { // note: no check if no name available in AST (don't fiddle with computed property names, etc.) - if (!nameInAST.equals(nameInModule)) { - val msg = "inconsistency between newly loaded AST and to-be-linked TModule: " - + "nameInAST=" + nameInAST + ", " - + "nameInModule=" + nameInModule + ", " - + "in: " + astNode.eResource?.URI; - logger.error(msg); - throw new IllegalStateException(msg); - } - } - } - - def package ModuleNamespaceVirtualType addNewModuleNamespaceVirtualType(TModule target, String name, TModule wrappedModule, boolean dynamic, TypeDefiningElement astNode) { - val type = TypesFactory.eINSTANCE.createModuleNamespaceVirtualType - type.name = name; - type.module = wrappedModule; - type.declaredDynamic = dynamic; - - type.astElement = astNode; - astNode.definedType = type; - - target.internalTypes += type; - - return type; - } - - def package boolean hasValidName(PropertyNameOwner pno) { - if (pno.name === null && pno.hasComputedPropertyName) { - if (N4JSLanguageUtils.isProcessedAsCompileTimeExpression(pno?.declaredName.expression)) { - return false; - } - - val litOrComp = pno.declaredName; - val G = RuleEnvironmentExtensions.newRuleEnvironment(pno); - val tac = n4jsScopeProviderLocalOnly.newCrossFileResolutionSuppressor(); - try { - val value = compileTimeEvaluator.evaluateCompileTimeExpression(G, litOrComp.expression); - val name = N4JSLanguageUtils.derivePropertyNameFromCompileTimeValue(value); - if (name === null) { - return false; - } - } finally { - tac.close(); - } - } - return true; - } - - - def package boolean validPNO(PropertyNameOwner pno) { - return pno.name !== null || pno.hasComputedPropertyName; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesFromTypeRefBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesFromTypeRefBuilder.java new file mode 100644 index 0000000000..e76c2cb91a --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesFromTypeRefBuilder.java @@ -0,0 +1,199 @@ +/** + * 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.typesbuilder; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; + +import java.util.Arrays; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression; +import org.eclipse.n4js.ts.typeRefs.StructuralTypeRef; +import org.eclipse.n4js.ts.types.TFormalParameter; +import org.eclipse.n4js.ts.types.TFunction; +import org.eclipse.n4js.ts.types.TStructField; +import org.eclipse.n4js.ts.types.TStructGetter; +import org.eclipse.n4js.ts.types.TStructMember; +import org.eclipse.n4js.ts.types.TStructMethod; +import org.eclipse.n4js.ts.types.TStructSetter; +import org.eclipse.n4js.ts.types.TStructuralType; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.utils.N4JSLanguageUtils; + +/** + * Methods for creating types from TypeRefs are collected in this class. + *

+ * The methods of this class might seem different from other createXYZ() methods in the types builder package, in that + * they take a subclass of TypeRef and not a typical AST node element. However, SturcturalTypeRefs and + * FunctionTypeExpressions are among those TypeRefs that may appear in the AST and play the role of an AST + * node. The methods in this class will only be invoked for such TypeRefs that appear in the AST, so these method are, + * in fact, very similar to the other createXYZ() methods. + */ +public class N4JSTypesFromTypeRefBuilder { + + /** + * Creates a TStructuralType in the target module if the StructuralTypeRef has structural members defined (in the + * with-clause). For more details why this is required, see API doc of StructuralTypeRef. + */ + void createStructuralType(StructuralTypeRef structTypeRef) { + if (structTypeRef.getAstStructuralMembers().isEmpty()) { + return; + } + + ResourceSet resSet = structTypeRef.eResource().getResourceSet(); + if (resSet == null) { + throw new IllegalArgumentException("structTypeRef must be contained in AST"); + } + + BuiltInTypeScope builtInTypeScope = BuiltInTypeScope.get(resSet); + TStructuralType structType = TypesFactory.eINSTANCE.createTStructuralType(); + + for (TStructMember memberInAST : structTypeRef.getAstStructuralMembers()) { + TStructMember memberForTModule = createTStructMember(memberInAST, builtInTypeScope); + if (memberInAST.isASTCallSignature()) { + if (structType.getCallSignature() == null) { + structType.setCallSignature((TStructMethod) memberForTModule); + } else { + // error case: duplicate call signatures + // --> to avoid scoping from returning elements that are not contained in a resource (esp. in case + // of + // type parameters of generic call signatures), we have to add 'memberForTModule' as an ordinary + // member + structType.getOwnedMembers().add(memberForTModule); + } + } else if (memberInAST.isASTConstructSignature()) { + if (structType.getConstructSignature() == null) { + structType.setConstructSignature((TStructMethod) memberForTModule); + } else { + // error case: duplicate construct signatures + // --> we have to add 'memberForTModule' as an ordinary member (see above) + structType.getOwnedMembers().add(memberForTModule); + } + } else { + structType.getOwnedMembers().add(memberForTModule); + } + } + + structTypeRef.setStructuralType(structType); + } + + private T createTStructMember(T memberInAST, BuiltInTypeScope builtInTypeScope) { + if (memberInAST == null) { + return null; + } + T memberForModule = TypeUtils.copyWithProxies(memberInAST); + applyDefaults(builtInTypeScope, memberForModule); + memberForModule.setAstElement(memberInAST); + memberInAST.setDefinedMember(memberForModule); + return memberForModule; + } + + /** + * Creates a TFunction in the target module if the FunctionTypeExpression is generic. For more details why this is + * required, see API doc of FunctionTypeExpression. + */ + void createTFunction(FunctionTypeExpression fte) { + if (!fte.isGeneric()) { + return; + } + + ResourceSet resSet = fte.eResource().getResourceSet(); + if (resSet == null) { + throw new IllegalArgumentException("fte must be contained in AST"); + } + + BuiltInTypeScope builtInTypeScope = BuiltInTypeScope.get(resSet); + TFunction ft = TypesFactory.eINSTANCE.createTFunction(); + + // TODO support hyper links + ft.getTypeVars().addAll(toList(map(fte.getTypeVars(), currTypeVar -> TypeUtils.copyWithProxies(currTypeVar)))); + ft.getFpars().addAll(toList(map(fte.getFpars(), currFpar -> { + TFormalParameter clone = TypeUtils.copyWithProxies(currFpar); + applyDefaults(builtInTypeScope, (EObject) clone); + clone.setAstElement(currFpar); + return clone; + }))); + ft.setReturnTypeRef(TypeUtils.copyWithProxies(fte.getReturnTypeRef())); + ft.setDeclaredThisType(TypeUtils.copyWithProxies(fte.getDeclaredThisType())); + + if (ft.getReturnTypeRef() == null) { + ft.setReturnTypeRef(builtInTypeScope.getAnyTypeRef()); + } + + fte.setDeclaredType(ft); + ft.setAstElement(fte); + } + + private void applyDefaults(BuiltInTypeScope builtInTypeScope, EObject getter) { + if (getter instanceof TStructGetter) { + applyDefaults(builtInTypeScope, (TStructGetter) getter); + return; + } else if (getter instanceof TStructMethod) { + applyDefaults(builtInTypeScope, (TStructMethod) getter); + return; + } else if (getter instanceof TStructSetter) { + applyDefaults(builtInTypeScope, (TStructSetter) getter); + return; + } else if (getter instanceof TStructField) { + applyDefaults(builtInTypeScope, (TStructField) getter); + return; + } else if (getter instanceof TFormalParameter) { + applyDefaults(builtInTypeScope, (TFormalParameter) getter); + return; + } else { + throw new IllegalArgumentException("Unhandled parameter types: " + + Arrays.asList(builtInTypeScope, getter).toString()); + } + } + + private void applyDefaults(BuiltInTypeScope builtInTypeScope, TStructField field) { + if (field.getTypeRef() == null) { + field.setTypeRef(builtInTypeScope.getAnyTypeRef()); + } + } + + private void applyDefaults(BuiltInTypeScope builtInTypeScope, TStructGetter getter) { + if (getter.getTypeRef() == null) { + getter.setTypeRef(builtInTypeScope.getAnyTypeRef()); + } + } + + private void applyDefaults(BuiltInTypeScope builtInTypeScope, TStructSetter setter) { + // note: setter.fpar==null and setter.fpar.getTypeRef()==null are disallowed by syntax, but + // setting default types for these cases gives us better behavior in case of broken ASTs + if (setter.getFpar() == null) { + setter.setFpar(TypesFactory.eINSTANCE.createTAnonymousFormalParameter()); + } + applyDefaults(builtInTypeScope, (EObject) setter.getFpar()); + } + + private void applyDefaults(BuiltInTypeScope builtInTypeScope, TStructMethod method) { + if (method.isASTCallSignature()) { + method.setName(N4JSLanguageUtils.CALL_SIGNATURE_NAME); + } + for (TFormalParameter it : method.getFpars()) { + applyDefaults(builtInTypeScope, it); + } + if (method.getReturnTypeRef() == null) { + method.setReturnTypeRef(builtInTypeScope.getVoidTypeRef()); + } + } + + private void applyDefaults(BuiltInTypeScope builtInTypeScope, TFormalParameter fpar) { + if (fpar.getTypeRef() == null) { + fpar.setTypeRef(builtInTypeScope.getAnyTypeRef()); + } + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesFromTypeRefBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesFromTypeRefBuilder.xtend deleted file mode 100644 index 69dc4774cb..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSTypesFromTypeRefBuilder.xtend +++ /dev/null @@ -1,162 +0,0 @@ -/** - * 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.typesbuilder; - -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.ts.typeRefs.FunctionTypeExpression -import org.eclipse.n4js.ts.typeRefs.StructuralTypeRef -import org.eclipse.n4js.ts.types.TFormalParameter -import org.eclipse.n4js.ts.types.TStructField -import org.eclipse.n4js.ts.types.TStructGetter -import org.eclipse.n4js.ts.types.TStructMember -import org.eclipse.n4js.ts.types.TStructMethod -import org.eclipse.n4js.ts.types.TStructSetter -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.utils.N4JSLanguageUtils - -/** - * Methods for creating types from TypeRefs are collected in this class. - *

- * The methods of this class might seem different from other createXYZ() methods in the types - * builder package, in that they take a subclass of TypeRef and not a typical AST node element. - * However, SturcturalTypeRefs and FunctionTypeExpressions are among those TypeRefs that - * may appear in the AST and play the role of an AST node. The methods in this class - * will only be invoked for such TypeRefs that appear in the AST, so these method are, in fact, - * very similar to the other createXYZ() methods. - */ -public class N4JSTypesFromTypeRefBuilder { - - /** - * Creates a TStructuralType in the target module if the StructuralTypeRef has structural - * members defined (in the with-clause). For more details why this is required, see API - * doc of StructuralTypeRef. - */ - def package void createStructuralType(StructuralTypeRef structTypeRef) { - if (!structTypeRef.astStructuralMembers.empty) { - - val resSet = structTypeRef.eResource.resourceSet; - if(resSet===null) { - throw new IllegalArgumentException("structTypeRef must be contained in AST"); - } - - val builtInTypeScope = BuiltInTypeScope.get(resSet); - val structType = TypesFactory.eINSTANCE.createTStructuralType; - - for (memberInAST : structTypeRef.astStructuralMembers) { - val memberForTModule = createTStructMember(memberInAST, builtInTypeScope); - if (memberInAST.isASTCallSignature()) { - if (structType.callSignature === null) { - structType.callSignature = memberForTModule as TStructMethod; - } else { - // error case: duplicate call signatures - // --> to avoid scoping from returning elements that are not contained in a resource (esp. in case of - // type parameters of generic call signatures), we have to add 'memberForTModule' as an ordinary member - structType.ownedMembers += memberForTModule; - } - } else if (memberInAST.isASTConstructSignature()) { - if (structType.constructSignature === null) { - structType.constructSignature = memberForTModule as TStructMethod; - } else { - // error case: duplicate construct signatures - // --> we have to add 'memberForTModule' as an ordinary member (see above) - structType.ownedMembers += memberForTModule; - } - } else { - structType.ownedMembers += memberForTModule; - } - } - - structTypeRef.structuralType = structType; - } - } - - def private T createTStructMember(T memberInAST, BuiltInTypeScope builtInTypeScope) { - if (memberInAST === null) { - return null; - } - val memberForModule = TypeUtils.copyWithProxies(memberInAST); - applyDefaults(builtInTypeScope, memberForModule); - memberForModule.astElement = memberInAST; - memberInAST.definedMember = memberForModule; - return memberForModule; - } - - - /** - * Creates a TFunction in the target module if the FunctionTypeExpression is generic. - * For more details why this is required, see API doc of FunctionTypeExpression. - */ - def package void createTFunction(FunctionTypeExpression fte) { - - if (fte.generic) { - - val resSet = fte.eResource.resourceSet; - if(resSet===null) { - throw new IllegalArgumentException("fte must be contained in AST"); - } - - val builtInTypeScope = BuiltInTypeScope.get(resSet); - val ft = TypesFactory.eINSTANCE.createTFunction(); - - ft.typeVars.addAll(fte.typeVars.map[currTypeVar|TypeUtils.copyWithProxies(currTypeVar)]); // TODO support hyper links - ft.fpars.addAll(fte.fpars.map[currFpar| - val clone = TypeUtils.copyWithProxies(currFpar); - applyDefaults(builtInTypeScope, clone); - clone.astElement = currFpar; - return clone; - ]); - ft.returnTypeRef = TypeUtils.copyWithProxies(fte.returnTypeRef); - ft.declaredThisType = TypeUtils.copyWithProxies(fte.declaredThisType); - - if(ft.returnTypeRef===null) { - ft.returnTypeRef = builtInTypeScope.getAnyTypeRef(); - } - - fte.declaredType = ft; - ft.astElement = fte; - } - } - - - def private dispatch void applyDefaults(BuiltInTypeScope builtInTypeScope, TStructField field) { - if(field.typeRef===null) { - field.typeRef = builtInTypeScope.getAnyTypeRef(); - } - } - def private dispatch void applyDefaults(BuiltInTypeScope builtInTypeScope, TStructGetter getter) { - if(getter.typeRef===null) { - getter.typeRef = builtInTypeScope.getAnyTypeRef(); - } - } - def private dispatch void applyDefaults(BuiltInTypeScope builtInTypeScope, TStructSetter setter) { - // note: setter.fpar===null and setter.fpar.typeRef===null are disallowed by syntax, but - // setting default types for these cases gives us better behavior in case of broken ASTs - if(setter.fpar===null) { - setter.fpar = TypesFactory.eINSTANCE.createTAnonymousFormalParameter(); - } - applyDefaults(builtInTypeScope, setter.fpar); - } - def private dispatch void applyDefaults(BuiltInTypeScope builtInTypeScope, TStructMethod method) { - if (method.isASTCallSignature) { - method.name = N4JSLanguageUtils.CALL_SIGNATURE_NAME; - } - method.fpars.forEach[applyDefaults(builtInTypeScope, it)]; - if(method.returnTypeRef===null) { - method.returnTypeRef = builtInTypeScope.voidTypeRef - } - } - def private dispatch void applyDefaults(BuiltInTypeScope builtInTypeScope, TFormalParameter fpar) { - if(fpar.typeRef===null) { - fpar.typeRef = builtInTypeScope.getAnyTypeRef(); - } - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSVariableStatementTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSVariableStatementTypesBuilder.java new file mode 100644 index 0000000000..0503fe27b9 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSVariableStatementTypesBuilder.java @@ -0,0 +1,222 @@ +/** + * 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.typesbuilder; + +import static org.eclipse.xtext.xbase.lib.IterableExtensions.fold; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.n4js.AnnotationDefinition; +import org.eclipse.n4js.N4JSLanguageConstants; +import org.eclipse.n4js.n4JS.ArrowFunction; +import org.eclipse.n4js.n4JS.BindingPattern; +import org.eclipse.n4js.n4JS.CatchVariable; +import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor; +import org.eclipse.n4js.n4JS.NewExpression; +import org.eclipse.n4js.n4JS.ObjectLiteral; +import org.eclipse.n4js.n4JS.TryStatement; +import org.eclipse.n4js.n4JS.VariableDeclaration; +import org.eclipse.n4js.n4JS.VariableDeclarationContainer; +import org.eclipse.n4js.n4JS.VariableStatement; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; +import org.eclipse.n4js.ts.types.AbstractNamespace; +import org.eclipse.n4js.ts.types.TVariable; +import org.eclipse.n4js.ts.types.TypesFactory; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.utils.ResourceType; + +import com.google.inject.Inject; + +class N4JSVariableStatementTypesBuilder { + + @Inject + N4JSTypesBuilderHelper _n4JSTypesBuilderHelper; + + @Inject + N4JSExportDefinitionTypesBuilder exportDefinitionTypesBuilder; + + int relinkVariableTypes(VariableDeclarationContainer n4VarDeclContainer, AbstractNamespace target, + boolean preLinkingPhase, int start) { + return relinkVariableTypes(n4VarDeclContainer.getVarDecl(), target, preLinkingPhase, start); + } + + int relinkVariableTypes(TryStatement tryStmnt, AbstractNamespace target, boolean preLinkingPhase, int start) { + CatchVariable catchVariable = tryStmnt.getCatch() == null ? null : tryStmnt.getCatch().getCatchVariable(); + if (catchVariable == null) { + return start; + } + + BindingPattern bindingPattern = catchVariable.getBindingPattern(); + if (bindingPattern != null) { + return relinkVariableTypes(bindingPattern.getAllVariableDeclarations(), target, preLinkingPhase, start); + } else { + TVariable tVariable = createVariable(catchVariable); + target.getLocalVariables().add(tVariable); + return start; + } + } + + private int relinkVariableTypes(Iterable n4VarDecls, AbstractNamespace target, + boolean preLinkingPhase, int start) { + return fold(n4VarDecls, start, (idx, decl) -> { + if (relinkVariableType(decl, target, preLinkingPhase, idx)) { + return idx + 1; + } + return idx; + }); + } + + private boolean relinkVariableType(VariableDeclaration n4VariableDeclaration, AbstractNamespace target, + boolean preLinkingPhase, int idx) { + if (n4VariableDeclaration.getName() == null) { + return false; + } + if (!n4VariableDeclaration.isDirectlyExported()) { + // local variables are not serialized, so we have to re-create them during re-linking + TVariable tVariable = createVariable(n4VariableDeclaration, preLinkingPhase); + target.getLocalVariables().add(tVariable); + return false; + } + + TVariable variable = target.getExportedVariables().get(idx); + _n4JSTypesBuilderHelper.ensureEqualName(n4VariableDeclaration, variable); + variable.setAstElement(n4VariableDeclaration); + n4VariableDeclaration.setDefinedVariable(variable); + return true; + } + + void createVariableTypes(VariableDeclarationContainer n4VarDeclContainer, AbstractNamespace target, + boolean preLinkingPhase) { + EList expVars = target.getExportedVariables(); + EList locVars = target.getLocalVariables(); + + boolean isExported = (n4VarDeclContainer instanceof VariableStatement) + ? ((VariableStatement) n4VarDeclContainer).isDirectlyExported() + : false; + + for (VariableDeclaration varDecl : n4VarDeclContainer.getVarDecl()) { + TVariable variable = createVariable(varDecl, preLinkingPhase); + if (variable != null) { + if (isExported) { + String exportedName = varDecl.getDirectlyExportedName(); + exportDefinitionTypesBuilder.createExportDefinitionForDirectlyExportedElement(variable, + exportedName, target, preLinkingPhase); + _n4JSTypesBuilderHelper.setTypeAccessModifier(variable, (VariableStatement) n4VarDeclContainer); + expVars.add(variable); + } else { + if (n4VarDeclContainer instanceof VariableStatement) { // could also be a ForStatement + _n4JSTypesBuilderHelper.setTypeAccessModifier(variable, (VariableStatement) n4VarDeclContainer); + } + locVars.add(variable); + } + } + } + } + + void createVariableTypes(TryStatement tryStmnt, AbstractNamespace target, boolean preLinkingPhase) { + EList locVars = target.getLocalVariables(); + + CatchVariable catchVariable = tryStmnt.getCatch() == null ? null : tryStmnt.getCatch().getCatchVariable(); + if (catchVariable == null) { + return; + } + + BindingPattern bindingPattern = catchVariable.getBindingPattern(); + if (bindingPattern != null) { + for (VariableDeclaration varDecl : bindingPattern.getAllVariableDeclarations()) { + TVariable variable = createVariable(varDecl, preLinkingPhase); + if (variable != null) { + locVars.add(variable); + } + } + } else { + TVariable variable = createVariable(catchVariable); + if (variable != null) { + locVars.add(variable); + } + } + } + + private TVariable createVariable(VariableDeclaration n4VariableDeclaration, boolean preLinkingPhase) { + if (n4VariableDeclaration.getName() == null) { + return null; + } + + TVariable variable = TypesFactory.eINSTANCE.createTVariable(); + variable.setName(n4VariableDeclaration.getName()); + variable.setConst(n4VariableDeclaration.isConst()); + variable.setObjectLiteral(n4VariableDeclaration.getExpression() instanceof ObjectLiteral); + variable.setNewExpression(n4VariableDeclaration.getExpression() instanceof NewExpression); + + _n4JSTypesBuilderHelper.copyAnnotations(variable, n4VariableDeclaration, preLinkingPhase); + variable.setDeclaredProvidedByRuntime( + AnnotationDefinition.PROVIDED_BY_RUNTIME.hasAnnotation(n4VariableDeclaration)); + + // set declared type (if any), otherwise type will be inferred in phase 2 + setVariableType(variable, n4VariableDeclaration, preLinkingPhase); + + variable.setAstElement(n4VariableDeclaration); + n4VariableDeclaration.setDefinedVariable(variable); + + return variable; + } + + private TVariable createVariable(CatchVariable catchVariable) { + if (catchVariable.getName() == null) { + return null; + } + + TVariable variable = TypesFactory.eINSTANCE.createTVariable(); + variable.setName(catchVariable.getName()); + + variable.setAstElement(catchVariable); + catchVariable.setDefinedVariable(variable); + + return variable; + } + + private void setVariableType(TVariable variable, VariableDeclaration n4VariableDeclaration, + boolean preLinkingPhase) { + if (n4VariableDeclaration.getDeclaredTypeRefInAST() != null) { + if (!preLinkingPhase) + // type of field was declared explicitly + variable.setTypeRef(TypeUtils.copyWithProxies(n4VariableDeclaration.getDeclaredTypeRefInAST())); + } else { + // in all other cases: + // leave it to the TypingASTWalker to infer the type (e.g. from the initializer expression, if given) + variable.setTypeRef(TypeUtils.createDeferredTypeRef()); + } + } + + TVariable createImplicitArgumentsVariable(FunctionOrFieldAccessor funOrAccDecl, AbstractNamespace target, + BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { + if (funOrAccDecl instanceof ArrowFunction) { + return null; // not available in arrow functions + } + ResourceType resourceType = ResourceType.getResourceType(funOrAccDecl); + if (resourceType != ResourceType.N4JS && resourceType != ResourceType.N4JSX) { + return null; // not required in definition files + } + + TVariable formalParameterType = TypesFactory.eINSTANCE.createTVariable(); + formalParameterType.setName(N4JSLanguageConstants.LOCAL_ARGUMENTS_VARIABLE_NAME); + + if (!preLinkingPhase) { + formalParameterType.setTypeRef(TypeUtils.createTypeRef(builtInTypeScope.getArgumentsType())); + } + + funOrAccDecl.setImplicitArgumentsVariable(formalParameterType); + formalParameterType.setAstElement(funOrAccDecl); + + target.getLocalVariables().add(formalParameterType); + + return formalParameterType; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSVariableStatementTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSVariableStatementTypesBuilder.xtend deleted file mode 100644 index 047756d35c..0000000000 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSVariableStatementTypesBuilder.xtend +++ /dev/null @@ -1,207 +0,0 @@ -/** - * 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.typesbuilder - -import com.google.inject.Inject -import org.eclipse.n4js.AnnotationDefinition -import org.eclipse.n4js.N4JSLanguageConstants -import org.eclipse.n4js.n4JS.ArrowFunction -import org.eclipse.n4js.n4JS.CatchVariable -import org.eclipse.n4js.n4JS.FunctionOrFieldAccessor -import org.eclipse.n4js.n4JS.NewExpression -import org.eclipse.n4js.n4JS.ObjectLiteral -import org.eclipse.n4js.n4JS.TryStatement -import org.eclipse.n4js.n4JS.VariableDeclaration -import org.eclipse.n4js.n4JS.VariableDeclarationContainer -import org.eclipse.n4js.n4JS.VariableStatement -import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope -import org.eclipse.n4js.ts.types.AbstractNamespace -import org.eclipse.n4js.ts.types.TVariable -import org.eclipse.n4js.ts.types.TypesFactory -import org.eclipse.n4js.types.utils.TypeUtils -import org.eclipse.n4js.utils.ResourceType - -package class N4JSVariableStatementTypesBuilder { - - @Inject extension N4JSTypesBuilderHelper - - @Inject N4JSExportDefinitionTypesBuilder exportDefinitionTypesBuilder; - - def package int relinkVariableTypes(VariableDeclarationContainer n4VarDeclContainer, AbstractNamespace target, boolean preLinkingPhase, int start) { - return relinkVariableTypes(n4VarDeclContainer.varDecl, target, preLinkingPhase, start); - } - - def package int relinkVariableTypes(TryStatement tryStmnt, AbstractNamespace target, boolean preLinkingPhase, int start) { - val catchVariable = tryStmnt.^catch?.catchVariable; - if (catchVariable === null) { - return start; - } - - val bindingPattern = catchVariable.bindingPattern; - if (bindingPattern !== null) { - return relinkVariableTypes(bindingPattern.allVariableDeclarations, target, preLinkingPhase, start); - } else { - val tVariable = createVariable(catchVariable, preLinkingPhase); - target.localVariables += tVariable; - return start; - } - } - - def private int relinkVariableTypes(Iterable n4VarDecls, AbstractNamespace target, boolean preLinkingPhase, int start) { - return n4VarDecls.fold(start) [ idx, decl | - if (decl.relinkVariableType(target, preLinkingPhase, idx)) { - return idx + 1; - } - return idx; - ]; - } - - def private boolean relinkVariableType(VariableDeclaration n4VariableDeclaration, AbstractNamespace target, boolean preLinkingPhase, int idx) { - if(n4VariableDeclaration.name === null) { - return false - } - if (!n4VariableDeclaration.directlyExported) { - // local variables are not serialized, so we have to re-create them during re-linking - val tVariable = createVariable(n4VariableDeclaration, preLinkingPhase); - target.localVariables += tVariable; - return false; - } - - val variable = target.exportedVariables.get(idx); - ensureEqualName(n4VariableDeclaration, variable); - variable.astElement = n4VariableDeclaration - n4VariableDeclaration.definedVariable = variable; - return true - } - - def package void createVariableTypes(VariableDeclarationContainer n4VarDeclContainer, AbstractNamespace target, boolean preLinkingPhase) { - val expVars = target.exportedVariables; - val locVars = target.localVariables; - - val isExported = if (n4VarDeclContainer instanceof VariableStatement) n4VarDeclContainer.directlyExported else false; - - for (varDecl : n4VarDeclContainer.varDecl) { - val variable = createVariable(varDecl, preLinkingPhase); - if (variable !== null) { - if (isExported) { - val exportedName = varDecl.directlyExportedName; - exportDefinitionTypesBuilder.createExportDefinitionForDirectlyExportedElement(variable, exportedName, target, preLinkingPhase); - variable.setTypeAccessModifier(n4VarDeclContainer as VariableStatement); - expVars += variable; - } else { - if (n4VarDeclContainer instanceof VariableStatement) { // could also be a ForStatement - variable.setTypeAccessModifier(n4VarDeclContainer); - } - locVars += variable; - } - } - } - } - - def package void createVariableTypes(TryStatement tryStmnt, AbstractNamespace target, boolean preLinkingPhase) { - val locVars = target.localVariables; - - val catchVariable = tryStmnt.^catch?.catchVariable; - if (catchVariable === null) { - return; - } - - val bindingPattern = catchVariable.bindingPattern; - if (bindingPattern !== null) { - for (varDecl : bindingPattern.allVariableDeclarations) { - val variable = createVariable(varDecl, preLinkingPhase); - if (variable !== null) { - locVars += variable; - } - } - } else { - val variable = createVariable(catchVariable, preLinkingPhase); - if (variable !== null) { - locVars += variable; - } - } - } - - def private TVariable createVariable(VariableDeclaration n4VariableDeclaration, boolean preLinkingPhase) { - if(n4VariableDeclaration.name === null) { - return null - } - - val variable = TypesFactory.eINSTANCE.createTVariable - variable.name = n4VariableDeclaration.name; - variable.const = n4VariableDeclaration.const; - variable.objectLiteral = n4VariableDeclaration.expression instanceof ObjectLiteral; - variable.newExpression = n4VariableDeclaration.expression instanceof NewExpression; - - variable.copyAnnotations(n4VariableDeclaration, preLinkingPhase) - variable.declaredProvidedByRuntime = AnnotationDefinition.PROVIDED_BY_RUNTIME.hasAnnotation(n4VariableDeclaration) - - // set declared type (if any), otherwise type will be inferred in phase 2 - setVariableType(variable, n4VariableDeclaration, preLinkingPhase) - - variable.astElement = n4VariableDeclaration - n4VariableDeclaration.definedVariable = variable; - - return variable - } - - def private TVariable createVariable(CatchVariable catchVariable, boolean preLinkingPhase) { - if (catchVariable.name === null) { - return null; - } - - val variable = TypesFactory.eINSTANCE.createTVariable - variable.name = catchVariable.name; - - variable.astElement = catchVariable; - catchVariable.definedVariable = variable; - - return variable - } - - def private void setVariableType(TVariable variable, VariableDeclaration n4VariableDeclaration, boolean preLinkingPhase) { - if(n4VariableDeclaration.declaredTypeRefInAST!==null) { - if (!preLinkingPhase) - // type of field was declared explicitly - variable.typeRef = TypeUtils.copyWithProxies(n4VariableDeclaration.declaredTypeRefInAST); - } - else { - // in all other cases: - // leave it to the TypingASTWalker to infer the type (e.g. from the initializer expression, if given) - variable.typeRef = TypeUtils.createDeferredTypeRef - } - } - - - def package TVariable createImplicitArgumentsVariable(FunctionOrFieldAccessor funOrAccDecl, AbstractNamespace target, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) { - if (funOrAccDecl instanceof ArrowFunction) { - return null; // not available in arrow functions - } - val resourceType = ResourceType.getResourceType(funOrAccDecl); - if (resourceType !== ResourceType.N4JS && resourceType !== ResourceType.N4JSX) { - return null; // not required in definition files - } - - val formalParameterType = TypesFactory::eINSTANCE.createTVariable(); - formalParameterType.name = N4JSLanguageConstants.LOCAL_ARGUMENTS_VARIABLE_NAME; - - if (!preLinkingPhase) { - formalParameterType.typeRef = TypeUtils.createTypeRef(builtInTypeScope.argumentsType); - } - - funOrAccDecl.implicitArgumentsVariable = formalParameterType; - formalParameterType.astElement = funOrAccDecl; - - target.localVariables += formalParameterType; - - return formalParameterType; - } -} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSImportValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSImportValidator.xtend index b5204fbda8..5a2b8422b5 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSImportValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSImportValidator.xtend @@ -340,7 +340,7 @@ class N4JSImportValidator extends AbstractN4JSDeclarativeValidator { private def handleNotImportedTypeRefs(Script script, List specifiersWithIssues, Map eObjectToIssueCode) { - val importedProvidedElementsWithIssuesByModule = specifiersWithIssues.mapToImportProvidedElements(jsVariantHelper).groupBy [ + val importedProvidedElementsWithIssuesByModule = mapToImportProvidedElements(specifiersWithIssues).groupBy [ importedModule ] val potentiallyAffectedTypeRefs = script.eAllContents.filter(ParameterizedTypeRef).filter [ diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSLambdaValidator.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSLambdaValidator.java index e840fed752..f29ee81369 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSLambdaValidator.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSLambdaValidator.java @@ -14,6 +14,7 @@ import org.eclipse.emf.ecore.EObject; import org.eclipse.n4js.n4JS.ArrowFunction; +import org.eclipse.n4js.n4JS.ThisLiteral; import org.eclipse.n4js.types.utils.LambdaUtils; import org.eclipse.n4js.utils.ContainerTypesHelper; import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator; @@ -60,7 +61,7 @@ public void checkTopLevelLambda(ArrowFunction arrowFun) { */ private void rejectUsagesOfThisInTopLevelLambda(ArrowFunction topLevelLambda) { assert LambdaUtils.isLambda(topLevelLambda); - Iterator thisUsages = LambdaUtils.thisLiterals(topLevelLambda.getBody()); + Iterator thisUsages = LambdaUtils.thisLiterals(topLevelLambda.getBody()); while (thisUsages.hasNext()) { EObject thisUsage = thisUsages.next(); addIssue(thisUsage, IssueCodes.KEY_THIS_REJECTED_IN_TOP_LEVEL_LAMBDA); From ae67c5a4fa964f70e9edfbd14496c339cf3b1d06 Mon Sep 17 00:00:00 2001 From: mmews-n4 Date: Thu, 18 Apr 2024 13:57:32 +0200 Subject: [PATCH 22/26] GH-2612: As a developer I want array literals to be typed as ArrayN<...> instead of just Array (#2613) * add test * first shot * adjust tests * add helper method * support type inference on indexed access * adjust test * tweaks for ArrayN inference * adjust tests * next try, added tests * next try * adjust tests * adjust tests * reducer respects structural subtype check wrt. optional properties * improved error message in case of failed poly processor * remove obsolete casts * adjust tests * adjust tests * improve nested object literals, improve non-backtracker wrt. struct. obj * adjust tests * fix concurrent exception * fix hover exception * add some tests, some src improvements * more tests, adjust tests * fix several issues: Deadlock during startup, Text Highlight and Documentation, Issue creation * adjust built-ins Array#concat to support unification of types * add tests * adjust tests * more tests / corner cases * add test, adjust tests * support parentheses around return expressions * adjusted tests * several unrelated changes * many improvements, performance, reduce unions with match, ... * add another test for bug regarding union of methods with type vars * enhance deadlock bugfix * fix handling type vars of composed methods * adjust some test expectations * fix double reporting, adjust tests, add test case * fix/mitigate hover bug * postpone to GH-2615 * incorporate review changes * bump minor version due to backwards incompatibility --- .../packages/n4js-cli/src/n4js/Globals.n4js | 2 +- .../mangelhaft/test/TestExecutorTests.n4js | 6 +- .../n4js/mangelhaft/InstrumentedTest.n4js | 2 +- .../n4js/mangelhaft/types/TestStatus.n4js | 2 +- .../ide/server/N4JSResourceTaskContext.java | 16 + .../symbol/N4JSDocumentSymbolService.java | 4 +- .../org/eclipse/n4js/n4JS/N4JSASTUtils.java | 9 +- .../n4js/smith/N4JSDataCollectors.java | 5 + .../ide/server/TextDocumentFrontend.java | 6 +- .../src-env/env/builtin_js.n4jsd | 2 +- .../n4js/naming/N4JSImportedNamesAdapter.java | 11 +- .../postprocessing/AbstractPolyProcessor.java | 25 ++ .../n4js/postprocessing/PolyProcessor.java | 21 +- .../PolyProcessor_ArrayLiteral.java | 321 +++++++++------ .../PolyProcessor_FunctionExpression.java | 35 +- .../PolyProcessor_ObjectLiteral.java | 12 +- .../n4js/postprocessing/TypeProcessor.java | 5 + .../resource/N4JSResourceDescription.java | 14 +- .../scoping/members/ComposedMemberInfo.java | 27 +- .../n4js/scoping/members/MethodFactory.java | 1 + .../tooling/N4JSDocumentationProvider.java | 10 +- .../eclipse/n4js/types/utils/TypeUtils.java | 92 ++++- .../n4js/typesystem/ExpectedTypeJudgment.java | 6 + .../n4js/typesystem/N4JSTypeSystem.java | 46 ++- .../n4js/typesystem/SubtypeJudgment.java | 7 + .../eclipse/n4js/typesystem/TypeJudgment.java | 23 +- .../n4js/typesystem/constraints/BoundSet.java | 279 +++++-------- .../constraints/InferenceContext.java | 32 +- .../n4js/typesystem/constraints/Reducer.java | 260 ++++++++---- .../typesystem/constraints/TypeBound.java | 26 +- .../constraints/TypeBoundCombiner.java | 256 ++++++++++++ .../typesystem/utils/GenericsComputer.xtend | 28 +- .../utils/RuleEnvironmentExtensions.xtend | 24 ++ .../utils/StructuralTypingComputer.xtend | 44 +- .../n4js/utils/DestructureHelper.xtend | 7 +- .../eclipse/n4js/validation/IssueCodes.java | 4 +- .../validators/N4JSExpressionValidator.xtend | 19 +- .../validators/N4JSTypeValidator.xtend | 17 +- ...ionOfUnionWrongForConstructorTypes.n4js.xt | 4 +- ...implifyUnion_must_not_oversimplify.n4js.xt | 4 +- .../Class_x_ST_US/01_instantiation.n4js.xt | 2 +- .../09_nested_ST_members.n4js.xt | 2 +- .../matrix/Ctor_x_Union/02_from_spec.n4js.xt | 2 +- .../02_as_return_value.n4js.xt | 2 +- .../Interface_x_ST_US/01_as_argument.n4js.xt | 2 +- .../matrix/Lambda/08_higher-order.n4js.xt | 2 +- .../n4js/typesystem/PolyProcessorTest.java | 3 +- .../N6_1_04_ArrayLiteralTypesystemTest.java | 33 +- ...exedAccessExpressionTypeInferenceTest.java | 26 +- .../N6_1_08_NewExpressionTypesystemTest.java | 4 +- ...teralTypes_inference_arrayLiterals.n4js.xt | 7 +- ...Types_inference_arrayLiterals_poly.n4js.xt | 23 ++ ...eralTypes_inference_objectLiterals.n4js.xt | 2 +- ...ference_objectLiterals_poly_nested.n4js.xt | 36 ++ .../TypeArgs_anyPlus.n4js.xt | 26 ++ ...n_Be_Assigned_Via_Public_Accessors.n4js.xt | 2 +- .../PolyProcessor_QuasiOptionalFields.n4js.xt | 45 +++ .../FieldsOptionalOrWithExpression.n4js.xt | 4 +- .../Req76_3_StructuralAndInstanceof.n4js.xt | 3 + .../generators-yield-star.n4js.xt | 4 +- .../Promisify_useCases.n4js.xt | 8 +- ...rayLiteral_asValueToBeDestructured.n4js.xt | 5 + ...eral_withTypeExpectation_IterableN.n4js.xt | 18 +- .../CommaExpression.n4js.xt | 2 +- .../Destruct_Array_Typed.n4js.xt | 33 ++ .../DestructTS_other_useCase2.n4js.xt | 4 +- .../DestructTS_other_useCase3.n4js.xt | 2 +- .../asyncIteration_useCase0.n4js.xt | 17 + .../asyncIteration_useCase1.n4js.xt | 2 +- ...tional_fields_object_literal_array.n4js.xt | 2 +- ...ructuralTypingThisAndObjectLiteral.n4js.xt | 4 +- .../typesystem/Any_X_structuralObject.n4js.xt | 28 ++ .../Generics_StructuralTyping.n4js.xt | 2 +- .../typesystem/Generics_Union_call.n4js.xt | 28 ++ ...cturalTypeRefWithTypeVarsInMembers.n4js.xt | 2 +- .../typesystem/performance/ArrLit.n4js.xt | 380 ++++++++++++++++++ .../ArrLit_callExpr_nesting.n4js.xt | 50 +++ .../polyExpressions/ArrLit_cast.n4js.xt | 32 ++ .../polyExpressions/ArrLit_concat.n4js.xt | 24 ++ .../ArrLit_empty_specialcase.n4js.xt | 23 ++ .../ArrLit_error_missing_prop.n4js.xt | 27 ++ .../polyExpressions/ArrLit_simple.n4js.xt | 12 +- .../polyExpressions/CallExpr_union.n4js.xt | 22 + .../polyExpressions/CondExpr.n4js.xt | 13 +- .../polyExpressions/ObjLit_combined.n4js.xt | 2 +- .../ObjLit_quasi_optional.n4js.xt | 23 ++ .../validation/types/StructuralTyping.n4js.xt | 2 +- version.json | 2 +- 88 files changed, 2112 insertions(+), 601 deletions(-) create mode 100644 plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/TypeBoundCombiner.java create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_arrayLiterals_poly.n4js.xt create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_objectLiterals_poly_nested.n4js.xt create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_05__Generic_Classifiers/TypeArgs_anyPlus.n4js.xt create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_02_01__StructuralThisTypeInCtorAndSpecParameter/PolyProcessor_QuasiOptionalFields.n4js.xt create mode 100644 tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring/Destruct_Array_Typed.n4js.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/asynchronousIteration/asyncIteration_useCase0.n4js.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/Any_X_structuralObject.n4js.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/Generics_Union_call.n4js.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/performance/ArrLit.n4js.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_callExpr_nesting.n4js.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_cast.n4js.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_concat.n4js.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_empty_specialcase.n4js.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_error_missing_prop.n4js.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/CallExpr_union.n4js.xt create mode 100644 tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ObjLit_quasi_optional.n4js.xt diff --git a/n4js-libs/packages/n4js-cli/src/n4js/Globals.n4js b/n4js-libs/packages/n4js-cli/src/n4js/Globals.n4js index 0ed8114e39..8c6e26ed06 100644 --- a/n4js-libs/packages/n4js-cli/src/n4js/Globals.n4js +++ b/n4js-libs/packages/n4js-cli/src/n4js/Globals.n4js @@ -37,7 +37,7 @@ export public const JRE_INFO_MAP = new Map([ [Platform.x64_sunos, null], [Platform.x32_win32, {bin: "bin/java.exe", name: "OpenJDK-jre_x86-32_windows_hotspot_2021-05-06-23-30.zip"}], [Platform.x64_win32, {bin: "bin/java.exe", name: "OpenJDK-jre_x64_windows_hotspot_2021-05-06-23-30.zip"}]] - as Iterable>); + ); @StringBased diff --git a/n4js-libs/packages/org.eclipse.n4js.mangelhaft.test/test/n4js/org/eclipse/n4js/mangelhaft/test/TestExecutorTests.n4js b/n4js-libs/packages/org.eclipse.n4js.mangelhaft.test/test/n4js/org/eclipse/n4js/mangelhaft/test/TestExecutorTests.n4js index 974c98cc87..d3f8adf6a2 100644 --- a/n4js-libs/packages/org.eclipse.n4js.mangelhaft.test/test/n4js/org/eclipse/n4js/mangelhaft/test/TestExecutorTests.n4js +++ b/n4js-libs/packages/org.eclipse.n4js.mangelhaft.test/test/n4js/org/eclipse/n4js/mangelhaft/test/TestExecutorTests.n4js @@ -264,7 +264,7 @@ export public class TestExecutorTests { ["fixme__multiScope___success", TestStatus.passed], ["fixme__multiScope___fail", TestStatus.failed], ] - const expectedMap = new Map(expected as Iterable>); + const expectedMap = new Map(expected); const tests: InstrumentedTest[] = [] tests.push(new InstrumentedTest().load(FixmeTests).setTestObject(new FixmeTests())); const val = await this.subject.executor.runTestsAsync(tests); @@ -286,7 +286,7 @@ export public class TestExecutorTests { ["fixme__multiScope___success", TestStatus.failed], ["fixme__multiScope___fail", TestStatus.skipped_fixme], ] - const expectedMap = new Map(expected as Iterable>); + const expectedMap = new Map(expected); const tests: InstrumentedTest[] = [] tests.push(new InstrumentedTest().load(FixmeTests).setTestObject(new FixmeTests())); const val = await this.subject.executor.runTestsAsync(tests, "SERVER"); @@ -308,7 +308,7 @@ export public class TestExecutorTests { ["fixme__multiScope___success", TestStatus.failed], ["fixme__multiScope___fail", TestStatus.skipped_fixme], ] - const expectedMap = new Map(expected as Iterable>); + const expectedMap = new Map(expected); const tests: InstrumentedTest[] = [] tests.push(new InstrumentedTest().load(FixmeTests).setTestObject(new FixmeTests())); const val = await this.subject.executor.runTestsAsync(tests, "MOCK"); diff --git a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/InstrumentedTest.n4js b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/InstrumentedTest.n4js index 3c7f3089ae..d6472cc935 100644 --- a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/InstrumentedTest.n4js +++ b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/InstrumentedTest.n4js @@ -155,7 +155,7 @@ export public class InstrumentedTest implements IInstrumentedTest { // Make shared TestController instance be accessible to test instances (via injection): const instance = testInjector.internalCreate(testClass, testInjector, new Map([ [`${TestController.n4type.origin}${TestController.n4type.fqn}`, controller] - ] as Iterable>)); + ])); return new InstrumentedTest(testClass, info, instance, null, parameterizedTests); } diff --git a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestStatus.n4js b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestStatus.n4js index 5641157c4a..ac5bda969b 100644 --- a/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestStatus.n4js +++ b/n4js-libs/packages/org.eclipse.n4js.mangelhaft/src/n4js/org/eclipse/n4js/mangelhaft/types/TestStatus.n4js @@ -28,7 +28,7 @@ let testStatusIntMap = new Map([ , [TestStatus.failed, 6] , [TestStatus.error, 7] -] as Iterable>); +]); export function aggregateTestStatuses(testStatus1: TestStatus, testStatus2: TestStatus): TestStatus { return testStatusIntMap.get(testStatus1) > testStatusIntMap.get(testStatus2) ? testStatus1 : testStatus2; diff --git a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/N4JSResourceTaskContext.java b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/N4JSResourceTaskContext.java index 75cfdbc4ed..c0bc5a8a39 100644 --- a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/N4JSResourceTaskContext.java +++ b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/N4JSResourceTaskContext.java @@ -13,8 +13,13 @@ import java.util.HashMap; import java.util.Map; +import org.eclipse.emf.common.util.URI; import org.eclipse.n4js.resource.N4JSResource; +import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; import org.eclipse.n4js.xtext.ide.server.ResourceTaskContext; +import org.eclipse.n4js.xtext.ide.server.ResourceTaskManager; +import org.eclipse.n4js.xtext.ide.server.util.XChunkedResourceDescriptions; +import org.eclipse.n4js.xtext.workspace.WorkspaceConfigSnapshot; import org.eclipse.xtext.resource.XtextResource; /** @@ -29,4 +34,15 @@ public class N4JSResourceTaskContext extends ResourceTaskContext { return options; } + @Override + public synchronized void initialize( + ResourceTaskManager parent, + URI uri, + boolean isTemporary, + XChunkedResourceDescriptions index, + WorkspaceConfigSnapshot workspaceConfig) { + + super.initialize(parent, uri, isTemporary, index, workspaceConfig); + BuiltInTypeScope.get(getResourceSet()).getNullType(); // force loading built-ins to avoid deadlock later + } } diff --git a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/symbol/N4JSDocumentSymbolService.java b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/symbol/N4JSDocumentSymbolService.java index 403de58427..1c298ce22e 100644 --- a/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/symbol/N4JSDocumentSymbolService.java +++ b/plugins/org.eclipse.n4js.ide/src/org/eclipse/n4js/ide/server/symbol/N4JSDocumentSymbolService.java @@ -109,7 +109,9 @@ public List getDefinitions(XtextResource resource, int offse .eGet(N4JSPackage.eINSTANCE.getPropertyNameValuePair_Expression())) { EObject elementInDestructuring = findReferenceHelper.getMemberInDestructuring(elemAtOffset); - addLocations(resourceAccess, cancelIndicator, elementInDestructuring, locations); + if (elementInDestructuring != null) { + addLocations(resourceAccess, cancelIndicator, elementInDestructuring, locations); + } } addLocations(resourceAccess, cancelIndicator, element, locations); diff --git a/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/N4JSASTUtils.java b/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/N4JSASTUtils.java index 8432e48538..abe5326c47 100644 --- a/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/N4JSASTUtils.java +++ b/plugins/org.eclipse.n4js.model/src/org/eclipse/n4js/n4JS/N4JSASTUtils.java @@ -346,12 +346,17 @@ public static FunctionOrFieldAccessor getContainingFunctionOrAccessor(EObject eo * arrow function; otherwise null is returned. */ public static ArrowFunction getContainingSingleExpressionArrowFunction(Expression expression) { - final EObject parent = expression.eContainer(); + EObject skippedParenthesesExpr = expression; + EObject parent = expression.eContainer(); + while (parent instanceof ParenExpression) { + skippedParenthesesExpr = parent; + parent = parent.eContainer(); + } final EObject grandparent = parent != null ? parent.eContainer() : null; final EObject grandgrandparent = grandparent != null ? grandparent.eContainer() : null; if (grandgrandparent instanceof ArrowFunction) { final ArrowFunction arrFun = (ArrowFunction) grandgrandparent; - if (arrFun.isSingleExprImplicitReturn() && arrFun.implicitReturnExpr() == expression) { + if (arrFun.isSingleExprImplicitReturn() && arrFun.implicitReturnExpr() == skippedParenthesesExpr) { return arrFun; } } diff --git a/plugins/org.eclipse.n4js.smith/src/org/eclipse/n4js/smith/N4JSDataCollectors.java b/plugins/org.eclipse.n4js.smith/src/org/eclipse/n4js/smith/N4JSDataCollectors.java index 909b9d4941..1673e05139 100644 --- a/plugins/org.eclipse.n4js.smith/src/org/eclipse/n4js/smith/N4JSDataCollectors.java +++ b/plugins/org.eclipse.n4js.smith/src/org/eclipse/n4js/smith/N4JSDataCollectors.java @@ -72,6 +72,11 @@ public final class N4JSDataCollectors { public static final DataCollector dcCacheMakeKeys = create("MakeKeys", dcCache); public static final DataCollector dcCacheSetTarget = create("SetTarget", dcCache); + public static final DataCollector dcInferenceContextSolve = create("Solve"); + public static final DataCollector dcInferenceContextReduce = create("Reduce", dcInferenceContextSolve); + public static final DataCollector dcInferenceContextIncorporate = create("Incorporate", dcInferenceContextSolve); + public static final DataCollector dcInferenceContextResolve = create("Resolve", dcInferenceContextSolve); + public static final DataCollector dcTypeHierachyTraverser = create("TypeHierachyTraverser"); public static final DataCollector dcTHT_AllMembersCollector = create("AllMembersCollector", dcTypeHierachyTraverser); diff --git a/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/TextDocumentFrontend.java b/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/TextDocumentFrontend.java index 3b7564d7cf..0eb5d78b5a 100644 --- a/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/TextDocumentFrontend.java +++ b/plugins/org.eclipse.n4js.xtext.ide/src/org/eclipse/n4js/xtext/ide/server/TextDocumentFrontend.java @@ -356,7 +356,11 @@ protected List documentHighlight(ResourceTaskContex } XtextResource res = rtc.getResource(); XDocument doc = rtc.getDocument(); - return service.getDocumentHighlights(doc, res, params, cancelIndicator); + try { + return service.getDocumentHighlights(doc, res, params, cancelIndicator); + } catch (Exception e) { + return Collections.emptyList(); + } } @Override diff --git a/plugins/org.eclipse.n4js/src-env/env/builtin_js.n4jsd b/plugins/org.eclipse.n4js/src-env/env/builtin_js.n4jsd index 848612ced5..fd1a9e33ab 100644 --- a/plugins/org.eclipse.n4js/src-env/env/builtin_js.n4jsd +++ b/plugins/org.eclipse.n4js/src-env/env/builtin_js.n4jsd @@ -377,7 +377,7 @@ export external public class Array { public toLocaleString(): string; public pop(): T; public push(...items: T): number; - public concat(...items: union {T, Array}): Array; + public concat(...items: union {S, Array}): Array; public join(separator: string = ): string; public reverse(): Array; public shift(): T; diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/naming/N4JSImportedNamesAdapter.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/naming/N4JSImportedNamesAdapter.java index e9c128984c..d0bbcafa0a 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/naming/N4JSImportedNamesAdapter.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/naming/N4JSImportedNamesAdapter.java @@ -10,10 +10,10 @@ */ package org.eclipse.n4js.naming; -import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; +import java.util.TreeSet; import org.eclipse.xtext.linking.impl.ImportedNamesAdapter; import org.eclipse.xtext.naming.QualifiedName; @@ -21,6 +21,7 @@ import org.eclipse.xtext.scoping.IScope; import com.google.common.base.Preconditions; +import com.google.common.collect.Sets; /** * Adapts default implementation to not normalize qualified names to be all lower case. @@ -72,18 +73,18 @@ public IScope wrap(IScope scope) { } @Override - public Set getImportedNames() { - return Collections.unmodifiableSet(nonNullImportedNames); + synchronized public TreeSet getImportedNames() { + return Sets.newTreeSet(nonNullImportedNames); } /** Adds given element to set of imported names. */ - public void addImportedName(QualifiedName name) { + synchronized public void addImportedName(QualifiedName name) { Preconditions.checkNotNull(name); nonNullImportedNames.add(name); } @Override - public void clear() { + synchronized public void clear() { nonNullImportedNames.clear(); } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractPolyProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractPolyProcessor.java index 92a9142382..3c8fb17295 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractPolyProcessor.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/AbstractPolyProcessor.java @@ -17,7 +17,10 @@ import static org.eclipse.xtext.xbase.lib.IterableExtensions.toSet; import static org.eclipse.xtext.xbase.lib.IteratorExtensions.exists; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -39,6 +42,7 @@ import org.eclipse.n4js.n4JS.PropertyNameValuePair; import org.eclipse.n4js.n4JS.PropertySetterDeclaration; import org.eclipse.n4js.n4JS.PropertySpread; +import org.eclipse.n4js.n4JS.ReturnStatement; import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef; import org.eclipse.n4js.ts.typeRefs.TypeRef; import org.eclipse.n4js.ts.types.InferenceVariable; @@ -56,6 +60,7 @@ import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; import org.eclipse.n4js.typesystem.utils.TypeSystemHelper.Callable; import org.eclipse.n4js.utils.N4JSLanguageUtils; +import org.eclipse.xtext.xbase.lib.IteratorExtensions; import com.google.inject.Inject; @@ -294,6 +299,26 @@ protected Map createPseudoSolution(InferenceContext return pseudoSolution; } + protected List getReturnExpressions(FunctionDefinition fun) { + if (fun instanceof ArrowFunction && ((ArrowFunction) fun).isSingleExprImplicitReturn()) { + Expression singleExpression = ((ArrowFunction) fun).getSingleExpression(); + if (singleExpression != null) { + return Collections.singletonList(singleExpression); + } + } + if (fun.getBody() != null) { + List returnStmts = IteratorExtensions.toList(fun.getBody().getAllReturnStatements()); + List returnExpr = new ArrayList<>(); + for (ReturnStatement rs : returnStmts) { + if (rs.getExpression() != null) { + returnExpr.add(rs.getExpression()); + } + } + return returnExpr; + } + return Collections.emptyList(); + } + // FIXME move to a better place protected boolean isReturningValue(FunctionDefinition fun) { return (fun.getBody() != null && exists(fun.getBody().getAllReturnStatements(), s -> s.getExpression() != null)) diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor.java index 2d07c2ade6..50e78b07e1 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor.java @@ -20,11 +20,13 @@ import org.eclipse.n4js.n4JS.Expression; import org.eclipse.n4js.n4JS.FormalParameter; import org.eclipse.n4js.n4JS.FunctionExpression; +import org.eclipse.n4js.n4JS.N4JSASTUtils; import org.eclipse.n4js.n4JS.ObjectLiteral; import org.eclipse.n4js.n4JS.ParameterizedCallExpression; import org.eclipse.n4js.n4JS.PropertyAssignment; import org.eclipse.n4js.n4JS.PropertyMethodDeclaration; import org.eclipse.n4js.n4JS.RelationalExpression; +import org.eclipse.n4js.n4JS.YieldExpression; import org.eclipse.n4js.ts.typeRefs.TypeRef; import org.eclipse.n4js.ts.types.TypableElement; import org.eclipse.n4js.ts.types.util.Variance; @@ -161,14 +163,14 @@ void inferType(RuleEnvironment G, Expression rootPoly, ASTMetaInfoCache cache) { infCtx.addConstraint(TypeConstraint.FALSE); } - TypeRef expectedTypeOfPoly = destructureHelper.calculateExpectedType(rootPoly, G, infCtx); + TypeRef expectedTypeByLiteralStructure = destructureHelper.calculateExpectedType(rootPoly, G, infCtx); // we have to pass the expected type to the #getType() method, so retrieve it first // (until the expectedType judgment is integrated into AST traversal, we have to invoke this judgment here; // in case of not-well-behaving expectedType rules, we use 'null' as expected type, i.e. no expectation) // TODO integrate expectedType judgment into AST traversal and remove #isProblematicCaseOfExpectedType() TypeRef expectedTypeRef = null; - if (expectedTypeOfPoly != null) { - expectedTypeRef = expectedTypeOfPoly; + if (expectedTypeByLiteralStructure != null) { + expectedTypeRef = expectedTypeByLiteralStructure; } else if (!isProblematicCaseOfExpectedType(rootPoly)) { expectedTypeRef = ts.expectedType(G, rootPoly.eContainer(), rootPoly); } @@ -261,7 +263,16 @@ protected TypeRef processExpr(RuleEnvironment G, Expression expr, TypeRef expect * Returns true if we are not allowed to ask for the expected type of 'node', because this would lead to illegal * forward references (temporary). */ - private boolean isProblematicCaseOfExpectedType(EObject node) { - return node != null && node.eContainer() instanceof RelationalExpression; + private boolean isProblematicCaseOfExpectedType(Expression node) { + if (node != null) { + EObject parent = N4JSASTUtils.skipParenExpressionUpward(node.eContainer()); + if (parent instanceof RelationalExpression) { + return true; + } + if (parent instanceof YieldExpression) { + return true; + } + } + return false; } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ArrayLiteral.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ArrayLiteral.java index 9462748ec2..350704d35f 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ArrayLiteral.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ArrayLiteral.java @@ -10,8 +10,9 @@ */ package org.eclipse.n4js.postprocessing; +import static org.eclipse.n4js.types.utils.TypeUtils.createWildcardExtends; import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.anyTypeRef; -import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.arrayNType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.anyTypeRefDynamic; import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.arrayNTypeRef; import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.arrayType; import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.arrayTypeRef; @@ -21,7 +22,6 @@ import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.iterableTypeRef; import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.stringType; import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.stringTypeRef; -import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.undefinedTypeRef; import static org.eclipse.xtext.xbase.lib.IterableExtensions.map; import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; @@ -36,6 +36,8 @@ import org.eclipse.n4js.n4JS.ArrayPadding; import org.eclipse.n4js.n4JS.DestructureUtils; import org.eclipse.n4js.n4JS.Expression; +import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression; import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; import org.eclipse.n4js.ts.typeRefs.TypeRef; @@ -53,7 +55,6 @@ import org.eclipse.n4js.typesystem.utils.RuleEnvironment; import org.eclipse.n4js.typesystem.utils.TypeSystemHelper; import org.eclipse.n4js.utils.N4JSLanguageUtils; -import org.eclipse.xtext.xbase.lib.IterableExtensions; import com.google.common.base.Optional; import com.google.inject.Inject; @@ -106,33 +107,32 @@ TypeRef processArrayLiteral(RuleEnvironment G, ArrayLiteral arrLit, TypeRef expe // no type expectation or some entirely wrong type expectation (i.e. other than Array, ArrayN) // -> just derive type from elements (and do not introduce a new inference variable for this ArrayLiteral!) List elemTypeRefs = new ArrayList<>(); - List nonNullElems = toList( - IterableExtensions.filter(arrLit.getElements(), ae -> ae.getExpression() != null)); - for (ArrayElement arrElem : nonNullElems) { - var arrElemTypeRef = polyProcessor.processExpr(G, arrElem.getExpression(), null, infCtx, cache); - arrElemTypeRef = ts.upperBoundWithReopen(G, arrElemTypeRef); - if (arrElem.isSpread()) { - // more than one in case of ArrayN; none in case of invalid value after spread operator - elemTypeRefs.addAll(extractSpreadTypeRefs(G, arrElemTypeRef)); + for (ArrayElement arrElem : arrLit.getElements()) { + if (arrElem.getExpression() == null) { + elemTypeRefs.add(anyTypeRef(G)); } else { - elemTypeRefs.add(arrElemTypeRef); + TypeRef arrElemTypeRef = polyProcessor.processExpr(G, arrElem.getExpression(), null, infCtx, cache); + arrElemTypeRef = ts.upperBoundWithReopen(G, arrElemTypeRef); + if (arrElem.isSpread()) { + // more than one in case of ArrayN; none in case of invalid value after spread operator + elemTypeRefs.addAll(extractSpreadTypeRefs(G, arrElemTypeRef)); + } else { + elemTypeRefs.add(arrElemTypeRef); + } } } infCtx.onSolved(solution -> handleOnSolvedPerformanceTweak(G, cache, arrLit, expectedElemTypeRefs)); - TypeRef unionOfElemTypes = (!elemTypeRefs.isEmpty()) - ? tsh.createUnionType(G, elemTypeRefs.toArray(new TypeRef[0])) - : anyTypeRef(G); - return arrayTypeRef(G, unionOfElemTypes); + return createArrayType(G, elemTypeRefs); } int resultLen = getResultLength(arrLit, expectedElemTypeRefs); TypeVariable[] resultInfVars = infCtx.newInferenceVariables(resultLen); - processElements(G, cache, infCtx, arrLit, resultLen, resultInfVars); + processElements(G, cache, infCtx, arrLit, expectedElemTypeRefs, resultInfVars); - TypeRef resultTypeRef = getResultTypeRef(G, resultLen, resultInfVars); + TypeRef resultTypeRef = getResultTypeRef(G, resultInfVars); // register onSolved handlers to add final types to cache (i.e. may not contain inference variables) infCtx.onSolved(solution -> handleOnSolved(G, cache, arrLit, expectedElemTypeRefs, resultTypeRef, solution)); @@ -172,35 +172,125 @@ private List getExpectedElemTypeRefs(RuleEnvironment G, TypeRef expecte return new ArrayList<>(); // no or invalid type expectation } + /** + * Writes final types to cache. + */ + private void handleOnSolvedPerformanceTweak(RuleEnvironment G, ASTMetaInfoCache cache, ArrayLiteral arrLit, + List expectedElemTypeRefs) { + + TypeRef fallbackTypeRef; + if (isEmptyArrayLiteralAndCallReceiver(arrLit)) { + fallbackTypeRef = arrayTypeRef(G, anyTypeRefDynamic(G)); + } else { + List betterElemTypeRefs = storeTypesOfArrayElements(G, cache, arrLit); + int resultLen = getResultLength(arrLit, betterElemTypeRefs); + fallbackTypeRef = buildFallbackTypeForArrayLiteral(resultLen, betterElemTypeRefs, + expectedElemTypeRefs, G); + } + + cache.storeType(arrLit, fallbackTypeRef); + } + + /** + * Support for a special case: + * + *

+	 * // XPECT type of 'c' --> Array
+	 * const c = [].concat([1]);
+	 * 
+ */ + private boolean isEmptyArrayLiteralAndCallReceiver(ArrayLiteral arrLit) { + if (arrLit.getElements().isEmpty() && arrLit.eContainer() instanceof ParameterizedPropertyAccessExpression) { + ParameterizedPropertyAccessExpression ppae = (ParameterizedPropertyAccessExpression) arrLit.eContainer(); + if (ppae.getTarget() == arrLit && ppae.eContainer() instanceof ParameterizedCallExpression) { + ParameterizedCallExpression pce = (ParameterizedCallExpression) ppae.eContainer(); + if (pce.getTarget() == ppae) { + return true; + } + } + } + return false; + } + + /** + * Writes final types to cache. + */ + private void handleOnSolved(RuleEnvironment G, ASTMetaInfoCache cache, ArrayLiteral arrLit, + List expectedElemTypeRefs, TypeRef resultTypeRef, + Optional> solution) { + + if (solution.isPresent()) { + // success case + TypeRef typeRef = applySolution(resultTypeRef, G, solution.get()); + cache.storeType(arrLit, typeRef); + } else { + // failure case (unsolvable constraint system) + List betterElemTypeRefs = toList(map( + arrLit.getElements(), ae -> getFinalResultTypeOfArrayElement(G, ae, Optional.absent()))); + int resultLen = getResultLength(arrLit, betterElemTypeRefs); + TypeRef typeRef = buildFallbackTypeForArrayLiteral(resultLen, betterElemTypeRefs, + expectedElemTypeRefs, G); + cache.storeType(arrLit, typeRef); + } + storeTypesOfArrayElements(G, cache, arrLit); + } + + /** + * choose correct number of type arguments in our to-be-created resultTypeRef (always 1 for Array or Iterable + * but N for ArrayN<..>, e.g. 3 for Array3) + */ + private int getResultLength(ArrayLiteral arrLit, List expectedElemTypeRefs) { + int numOfElems = arrLit.getElements().size(); + int lenA = Math.min( + expectedElemTypeRefs.size(), // use number of type arguments provided by type expectation as a basis + numOfElems // ... but never more than we have elements in the array literal + ); + + int lenB = Math.min( + lenA, + BuiltInTypeScope.ITERABLE_N__MAX_LEN // ... and never more than the max. allowed number of type + // arguments for ArrayN + ); + + int resultLen = Math.max( + lenB, + 1 // ... but at least 1 (even if numOfElems is 0, for example) + ); + return resultLen; + } + /** * Makes a best effort for building a type in case something went awry. It's only non-trivial in case we have an * expectation of IterableN. */ - private TypeRef buildFallbackTypeForArrayLiteral(boolean isArrayN, int resultLen, + private TypeRef buildFallbackTypeForArrayLiteral(int resultLen, List elemTypeRefsWithLiteralTypes, List expectedElemTypeRefs, RuleEnvironment G) { List elemTypeRefs = toList(map( elemTypeRefsWithLiteralTypes, elem -> N4JSLanguageUtils.getLiteralTypeBase(G, elem))); - if (isArrayN) { - TypeRef[] typeArgs = new TypeRef[resultLen]; - for (var i = 0; i < resultLen; i++) { - boolean isLastElem = i == (resultLen - 1); - TypeRef typeRef = null; - if (isLastElem && elemTypeRefs.size() > resultLen) { - // special case: - // we are at the last element AND we actually have more elements than we expect elements - // -> have to check all remaining elements against the last expectation! - List allRemainingElementTypeRefs = new ArrayList<>(); + List typeArgs = new ArrayList<>(); + for (var i = 0; i < resultLen; i++) { + boolean isLastElem = i == (resultLen - 1); + TypeRef typeRef = null; + if (isLastElem && elemTypeRefs.size() > resultLen) { + // special case: + // we are at the last element AND we actually have more elements than we expect elements + // -> have to check all remaining elements against the last expectation! + List allRemainingElementTypeRefs = elemTypeRefs.subList(i, elemTypeRefs.size()); + + if (expectedElemTypeRefs.isEmpty()) { + typeRef = tsh.createUnionType(G, allRemainingElementTypeRefs.toArray(new TypeRef[0])); + + } else { TypeRef currExpectedElemTypeRef = expectedElemTypeRefs.get(i); - // if all remaining elements are a subtype of the last expectation, then use expectation, otherwise + // if all remaining elements are a subtype of the last expectation, then use expectation, + // otherwise // form union boolean allMatch = true; for (var j = i; j < elemTypeRefs.size(); j++) { - TypeRef currElementTypeRef = elemTypeRefs.get(j); - allRemainingElementTypeRefs.add(currElementTypeRef); if (allMatch) { // don't try further subtype checks if already failed boolean actualIsSubtypeOfExpected = ts.subtypeSucceeded(G, currElementTypeRef, @@ -217,8 +307,10 @@ private TypeRef buildFallbackTypeForArrayLiteral(boolean isArrayN, int resultLen // use actual types (will lead to follow-up errors caught by validations) typeRef = tsh.createUnionType(G, allRemainingElementTypeRefs.toArray(new TypeRef[0])); } - } else { - TypeRef currElemTypeRef = elemTypeRefs.get(i); + } + } else if (i < elemTypeRefs.size()) { + TypeRef currElemTypeRef = elemTypeRefs.get(i); + if (i < expectedElemTypeRefs.size()) { TypeRef currExpectedElemTypeRef = expectedElemTypeRefs.get(i); boolean actualIsSubtypeOfExpected = ts.subtypeSucceeded(G, currElemTypeRef, currExpectedElemTypeRef); @@ -229,49 +321,54 @@ private TypeRef buildFallbackTypeForArrayLiteral(boolean isArrayN, int resultLen // use actual type (will lead to follow-up errors caught by validations) typeRef = currElemTypeRef; } + } else { + typeRef = currElemTypeRef; } - typeArgs[i] = typeRef; } - - if (elemTypeRefs.size() > resultLen) { - // replace last entry in 'typeArgs' with union of all remaining in elemTypeRefs - TypeRef[] remaining = Arrays.copyOfRange(elemTypeRefs.toArray(new TypeRef[0]), resultLen - 1, - elemTypeRefs.size()); - - typeArgs[resultLen - 1] = tsh.createUnionType(G, remaining); + if (typeRef != null) { + typeArgs.add(typeRef); } + } - return arrayNTypeRef(G, resultLen, typeArgs); + if (elemTypeRefs.size() > resultLen) { + // replace last entry in 'typeArgs' with union of all remaining in elemTypeRefs + TypeRef[] remaining = Arrays.copyOfRange(elemTypeRefs.toArray(new TypeRef[0]), resultLen - 1, + elemTypeRefs.size()); + + typeArgs.add(tsh.createUnionType(G, remaining)); } else { - TypeRef unionOfElemTypes = (!elemTypeRefs.isEmpty()) - ? tsh.createUnionType(G, elemTypeRefs.toArray(new TypeRef[0])) - : anyTypeRef(G); - return arrayTypeRef(G, unionOfElemTypes); + while (typeArgs.size() > 1) { + int size = typeArgs.size(); + TypeRef last = typeArgs.get(size - 1); + TypeRef beforeLast = typeArgs.get(size - 2); + if (ts.equaltypeApproxSucceeded(beforeLast, last)) { + typeArgs.remove(size - 1); + } else { + break; + } + } } - } - - /** - * choose correct number of type arguments in our to-be-created resultTypeRef (always 1 for Array or Iterable - * but N for ArrayN<..>, e.g. 3 for Array3) - */ - private int getResultLength(ArrayLiteral arrLit, List expectedElemTypeRefs) { - int numOfElems = arrLit.getElements().size(); - int lenA = Math.min( - expectedElemTypeRefs.size(), // use number of type arguments provided by type expectation as a basis - numOfElems // ... but never more than we have elements in the array literal - ); - int lenB = Math.min( - lenA, - BuiltInTypeScope.ITERABLE_N__MAX_LEN // ... and never more than the max. allowed number of type - // arguments for ArrayN - ); + return createArrayType(G, typeArgs); + } - int resultLen = Math.max( - lenB, - 1 // ... but at least 1 (even if numOfElems is 0, for example) - ); - return resultLen; + private TypeRef createArrayType(RuleEnvironment G, List elemTypeRefs) { + if (elemTypeRefs.size() == 0) { + return arrayTypeRef(G, anyTypeRef(G)); + } else if (elemTypeRefs.size() == 1) { + return arrayTypeRef(G, elemTypeRefs.get(0)); + } else if (elemTypeRefs.size() > 1) { + if (elemTypeRefs.size() <= BuiltInTypeScope.ITERABLE_N__MAX_LEN) { + return arrayNTypeRef(G, elemTypeRefs.size(), elemTypeRefs.toArray(new TypeRef[0])); + } else { + List arrayNTypes = new ArrayList<>( + elemTypeRefs.subList(0, BuiltInTypeScope.ITERABLE_N__MAX_LEN - 1)); + List tail = elemTypeRefs.subList(BuiltInTypeScope.ITERABLE_N__MAX_LEN, elemTypeRefs.size()); + arrayNTypes.add(tsh.createUnionType(G, tail.toArray(new TypeRef[0]))); + return arrayNTypeRef(G, BuiltInTypeScope.ITERABLE_N__MAX_LEN, arrayNTypes.toArray(new TypeRef[0])); + } + } + return arrayTypeRef(G, anyTypeRef(G)); // unreachable } /** @@ -281,13 +378,12 @@ private int getResultLength(ArrayLiteral arrLit, List expectedElemTypeR *
  • ArrayN (where T1,...TN are new inference variables, N>=2)
  • * */ - private TypeRef getResultTypeRef(RuleEnvironment G, int resultLen, TypeVariable[] resultInfVars) { - boolean isArrayN = resultLen >= 2; - TClass declaredType = (isArrayN) ? arrayNType(G, resultLen) : arrayType(G); - List typeArgs = toList( - map(Arrays.asList(resultInfVars), v -> TypeUtils.createTypeRef(v))); - TypeRef resultTypeRef = TypeUtils.createTypeRef(declaredType, typeArgs.toArray(new ParameterizedTypeRef[0])); - return resultTypeRef; + private TypeRef getResultTypeRef(RuleEnvironment G, TypeVariable[] resultInfVars) { + List ptRefs = new ArrayList<>(); + for (int i = 0; i < resultInfVars.length; i++) { + ptRefs.add(TypeUtils.createTypeRef(resultInfVars[i])); + } + return createArrayType(G, ptRefs); } /** @@ -295,62 +391,40 @@ private TypeRef getResultTypeRef(RuleEnvironment G, int resultLen, TypeVariable[ * type of the array element's expression */ private void processElements(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, - ArrayLiteral arrLit, - int resultLen, TypeVariable[] resultInfVars) { + ArrayLiteral arrLit, List expectedElemTypeRefs, TypeVariable[] resultInfVars) { + int numOfElems = arrLit.getElements().size(); - for (var idxElem = 0; idxElem < numOfElems; idxElem++) { + for (int idxElem = 0; idxElem < numOfElems; idxElem++) { ArrayElement currElem = arrLit.getElements().get(idxElem); if (currElem == null || currElem.getExpression() == null) { // currElem is null, or has no expression (broken AST), or is an ArrayPadding element // -> ignore (no constraint to add) } else { // currElem is a valid ArrayElement with an expression - // -> add constraint currElemTypeRef <: Ti (Ti being the corresponding inf. variable in resultTypeRef) - int idxResult = Math.min(idxElem, resultLen - 1); - TypeVariable currResultInfVar = resultInfVars[idxResult]; - TypeRef currResultInfVarTypeRef = TypeUtils.createTypeRef(currResultInfVar); - TypeRef currExpectedTypeRef = (currElem.isSpread()) - ? iterableTypeRef(G, TypeUtils.createWildcardExtends(currResultInfVarTypeRef)) - : currResultInfVarTypeRef; - TypeRef currElemTypeRef = polyProcessor.processExpr(G, currElem.getExpression(), currExpectedTypeRef, - infCtx, cache); - infCtx.addConstraint(currElemTypeRef, currExpectedTypeRef, Variance.CO); - } - } - } + // -> add constraint currElemTypeRef <: Ti (Ti being the corresponding inf. variable in + // resultTypeRef) - /** - * Writes final types to cache. - */ - private void handleOnSolvedPerformanceTweak(RuleEnvironment G, ASTMetaInfoCache cache, ArrayLiteral arrLit, - List expectedElemTypeRefs) { - List betterElemTypeRefs = storeTypesOfArrayElements(G, cache, arrLit); - TypeRef fallbackTypeRef = buildFallbackTypeForArrayLiteral(false, 1, betterElemTypeRefs, expectedElemTypeRefs, - G); - cache.storeType(arrLit, fallbackTypeRef); - } + TypeRef currExpectedTypeRef = expectedElemTypeRefs.isEmpty() + ? null + : expectedElemTypeRefs.get(Math.min(idxElem, expectedElemTypeRefs.size() - 1)); - /** - * Writes final types to cache. - */ - private void handleOnSolved(RuleEnvironment G, ASTMetaInfoCache cache, ArrayLiteral arrLit, - List expectedElemTypeRefs, TypeRef resultTypeRef, - Optional> solution) { - int resultLen = getResultLength(arrLit, expectedElemTypeRefs); - boolean isArrayN = resultLen >= 2; - if (solution.isPresent()) { - // success case - TypeRef typeRef = applySolution(resultTypeRef, G, solution.get()); - cache.storeType(arrLit, typeRef); - } else { - // failure case (unsolvable constraint system) - List betterElemTypeRefs = toList(map( - arrLit.getElements(), ae -> getFinalResultTypeOfArrayElement(G, ae, Optional.absent()))); - TypeRef typeRef = buildFallbackTypeForArrayLiteral(isArrayN, resultLen, betterElemTypeRefs, - expectedElemTypeRefs, G); - cache.storeType(arrLit, typeRef); + TypeRef currResultTypeRef; + if (isArrayN(G, currExpectedTypeRef) || isIterableN(G, currExpectedTypeRef)) { + currResultTypeRef = currExpectedTypeRef; + } else { + int idxResult = Math.min(idxElem, resultInfVars.length - 1); + TypeVariable currResultInfVar = resultInfVars[idxResult]; + currResultTypeRef = TypeUtils.createTypeRef(currResultInfVar); + if (currElem.isSpread()) { + currResultTypeRef = iterableTypeRef(G, createWildcardExtends(currResultTypeRef)); + } + } + + TypeRef currElemTypeRef = polyProcessor.processExpr(G, currElem.getExpression(), + currResultTypeRef, infCtx, cache); + infCtx.addConstraint(currElemTypeRef, currResultTypeRef, Variance.CO); + } } - storeTypesOfArrayElements(G, cache, arrLit); } // PolyProcessor#isResponsibleFor(TypableElement) claims responsibility of AST nodes of type 'ArrayElement' @@ -361,7 +435,8 @@ private List storeTypesOfArrayElements(RuleEnvironment G, ASTMetaInfoCa List storedElemTypeRefs = new ArrayList<>(); for (ArrayElement currElem : arrLit.getElements()) { if (currElem instanceof ArrayPadding) { - cache.storeType(currElem, undefinedTypeRef(G)); + cache.storeType(currElem, anyTypeRef(G)); + storedElemTypeRefs.add(anyTypeRef(G)); } else { TypeRef currElemTypeRef = getFinalResultTypeOfArrayElement(G, currElem, Optional.of(storedElemTypeRefs)); diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_FunctionExpression.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_FunctionExpression.java index e0c7caff77..2304a4b2a9 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_FunctionExpression.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_FunctionExpression.java @@ -28,15 +28,20 @@ import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList; import static org.eclipse.xtext.xbase.lib.IteratorExtensions.toIterable; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import org.eclipse.emf.ecore.EObject; import org.eclipse.n4js.n4JS.ArrowFunction; import org.eclipse.n4js.n4JS.Block; +import org.eclipse.n4js.n4JS.CastExpression; import org.eclipse.n4js.n4JS.Expression; import org.eclipse.n4js.n4JS.FormalParameter; import org.eclipse.n4js.n4JS.FunctionExpression; import org.eclipse.n4js.n4JS.IdentifierRef; +import org.eclipse.n4js.n4JS.N4JSASTUtils; import org.eclipse.n4js.ts.typeRefs.DeferredTypeRef; import org.eclipse.n4js.ts.typeRefs.ExistentialTypeRef; import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef; @@ -89,7 +94,13 @@ TypeRef processFunctionExpression(RuleEnvironment G, FunctionExpression funExpr, InferenceContext infCtx, ASTMetaInfoCache cache) { TFunction fun = (TFunction) funExpr.getDefinedType(); // types builder will have created this already - if (!isPoly(funExpr)) { // funExpr has declared types on all fpars and explicitly declared return type + if (fun == null) { + // on hovering fun might be null TODO: investigate + return TypeRefsFactory.eINSTANCE.createUnknownTypeRef(); + } + + if (!isPoly(funExpr)) { + // funExpr has declared types on all fpars and explicitly declared return type // can't use xsemantics here, because it would give us a DeferredTypeRef // return ts.type(G, funExpr).getValue(); FunctionTypeExpression funTE = TypeUtils.createFunctionTypeExpression(null, emptyList(), fun.getFpars(), @@ -261,6 +272,24 @@ private void processReturnType(RuleEnvironment G, ASTMetaInfoCache cache, Infere // introduce new inference variable for (inner) return type InferenceVariable iv = infCtx.newInferenceVariable(); returnTypeRef = TypeUtils.createTypeRef(iv); + + // no return type was declared: + // infer constraint for return type from cast expression if available + List returnExpressions = getReturnExpressions(funExpr); + if (!returnExpressions.isEmpty()) { + List retrs = new ArrayList<>(); + for (Expression re : returnExpressions) { + EObject eob = N4JSASTUtils.skipParenExpressionDownward(re); + if (eob instanceof CastExpression) { + CastExpression ce = (CastExpression) eob; + retrs.add(TypeUtils.copy(ce.getTargetTypeRefNode().getTypeRefInAST())); + } + } + if (!retrs.isEmpty()) { + TypeRef tRef = tsh.createUnionType(G, retrs.toArray(new TypeRef[1])); + infCtx.addConstraint(TypeUtils.createTypeRef(iv), tRef, Variance.CONTRA); + } + } } else { // void returnTypeRef = voidTypeRef(G); @@ -280,9 +309,9 @@ private void processReturnType(RuleEnvironment G, ASTMetaInfoCache cache, Infere * Writes final types to cache */ private void handleOnSolved(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, - FunctionExpression funExpr, - TypeRef expectedTypeRef, FunctionTypeExpression resultTypeRef, + FunctionExpression funExpr, TypeRef expectedTypeRef, FunctionTypeExpression resultTypeRef, Optional> solution) { + Map solution2 = (solution.isPresent()) ? solution.get() : createPseudoSolution(infCtx, anyTypeRef(G)); // sanitize parameter types diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ObjectLiteral.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ObjectLiteral.java index e6d628825e..01541d1d94 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ObjectLiteral.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/PolyProcessor_ObjectLiteral.java @@ -86,7 +86,7 @@ TypeRef processObjectLiteral(RuleEnvironment G, ObjectLiteral objLit, TypeRef ex // quick mode as a performance tweak: boolean haveUsableExpectedType = expectedTypeRef != null && expectedTypeRef.isStructuralTyping(); // TODO // reconsider - boolean quickMode = !haveUsableExpectedType && !TypeUtils.isInferenceVariable(expectedTypeRef); + boolean quickMode = !haveUsableExpectedType && TypeUtils.isProper(expectedTypeRef); List tMembers = new ArrayList<>(); // in standard mode: the following list will contain pairs from property assignments to inference variables @@ -259,15 +259,16 @@ private void linkGetterSetterPairs(InferenceContext infCtx, List * Writes final types to cache */ private void handleOnSolved(RuleEnvironment G, ASTMetaInfoCache cache, InferenceContext infCtx, - ObjectLiteral objLit, - boolean quickMode, List> props2InfVarOrFallbackType, + ObjectLiteral objLit, boolean quickMode, + List> props2InfVarOrFallbackType, Optional> solution) { + for (Pair propPair : props2InfVarOrFallbackType) { PropertyAssignment propAssignm = propPair.getKey(); TStructMember memberInTModule = propAssignm.getDefinedMember(); if (memberInTModule != null) { TypeRef memberType = getMemberType(G, infCtx, solution, quickMode, propPair); - boolean resolveLiteralTypes = (quickMode) + boolean resolveLiteralTypes = (quickMode || !solution.isPresent()) ? // quick mode means we do not have a type expectation, so we handle literal types exactly // as when inferring the implicit type of variables with an initializer expression !N4JSASTUtils.isImmutable(propAssignm) @@ -284,8 +285,7 @@ private void handleOnSolved(RuleEnvironment G, ASTMetaInfoCache cache, Inference } ParameterizedTypeRefStructural resultFinal = TypeUtils.createParameterizedTypeRefStructural(objectType(G), - TypingStrategy.STRUCTURAL, - (TStructuralType) objLit.getDefinedType()); + TypingStrategy.STRUCTURAL, (TStructuralType) objLit.getDefinedType()); resultFinal.setASTNodeOptionalFieldStrategy(OptionalFieldStrategy.FIELDS_AND_ACCESSORS_OPTIONAL); cache.storeType(objLit, resultFinal); diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeProcessor.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeProcessor.java index 14d165f341..b1dd4c6442 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeProcessor.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/postprocessing/TypeProcessor.java @@ -108,6 +108,11 @@ public void typeNode(RuleEnvironment G, EObject node, ASTMetaInfoCache cache, in } } + /** Returns true iff the given expression is a poly expression */ + public boolean isPoly(Expression expr) { + return polyProcessor.isPoly(expr); + } + /** * Infers type of given AST node and stores the result in the given cache. *

    diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSResourceDescription.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSResourceDescription.java index c2aabae30b..fc2a1102cd 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSResourceDescription.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/resource/N4JSResourceDescription.java @@ -22,6 +22,7 @@ import org.apache.log4j.Logger; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.n4js.naming.N4JSImportedNamesAdapter; import org.eclipse.n4js.ts.typeRefs.TypeRef; import org.eclipse.n4js.ts.types.ContainerType; import org.eclipse.n4js.ts.types.TEnum; @@ -145,18 +146,15 @@ public Iterable getImportedNames() { // also all names are collected that cannot be resolved EcoreUtil2.resolveLazyCrossReferences(getResource(), CancelIndicator.NullImpl); - ImportedNamesAdapter adapter = ImportedNamesAdapter.find(getResource()); - Iterable superImportedNames = Collections.emptySet(); - if (adapter != null) { - superImportedNames = adapter.getImportedNames(); - } + N4JSImportedNamesAdapter adapter = (N4JSImportedNamesAdapter) ImportedNamesAdapter + .find(getResource()); // use sorted set to ensure order of items final SortedSet importedNames; - if (superImportedNames != null) { - importedNames = Sets.newTreeSet(superImportedNames); - } else { + if (adapter == null) { importedNames = Sets. newTreeSet(); + } else { + importedNames = adapter.getImportedNames(); } // import our own module name to get a proper change notification Resource resource = getResource(); diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/ComposedMemberInfo.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/ComposedMemberInfo.java index 4658213ca0..0d38a7c5e4 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/ComposedMemberInfo.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/ComposedMemberInfo.java @@ -11,8 +11,10 @@ package org.eclipse.n4js.scoping.members; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -24,8 +26,10 @@ import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.n4js.scoping.members.ComposedMemberInfoBuilder.ToBeComposedMemberInfo; +import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; import org.eclipse.n4js.ts.typeRefs.TypeRef; import org.eclipse.n4js.ts.typeRefs.UnknownTypeRef; +import org.eclipse.n4js.ts.types.GenericType; import org.eclipse.n4js.ts.types.MemberAccessModifier; import org.eclipse.n4js.ts.types.MemberType; import org.eclipse.n4js.ts.types.TField; @@ -33,6 +37,7 @@ import org.eclipse.n4js.ts.types.TMember; import org.eclipse.n4js.ts.types.TMethod; import org.eclipse.n4js.ts.types.TSetter; +import org.eclipse.n4js.ts.types.TypeVariable; import org.eclipse.n4js.ts.types.VoidType; import org.eclipse.n4js.types.utils.TypeUtils; import org.eclipse.n4js.typesystem.N4JSTypeSystem; @@ -85,13 +90,14 @@ public class ComposedMemberInfo { private final boolean hasValidationProblem = false; private MemberAccessModifier accessibilityMin = MemberAccessModifier.PUBLIC; private MemberAccessModifier accessibilityMax = MemberAccessModifier.PRIVATE; + private final Map memberTypeVars = new LinkedHashMap<>(); private final Multimap typeRefsMap = LinkedHashMultimap.create(); private final List typeRefs = new ArrayList<>(); private final List methodTypeRefsVoid = new ArrayList<>(); private final List methodTypeRefsNonVoid = new ArrayList<>(); private final Map typeRef2G = new HashMap<>(); - private final List fParameters = new ArrayList<>(); + private boolean isVariadicButLastFParIsDifferent = false; /** @@ -174,6 +180,7 @@ synchronized private void initMemberAggregate() { RuleEnvironment G = toBeComposedMemberInfo.G; boolean structFieldInitMode = toBeComposedMemberInfo.structFieldInitMode; + handleTypeVars(member, G); lastMType = handleMemberTypes(lastMType, member, structFieldInitMode); handleReadOnlyField(member); handleAccessibility(member); @@ -266,6 +273,18 @@ private void handleAccessibility(TMember member) { accessibilityMin = currAccessibility; } + private void handleTypeVars(TMember member, RuleEnvironment G) { + if (member instanceof GenericType) { + GenericType method = (GenericType) member; + for (TypeVariable tv : method.getTypeVars()) { + TypeVariable tvCopy = TypeUtils.copyIfContained(tv); + ParameterizedTypeRef tvCopyTRef = TypeUtils.createTypeRef(tvCopy); + G.put(tv, tvCopyTRef); + memberTypeVars.put(tv, tvCopy); + } + } + } + private void handleTypeRefLists(TMember member, RuleEnvironment G) { TypeRef typeRef = TypeUtils.getMemberTypeRef(member); TypeRef typeRefSubst = ts.substTypeVariables(G, typeRef); @@ -473,6 +492,12 @@ public boolean hasValidationProblem() { return hasValidationProblem; } + /** Returns all type variables */ + public Collection getTypeVariables() { + initMemberAggregate(); + return memberTypeVars.values(); + } + /** * Returns a list of all return {@link TypeRef}s of the given {@link MemberType}s. If no {@link MemberType} is * given, all {@link TypeRef}s are returned. diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/MethodFactory.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/MethodFactory.java index 09bdf7b60d..97fdb298e0 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/MethodFactory.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/scoping/members/MethodFactory.java @@ -88,6 +88,7 @@ public TMethod create(String name) { TFormalParameter tFPar = currFparDesc.create(); method.getFpars().add(tFPar); } + method.getTypeVars().addAll(cma.getTypeVariables()); return method; } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/N4JSDocumentationProvider.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/N4JSDocumentationProvider.java index 7692abb3bb..98865f70e0 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/N4JSDocumentationProvider.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/tooling/N4JSDocumentationProvider.java @@ -85,7 +85,14 @@ public List getDocumentationNodes(EObject object) { * fix for ASI */ public List getDocumentationNodes(EObject object, boolean enableSpecialASIFix) { - EObject astNode = N4JSASTUtils.getCorrespondingASTNode(object); + EObject astNode = null; + try { + astNode = N4JSASTUtils.getCorrespondingASTNode(object); + } catch (Exception e) { + // Exception can happen in dirty states when retrieving the ast node + logger.warn("Could not find ast node: " + e.getMessage()); + } + // TODO GH-1958 approach for documentation look-up in case of hash mismatch: // if (astNode != null && astNode.eIsProxy()) { // // proxy from TModule back to AST could not be resolved (e.g. reconciliation failed due to hash mismatch) @@ -97,6 +104,7 @@ public List getDocumentationNodes(EObject object, boolean enableSpecialAS // astNode = EcoreUtil.resolve(astNode, tempResSet); // TODO disable types builder & post-processing! // } // } + if (astNode != null && !astNode.eIsProxy()) { final String fileExt = URIUtils.fileExtension(astNode.eResource().getURI()); if (N4JSGlobals.DTS_FILE_EXTENSION.equals(fileExt)) { diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/TypeUtils.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/TypeUtils.java index eecf367af6..c2a70f9e48 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/TypeUtils.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/types/utils/TypeUtils.java @@ -19,6 +19,7 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; +import org.eclipse.n4js.AnnotationDefinition; import org.eclipse.n4js.n4JS.FormalParameter; import org.eclipse.n4js.n4JS.FunctionDefinition; import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope; @@ -44,6 +45,7 @@ import org.eclipse.n4js.ts.types.IdentifiableElement; import org.eclipse.n4js.ts.types.InferenceVariable; import org.eclipse.n4js.ts.types.MemberType; +import org.eclipse.n4js.ts.types.TField; import org.eclipse.n4js.ts.types.TFormalParameter; import org.eclipse.n4js.ts.types.TMember; import org.eclipse.n4js.ts.types.TSetter; @@ -55,10 +57,20 @@ import org.eclipse.n4js.ts.types.TypingStrategy; import org.eclipse.n4js.utils.RecursionGuard; +import com.google.common.base.Stopwatch; + /** * Static utility methods for type and type ref handling, for non-static utility methods see {@link TypeHelper}. */ public class TypeUtils { + // GH-2615 FIXME: evaluate, remove + public static Stopwatch sw0 = Stopwatch.createUnstarted(); + public static Stopwatch sw1 = Stopwatch.createUnstarted(); + public static Stopwatch sw2 = Stopwatch.createUnstarted(); + public static Stopwatch sw3 = Stopwatch.createUnstarted(); + public static Stopwatch sw4 = Stopwatch.createUnstarted(); + public static Stopwatch sw5 = Stopwatch.createUnstarted(); + public static Stopwatch sw6 = Stopwatch.createUnstarted(); /** @see org.eclipse.n4js.ts.types.util.TypeUtils#createTSetter(String, String, TypeRef) */ public static TSetter createTSetter(String name, String fparName, TypeRef fparTypeRef) { @@ -321,33 +333,63 @@ public static boolean isProper(TypeArgument typeRef) { /** @see org.eclipse.n4js.ts.types.util.TypeUtils#isOrContainsType(TypeRef, Type) */ public static boolean isOrContainsType(TypeRef typeRef, Type declaredType) { - return org.eclipse.n4js.ts.types.util.TypeUtils.isOrContainsType(typeRef, declaredType); + try { + // sw0.start(); + return org.eclipse.n4js.ts.types.util.TypeUtils.isOrContainsType(typeRef, declaredType); + } finally { + // sw0.stop(); + } } /** @see org.eclipse.n4js.ts.types.util.TypeUtils#isOrContainsTypeRefOfType(TypeRef, Class) */ public static boolean isOrContainsTypeRefOfType(TypeRef typeRef, final Class typeOfTypeRef) { - return org.eclipse.n4js.ts.types.util.TypeUtils.isOrContainsTypeRefOfType(typeRef, typeOfTypeRef); + try { + // sw1.start(); + return org.eclipse.n4js.ts.types.util.TypeUtils.isOrContainsTypeRefOfType(typeRef, typeOfTypeRef); + } finally { + // sw1.stop(); + } } /** @see org.eclipse.n4js.ts.types.util.TypeUtils#isOrContainsRefToTypeVar(EObject, TypeVariable...) */ public static boolean isOrContainsRefToTypeVar(EObject obj, TypeVariable... typeVars) { - return org.eclipse.n4js.ts.types.util.TypeUtils.isOrContainsRefToTypeVar(obj, typeVars); + try { + // sw2.start(); + return org.eclipse.n4js.ts.types.util.TypeUtils.isOrContainsRefToTypeVar(obj, typeVars); + } finally { + // sw2.stop(); + } } /** @see org.eclipse.n4js.ts.types.util.TypeUtils#isOrContainsRefToInfVar(EObject, InferenceVariable...) */ public static boolean isOrContainsRefToInfVar(EObject obj, InferenceVariable... infVars) { - return org.eclipse.n4js.ts.types.util.TypeUtils.isOrContainsRefToInfVar(obj, infVars); + try { + // sw3.start(); + return org.eclipse.n4js.ts.types.util.TypeUtils.isOrContainsRefToInfVar(obj, infVars); + } finally { + // sw3.stop(); + } } /** @see org.eclipse.n4js.ts.types.util.TypeUtils#getReferencedTypeVars(EObject) */ public static Set getReferencedTypeVars(EObject obj) { - return org.eclipse.n4js.ts.types.util.TypeUtils.getReferencedTypeVars(obj); + try { + // sw4.start(); + return org.eclipse.n4js.ts.types.util.TypeUtils.getReferencedTypeVars(obj); + } finally { + // sw4.stop(); + } } /** @see org.eclipse.n4js.ts.types.util.TypeUtils#getReferencedDeclaredTypes(EObject) */ public static Set getReferencedDeclaredTypes(EObject obj) { - return org.eclipse.n4js.ts.types.util.TypeUtils.getReferencedDeclaredTypes(obj); + try { + // sw5.start(); + return org.eclipse.n4js.ts.types.util.TypeUtils.getReferencedDeclaredTypes(obj); + } finally { + // sw5.stop(); + } } /** @@ -359,8 +401,13 @@ public static boolean forAllTypeRefs(EObject obj, Class t Predicate ignore, Predicate operation, RecursionGuard guard) { - return org.eclipse.n4js.ts.types.util.TypeUtils.forAllTypeRefs(obj, typeRefKind, includeChildren, - followFunctionTypeRefs, ignore, operation, guard); + try { + // sw6.start(); + return org.eclipse.n4js.ts.types.util.TypeUtils.forAllTypeRefs(obj, typeRefKind, includeChildren, + followFunctionTypeRefs, ignore, operation, guard); + } finally { + // sw6.stop(); + } } /** @see org.eclipse.n4js.ts.types.util.TypeUtils#isAccessorPair(TMember, TMember) */ @@ -684,4 +731,33 @@ public static TypeRef wrapIfVariadic(BuiltInTypeScope scope, TypeRef typeRef, Fo } return typeRef; } + + /** + * Returns with {@code true} if the member argument is + *

      + *
    • *NOT* {@link TMember#isOptional() optional} member,
    • + *
    • *NOT* {@link #isInitializedField(TMember) initialized field} and
    • + *
    • *NOT* {@link #isOptionalSetter(TMember) optional setter}.
    • + *
    + * Otherwise returns with {@code false}. + */ + public static boolean isMandatoryField(TMember it) { + return null != it && !it.isOptional() && !isInitializedField(it) && !isOptionalSetter(it); + } + + /** + * Argument is an instance of a {@link TField field} and {@link TField#isHasExpression() has initializer + * expression}. This method is {@code null} safe. + */ + public static boolean isInitializedField(TMember it) { + return (it instanceof TField) ? ((TField) it).isHasExpression() : false; + } + + /** + * Returns {@code true} if the member argument is an instance of a {@link TSetter setter} and has + * {@link AnnotationDefinition#PROVIDES_INITIALZER} annotation. Otherwise returns with {@code false}. + */ + public static boolean isOptionalSetter(TMember it) { + return it instanceof TSetter && AnnotationDefinition.PROVIDES_INITIALZER.hasAnnotation(it); + } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/ExpectedTypeJudgment.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/ExpectedTypeJudgment.java index d688f82360..a94f851873 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/ExpectedTypeJudgment.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/ExpectedTypeJudgment.java @@ -61,6 +61,7 @@ import org.eclipse.n4js.n4JS.N4JSASTUtils; import org.eclipse.n4js.n4JS.NewExpression; import org.eclipse.n4js.n4JS.ParameterizedCallExpression; +import org.eclipse.n4js.n4JS.ParenExpression; import org.eclipse.n4js.n4JS.PostfixExpression; import org.eclipse.n4js.n4JS.PropertyNameValuePair; import org.eclipse.n4js.n4JS.PropertySpread; @@ -488,6 +489,11 @@ public TypeRef caseRelationalExpression(RelationalExpression e) { }// end switch } + @Override + public TypeRef caseParenExpression(ParenExpression e) { + return doSwitch(e.eContainer()); + } + /** * Always returns any. Note that it is not possible to require both sides to have the same type, as e.g., in * {@code Object === any} the concrete types for both sides could be subtypes of {@code Object}. diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/N4JSTypeSystem.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/N4JSTypeSystem.java index 360acd6a7b..e5b9ae1094 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/N4JSTypeSystem.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/N4JSTypeSystem.java @@ -11,6 +11,7 @@ package org.eclipse.n4js.typesystem; import java.util.List; +import java.util.Objects; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; @@ -170,17 +171,52 @@ public Result supertype(RuleEnvironment G, TypeArgument left, TypeArgument right /** Tells if {@code left} is equal to {@code right}. Never returns null. */ public Result equaltype(RuleEnvironment G, TypeArgument left, TypeArgument right) { + return doEqualtype(G, left, right, true); + } + + private Result doEqualtype(RuleEnvironment G, TypeArgument left, TypeArgument right, boolean resolveMsg) { if (subtype(G, left, right).isSuccess() && subtype(G, right, left).isSuccess()) { return Result.success(); } else { return Result.failure( - left.getTypeRefAsString() + " is not equal to " + right.getTypeRefAsString(), false, null); + left.getTypeRefAsString(resolveMsg) + " is not equal to " + right.getTypeRefAsString(resolveMsg), + false, null); } } /** Tells if {@code left} is equal to {@code right}. */ public boolean equaltypeSucceeded(RuleEnvironment G, TypeArgument left, TypeArgument right) { - return equaltype(G, left, right).isSuccess(); + return doEqualtype(G, left, right, false).isSuccess(); + } + + /** + * Tells if {@code left} looks equal to {@code right}. Never returns null. Under-approximation of + * {@link #equaltype(RuleEnvironment, TypeArgument, TypeArgument)}. + * + * Only relies on comparison of types as strings. + */ + // GH-2615 FIXME: evaluate, necessary? + public Result equaltypeApprox(TypeArgument left, TypeArgument right) { + String leftStr = left.getTypeRefAsString(false); + String rightStr = right.getTypeRefAsString(false); + if (leftStr == null && rightStr == null) { + return Result.success(); + } else if (Objects.equals(leftStr, rightStr)) { + return Result.success(); + } + return Result.failure( + left.getTypeRefAsString(false) + " is not equal to " + right.getTypeRefAsString(false), false, + null); + } + + /** + * Tells if {@code left} is equal to {@code right}. Under-approximation of + * {@link #equaltypeSucceeded(RuleEnvironment, TypeArgument, TypeArgument)}. + * + * Only relies on comparison of types as strings. + */ + public boolean equaltypeApproxSucceeded(TypeArgument left, TypeArgument right) { + return equaltypeApprox(left, right).isSuccess(); } /** @@ -589,4 +625,10 @@ public TypeRef createSimplifiedIntersection(List typeRefs, Resource res return null; } } + + /** @see TypeProcessor#isPoly(Expression) */ + public boolean isPoly(Expression expr) { + return typeProcessor.isPoly(expr); + } + } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/SubtypeJudgment.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/SubtypeJudgment.java index 70e17eab95..cac4651a97 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/SubtypeJudgment.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/SubtypeJudgment.java @@ -211,6 +211,13 @@ private Result doApply(RuleEnvironment G, TypeArgument leftArg, TypeArgument rig if (TypeUtils.isNull(left) && !TypeUtils.isUndefined(right)) { return success(); } + if (TypeUtils.isAny(left)) { + if (TypeUtils.isAny(right)) { + return success(); + } else { + return failure(); + } + } // ExistentialTypeRef if (left instanceof ExistentialTypeRef) { diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/TypeJudgment.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/TypeJudgment.java index e75f34bbac..fd967902cb 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/TypeJudgment.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/TypeJudgment.java @@ -53,6 +53,7 @@ import org.eclipse.emf.ecore.EPackage; import org.eclipse.n4js.AnnotationDefinition; import org.eclipse.n4js.compileTime.CompileTimeValue; +import org.eclipse.n4js.compileTime.CompileTimeValue.ValueNumber; import org.eclipse.n4js.flowgraphs.dataflow.guards.GuardAssertion; import org.eclipse.n4js.flowgraphs.dataflow.guards.InstanceofGuard; import org.eclipse.n4js.n4JS.AdditiveExpression; @@ -166,6 +167,7 @@ import org.eclipse.n4js.ts.types.util.TypesSwitch; import org.eclipse.n4js.types.utils.TypeUtils; import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; import org.eclipse.n4js.typesystem.utils.TypeSystemHelper.Callable; import org.eclipse.n4js.typesystem.utils.TypeSystemHelper.Newable; import org.eclipse.n4js.utils.DestructureHelper; @@ -929,10 +931,23 @@ public TypeRef caseIndexedAccessExpression(IndexedAccessExpression expr) { final RuleEnvironment G2 = wrap(G); typeSystemHelper.addSubstitutions(G2, targetTypeRef); setThisBinding(G2, targetTypeRef); - final TypeRef elementTypeRef = targetIsLiteralOfStringBasedEnum - ? stringType(G).getElementType() - : targetDeclType.getElementType(); - T = ts.substTypeVariables(G2, elementTypeRef); + + int n = RuleEnvironmentExtensions.getArrayNNumber(G2, targetDeclType); + int idx = Integer.MAX_VALUE; + if (n > 0 && indexValue.isValid() && indexValue instanceof ValueNumber) { + ValueNumber valueNumber = (ValueNumber) indexValue; + idx = valueNumber.getValue().intValue(); + } + if (idx <= n && idx < targetTypeRef.getTypeArgsWithDefaults().size()) { + TypeArgument typeArgument = targetTypeRef.getTypeArgsWithDefaults().get(idx); + T = ts.substTypeVariables(G2, TypeUtils.convertTypeArgToRef(typeArgument)); + } else { + final TypeRef elementTypeRef = targetIsLiteralOfStringBasedEnum + ? stringType(G).getElementType() + : targetDeclType.getElementType(); + T = ts.substTypeVariables(G2, elementTypeRef); + } + } } else if (memberName != null) { // indexing via constant computed-name, sub-cases: static or instance member, for the latter diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/BoundSet.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/BoundSet.java index 7347bc3244..6890b8a834 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/BoundSet.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/BoundSet.java @@ -32,12 +32,12 @@ import org.eclipse.n4js.ts.types.InferenceVariable; import org.eclipse.n4js.ts.types.Type; import org.eclipse.n4js.ts.types.TypeVariable; -import org.eclipse.n4js.ts.types.util.Variance; import org.eclipse.n4js.types.utils.TypeUtils; import org.eclipse.n4js.typesystem.N4JSTypeSystem; import org.eclipse.n4js.typesystem.utils.RuleEnvironment; import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; +import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableMap; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.SetMultimap; @@ -58,9 +58,9 @@ private static final boolean DEBUG = InferenceContext.DEBUG; private final InferenceContext ic; - private final RuleEnvironment G; private final N4JSTypeSystem ts; + private final TypeBoundCombiner tbc; /** Bounds within this bound set, stored per inference variable. */ private final SetMultimap boundsPerInfVar = LinkedHashMultimap.create(); @@ -89,6 +89,7 @@ public BoundSet(InferenceContext ic, RuleEnvironment G, N4JSTypeSystem ts) { this.ic = ic; this.G = G; this.ts = ts; + this.tbc = new TypeBoundCombiner(G, ts); } private BoundSet(BoundSet other) { @@ -208,7 +209,7 @@ private boolean internal_addBound(TypeBound bound) { * For internal use only! Bounds cannot really be removed from a {@code BoundSet}; this is only provided for * performance reasons to allow removal of type bounds that do no longer have any effect. Use with care. */ - private void removeBound(TypeBound bound) { + void removeBound(TypeBound bound) { boundsPerInfVar.remove(bound.left, bound); incorporatedBounds.remove(bound); } @@ -332,212 +333,124 @@ public void dumpInstantiations() { * {@link #combine(TypeBound, TypeBound)}, which is then reduced. */ public void incorporate() { + incorporateInstantiations(new ArrayList<>(boundsPerInfVar.values())); + + for (InferenceVariable infVar : new ArrayList<>(boundsPerInfVar.keySet())) { + ArrayList bounds = new ArrayList<>(boundsPerInfVar.get(infVar)); + incorporateBounds(bounds, false); + } + incorporateFixpoint(); + } + + public void incorporateFixpoint() { boolean updated; do { - updated = false; - final TypeBound[] bounds = getAllBounds(); - final int len = bounds.length; - if (len < 2) { - return; - } - for (int i = 0; i < len; ++i) { - final TypeBound boundI = bounds[i]; - final boolean isIncorporatedI = incorporatedBounds.contains(boundI); - for (int j = i + 1; j < len; ++j) { - final TypeBound boundJ = bounds[j]; - final boolean isIncorporatedJ = incorporatedBounds.contains(boundJ); - final boolean bothAlreadyIncorporated = (isIncorporatedI && isIncorporatedJ); - if (!bothAlreadyIncorporated) { - if (DEBUG) { - log("--- incorporating: " + boundI + " | " + boundJ); - } - final TypeConstraint newConstraint = combine(boundI, boundJ); - if (newConstraint != null) { - // this is where incorporation triggers reduction (of the new constraint) - // reduction may in turn trigger incorporation (provided it adds bounds) - updated |= ic.reducer.reduce(newConstraint); - } - if (ic.isDoomed()) { - return; - } - } - } - if (!isIncorporatedI) { - incorporatedBounds.add(boundI); - } - } + // PERFORMANCE: incorporate instantiations at once first reduces computation + incorporateInstantiations(new ArrayList<>(boundsPerInfVar.values())); + updated = incorporateBounds(new ArrayList<>(boundsPerInfVar.values()), true); } while (updated); } + public int counter = 0; + public Stopwatch sw = Stopwatch.createUnstarted(); + /** - * In terms of JLS8, this method embodies the implication rules listed in Sec. 18.3.1 (the other implication rules - * in JLS8 take as input capture conversion constraints). + * All instantiations are incorporated at once instead of one at a time. This reduces calls to + * {@link Reducer#reduce(Iterable)} drastically. */ - private TypeConstraint combine(TypeBound boundI, TypeBound boundJ) { - switch (boundI.variance) { - case INV: - switch (boundJ.variance) { - case INV: - return combineInvInv(boundI, boundJ); - case CO: - case CONTRA: - return combineInvVar(boundI, boundJ); - } - break; - case CO: - switch (boundJ.variance) { - case INV: - return combineInvVar(boundJ, boundI); // note: reversed arguments! - case CONTRA: - return combineContraCo(boundJ, boundI); // note: reversed arguments! - case CO: - return combineBothCoOrBothContra(boundI, boundJ); + private void incorporateInstantiations(ArrayList bounds) { + final int len = bounds.size(); + if (len < 2) { + return; + } + + for (int j = 0; j < len; ++j) { + final TypeBound boundJ = bounds.get(j); + + List mutualInfVars = new ArrayList<>(); + for (InferenceVariable refInfVar : boundJ.referencedInfVars) { + if (instantiations.containsKey(refInfVar)) { + mutualInfVars.add(refInfVar); + } } - break; - case CONTRA: - switch (boundJ.variance) { - case INV: - return combineInvVar(boundJ, boundI); // note: reversed arguments! - case CO: - return combineContraCo(boundI, boundJ); - case CONTRA: - return combineBothCoOrBothContra(boundI, boundJ); + + if (!mutualInfVars.isEmpty()) { + TypeRef rightJ = boundJ.right; + for (InferenceVariable mutVar : mutualInfVars) { + final TypeRef boundIRight = instantiations.get(mutVar); + // (5) `α = S` (where S is proper) and `β Φ T` implies `β Φ T[α:=U]` + rightJ = substituteInferenceVariable(rightJ, mutVar, boundIRight); + } + + removeBound(boundJ); // performance tweak: avoid unnecessary growth of bounds + ic.reducer.reduce(new TypeConstraint(typeRef(boundJ.left), rightJ, boundJ.variance)); } } - throw new IllegalStateException("unreachable"); } - /** - * Case: both bounds are equalities. - */ - private TypeConstraint combineInvInv(TypeBound boundS, TypeBound boundT) { - if (boundS.left == boundT.left) { - // `α = S` and `α = T` implies `S = T` - return new TypeConstraint(boundS.right, boundT.right, INV); - } - // inference variables are different - // -> try to substitute a proper RHS in the RHS of the other bound, to make it a proper type itself - TypeConstraint newConstraint = combineInvInvWithProperType(boundS, boundT); - if (newConstraint != null) { - return newConstraint; - } - newConstraint = combineInvInvWithProperType(boundT, boundS); - if (newConstraint != null) { - return newConstraint; + private boolean incorporateBounds(ArrayList bounds, boolean addToIncorporated) { + boolean updated = false; + final int len = bounds.size(); + if (len < 2) { + return updated; } - return null; - } - /** - * Given two type bounds `α = U` and `β = T` with α ≠ β, will return a new constraint `β = T[α:=U]` if - *
      - *
    • U is proper, and - *
    • T mentions α. - *
    - * Otherwise, null is returned. - */ - private TypeConstraint combineInvInvWithProperType(TypeBound boundWithProperRHS, TypeBound boundOther) { - final InferenceVariable alpha = boundWithProperRHS.left; - final TypeRef U = boundWithProperRHS.right; - final TypeRef T = boundOther.right; - if (TypeUtils.isProper(U) && TypeUtils.getReferencedTypeVars(T).contains(alpha)) { - final InferenceVariable beta = boundOther.left; - final TypeRef T_subst = substituteInferenceVariable(T, alpha, U); // returns T[α:=U] - removeBound(boundOther); // performance tweak: avoid unnecessary growth of bounds - return new TypeConstraint(typeRef(beta), T_subst, INV); + int knownUntilIdx = 0; + while (knownUntilIdx < bounds.size() && incorporatedBounds.contains(bounds.get(knownUntilIdx))) { + knownUntilIdx++; } - return null; - } - /** - * Case: first bound is an equality, while the second isn't: `α = S` and `β Φ T` with Φ either {@code <:} or - * {@code :>}. - */ - private TypeConstraint combineInvVar(TypeBound boundS, TypeBound boundT) { - final InferenceVariable alpha = boundS.left; - final InferenceVariable beta = boundT.left; - final TypeRef S = boundS.right; - final TypeRef T = boundT.right; - final Variance Phi = boundT.variance; - if (alpha == beta) { - // (1) `α = S` and `α Φ T` implies `S Φ T` - return new TypeConstraint(S, T, Phi); - } - // both bounds have different inference variables, i.e. α != β - if (alpha == T.getDeclaredType()) { - // (2) `α = S` and `β Φ α` implies `β Φ S` - return new TypeConstraint(typeRef(beta), S, Phi); - } - if (TypeUtils.isInferenceVariable(S)) { - // first bound is of the form `α = γ` (with γ being another inference variable) - final InferenceVariable gamma = (InferenceVariable) S.getDeclaredType(); - if (gamma == beta) { - // (3) `α = β` and `β Φ T` implies `α Φ T` - return new TypeConstraint(typeRef(alpha), T, Phi); + for (int i = 0; i < len; ++i) { + final TypeBound boundI = bounds.get(i); + final boolean isIncorporatedI = incorporatedBounds.contains(boundI); + for (int j = Math.max(knownUntilIdx, i + 1); j < len; ++j) { + counter++; + final TypeBound boundJ = bounds.get(j); + final boolean isIncorporatedJ = incorporatedBounds.contains(boundJ); + final boolean bothAlreadyIncorporated = (isIncorporatedI && isIncorporatedJ); + if (!bothAlreadyIncorporated) { + if (DEBUG) { + log("--- incorporating: " + boundI + " | " + boundJ); + } + sw.start(); + final TypeConstraint newConstraint = combine(boundI, boundJ); + sw.stop(); + if (newConstraint != null) { + // this is where incorporation triggers reduction (of the new constraint) + // reduction may in turn trigger incorporation (provided it adds bounds) + updated |= ic.reducer.reduce(newConstraint); + } + if (ic.isDoomed()) { + return false; + } + } } - if (gamma == T.getDeclaredType()) { - // (4) `α = γ` and `β Φ γ` implies `β Φ α` - return new TypeConstraint(typeRef(beta), typeRef(alpha), Phi); + if (addToIncorporated && !isIncorporatedI) { + incorporatedBounds.add(boundI); } } - // so, S is not an inference variable - if (TypeUtils.isProper(S) && TypeUtils.getReferencedTypeVars(T).contains(alpha)) { - // (5) `α = S` (where S is proper) and `β Φ T` implies `β Φ T[α:=U]` - final TypeRef T_subst = substituteInferenceVariable(T, alpha, S); // returns T[α:=U] - removeBound(boundT); // performance tweak: avoid unnecessary growth of bounds - return new TypeConstraint(typeRef(beta), T_subst, Phi); - } - return null; + + return updated; } - /** - * Case: `α :> S` and `β <: T`. - */ - private TypeConstraint combineContraCo(TypeBound boundS, TypeBound boundT) { - final InferenceVariable alpha = boundS.left; - final InferenceVariable beta = boundT.left; - final TypeRef S = boundS.right; - final TypeRef T = boundT.right; - if (alpha == beta) { - // transitivity, using LHS as bridge: - // α :> S and α <: T implies S <: T - return new TypeConstraint(S, T, CO); - } - // so, α and β are different - if (TypeUtils.isInferenceVariable(S)) { - final InferenceVariable gamma = (InferenceVariable) S.getDeclaredType(); - if (gamma == T.getDeclaredType()) { - // transitivity, using RHS as bridge: - // α :> γ and β <: γ implies α :> β - return new TypeConstraint(typeRef(alpha), typeRef(beta), CONTRA); - } - } - return null; + private TypeConstraint combine(TypeBound boundI, TypeBound boundJ) { + return tbc.combine(boundI, boundJ, this); } /** - * Case: inequalities of same direction, i.e. - *
      - *
    • `α <: S` and `β <: T` or - *
    • `α :> S` and `β :> T`. - *
    + * Side effect free, i.e. no bounds will be removed from this {@link #BoundSet} (as an optimization) when calling + * this method. */ - private TypeConstraint combineBothCoOrBothContra(TypeBound boundS, TypeBound boundT) { - final InferenceVariable alpha = boundS.left; - final InferenceVariable beta = boundT.left; - final TypeRef S = boundS.right; - final TypeRef T = boundT.right; - if (alpha == T.getDeclaredType()) { - // α <: S and β <: α implies β <: S - // α :> S and β :> α implies β :> S - return new TypeConstraint(typeRef(beta), S, boundS.variance); - } - if (S.getDeclaredType() == beta) { - // α <: β and β <: T implies α <: T - // α :> β and β :> T implies α :> T - return new TypeConstraint(typeRef(alpha), T, boundS.variance); + List combineAll(TypeBound newBound) { + List result = new ArrayList<>(); + Set bounds = ic.currentBounds.getBounds(newBound.left); + for (TypeBound tBound : bounds) { + TypeConstraint newConstraint = tbc.combine(newBound, tBound, null); + if (newConstraint != null) { + result.add(newConstraint); + } } - return null; + return result; } private static TypeRef typeRef(InferenceVariable infVar) { diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/InferenceContext.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/InferenceContext.java index 156d04583a..3e429e77b6 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/InferenceContext.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/InferenceContext.java @@ -26,6 +26,8 @@ import java.util.stream.Stream; import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.n4js.smith.Measurement; +import org.eclipse.n4js.smith.N4JSDataCollectors; import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef; import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef; import org.eclipse.n4js.ts.typeRefs.TypeArgument; @@ -372,6 +374,12 @@ public void addConstraint(int idx, TypeConstraint constraint) { * {@link #isPromisingPartialSolution(InferenceVariable, TypeRef)} might be helpful in some cases. */ public Map solve() { + try (Measurement m = N4JSDataCollectors.dcInferenceContextSolve.getMeasurement()) { + return doSolve(); + } + } + + private Map doSolve() { if (isSolved) { return solution; } @@ -393,7 +401,9 @@ public Map solve() { if (DEBUG) { log("****** Reduction"); } - reducer.reduce(constraints); + try (Measurement m = N4JSDataCollectors.dcInferenceContextReduce.getMeasurement()) { + reducer.reduce(constraints); + } // clearing the list of constraints is ok given their information has been transferred to the bound set, // to which bounds are added but never removed. constraints.clear(); @@ -405,7 +415,9 @@ public Map solve() { log("****** Incorporation"); } if (!isDoomed()) { - currentBounds.incorporate(); + try (Measurement m = N4JSDataCollectors.dcInferenceContextIncorporate.getMeasurement()) { + currentBounds.incorporate(); + } } // --------------------------------------------------------------------------- @@ -414,13 +426,15 @@ public Map solve() { if (DEBUG) { log("****** Resolution"); } - final boolean success = resolve(); - if (DEBUG) { - if (!success) { - log("NO SOLUTION FOUND"); - } else { - log("SOLUTION:"); - currentBounds.dumpInstantiations(); + try (Measurement m = N4JSDataCollectors.dcInferenceContextResolve.getMeasurement()) { + final boolean success = resolve(); + if (DEBUG) { + if (!success) { + log("NO SOLUTION FOUND"); + } else { + log("SOLUTION:"); + currentBounds.dumpInstantiations(); + } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/Reducer.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/Reducer.java index a5a870cc34..f6bdd2cecd 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/Reducer.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/Reducer.java @@ -13,15 +13,20 @@ import static org.eclipse.n4js.ts.types.util.Variance.CO; import static org.eclipse.n4js.ts.types.util.Variance.CONTRA; import static org.eclipse.n4js.ts.types.util.Variance.INV; +import static org.eclipse.n4js.types.utils.TypeUtils.isInferenceVariable; import static org.eclipse.n4js.typesystem.constraints.Reducer.BooleanOp.CONJUNCTION; import static org.eclipse.n4js.typesystem.constraints.Reducer.BooleanOp.DISJUNCTION; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.isAnyDynamic; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.isObjectStructural; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; +import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.ts.typeRefs.BoundThisTypeRef; import org.eclipse.n4js.ts.typeRefs.ComposedTypeRef; import org.eclipse.n4js.ts.typeRefs.ExistentialTypeRef; import org.eclipse.n4js.ts.typeRefs.FunctionTypeExprOrRef; @@ -36,7 +41,6 @@ import org.eclipse.n4js.ts.typeRefs.Wildcard; import org.eclipse.n4js.ts.types.ContainerType; import org.eclipse.n4js.ts.types.InferenceVariable; -import org.eclipse.n4js.ts.types.PrimitiveType; import org.eclipse.n4js.ts.types.TClassifier; import org.eclipse.n4js.ts.types.TFormalParameter; import org.eclipse.n4js.ts.types.TMember; @@ -79,6 +83,12 @@ private final TypeSystemHelper tsh; private final DeclMergingHelper declMergingHelper; + /** + * Rational: During first reduction, constraints are allowed to fail. In a second try new bounds or instantiations + * might help to reduce the before failed constraint. + */ + private boolean firstReduction; + enum BooleanOp { CONJUNCTION, DISJUNCTION } @@ -133,9 +143,23 @@ private boolean giveUp(EObject left, EObject right, Variance variance) { * @return true iff new bounds were added */ public boolean reduce(Iterable constraints) { + firstReduction = true; boolean wasAdded = false; + List tryAgain = new ArrayList<>(); for (TypeConstraint constraint : constraints) { - wasAdded |= reduce(constraint); + boolean cWasAdded = reduce(constraint); + wasAdded |= cWasAdded; + if (ic.isDoomed()) { + break; + } + if (!cWasAdded) { + tryAgain.add(constraint); + } + } + firstReduction = false; + for (TypeConstraint constraint : tryAgain) { + boolean cWasAdded = reduce(constraint); + wasAdded |= cWasAdded; if (ic.isDoomed()) { break; } @@ -241,6 +265,9 @@ private boolean reduce(TypeRef left, List rights, Variance variance, Bo } else if (rightsSize == 1) { return reduce(left, rights.get(0), variance); } else { + if (firstReduction) { + return false; + } // preparation: // if the left side is a ComposedTypeRef that would lead to a conjunction, we have to tear it apart // first to avoid incorrect results (for example, A|B <: [A,B,C] with operator DISJUNCTION must be @@ -257,70 +284,31 @@ private boolean reduce(TypeRef left, List rights, Variance variance, Bo // choose the "most promising" of the disjoint constraints and continue with that (and simply ignore the // other possible paths) int idx = -1; - if (idx == -1 && left instanceof FunctionTypeExprOrRef) { - // choose first function type (except those for which it is obvious they cannot match) + boolean isFunTypeExprOrRef = left instanceof FunctionTypeExprOrRef; + boolean isParaTypeRef = left instanceof ParameterizedTypeRef && !isInferenceVariable(left); + if (isFunTypeExprOrRef || isParaTypeRef) { + List potIdx = new ArrayList<>(); for (int i = 0; i < rightsSize; i++) { - final TypeRef currElem = rights.get(i); - if (currElem instanceof FunctionTypeExprOrRef) { - final FunctionTypeExprOrRef leftCasted = (FunctionTypeExprOrRef) left; - final FunctionTypeExprOrRef currElemCasted = (FunctionTypeExprOrRef) currElem; - final boolean mightMatch = (variance == CO && mightBeSubtypeOf(leftCasted, currElemCasted)) - || (variance == CONTRA && mightBeSubtypeOf(currElemCasted, leftCasted)) - || (variance == INV && mightBeSubtypeOf(leftCasted, currElemCasted) - && mightBeSubtypeOf(currElemCasted, leftCasted)); - if (mightMatch) { - idx = i; - break; - } + final TypeRef currRight = rights.get(i); + TypeRef subType = variance == CONTRA ? currRight : left; + TypeRef superType = variance == CONTRA ? left : currRight; + if (mightBeSubtypeOf(subType, superType)) { + potIdx.add(i); } } - } - if (idx == -1 && left instanceof ParameterizedTypeRef && !TypeUtils.isInferenceVariable(left)) { - final Type leftDecl = left.getDeclaredType(); - if (idx == -1 && leftDecl != null) { - // choose first matching declared type - for (int i = 0; i < rightsSize; i++) { - final TypeRef currElem = rights.get(i); - if (leftDecl == currElem.getDeclaredType()) { - idx = i; - break; - } - } - } - if (idx == -1 && leftDecl instanceof PrimitiveType) { - // choose first naked inference variable (if any) - // (note: same as below, but has higher priority for primitive types than next heuristic) - idx = chooseFirstInferenceVariable(rights); - } - if (idx == -1 && variance == CO && leftDecl instanceof ContainerType) { - // choose first supertype of left - final List superTypesOfLeft = AllSuperTypesCollector - .collect((ContainerType) leftDecl, declMergingHelper); - for (int i = 0; i < rightsSize; i++) { - final TypeRef currElem = rights.get(i); - final Type currElemDecl = currElem.getDeclaredType(); - if (currElemDecl != null && superTypesOfLeft.contains(currElemDecl)) { - idx = i; - break; - } - } - } - if (idx == -1 && variance == CONTRA && leftDecl != null) { - // choose first subtype of left - for (int i = 0; i < rightsSize; i++) { - final TypeRef currElem = rights.get(i); - final Type currElemDecl = currElem.getDeclaredType(); - if (currElemDecl instanceof ContainerType) { - // TODO improve performance by using a super class iterator or super interfaces iterator - // depending on type of leftDecl - final List superTypesOfCurrElem = AllSuperTypesCollector - .collect((ContainerType) currElemDecl, declMergingHelper); - if (superTypesOfCurrElem.contains(leftDecl)) { - idx = i; - break; - } + if (potIdx.size() == 1) { + idx = potIdx.get(0); + } else if (potIdx.size() > 1) { + int bestMatchIdx = 0; + int bestMatchCnt = 0; + for (int i : potIdx) { + int currMatchCnt = computeMatchCount(left, rights.get(i), variance); + if (currMatchCnt > bestMatchCnt) { + bestMatchIdx = i; + bestMatchCnt = currMatchCnt; } } + idx = bestMatchIdx; } } if (idx == -1) { @@ -352,11 +340,107 @@ private boolean reduce(TypeRef left, List rights, Variance variance, Bo } } + private int computeMatchCount(TypeRef left, TypeRef right, Variance variance) { + int matchCount = 1000; + Type leftDT = left.getDeclaredType(); + Type rightDT = right.getDeclaredType(); + + if (leftDT != null && leftDT == rightDT) { + matchCount += 1000; + + if (leftDT.isGeneric()) { + EList lTArgs = left.getTypeArgsWithDefaults(); + EList rTArgs = right.getTypeArgsWithDefaults(); + if (lTArgs.size() == rTArgs.size()) { + matchCount += 100; + + for (int i = 0; i < lTArgs.size(); i++) { + if (mightSufficeExistingBounds(lTArgs.get(i), rTArgs.get(i), variance)) { + matchCount += 10; + } + } + } + } + return matchCount; + } + + if (variance == CO && rightDT != null && leftDT instanceof ContainerType) { + // choose first supertype of left + ContainerType lCT = (ContainerType) leftDT; + List lSTs = AllSuperTypesCollector.collect(lCT, declMergingHelper); + for (TClassifier leftSuperType : lSTs) { + if (leftSuperType == rightDT) { + return matchCount; + } + matchCount--; + } + } + if (variance == CONTRA && leftDT != null && rightDT instanceof ContainerType) { + // choose first subtype of left + // TODO improve performance by using a super class iterator or super interfaces + // iterator depending on type of leftDecl + ContainerType rightCT = (ContainerType) rightDT; + List rSTs = AllSuperTypesCollector.collect(rightCT, declMergingHelper); + for (TClassifier rightSuperType : rSTs) { + if (rightSuperType == leftDT) { + return matchCount; + } + matchCount--; + } + } + if (left instanceof FunctionTypeExprOrRef && right instanceof FunctionTypeExprOrRef) { + return 100; + } + if (isObjectStructural(G, left) && isObjectStructural(G, right)) { + return 100; + } + return 0; + } + + private boolean mightSufficeExistingBounds(TypeArgument left, TypeArgument right, Variance variance) { + if (!(left instanceof TypeRef) || !isInferenceVariable((TypeRef) left)) { + if (!(right instanceof TypeRef) || !isInferenceVariable((TypeRef) right)) { + return false; + } + TypeArgument tmp = left; + left = right; + right = tmp; + variance = variance.inverse(); + } + + if (left instanceof TypeRef && isInferenceVariable((TypeRef) left) && right instanceof TypeRef) { + Type lDT = left.getDeclaredType(); + if (lDT instanceof InferenceVariable) { + InferenceVariable lInfVar = (InferenceVariable) lDT; + TypeRef rTR = (TypeRef) right; + TypeBound newTypeBound = new TypeBound(lInfVar, rTR, variance); + List newConstraints = ic.currentBounds.combineAll(newTypeBound); + for (TypeConstraint newConstraint : newConstraints) { + if (newConstraint.left instanceof TypeRef && newConstraint.right instanceof TypeRef) { + TypeRef lTRef = (TypeRef) newConstraint.left; + TypeRef rTRef = (TypeRef) newConstraint.right; + if (newConstraint.variance == CONTRA) { + if (!mightBeSubtypeOf(rTRef, lTRef)) { + return false; + } + } else { + if (!mightBeSubtypeOf(lTRef, rTRef)) { + return false; + } + } + } + } + return true; + } + } + return false; + } + private final int chooseFirstInferenceVariable(List typeRefs) { final int typeRefsSize = typeRefs.size(); for (int i = 0; i < typeRefsSize; i++) { final TypeRef currTypeRef = typeRefs.get(i); - if (TypeUtils.isInferenceVariable(currTypeRef)) { + if (isInferenceVariable(currTypeRef)) { return i; } } @@ -381,8 +465,8 @@ private boolean reduceTypeRef(TypeRef left, TypeRef right, Variance variance) { return reduceProper(left, right, variance); } - final boolean isLeftInfVar = TypeUtils.isInferenceVariable(left); - final boolean isRightInfVar = TypeUtils.isInferenceVariable(right); + final boolean isLeftInfVar = isInferenceVariable(left); + final boolean isRightInfVar = isInferenceVariable(right); if (isLeftInfVar || isRightInfVar) { if (isLeftInfVar) { return addBound((InferenceVariable) left.getDeclaredType(), right, variance); @@ -391,11 +475,21 @@ private boolean reduceTypeRef(TypeRef left, TypeRef right, Variance variance) { } } - final boolean isLeftStructural = left.isUseSiteStructuralTyping() || left.isDefSiteStructuralTyping(); - final boolean isRightStructural = right.isUseSiteStructuralTyping() || right.isDefSiteStructuralTyping(); - if ((isLeftStructural && (variance == CONTRA || variance == INV)) - || (isRightStructural && (variance == CO || variance == INV))) { - return reduceStructuralTypeRef(left, right, variance); + // top and bottom types, including the pseudo-bottom type 'null' + // (NOTE: doing this up-front here instead of in method #applyParameterizedTypeRef() + // simplifies the handling of other special cases) + boolean isBottomType = (variance == CONTRA ? right : left).isBottomType(); + boolean isTopType = (variance == CONTRA ? left : right).isTopType(); + if (isBottomType || isTopType) { + return true; + } + boolean isNull = TypeUtils.isNull(variance == CONTRA ? right : left); + boolean isUndefined = TypeUtils.isUndefined(variance == CONTRA ? left : right); + if (isNull && !isUndefined) { + return true; + } + if (isAnyDynamic(G, left) || isAnyDynamic(G, right)) { + return true; } // note: one side might still be structural, but we can ignore this // (e.g. given ⟨ S <: N ⟩ with S being structural, N nominal, we have a plain nominal subtype relation) @@ -407,6 +501,13 @@ private boolean reduceTypeRef(TypeRef left, TypeRef right, Variance variance) { return reduceComposedTypeRef(left, (ComposedTypeRef) right, variance); } + final boolean isLeftStructural = left.isUseSiteStructuralTyping() || left.isDefSiteStructuralTyping(); + final boolean isRightStructural = right.isUseSiteStructuralTyping() || right.isDefSiteStructuralTyping(); + if ((isLeftStructural && (variance == CONTRA || variance == INV)) + || (isRightStructural && (variance == CO || variance == INV))) { + return reduceStructuralTypeRef(left, right, variance); + } + if (left instanceof TypeTypeRef && right instanceof TypeTypeRef) { return reduceTypeTypeRef((TypeTypeRef) left, (TypeTypeRef) right, variance); } else if (left instanceof FunctionTypeExprOrRef && right instanceof FunctionTypeExprOrRef) { @@ -846,13 +947,20 @@ private boolean reduceStructuralTypeRef(TypeRef left, TypeRef right, Variance va // in case a call signature is missing on the left side, it is ok // if the left side is itself a function reduceFunctionTypeExprOrRef((FunctionTypeExpression) left, rightTypeRef, variance); - } + } else - // ignore missing members - // (Note: we're ignoring this altogether, here. We could check if the existing member is optional and - // otherwise add bound FALSE, but this is not our job. There are other validations checking that and - // commencing with type inference here produces better error messages.) - continue; + // Note: There are also other validations checking that and produce better error messages. + if (variance == CO && r != null && !TypeUtils.isMandatoryField(r)) { + // check if the existing member is optional + continue; + } else if (variance == CO && right instanceof BoundThisTypeRef) { + // check if the existing member is quasi-optional due to being used as argument for @Spec + // constructor. + continue; + } else { + // otherwise add bound FALSE. + return giveUp(l, r, variance); + } } final List constraints = new ArrayList<>(); switch (variance) { @@ -927,7 +1035,7 @@ private boolean isSubtypeOf(TypeRef left, TypeRef right, Variance variance) { throw new IllegalStateException("unreachable"); // actually unreachable, each case above returns } - private boolean mightBeSubtypeOf(FunctionTypeExprOrRef left, FunctionTypeExprOrRef right) { + private boolean mightBeSubtypeOf(TypeRef left, TypeRef right) { // step 1: replace all inference variables by UnknownTypeRef final TypeRef unknown = TypeRefsFactory.eINSTANCE.createUnknownTypeRef(); final RuleEnvironment G_temp = RuleEnvironmentExtensions.newRuleEnvironment(G); diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/TypeBound.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/TypeBound.java index 79bd630bb8..78d298ecae 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/TypeBound.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/TypeBound.java @@ -10,6 +10,12 @@ */ package org.eclipse.n4js.typesystem.constraints; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; +import static org.eclipse.xtext.xbase.lib.IterableExtensions.toSet; + +import java.util.Collections; +import java.util.Set; + import org.eclipse.n4js.ts.typeRefs.TypeArgument; import org.eclipse.n4js.ts.typeRefs.TypeRef; import org.eclipse.n4js.ts.types.InferenceVariable; @@ -26,24 +32,32 @@ public final InferenceVariable left; public final TypeRef right; public final Variance variance; + public final Set referencedInfVars; - private Integer hashCode = null; + private final int hashCode; /** * Creates an instance. */ public TypeBound(InferenceVariable left, TypeRef right, Variance variance) { + this(left, right, variance, toSet(filter(TypeUtils.getReferencedTypeVars(right), InferenceVariable.class))); + } + + /** + * Creates an instance. + */ + public TypeBound(InferenceVariable left, TypeRef right, Variance variance, + Set referencedInfVars) { this.left = left; this.right = right; this.variance = variance; + this.referencedInfVars = Collections.unmodifiableSet(referencedInfVars); + this.hashCode = this.toString().hashCode(); // TODO find better way to compute hash code } @Override public int hashCode() { - if (hashCode == null) { - hashCode = this.toString().hashCode(); // TODO find better way to compute hash code - } - return hashCode.intValue(); + return hashCode; } @Override @@ -82,7 +96,7 @@ public boolean isTrivial() { */ public TypeBound sanitizeRawTypeRef() { if (TypeUtils.isRawTypeRef(right)) { - final TypeBound cpy = new TypeBound(left, TypeUtils.copy(right), variance); + final TypeBound cpy = new TypeBound(left, TypeUtils.copy(right), variance, referencedInfVars); TypeUtils.sanitizeRawTypeRef(cpy.right); return cpy; } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/TypeBoundCombiner.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/TypeBoundCombiner.java new file mode 100644 index 0000000000..ccb4b5f1a3 --- /dev/null +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/constraints/TypeBoundCombiner.java @@ -0,0 +1,256 @@ +/** + * 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.typesystem.constraints; + +import static org.eclipse.n4js.ts.types.util.Variance.CO; +import static org.eclipse.n4js.ts.types.util.Variance.CONTRA; +import static org.eclipse.n4js.ts.types.util.Variance.INV; + +import java.util.HashMap; +import java.util.Set; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.n4js.ts.typeRefs.TypeArgument; +import org.eclipse.n4js.ts.typeRefs.TypeRef; +import org.eclipse.n4js.ts.types.InferenceVariable; +import org.eclipse.n4js.ts.types.TypeVariable; +import org.eclipse.n4js.ts.types.util.Variance; +import org.eclipse.n4js.types.utils.TypeUtils; +import org.eclipse.n4js.typesystem.N4JSTypeSystem; +import org.eclipse.n4js.typesystem.utils.RuleEnvironment; +import org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions; + +/** */ +/* package */ final class TypeBoundCombiner { + private final RuleEnvironment G; + private final N4JSTypeSystem ts; + + private final HashMap> cachedReferencedTypeVars = new HashMap<>(); + + /** + * Creates an instance. + */ + TypeBoundCombiner(RuleEnvironment G, N4JSTypeSystem ts) { + this.G = G; + this.ts = ts; + } + + /** + * @see #combine(TypeBound, TypeBound, BoundSet) + */ + TypeConstraint combine(TypeBound boundI, TypeBound boundJ) { + return combine(boundI, boundJ, null); + } + + /** + * In terms of JLS8, this method embodies the implication rules listed in Sec. 18.3.1 (the other implication rules + * in JLS8 take as input capture conversion constraints). + */ + TypeConstraint combine(TypeBound boundI, TypeBound boundJ, BoundSet bset) { + switch (boundI.variance) { + case INV: + switch (boundJ.variance) { + case INV: + return combineInvInv(boundI, boundJ, bset); + case CO: + case CONTRA: + return combineInvVar(boundI, boundJ, bset); + } + break; + case CO: + switch (boundJ.variance) { + case INV: + return combineInvVar(boundJ, boundI, bset); // note: reversed arguments! + case CONTRA: + return combineContraCo(boundJ, boundI); // note: reversed arguments! + case CO: + return combineBothCoOrBothContra(boundI, boundJ); + } + break; + case CONTRA: + switch (boundJ.variance) { + case INV: + return combineInvVar(boundJ, boundI, bset); // note: reversed arguments! + case CO: + return combineContraCo(boundI, boundJ); + case CONTRA: + return combineBothCoOrBothContra(boundI, boundJ); + } + } + throw new IllegalStateException("unreachable"); + } + + /** + * Case: both bounds are equalities. + */ + private TypeConstraint combineInvInv(TypeBound boundS, TypeBound boundT, BoundSet bset) { + if (boundS.left == boundT.left) { + // `α = S` and `α = T` implies `S = T` + return new TypeConstraint(boundS.right, boundT.right, INV); + } + // inference variables are different + // -> try to substitute a proper RHS in the RHS of the other bound, to make it a proper type itself + TypeConstraint newConstraint = combineInvInvWithProperType(boundS, boundT, bset); + if (newConstraint != null) { + return newConstraint; + } + newConstraint = combineInvInvWithProperType(boundT, boundS, bset); + if (newConstraint != null) { + return newConstraint; + } + return null; + } + + /** + * Given two type bounds `α = U` and `β = T` with α ≠ β, will return a new constraint `β = T[α:=U]` if + *
      + *
    • U is proper, and + *
    • T mentions α. + *
    + * Otherwise, null is returned. + */ + private TypeConstraint combineInvInvWithProperType(TypeBound boundWithProperRHS, TypeBound boundOther, + BoundSet bset) { + final InferenceVariable alpha = boundWithProperRHS.left; + final TypeRef U = boundWithProperRHS.right; + final TypeRef T = boundOther.right; + if (TypeUtils.isProper(U) && getCachedReferencedTypeVars(T).contains(alpha)) { + final InferenceVariable beta = boundOther.left; + final TypeRef T_subst = substituteInferenceVariable(T, alpha, U); // returns T[α:=U] + if (bset != null) { + bset.removeBound(boundOther); // performance tweak: avoid unnecessary growth of bounds + } + return new TypeConstraint(typeRef(beta), T_subst, INV); + } + return null; + } + + /** + * Case: first bound is an equality, while the second isn't: `α = S` and `β Φ T` with Φ either {@code <:} or + * {@code :>}. + */ + private TypeConstraint combineInvVar(TypeBound boundS, TypeBound boundT, BoundSet bset) { + final InferenceVariable alpha = boundS.left; + final InferenceVariable beta = boundT.left; + final TypeRef S = boundS.right; + final TypeRef T = boundT.right; + final Variance Phi = boundT.variance; + if (alpha == beta) { + // (1) `α = S` and `α Φ T` implies `S Φ T` + return new TypeConstraint(S, T, Phi); + } + // both bounds have different inference variables, i.e. α != β + if (alpha == T.getDeclaredType()) { + // (2) `α = S` and `β Φ α` implies `β Φ S` + return new TypeConstraint(typeRef(beta), S, Phi); + } + if (TypeUtils.isInferenceVariable(S)) { + // first bound is of the form `α = γ` (with γ being another inference variable) + final InferenceVariable gamma = (InferenceVariable) S.getDeclaredType(); + if (gamma == beta) { + // (3) `α = β` and `β Φ T` implies `α Φ T` + return new TypeConstraint(typeRef(alpha), T, Phi); + } + if (gamma == T.getDeclaredType()) { + // (4) `α = γ` and `β Φ γ` implies `β Φ α` + return new TypeConstraint(typeRef(beta), typeRef(alpha), Phi); + } + } + // so, S is not an inference variable + if (TypeUtils.isProper(S) && getCachedReferencedTypeVars(T).contains(alpha)) { + // (5) `α = S` (where S is proper) and `β Φ T` implies `β Φ T[α:=U]` + final TypeRef T_subst = substituteInferenceVariable(T, alpha, S); // returns T[α:=U] + if (bset != null) { + bset.removeBound(boundT); // performance tweak: avoid unnecessary growth of bounds + } + return new TypeConstraint(typeRef(beta), T_subst, Phi); + } + return null; + } + + private Set getCachedReferencedTypeVars(EObject obj) { + Set result = cachedReferencedTypeVars.get(obj); + if (result == null) { + result = TypeUtils.getReferencedTypeVars(obj); + cachedReferencedTypeVars.put(obj, result); + } + return result; + } + + /** + * Case: `α :> S` and `β <: T`. + */ + private TypeConstraint combineContraCo(TypeBound boundS, TypeBound boundT) { + final InferenceVariable alpha = boundS.left; + final InferenceVariable beta = boundT.left; + final TypeRef S = boundS.right; + final TypeRef T = boundT.right; + if (alpha == beta) { + // transitivity, using LHS as bridge: + // α :> S and α <: T implies S <: T + return new TypeConstraint(S, T, CO); + } + // so, α and β are different + if (TypeUtils.isInferenceVariable(S)) { + final InferenceVariable gamma = (InferenceVariable) S.getDeclaredType(); + if (gamma == T.getDeclaredType()) { + // transitivity, using RHS as bridge: + // α :> γ and β <: γ implies α :> β + return new TypeConstraint(typeRef(alpha), typeRef(beta), CONTRA); + } + } + return null; + } + + /** + * Case: inequalities of same direction, i.e. + *
      + *
    • `α <: S` and `β <: T` or + *
    • `α :> S` and `β :> T`. + *
    + */ + private TypeConstraint combineBothCoOrBothContra(TypeBound boundS, TypeBound boundT) { + final InferenceVariable alpha = boundS.left; + final InferenceVariable beta = boundT.left; + final TypeRef S = boundS.right; + final TypeRef T = boundT.right; + if (alpha == T.getDeclaredType()) { + // α <: S and β <: α implies β <: S + // α :> S and β :> α implies β :> S + return new TypeConstraint(typeRef(beta), S, boundS.variance); + } + if (S.getDeclaredType() == beta) { + // α <: β and β <: T implies α <: T + // α :> β and β :> T implies α :> T + return new TypeConstraint(typeRef(alpha), T, boundS.variance); + } + return null; + } + + private static TypeRef typeRef(InferenceVariable infVar) { + return TypeUtils.createTypeRef(infVar, new TypeArgument[0]); + } + + /** + * Returns a copy of {@code typeRef} in which {@code infVar} is substituted by {@code typeArg} or {@code typeRef} + * itself if no change has occurred. + * + * @return typeRef[infVar:=typeArg] + */ + private TypeRef substituteInferenceVariable(TypeRef typeRef, InferenceVariable infVar, TypeArgument typeArg) { + final RuleEnvironment Gtemp = RuleEnvironmentExtensions.wrap(this.G); + RuleEnvironmentExtensions.addTypeMapping(Gtemp, infVar, typeArg); + final TypeRef result = this.ts.substTypeVariables(Gtemp, typeRef); + // note: infVar may still occur in result, if infVar->typeArg is not a valid type mapping! + // assert !(TypeVarUtils.occursIn(infVar, result)); + return result; + } +} diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/GenericsComputer.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/GenericsComputer.xtend index e3ba0eccdf..1c2729f25a 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/GenericsComputer.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/GenericsComputer.xtend @@ -14,7 +14,6 @@ import com.google.common.base.Optional import com.google.inject.Inject import java.util.ArrayList import java.util.Collection -import java.util.Collections import java.util.List import java.util.Set import java.util.function.Function @@ -539,25 +538,24 @@ package class GenericsComputer extends TypeSystemHelperStrategy { val rightArgUpper = ts.upperBound(G, rightArg); val rightArgLower = ts.lowerBound(G, rightArg); - // minor tweak to slightly beautify solutions of the constraint solver - // (i.e. having a single constraint ⟨ α = X ⟩ instead of two constraints ⟨ α :> X ⟩, ⟨ α <: X ⟩ helps the - // solver to avoid large unions in which one element is the super type of all others, in certain typical - // cases involving array/object literals) - if (useFancyConstraints - && variance === Variance.INV - && leftArgUpper === leftArg && leftArgLower === leftArg - && rightArgUpper === rightArg && rightArgLower === rightArg) { - return Collections.singletonList(new TypeConstraint(leftArg, rightArg, Variance.INV)); - } val List result = new ArrayList(2); // require leftArgUpper <: rightArgUpper, except we have contravariance - if (variance !== Variance.CONTRA) { + if (variance === Variance.INV) { + if (leftArgUpper == leftArgLower && rightArgLower == rightArgUpper) { + // having a single constraint ⟨ α = X ⟩ instead of two constraints ⟨ α :> X ⟩, ⟨ α <: X ⟩ helps the + // solver to avoid large unions in which one element is the super type of all others, in certain typical + // cases involving array/object literals) + result.add(new TypeConstraint(leftArgUpper, rightArgUpper, Variance.INV)); + } else { + result.add(new TypeConstraint(leftArgUpper, rightArgUpper, Variance.CO)); + result.add(new TypeConstraint(rightArgLower, leftArgLower, Variance.CO)); + } + } else if (variance === Variance.CO) { result.add(new TypeConstraint(leftArgUpper, rightArgUpper, Variance.CO)); - } - // require rightArgLower <: leftArgLower, except we have covariance - if (variance !== Variance.CO) { + } else if (variance === Variance.CONTRA) { + // require rightArgLower <: leftArgLower, except we have covariance result.add(new TypeConstraint(rightArgLower, leftArgLower, Variance.CO)); } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/RuleEnvironmentExtensions.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/RuleEnvironmentExtensions.xtend index de4ea30ba7..a963f66b6f 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/RuleEnvironmentExtensions.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/RuleEnvironmentExtensions.xtend @@ -747,6 +747,23 @@ class RuleEnvironmentExtensions { G.getPredefinedTypes().builtInTypeScope.getArrayNTypes } + /** + * Returns true iff obj is a {@link Type} or {@link TypeRef} and is or points to + * one of the Array<T> built-in type. Does not check for the + * built-in types ArrayN<...>. + */ + public def static boolean isArray(RuleEnvironment G, EObject obj) { + val type = switch(obj) { + Type: obj + TypeRef: obj.declaredType + }; + return isArray(G, type); + } + + public def static boolean isArray(RuleEnvironment G, Type type) { + return type !== null && G.arrayType == type; + } + /** * Returns true iff obj is a {@link Type} or {@link TypeRef} and is or points to * one of the ArrayN<...> built-in types. Does not check for the @@ -764,6 +781,13 @@ class RuleEnvironmentExtensions { return type !== null && G.arrayNTypes.contains(type); } + public def static int getArrayNNumber(RuleEnvironment G, Type type) { + if (!isArrayN(G, type)) { + return -1; + } + return Integer.parseInt(type.name.substring("Array".length)); + } + /* Returns built-in type {@code Promise} */ public def static promiseType(RuleEnvironment G) { G.getPredefinedTypes().builtInTypeScope.promiseType diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/StructuralTypingComputer.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/StructuralTypingComputer.xtend index b45f7802c7..5adde4c0ee 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/StructuralTypingComputer.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesystem/utils/StructuralTypingComputer.xtend @@ -16,7 +16,6 @@ import com.google.inject.Singleton import java.util.Collections import java.util.List import org.eclipse.emf.ecore.util.EcoreUtil.EqualityHelper -import org.eclipse.n4js.AnnotationDefinition import org.eclipse.n4js.ts.typeRefs.OptionalFieldStrategy import org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef import org.eclipse.n4js.ts.typeRefs.TypeArgument @@ -44,14 +43,13 @@ import org.eclipse.n4js.utils.StructuralTypesHelper import org.eclipse.n4js.validation.N4JSElementKeywordProvider import org.eclipse.xtend.lib.annotations.Data -import static org.eclipse.n4js.AnnotationDefinition.* import static org.eclipse.n4js.ts.types.TypingStrategy.* import static org.eclipse.n4js.typesystem.utils.StructuralTypingResult.* import static org.eclipse.n4js.utils.StructuralMembersPredicates.* +import static org.eclipse.n4js.validation.IssueCodes.TYS_NO_SUBTYPE import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* import static extension org.eclipse.n4js.utils.N4JSLanguageUtils.* -import static org.eclipse.n4js.validation.IssueCodes.TYS_NO_SUBTYPE /** */ @@ -247,7 +245,7 @@ class StructuralTypingComputer extends TypeSystemHelperStrategy { // For any non-optional and writable right members. // Important: unlike in case of ~r~, here we treat initialized fields, such as @Final ones as optional fields. - if (WRITABLE_FIELDS_PREDICATE.apply(rightMember) && rightMember.mandatoryField) { + if (WRITABLE_FIELDS_PREDICATE.apply(rightMember) && TypeUtils.isMandatoryField(rightMember)) { // If left is ~w~, then getters are required. if (STRUCTURAL_WRITE_ONLY_FIELDS === leftStrategy @@ -352,8 +350,8 @@ class StructuralTypingComputer extends TypeSystemHelperStrategy { return; } } - } - if (right instanceof TField) { + + } else if (right instanceof TField) { val leftOptionalStrategy = leftTypeRef.ASTNodeOptionalFieldStrategy; if (leftOptionalStrategy === OptionalFieldStrategy.GETTERS_OPTIONAL) { info.missingMembers.add("setter or field " + right.name); @@ -368,7 +366,6 @@ class StructuralTypingComputer extends TypeSystemHelperStrategy { // found a corresponding member // -> make sure types are compatible - val mtypes = getMemberTypes(left, right, info); var Variance variance; if (left.optional && !right.optional) { @@ -395,6 +392,7 @@ class StructuralTypingComputer extends TypeSystemHelperStrategy { variance = Variance.CO; } + val mtypes = getMemberTypes(left, right, info); val result = tsh.checkTypeArgumentCompatibility(G, mtypes.key, mtypes.value, Optional.of(variance), true); if (result.failure) { info.wrongMembers.add(getMemberName(right) + " failed: " + result.failureMessage); @@ -430,7 +428,6 @@ class StructuralTypingComputer extends TypeSystemHelperStrategy { } } else { - val mtypes = getMemberTypes(left, right, info); var Variance variance; if (left.optional && !right.optional) { @@ -448,6 +445,7 @@ class StructuralTypingComputer extends TypeSystemHelperStrategy { } else { variance = Variance.CO; } + val mtypes = getMemberTypes(left, right, info); return tsh.reduceTypeArgumentCompatibilityCheck(G, mtypes.key, mtypes.value, Optional.of(variance), false); } } @@ -498,7 +496,7 @@ class StructuralTypingComputer extends TypeSystemHelperStrategy { case STRUCTURAL_FIELD_INITIALIZER: { // L <: ~i~N (right.optional && leftOptionalStrategy.isOptionalityLessRestrictedOrEqual(OptionalFieldStrategy.GETTERS_OPTIONAL)) || - right.initializedField || right.optionalSetter + TypeUtils.isInitializedField(right) || TypeUtils.isOptionalSetter(right) } default: { @@ -575,34 +573,6 @@ class StructuralTypingComputer extends TypeSystemHelperStrategy { return typeLeft -> typeRight; } - /** - * Returns with {@code true} if the member argument is - *
      - *
    • *NOT* {@link TMember#isOptional() optional} member,
    • - *
    • *NOT* {@link #isInitializedField(TMember) initialized field} and
    • - *
    • *NOT* {@link #isOptionalSetter(TMember) optional setter}.
    • - *
    - * Otherwise returns with {@code false}. - */ - def private isMandatoryField(TMember it) { - null !== it && !optional && !initializedField && !optionalSetter; - } - - /** - * Argument is an instance of a {@link TField field} and {@link TField#isHasExpression() has initializer expression}. - * This method is {@code null} safe. - */ - def private isInitializedField(TMember it) { - if (it instanceof TField) { hasExpression } else false; - } - - /** - * Returns {@code true} if the member argument is an instance of a {@link TSetter setter} and has - * {@link AnnotationDefinition#IDE_1996 IDE_1996} annotation. Otherwise returns with {@code false}. - */ - def private isOptionalSetter(TMember it) { - it instanceof TSetter && PROVIDES_INITIALZER.hasAnnotation(it); - } def private String getMemberName(TMember member) { if (member instanceof TMethod) { diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/DestructureHelper.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/DestructureHelper.xtend index b45c9f1d3e..8ca4043731 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/DestructureHelper.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/utils/DestructureHelper.xtend @@ -32,7 +32,6 @@ import org.eclipse.n4js.scoping.members.MemberScopingHelper import org.eclipse.n4js.scoping.utils.AbstractDescriptionWithError import org.eclipse.n4js.ts.typeRefs.TypeArgument import org.eclipse.n4js.ts.typeRefs.TypeRef -import org.eclipse.n4js.ts.typeRefs.TypeRefsFactory import org.eclipse.n4js.ts.types.TField import org.eclipse.n4js.ts.types.TGetter import org.eclipse.n4js.ts.types.TStructMember @@ -333,7 +332,7 @@ class DestructureHelper { calculateExpectedType(nestedNode, G, infCtx) } else { // Extract type of leaf node - nestedNode.createTypeFromLeafDestructNode(G) + createTypeFromLeafDestructNode(nestedNode, G); } if (nestedNode.propName !== null) { @@ -352,7 +351,9 @@ class DestructureHelper { if (elemExpectedType !== null) { elementTypes.add(elemExpectedType) } else { - elementTypes.add(TypeRefsFactory.eINSTANCE.createWildcard) + // If the expected type is not specified, the expected type is arbitrary hence return a new inference variable. + val iv = infCtx.newInferenceVariable; + elementTypes.add(TypeUtils.createTypeRef(iv)); } } } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java index 8a87c609a9..140cd3d3e9 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/IssueCodes.java @@ -2122,7 +2122,9 @@ public String getMessage(Object... values) { } String message = msgTemplate; for (int i = 0; i < values.length; i++) { - message = message.replace("{" + i + "}", values[i].toString()); + Object value = values[i]; + String replace = value == null ? "?" : value.toString(); + message = message.replace("{" + i + "}", replace); } return message; } diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSExpressionValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSExpressionValidator.xtend index 75b37b8066..53666ba7a6 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSExpressionValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSExpressionValidator.xtend @@ -141,6 +141,7 @@ import org.eclipse.xtext.validation.EValidatorRegistrar import static org.eclipse.n4js.validation.IssueCodes.* import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* +import org.eclipse.n4js.n4JS.N4JSASTUtils /** */ @@ -447,11 +448,8 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { if (!N4JSLanguageUtils.isAsync(fteor, G)) { return } - var container = callExpression.eContainer - while (container instanceof ParenExpression) { - // related: ExpressionExtensions.isPotentialEvalResult() - container = container.eContainer - } + // related: ExpressionExtensions.isPotentialEvalResult() + var container = N4JSASTUtils.skipParenExpressionUpward(callExpression.eContainer); val isAwaitedFor = (container instanceof AwaitExpression); val isTopLevel = (container instanceof ExpressionStatement && container.eContainer instanceof Script); if (isAwaitedFor || isTopLevel) { @@ -794,10 +792,7 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { } else if (expression instanceof ParameterizedPropertyAccessExpression) { // guard against broken models: if (expression.property !== null && !expression.property.eIsProxy) { - var target = expression.target; - while (target instanceof ParenExpression) { - target = target.expression; - } + var target = N4JSASTUtils.skipParenExpressionDownward(expression.target); if (target instanceof IdentifierRef) { val id = target.id; // handle namespace imports: @@ -1357,6 +1352,12 @@ class N4JSExpressionValidator extends AbstractN4JSDeclarativeValidator { || (S.declaredType instanceof TEnum && isLiteralOfNumberStringBasedEnum(T, S.declaredType as TEnum))) { // allow casting numbers/strings to @NumberBased/@StringBased enums return true; // cast is ok + } else if (castExpression.expression instanceof ArrayLiteral && RuleEnvironmentExtensions.isArrayN(G, S)) { + // GH-2615 FIXME: do some type checking of TypeArgs + if (RuleEnvironmentExtensions.isArray(G, T)) { + return true; + } + return true; // cast is ok } else if (canCheck(G, S, T, actualSourceTypeIsCPOE)) { // Constraint 81.3 (Cast Validation At Compile-Time): var castOK = ts.subtypeSucceeded(G, T, S); if (!castOK && S.isUseSiteStructuralTyping && S instanceof StructuralTypeRef && !(S as StructuralTypeRef).structuralMembers.empty) { diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSTypeValidator.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSTypeValidator.xtend index 2e7936d725..a68e718eba 100644 --- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSTypeValidator.xtend +++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/validation/validators/N4JSTypeValidator.xtend @@ -103,6 +103,7 @@ import static org.eclipse.n4js.validation.IssueCodes.* import static extension org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.* import org.eclipse.emf.ecore.EStructuralFeature import org.eclipse.n4js.validation.IssueItem +import org.eclipse.n4js.n4JS.ParenExpression /** * Class for validating the N4JS types. @@ -434,10 +435,10 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { return; } - // expressionAnnotationList occur on function- and class-expressions. - // checking of the content is done in N4JSAnnotationValidation if (expression instanceof ExpressionAnnotationList) { - return + // expressionAnnotationList occur on function- and class-expressions. + // checking of the content is done in N4JSAnnotationValidation + return; } var G = expression.newRuleEnvironment; @@ -451,6 +452,16 @@ class N4JSTypeValidator extends AbstractN4JSDeclarativeValidator { val expectedTypeRef = ts.expectedType(G, expression.eContainer, expression); if (expectedTypeRef !== null) { + + + if (expression instanceof ParenExpression) { + val expectedTypeRefInner = ts.expectedType(G, expression, expression.expression); + if (expectedTypeRefInner !== null && ts.equaltypeSucceeded(G, expectedTypeRef, expectedTypeRefInner)) { + // skip further checks to avoid double reporting of issues + return; + } + } + // for certain problems in single-expression arrow functions, we want a special error message val singleExprArrowFunction = N4JSASTUtils.getContainingSingleExpressionArrowFunction(expression); diff --git a/tests/org.eclipse.n4js.bugreports.tests/xt-tests/IDEBUG_0305_SimplificationOfUnionWrongForConstructorTypes.n4js.xt b/tests/org.eclipse.n4js.bugreports.tests/xt-tests/IDEBUG_0305_SimplificationOfUnionWrongForConstructorTypes.n4js.xt index 6cd343e79f..34672194e2 100644 --- a/tests/org.eclipse.n4js.bugreports.tests/xt-tests/IDEBUG_0305_SimplificationOfUnionWrongForConstructorTypes.n4js.xt +++ b/tests/org.eclipse.n4js.bugreports.tests/xt-tests/IDEBUG_0305_SimplificationOfUnionWrongForConstructorTypes.n4js.xt @@ -32,9 +32,9 @@ class G { // XPECT noerrors --> var gFine : Array = [ C, C1 ]; -// XPECT errors --> "Array is not a subtype of Array." at "[ C, C1, C2 ]" +// XPECT errors --> "Array3 is not a subtype of Array." at "[ C, C1, C2 ]" var gBad : Array = [ C, C1, C2 ]; // XPECT noerrors --> var gFixed : Array = [ C, C1, C2 ]; -// XPECT type of '[ C, C1, C2 ]' --> Array +// XPECT type of '[ C, C1, C2 ]' --> Array3 var test = [ C, C1, C2 ]; diff --git a/tests/org.eclipse.n4js.bugreports.tests/xt-tests/IDEBUG_0612_SimplifyUnion_must_not_oversimplify.n4js.xt b/tests/org.eclipse.n4js.bugreports.tests/xt-tests/IDEBUG_0612_SimplifyUnion_must_not_oversimplify.n4js.xt index d4eb16b848..0bacfaf6f1 100644 --- a/tests/org.eclipse.n4js.bugreports.tests/xt-tests/IDEBUG_0612_SimplifyUnion_must_not_oversimplify.n4js.xt +++ b/tests/org.eclipse.n4js.bugreports.tests/xt-tests/IDEBUG_0612_SimplifyUnion_must_not_oversimplify.n4js.xt @@ -17,8 +17,8 @@ class B {} class C {} class D {} // arr1 will be inferred to wrong type "Array>" -// XPECT type of 'arr1' --> Array,Array}> +// XPECT type of 'arr1' --> Array2,Array2> var arr1 = [ [42,""], [new A, new B] ]; // arr2 will be inferred to wrong type "Array" -// XPECT type of 'arr2' --> Array +// XPECT type of 'arr2' --> Array4 var arr2 = [ A, B, C, D ]; diff --git a/tests/org.eclipse.n4js.expectmatrix.tests/xt-pending/matrix/Class_x_ST_US/01_instantiation.n4js.xt b/tests/org.eclipse.n4js.expectmatrix.tests/xt-pending/matrix/Class_x_ST_US/01_instantiation.n4js.xt index 610cfea8ef..d24a012b74 100644 --- a/tests/org.eclipse.n4js.expectmatrix.tests/xt-pending/matrix/Class_x_ST_US/01_instantiation.n4js.xt +++ b/tests/org.eclipse.n4js.expectmatrix.tests/xt-pending/matrix/Class_x_ST_US/01_instantiation.n4js.xt @@ -48,7 +48,7 @@ a2 instanceof ~A2; // GHOLD-9 (IDEBUG-163) instanceof XPECT FIXME errors --> "Cannot use structural field type with instanceof." at "A2" a3 instanceof ~~A2; -// missing members XPECT errors --> "~Object with { a: number } is not a structural subtype of ~A2: missing method f." at "{a: 2}" +// missing members XPECT errors --> "~Object with { a: int } is not a structural subtype of ~A2: missing method f." at "{a: 2}" var a4 : ~A2 = {a: 2}; /* superfluous members in field type, noerrors but XPECT warnings --- diff --git a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Class_x_ST_US/09_nested_ST_members.n4js.xt b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Class_x_ST_US/09_nested_ST_members.n4js.xt index e2fb1e1bad..39d8580a58 100644 --- a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Class_x_ST_US/09_nested_ST_members.n4js.xt +++ b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Class_x_ST_US/09_nested_ST_members.n4js.xt @@ -83,7 +83,7 @@ var f3aOK : ~C = g.f({n: 3, foo: function (){} }); /* type returned and argument incompatible XPECT errors --- "Structural type ~C is not a subtype of non-structural type C." at "g.f({n: 3})" -"~Object with { n: number } is not a structural subtype of ~C: missing method foo." at "{n: 3}" +"~Object with { n: int } is not a structural subtype of ~C: missing method foo." at "{n: 3}" --- */ var f3b : C = g.f({n: 3}); diff --git a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Ctor_x_Union/02_from_spec.n4js.xt b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Ctor_x_Union/02_from_spec.n4js.xt index 7d3a8be77d..5eddfc6e1b 100644 --- a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Ctor_x_Union/02_from_spec.n4js.xt +++ b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Ctor_x_Union/02_from_spec.n4js.xt @@ -25,7 +25,7 @@ class B {} // one element of union XPECT noerrors --> var a1 = new A({x: 4}); -// not the element of union XPECT errors --> "~Object with { x: true } is not a structural subtype of ~i~A: x failed: true is not equal to union{number,string,B}." at "{x: true}" +// not the element of union XPECT errors --> "~Object with { x: boolean } is not a structural subtype of ~i~A: x failed: boolean is not equal to union{number,string,B}." at "{x: true}" var a2 = new A({x: true}); var x : union{number,string,B}; diff --git a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Interface_x_ST_DS/02_as_return_value.n4js.xt b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Interface_x_ST_DS/02_as_return_value.n4js.xt index 356e6446fd..e8eeeb106a 100644 --- a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Interface_x_ST_DS/02_as_return_value.n4js.xt +++ b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Interface_x_ST_DS/02_as_return_value.n4js.xt @@ -34,7 +34,7 @@ class C1 { // return value must be nominal type XPECT errors --> "Structural type ~Object with { x: int; foo: {function():void} } is not a subtype of non-structural type I." at "{x: 3, foo: this.f}" public f1 () : I { return {x: 3, foo: this.f}; }; - // return value must be ~I, missing foo field XPECT errors --> "~Object with { x: ~int } is not a structural subtype of ~I: missing method foo." at "{x: 3}" + // return value must be ~I, missing foo field XPECT errors --> "~Object with { x: int } is not a structural subtype of ~I: missing method foo." at "{x: 3}" public f2a () : ~I { return {x: 3}; }; // return value must be ~I, all well XPECT noerrors --> diff --git a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Interface_x_ST_US/01_as_argument.n4js.xt b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Interface_x_ST_US/01_as_argument.n4js.xt index fdd3aafeb9..2d44a135c8 100644 --- a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Interface_x_ST_US/01_as_argument.n4js.xt +++ b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Interface_x_ST_US/01_as_argument.n4js.xt @@ -46,7 +46,7 @@ f(new C2()); // C2 !<: ~I XPECT errors --> "C2 is not a structural subtype of ~I: x failed: string is not equal to number." at "new C2()" f(new C2()); -// got ~~I, ~I expected XPECT errors --> "~Object with { x: number } is not a structural subtype of ~I: missing method foo." at "{x:10}" +// got ~~I, ~I expected XPECT errors --> "~Object with { x: int } is not a structural subtype of ~I: missing method foo." at "{x:10}" f({x:10}); // got ~~I as expected XPECT noerrors --> diff --git a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Lambda/08_higher-order.n4js.xt b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Lambda/08_higher-order.n4js.xt index cd7e21b58d..bf02c176fc 100644 --- a/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Lambda/08_higher-order.n4js.xt +++ b/tests/org.eclipse.n4js.expectmatrix.tests/xt-tests/matrix/Lambda/08_higher-order.n4js.xt @@ -44,7 +44,7 @@ function bar1 () : {function (number) : number} { } function bar2 () : {function (number) : number} { - // IDE-2140, IDEBUG-177 lambda as return, good syntax XPECT errors -->"{function(number):any} is not a subtype of {function(number):number}." at "( (n : number) => { return n+6 } )" + // IDE-2140, IDEBUG-177 lambda as return, good syntax XPECT noerrors --> "{function(number):any} is not a subtype of {function(number):number}." at "( (n : number) => { return n+6 } )" return ( (n : number) => { return n+6 } ); } diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/PolyProcessorTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/PolyProcessorTest.java index d51e7ee897..f802bb8714 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/PolyProcessorTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/typesystem/PolyProcessorTest.java @@ -15,6 +15,7 @@ import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.arrayNType; import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.arrayType; import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.numberType; +import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.numberTypeRef; import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.stringType; import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.stringTypeRef; import static org.eclipse.n4js.typesystem.utils.RuleEnvironmentExtensions.voidType; @@ -303,7 +304,7 @@ public void test_ArrayLiteral_noExpectation() { assertType(firstArrayLiteral(parseAndValidate(""" var arr = ["hello", 42]; """)), - of(arrayType(_G), union(numberType(_G), stringType(_G))) // Array + of(arrayNType(_G, 2), stringTypeRef(_G), numberTypeRef(_G)) // Array2 ); } diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_04_ArrayLiteralTypesystemTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_04_ArrayLiteralTypesystemTest.java index a24a8bf005..9e9c955603 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_04_ArrayLiteralTypesystemTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_04_ArrayLiteralTypesystemTest.java @@ -88,7 +88,7 @@ public void testArraySingleElementType() { assertArrayLiteralType("Array", "[1,2,3]"); assertArrayLiteralType("Array", "[n1]"); assertArrayLiteralType("Array", "[n1,n2]"); - assertArrayLiteralType("Array", "[n1,2,3]"); + assertArrayLiteralType("Array2", "[n1,2,3]"); assertArrayLiteralType("Array", "[s1]"); assertArrayLiteralType("Array", "[s1,s2]"); assertArrayLiteralType("Array
    ", "[a]"); @@ -98,27 +98,32 @@ public void testArraySingleElementType() { @Test public void testArrayUnionElementType() { // syntax error was intended (I guess) - assertArrayLiteralType("Array", "[\"Walter\", 1\"]"); + assertArrayLiteralType("Array2", "[\"Walter\", 1\"]"); // syntax error was intended (I guess) - assertArrayLiteralType("Array", "[\"Walter\", a, 1\"]"); - assertArrayLiteralType("Array", "[a,b]"); - assertArrayLiteralType("Array", "[a,b,a]"); - assertArrayLiteralType("Array", "[a,b,a,b,a,a,b]"); + assertArrayLiteralType("Array3", "[\"Walter\", a, 1\"]"); + assertArrayLiteralType("Array2", "[a,b]"); + assertArrayLiteralType("Array3", "[a,b,a]"); + assertArrayLiteralType("Array7", "[a,b,a,b,a,a,b]"); + } + + @Test + public void testArrayUnionElementType2() { + assertArrayLiteralType("Array3>", "[a,b,[a,b]]"); } @Test public void testArrayElementTypeWithIgnoredPadding() { assertArrayLiteralType("Array", "[a,]"); - assertArrayLiteralType("Array", "[,a]"); - assertArrayLiteralType("Array", "[,a,]"); - assertArrayLiteralType("Array", "[,a,,,,]"); + assertArrayLiteralType("Array2", "[,a]"); + assertArrayLiteralType("Array2", "[,a,]"); // trailing comma => length is 2! + assertArrayLiteralType("Array3", "[,a,,,,]"); // syntax error was intended (I guess) - assertArrayLiteralType("Array", "[,\"Walter\", 1\"]"); + assertArrayLiteralType("Array3", "[,\"Walter\", 1\"]"); // syntax error was intended (I guess) - assertArrayLiteralType("Array", "[\"Walter\", a, 1\",]"); - assertArrayLiteralType("Array", "[a,b,,]"); - assertArrayLiteralType("Array", "[a,b,a,,,]"); - assertArrayLiteralType("Array", "[a,b,a,,a,,b]"); + assertArrayLiteralType("Array3", "[\"Walter\", a, 1\",]"); + assertArrayLiteralType("Array3", "[a,b,,]"); + assertArrayLiteralType("Array4", "[a,b,a,,,]"); + assertArrayLiteralType("Array7", "[a,b,a,,a,,b]"); } } diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_07_IndexedAccessExpressionTypeInferenceTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_07_IndexedAccessExpressionTypeInferenceTest.java index ce7f31feab..05c0f54d29 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_07_IndexedAccessExpressionTypeInferenceTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_07_IndexedAccessExpressionTypeInferenceTest.java @@ -119,12 +119,10 @@ public void testSingleElementType() { @Test public void testUnionElementType() { - assertIndexedAccessExpressionType("union{string,int}", "[\"Walter\", 1]"); - assertIndexedAccessExpressionType("union{string,int}", "[\"Walter\", 1\"]"); // syntax error was intended (I - // guess) - assertIndexedAccessExpressionType("union{string,A,int}", "[\"Walter\", a, 1]"); - assertIndexedAccessExpressionType("union{string,A,int}", "[\"Walter\", a, 1\"]"); // syntax error was intended - // (I guess) + assertIndexedAccessExpressionType("string", "[\"Walter\", 1]"); + assertIndexedAccessExpressionType("string", "[\"Walter\", 1\"]"); // syntax error was intended (I guess) + assertIndexedAccessExpressionType("string", "[\"Walter\", a, 1]"); + assertIndexedAccessExpressionType("string", "[\"Walter\", a, 1\"]"); // syntax error was intended (I guess) assertIndexedAccessExpressionType("A", "[a,b]"); assertIndexedAccessExpressionType("A", "[a,b,a]"); assertIndexedAccessExpressionType("A", "[a,b,a,b,a,a,b]"); @@ -133,16 +131,14 @@ public void testUnionElementType() { @Test public void testElementTypeWithIgnoredPadding() { assertIndexedAccessExpressionType("A", "[a,]"); - assertIndexedAccessExpressionType("A", "[,a]"); - assertIndexedAccessExpressionType("A", "[,a,]"); - assertIndexedAccessExpressionType("A", "[,a,,,,]"); + assertIndexedAccessExpressionType("any", "[,a]"); + assertIndexedAccessExpressionType("any", "[,a,]"); + assertIndexedAccessExpressionType("any", "[,a,,,,]"); - assertIndexedAccessExpressionType("union{string,int}", "[,\"Walter\", 1]"); - assertIndexedAccessExpressionType("union{string,int}", "[,\"Walter\", 1\"]"); // syntax error was intended (I - // guess) - assertIndexedAccessExpressionType("union{string,A,int}", "[\"Walter\", a, 1,]"); - assertIndexedAccessExpressionType("union{string,A,int}", "[\"Walter\", a, 1\",]"); // syntax error was intended - // (I guess) + assertIndexedAccessExpressionType("any", "[,\"Walter\", 1]"); + assertIndexedAccessExpressionType("any", "[,\"Walter\", 1\"]"); // syntax error was intended (I guess) + assertIndexedAccessExpressionType("string", "[\"Walter\", a, 1,]"); + assertIndexedAccessExpressionType("string", "[\"Walter\", a, 1\",]"); // syntax error was intended (I guess) assertIndexedAccessExpressionType("A", "[a,b,,]"); assertIndexedAccessExpressionType("A", "[a,b,a,,,]"); assertIndexedAccessExpressionType("A", "[a,b,a,,a,,b]"); diff --git a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_08_NewExpressionTypesystemTest.java b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_08_NewExpressionTypesystemTest.java index 49176e203b..d9415f54e0 100644 --- a/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_08_NewExpressionTypesystemTest.java +++ b/tests/org.eclipse.n4js.lang.tests/src/org/eclipse/n4js/xsemantics/N6_1_08_NewExpressionTypesystemTest.java @@ -191,7 +191,7 @@ class C { new C( {f: 42} ) // fail """, """ - ~Object with { f: 42 } is not a structural subtype of ~~C: f failed: 42 is not equal to string. + ~Object with { f: int } is not a structural subtype of ~~C: f failed: int is not equal to string. """); } @@ -213,7 +213,7 @@ class E extends D { new E( {f: "hello", n: "oops"} ) // fail """, """ - ~Object with { f: string; n: "oops" } is not a structural subtype of ~~E: n failed: "oops" is not equal to number. + ~Object with { f: string; n: string } is not a structural subtype of ~~E: n failed: string is not equal to number. """); } diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_arrayLiterals.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_arrayLiterals.n4js.xt index b9b692e07d..b75485ede3 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_arrayLiterals.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_arrayLiterals.n4js.xt @@ -22,8 +22,11 @@ let arr2 = [ 42 ]; // XPECT type of 'arr3' --> Array let arr3 = [ 0, 42 ]; -// XPECT type of 'arr4' --> Array +// XPECT type of 'arr4' --> Array2 let arr4 = [ 42, 4.3 ]; -// XPECT type of 'arr5' --> Array +// XPECT type of 'arr5' --> Array2 let arr5 = [ 42, "hello" ]; + +// XPECT type of 'arr6' --> Array3> +let arr6 = [ 42, "hello", [ true, "hi" ] ]; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_arrayLiterals_poly.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_arrayLiterals_poly.n4js.xt new file mode 100644 index 0000000000..28e63eac3e --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_arrayLiterals_poly.n4js.xt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest END_SETUP */ + + +// XPECT type of '["2", {}]' --> Array2 +// XPECT noerrors --> +let arr1 : [int, int]|[string, any] = ["2", {}]; + +function f(): [int, int]|[string, any] { +// XPECT type of '["2", {}]' --> Array2 +// XPECT noerrors --> + return ["2", {}]; +} \ No newline at end of file diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_objectLiterals.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_objectLiterals.n4js.xt index d3e0188132..867ec31f04 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_objectLiterals.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_objectLiterals.n4js.xt @@ -35,5 +35,5 @@ let obj3: ~Object with { prop: 0 | 42 } = { prop: 42, propWithoutExpectation: 43 // In the next test case, we want to avoid seeing the following extremely confusing error message: // ~Object with { prop1: "hello"; prop2: "BAD!" } is not a structural subtype of ~Object with { prop1: string; prop2: number }: prop1 failed: "hello" is not equal to string and 1 more problems. -// XPECT errors --> "~Object with { prop1: string; prop2: "BAD!" } is not a structural subtype of ~Object with { prop1: string; prop2: number }: prop2 failed: "BAD!" is not equal to number." at "{ prop1: "hello", prop2: "BAD!" }" +// XPECT errors --> "~Object with { prop1: string; prop2: string } is not a structural subtype of ~Object with { prop1: string; prop2: number }: prop2 failed: string is not equal to number." at "{ prop1: "hello", prop2: "BAD!" }" let obj4: ~Object with { prop1: string, prop2: number } = { prop1: "hello", prop2: "BAD!" }; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_objectLiterals_poly_nested.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_objectLiterals_poly_nested.n4js.xt new file mode 100644 index 0000000000..1c7cc4bad0 --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch04_15__LiteralTypes/LiteralTypes_inference_objectLiterals_poly_nested.n4js.xt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest END_SETUP */ + + + +interface ~I { + public valueI : int|string|V; +} +interface ~V { + public valueV : int|string; +} + +// XPECT noerrors --> +// XPECT type of '{ valueI: { valueV: 2 } }' --> ~Object with { valueI: union{int,string,V} } +const i1 : I = { valueI: { valueV: 2 } }; +i1; + +// XPECT errors --> "~Object with { valueI: V } is not a structural subtype of I: valueI failed: V is not equal to union{int,string,V}." at "{ V valueI: { valueV: 2 } }" +// XPECT type of '{ V valueI: { valueV: 2 } }' --> ~Object with { valueI: V } +const i2 : I = { V valueI: { valueV: 2 } }; +i2; + +// XPECT errors --> "~Object with { valueI: V } is not a structural subtype of I: valueI failed: V is not equal to union{int,string,V}." at "{ V valueI: { valueV: 2 } }" +// XPECT type of '{ V valueI: { valueV: 2 } }' --> ~Object with { valueI: V } +const i3 : I = { V valueI: { valueV: 2 } }; +i3; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_05__Generic_Classifiers/TypeArgs_anyPlus.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_05__Generic_Classifiers/TypeArgs_anyPlus.n4js.xt new file mode 100644 index 0000000000..f85e7b6ada --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_01_05__Generic_Classifiers/TypeArgs_anyPlus.n4js.xt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest END_SETUP */ + + + +// XPECT noerrors --> + +function from(source: Iterable|ArrayLike|Iterator|string, mapFn: (I, int) => any=, thisArg: Object=): I[] { + return null; +} + +function f() : int[] { + let i : any+ = 23; + // XPECT type of 'from(i)' --> Array + return from(i); +} \ No newline at end of file diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_02_01__StructuralThisTypeInCtorAndSpecParameter/Constraints_55_9_Structural_Fields_Can_Be_Assigned_Via_Public_Accessors.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_02_01__StructuralThisTypeInCtorAndSpecParameter/Constraints_55_9_Structural_Fields_Can_Be_Assigned_Via_Public_Accessors.n4js.xt index 51223899af..7bff37a0b5 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_02_01__StructuralThisTypeInCtorAndSpecParameter/Constraints_55_9_Structural_Fields_Can_Be_Assigned_Via_Public_Accessors.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_02_01__StructuralThisTypeInCtorAndSpecParameter/Constraints_55_9_Structural_Fields_Can_Be_Assigned_Via_Public_Accessors.n4js.xt @@ -45,5 +45,5 @@ class C { // XPECT noerrors --> "" at "t" new C({ t: 42 }) -// XPECT errors --> "~Object with { t: 42 } is not a structural subtype of ~i~C: t failed: 42 is not a super type of string." at "{ t: 42 }" +// XPECT errors --> "~Object with { t: int } is not a structural subtype of ~i~C: t failed: int is not a super type of string." at "{ t: 42 }" new C({ t: 42 }) diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_02_01__StructuralThisTypeInCtorAndSpecParameter/PolyProcessor_QuasiOptionalFields.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_02_01__StructuralThisTypeInCtorAndSpecParameter/PolyProcessor_QuasiOptionalFields.n4js.xt new file mode 100644 index 0000000000..963c0c4e29 --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_02_02_01__StructuralThisTypeInCtorAndSpecParameter/PolyProcessor_QuasiOptionalFields.n4js.xt @@ -0,0 +1,45 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest END_SETUP */ + + + + +abstract class TestS { + public objectState = 23; + + public constructor(@Spec spec: ~i~this) { + } +} + +class Test1 extends TestS { + public collection: any; + + public constructor(@Spec spec: ~i~this) { + super(spec); + } +} + +// XPECT noerrors --> +new Test1({collection : 23}); + + + +class Test2 { + public objectState2 = 23; + public collection: any; + + public constructor(@Spec spec: ~i~this) { + } +} +// XPECT noerrors --> +new Test2({collection : 23}); diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_03__StructuralTyping/FieldsOptionalOrWithExpression.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_03__StructuralTyping/FieldsOptionalOrWithExpression.n4js.xt index 0d17d6ec03..a0dea3fc56 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_03__StructuralTyping/FieldsOptionalOrWithExpression.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_03__StructuralTyping/FieldsOptionalOrWithExpression.n4js.xt @@ -30,7 +30,7 @@ var b : ~B = {}; // XPECT errors --> "~Object is not a structural subtype of ~C: missing field n." at "{}" var c : ~C = {}; -// XPECT errors --> "~Object with { n: number } is not a structural subtype of ~A with { s: string }: missing structural field s." at "{ n: 42 }" +// XPECT errors --> "~Object with { n: int } is not a structural subtype of ~A with { s: string }: missing structural field s." at "{ n: 42 }" var aws1 : ~A with { s : string; } = { n: 42 }; // XPECT noerrors --> var aws2 : ~A with { s? : string; } = { n: 42 }; // ok! @@ -54,7 +54,7 @@ var i : ~I = {}; // XPECT noerrors --> "" var j : ~J = {}; -// XPECT errors --> "~Object with { n: number } is not a structural subtype of ~I with { s: string }: missing structural field s." at "{ n: 42 }" +// XPECT errors --> "~Object with { n: int } is not a structural subtype of ~I with { s: string }: missing structural field s." at "{ n: 42 }" var iws1 : ~I with { s : string; } = { n: 42 }; // XPECT noerrors --> var iws2 : ~I with { s? : string; } = { n: 42 }; // ok! diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_03__StructuralTyping/Req76_3_StructuralAndInstanceof.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_03__StructuralTyping/Req76_3_StructuralAndInstanceof.n4js.xt index ebc46387a9..f399dc2d2f 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_03__StructuralTyping/Req76_3_StructuralAndInstanceof.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch05_03__StructuralTyping/Req76_3_StructuralAndInstanceof.n4js.xt @@ -34,6 +34,9 @@ a instanceof --x; // XPECT errors --> "number is not a subtype of union{Function,type{Object},type{N4Enum}}." at "~x" a instanceof ~x +// XPECT errors --> "47 is not a subtype of union{Function,type{Object},type{N4Enum}}." at "47" +a instanceof 47; + // XPECT errors --> "number is not a subtype of union{Function,type{Object},type{N4Enum}}." at "~(3 + 4)" a instanceof ~(3 + 4) diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_02__Generator_Functions/generators-yield-star.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_02__Generator_Functions/generators-yield-star.n4js.xt index 50b15c25c6..ec0aae8a4f 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_02__Generator_Functions/generators-yield-star.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_03_02__Generator_Functions/generators-yield-star.n4js.xt @@ -129,11 +129,11 @@ async function *ait2() : AsyncGenerator { } function *it3() : Generator { - // XPECT errors --> "Array is not a structural subtype of Iterable: #iterator failed: {function():Iterator} is not a subtype of {function():Iterator}." at "([1,2,3])" + // XPECT errors --> "Array is not a structural subtype of Iterable: #iterator failed: {function():Iterator} is not a subtype of {function():Iterator}." at "[1,2,3]" yield* ([1,2,3]); } async function *ait3() : AsyncGenerator { - // XPECT errors --> "Array is not a structural subtype of Iterable: #iterator failed: {function():Iterator} is not a subtype of {function():Iterator}." at "([1,2,3])" + // XPECT errors --> "Array is not a structural subtype of Iterable: #iterator failed: {function():Iterator} is not a subtype of {function():Iterator}." at "[1,2,3]" yield* ([1,2,3]); } diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_05_02__PromisifiableFunctions/Promisify_useCases.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_05_02__PromisifiableFunctions/Promisify_useCases.n4js.xt index 814943ad8a..6cc303b437 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_05_02__PromisifiableFunctions/Promisify_useCases.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch06_05_02__PromisifiableFunctions/Promisify_useCases.n4js.xt @@ -121,12 +121,12 @@ async function testWithMethod(allDone : {function()}) { console.log('****** method mNone:'); console.log('use case #1: with await, long syntax'); - // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "(await @Promisify c.mNone('some path'))" + // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "await @Promisify c.mNone('some path')" var res31 = (await @Promisify c.mNone('some path')); // assigning undefined to Object here to be able to assert that 'undefined' is returned at runtime console.log('-> res31:', res31); console.log('use case #2: with await, short syntax'); - // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "(await @Promisify c.mNone('some path'))" + // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "await @Promisify c.mNone('some path')" var res32 = (await @Promisify c.mNone('some path')); // assigning undefined to Object here to be able to assert that 'undefined' is returned at runtime console.log('-> res32:', res32); @@ -155,12 +155,12 @@ async function testWithMethod(allDone : {function()}) { console.log('****** method mNoneNoErr:'); console.log('use case #1: with await, long syntax'); - // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "(await @Promisify c.mNoneNoErr('some path'))" + // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "await @Promisify c.mNoneNoErr('some path')" var res61 = (await @Promisify c.mNoneNoErr('some path')); // assigning undefined to Object here to be able to assert that 'undefined' is returned at runtime console.log('-> res61:', res61); console.log('use case #2: with await, short syntax'); - // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "(await @Promisify c.mNoneNoErr('some path'))" + // XPECT warnings --> "The type of this expression is 'undefined', so it will never evaluate to a value other than 'undefined'." at "await @Promisify c.mNoneNoErr('some path')" var res62 = (await @Promisify c.mNoneNoErr('some path')); // assigning undefined to Object here to be able to assert that 'undefined' is returned at runtime console.log('-> res62:', res62); diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_04__ArrayLiteral/ArrayLiteral_asValueToBeDestructured.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_04__ArrayLiteral/ArrayLiteral_asValueToBeDestructured.n4js.xt index e8f28ebc1f..fc4a3dd1e7 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_04__ArrayLiteral/ArrayLiteral_asValueToBeDestructured.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_04__ArrayLiteral/ArrayLiteral_asValueToBeDestructured.n4js.xt @@ -17,6 +17,11 @@ var [a1,b1] = ["",42]; +// XPECT type of 'aa1' --> string +// XPECT type of 'bb1' --> int +var [[aa1,bb1]] = [["",42]]; + + var a2 : string, b2 : number; // XPECT noerrors --> [a2,b2] = ["",42]; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_04__ArrayLiteral/ArrayLiteral_withTypeExpectation_IterableN.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_04__ArrayLiteral/ArrayLiteral_withTypeExpectation_IterableN.n4js.xt index e417c3b4ae..88f6711066 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_04__ArrayLiteral/ArrayLiteral_withTypeExpectation_IterableN.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_04__ArrayLiteral/ArrayLiteral_withTypeExpectation_IterableN.n4js.xt @@ -35,9 +35,9 @@ var v00 : Iterable = [b]; var v01 : Iterable = [b,c,b]; // XPECT type of '[b,c,b]' --> Array var v02 : Array = [b,c,b]; -// XPECT type of '[b,c,b]' --> Array +// XPECT type of '[b,c,b]' --> Array3 var v03 = [b,c,b]; -// XPECT errors --> "Array is not a subtype of X." at "[b,c,b]" +// XPECT errors --> "Array3 is not a subtype of X." at "[b,c,b]" var v04 : X = [b,c,b]; @@ -67,18 +67,18 @@ var v13a : Iterable3 = [b,c,b,b,b,c,b]; var v13b : Array3 = [b,c,b,b,b,c,b]; // found during IDE-1852: XPECT FIXME noerrors -// case NOT all remaining match XPECT type of '[b,c,b,b,b,x,b]' --> Array3 +// case NOT all remaining match XPECT type of '[b,c,b,b,b,x,b]' --> Array7 var v14a : Iterable3 = [b,c,b,b,b,x,b]; // found during IDE-1852: XPECT FIXME noerrors -// case NOT all remaining match XPECT type of '[b,c,b,b,b,x,b]' --> Array3 +// case NOT all remaining match XPECT type of '[b,c,b,b,b,x,b]' --> Array7 var v14b : Array3 = [b,c,b,b,b,x,b]; // expectation is longer: -// XPECT errors --> "Array3 is not a subtype of Iterable4." at "[b,c,b]" +// XPECT errors --> "Array is not a subtype of Iterable4." at "[b,c,b]" var v15a : Iterable4 = [b,c,b]; -// XPECT errors --> "Array3 is not a subtype of Array4." at "[b,c,b]" +// XPECT errors --> "Array is not a subtype of Array4." at "[b,c,b]" var v15b : Array4 = [b,c,b]; // XPECT errors --> "Array3 is not a subtype of Iterable4." at "[b,x,b]" @@ -131,3 +131,9 @@ var v22b : union{Array2,Array2} = [a,x]; var v23a : union{Iterable2,X} = [a,b]; // XPECT noerrors --> var v23b : union{Array2,X} = [a,b]; + +// XPECT type of 'v24' --> Array2> +var v24 : Array2> = [a,[b,"hi"]]; + +// XPECT type of 'v25' --> Array> +var v25 : Array> = [[b,c]]; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_22__CommaExpression/CommaExpression.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_22__CommaExpression/CommaExpression.n4js.xt index 27f03b3a9c..98529b09ec 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_22__CommaExpression/CommaExpression.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch08_01_22__CommaExpression/CommaExpression.n4js.xt @@ -29,5 +29,5 @@ bA = true,12,34,false; // XPECT errors --> "2 is not a subtype of boolean." at "2" bA = 2,1,0; -// XPECT errors --> ""g" is not a subtype of boolean." at "( 2,true,"g" )" +// XPECT errors --> ""g" is not a subtype of boolean." at "2,true,"g"" bA = ( 2,true,"g" ); diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring/Destruct_Array_Typed.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring/Destruct_Array_Typed.n4js.xt new file mode 100644 index 0000000000..ef6da0a8bb --- /dev/null +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring/Destruct_Array_Typed.n4js.xt @@ -0,0 +1,33 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.spec.tests.SpecXtTest END_SETUP */ + + +// XPECT type of 'arr' --> Array3 +const arr = [1, "2", 3]; + + +// XPECT type of 'ay' --> int +// XPECT type of 'by' --> string +// XPECT type of 'cy' --> int +const [ay, by, cy] = arr; + +ay;by;cy; + +// XPECT type of 'ax' --> int +const ax = arr[0]; +// XPECT type of 'bx' --> string +const bx = arr[1]; +// XPECT type of 'cx' --> int +const cx = arr[2]; + +ax;bx;cx; diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_other_useCase2.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_other_useCase2.n4js.xt index 08a1e0223b..d6c1913aec 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_other_useCase2.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_other_useCase2.n4js.xt @@ -23,6 +23,6 @@ function swap(param : Iterable2) : Iterable2 { } -// XPECT type of 'atIndex0' --> number +// XPECT type of 'atIndex0' --> int // XPECT type of 'atIndex1' --> string -var [atIndex0,atIndex1] = swap(["",42] as Iterable2); +var [atIndex0,atIndex1] = swap(["",42]); diff --git a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_other_useCase3.n4js.xt b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_other_useCase3.n4js.xt index 3a7ed319f8..a9bc275b3a 100644 --- a/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_other_useCase3.n4js.xt +++ b/tests/org.eclipse.n4js.spec.tests/xt-tests/Ch11_01__Array_and_Object_Destructuring/destructuring_typesystem/DestructTS_other_useCase3.n4js.xt @@ -42,5 +42,5 @@ async function waitForBoth(param : Iterable2,Promise async function foo2() { // XPECT type of 'result1' --> string // XPECT type of 'result2' --> number - var [result1,result2] = await waitForBoth( [p1,p2] as Iterable2,Promise> ); // TODO get rid of cast! + var [result1,result2] = await waitForBoth( [p1,p2] ); } diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/asynchronousIteration/asyncIteration_useCase0.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/asynchronousIteration/asyncIteration_useCase0.n4js.xt new file mode 100644 index 0000000000..5e03dc39aa --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/asynchronousIteration/asyncIteration_useCase0.n4js.xt @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest + END_SETUP + */ + +// XPECT noerrors --> +Promise.resolve({ string value: undefined, done: true }); diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/asynchronousIteration/asyncIteration_useCase1.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/asynchronousIteration/asyncIteration_useCase1.n4js.xt index 3b240d56d0..6bd2cdee62 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/asynchronousIteration/asyncIteration_useCase1.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/asynchronousIteration/asyncIteration_useCase1.n4js.xt @@ -13,7 +13,7 @@ END_SETUP */ - +// XPECT noerrors --> const asyncIterable = { elems: [ '1st', '2nd' ], idx: 0, diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typemodifier/optional_fields_object_literal_array.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typemodifier/optional_fields_object_literal_array.n4js.xt index 43e2ab3958..fe51ef6a7a 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typemodifier/optional_fields_object_literal_array.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typemodifier/optional_fields_object_literal_array.n4js.xt @@ -14,7 +14,7 @@ // XPECT noerrors var v1: Array<~Object with {a?: string}> = [{}]; -// XPECT errors --> "Array<~Object with { a: 42 }> is not a subtype of Array<~Object with { a?: string }> due to incompatible type arguments: ~Object with { a: 42 } is not a structural subtype of ~Object with { a?: string }: a failed: 42 is not equal to string." at "[{a: 42}]" +// XPECT errors --> "Array<~Object with { a: int }> is not a subtype of Array<~Object with { a?: string }> due to incompatible type arguments: ~Object with { a: int } is not a structural subtype of ~Object with { a?: string }: a failed: int is not equal to string." at "[{a: 42}]" var v2: Array<~Object with {a?: string}> = [{a: 42}]; const v3 = {}; diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/AT_691_structuralTypingThisAndObjectLiteral.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/AT_691_structuralTypingThisAndObjectLiteral.n4js.xt index 017da70c9c..1d09707c55 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/AT_691_structuralTypingThisAndObjectLiteral.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/AT_691_structuralTypingThisAndObjectLiteral.n4js.xt @@ -24,12 +24,12 @@ function bar(p : ~~S) {} foo({s: "Hello"}); // ok foo({s: "Hello", foo: function(){}}); -// "s has wrong type: int is not a subtype of string" XPECT errors --> "~Object with { s: 42; f: {function():void} } is not a structural subtype of ~S: missing method foo; s failed: 42 is not equal to string." at "{s: 42, f: function(){}}" +// "s has wrong type: int is not a subtype of string" XPECT errors --> "~Object with { s: int; f: {function():void} } is not a structural subtype of ~S: missing method foo; s failed: int is not equal to string." at "{s: 42, f: function(){}}" foo({s: 42, f: function(){}}); // ok bar({s: "Hello"}); // XPECT warnings --> "foo is not defined in ~~S; it will not be accessible from the receiving parameter." at "foo" bar({s: "Hello", foo: function(){}}); -// "s has wrong type: int is not a subtype of string" XPECT errors --> "~Object with { s: 42; foo: {function():void} } is not a structural subtype of ~~S: s failed: 42 is not equal to string." at "{s: 42, foo: function(){}}" +// "s has wrong type: int is not a subtype of string" XPECT errors --> "~Object with { s: int; foo: {function():void} } is not a structural subtype of ~~S: s failed: int is not equal to string." at "{s: 42, foo: function(){}}" bar({s: 42, foo: function(){}}); diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/Any_X_structuralObject.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/Any_X_structuralObject.n4js.xt new file mode 100644 index 0000000000..75cf030092 --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/Any_X_structuralObject.n4js.xt @@ -0,0 +1,28 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest END_SETUP */ + + + +let m : any = false; +let n : ~Object = {}; +m = n; +// XPECT errors --> "any is not a subtype of ~Object." at "m" +n = m; + + +let arr1 = [2, ""] +let arr2 : Array = []; +// XPECT errors --> "Array is not a subtype of Array2." at "arr2" +arr1 = arr2; +// XPECT noerrors --> +arr2 = arr1; diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/Generics_StructuralTyping.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/Generics_StructuralTyping.n4js.xt index 9c9e5293a8..97cc134234 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/Generics_StructuralTyping.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/Generics_StructuralTyping.n4js.xt @@ -30,5 +30,5 @@ var a : A = new A({t: "Hello"}); var b : B = new B({t: "Hello"}); // should be ok b.foo({t: "Hello"}).t = "Hello"; -// XPECT errors --> "~Object with { t: 10 } is not a structural subtype of ~~B: t failed: 10 is not equal to string." at "{t: 10}" +// XPECT errors --> "~Object with { t: int } is not a structural subtype of ~~B: t failed: int is not equal to string." at "{t: 10}" b.foo({t: 10}).t = "Hello"; diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/Generics_Union_call.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/Generics_Union_call.n4js.xt new file mode 100644 index 0000000000..33e824c62e --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/Generics_Union_call.n4js.xt @@ -0,0 +1,28 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest END_SETUP */ + + + + +interface ~A { + public concat(elem: S|Array): Array; +} +interface ~B { + public concat(elem: S|Array): Array; +} + +const c: A|B = null; + +// XPECT noerrors --> +// XPECT type of 'r' --> Array +const r = c.concat(""); diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/StructuralTypeRefWithTypeVarsInMembers.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/StructuralTypeRefWithTypeVarsInMembers.n4js.xt index 5d3bd61625..8f61a82307 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/StructuralTypeRefWithTypeVarsInMembers.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/StructuralTypeRefWithTypeVarsInMembers.n4js.xt @@ -94,7 +94,7 @@ var c3s : C3; c3s.m({prop: "Hello prop!"}); // TODO improve typeRefAsString in StructuralTypeRef // XPECT FIXME errors --> "~Object with { prop: 42; } is not a structural subtype of ~Object with { prop: string }: prop failed: 42 is not equal to string." at "{prop: 42}" -// XPECT errors --> "~Object with { prop: 42 } is not a structural subtype of ~Object with { prop: T } [[T->string]]: prop failed: 42 is not equal to string." at "{prop: 42}" +// XPECT errors --> "~Object with { prop: int } is not a structural subtype of ~Object with { prop: T } [[T->string]]: prop failed: int is not equal to string." at "{prop: 42}" c3s.m({prop: 42}); diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/performance/ArrLit.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/performance/ArrLit.n4js.xt new file mode 100644 index 0000000000..359bc17d3e --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/performance/ArrLit.n4js.xt @@ -0,0 +1,380 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest + END_SETUP + */ + +// XPECT noerrors --> + +@StringBased +export public enum Colors { + grey: "#000000" /* rgb(0, 0, 0) */ +} + + +@StringBased +export public enum PageThemeCssVar { + primary: "--primary", + secondary: "--secondary", + accent: "--accent", + text: "--text", + outline: "--outline", + background: "--background", + surface: "--surface", + onPrimary: "--on-primary", + onSecondary: "--on-secondary", + statusNormal: "--status-normal", + statusAllGood: "--status-all-good", + statusWarning: "--status-warning", + statusProblem: "--status-problem", + statusInactive: "--status-inactive", + highlightGlue: "--highlight-glue", + highlightTeal: "--highlight-teal", + highlightYellow: "--highlight-yellow", + highlightGolden: "--highlight-golden", + highlightPurple: "--highlight-purple", + ncShadow: "--nc-shadow", + ncOnShadow: "--nc-on-shadow", + ncPopupDimming: "--nc-popup-dimming", + ncTransparent: "--nc-transparent", + _creative, + _audioHaptics, + _audioHapticTick, + _audioHapticTickOff, + _audioHapticOpenOverlay, + _audioHapticError, + ffPrimary: "--ff-primary", + fwNormal: "--fw-normal", + fwMedium: "--fw-medium", + fwBold: "--fw-bold", + _mixColorPos, + _mixColorNeg, + _siteHeaderType, + _siteHeaderNavBarBackground, + _siteHeaderDisableBusinessName +} + +export public interface ~PageThemeStyles { + public label?: string; + public colorScheme?: "light"|"dark"; + + public [PageThemeCssVar.primary]?: string; + public [PageThemeCssVar.secondary]?: string; + public [PageThemeCssVar.accent]?: string; + public [PageThemeCssVar.text]?: string; + public [PageThemeCssVar.outline]?: string; + public [PageThemeCssVar.background]?: string; + public [PageThemeCssVar.surface]?: string; + public [PageThemeCssVar.onPrimary]?: string; + public [PageThemeCssVar.onSecondary]?: string; + public [PageThemeCssVar.statusNormal]?: string; + public [PageThemeCssVar.statusAllGood]?: string; + public [PageThemeCssVar.statusWarning]?: string; + public [PageThemeCssVar.statusProblem]?: string; + public [PageThemeCssVar.statusInactive]?: string; + public [PageThemeCssVar.highlightGlue]?: string; + public [PageThemeCssVar.highlightTeal]?: string; + public [PageThemeCssVar.highlightYellow]?: string; + public [PageThemeCssVar.highlightGolden]?: string; + public [PageThemeCssVar.highlightPurple]?: string; + public [PageThemeCssVar.ncShadow]?: string; + public [PageThemeCssVar.ncOnShadow]?: string; + public [PageThemeCssVar.ncPopupDimming]?: string; + public [PageThemeCssVar.ncTransparent]?: string; + public [PageThemeCssVar._creative]?: any; + public [PageThemeCssVar._audioHaptics]?: any; + public [PageThemeCssVar._audioHapticTick]?: any; + public [PageThemeCssVar._audioHapticTickOff]?: any; + public [PageThemeCssVar._audioHapticOpenOverlay]?: any; + public [PageThemeCssVar._audioHapticError]?: any; + public [PageThemeCssVar.ffPrimary]?: string; + public [PageThemeCssVar.fwNormal]?: string; + public [PageThemeCssVar.fwMedium]?: string; + public [PageThemeCssVar.fwBold]?: string; + public [PageThemeCssVar._mixColorPos]?: any; + public [PageThemeCssVar._mixColorNeg]?: any; + public [PageThemeCssVar._siteHeaderType]?: any; + public [PageThemeCssVar._siteHeaderNavBarBackground]?: any; + public [PageThemeCssVar._siteHeaderDisableBusinessName]?: any; +} + +export default public const brownTheme: [PageThemeStyles+, PageThemeStyles+] = [{ + label: "brown", + + colorScheme: "light", + "--primary": "#592d1d", + "--secondary": "#e45c46", + "--accent": "#ce8503", + "--text": Colors.grey, + "--outline": Colors.grey, + "--background": Colors.grey, + "--surface": Colors.grey, + "--on-primary": Colors.grey, + "--on-secondary": Colors.grey, + "--status-normal": Colors.grey, + "--status-all-good": Colors.grey, + "--status-warning": Colors.grey, + "--status-problem": Colors.grey, + "--status-inactive": Colors.grey, + "--highlight-glue": Colors.grey, + "--highlight-teal": Colors.grey, + "--highlight-yellow": Colors.grey, + "--highlight-golden": Colors.grey, + "--highlight-purple": Colors.grey, + "--nc-shadow": "255,255,255", + "--nc-on-shadow": "0,0,0", + "--nc-popup-dimming": "rgba(0,0,0,.3)", + "--nc-transparent": Colors.grey, + _creative: false, + _audioHaptics: false, + _audioHapticTick: "switch-on.mp3", + _audioHapticTickOff: "switch-off.mp3", + _audioHapticOpenOverlay: "pop.mp3", + _audioHapticError: "boop.mp3", + "--ff-primary": "Nunito", + "--fw-normal": "400", + "--fw-medium": "500", + "--fw-bold": "700", + _mixColorPos: [255,255,255,1], + _mixColorNeg: [0,0,0,1], + _siteHeaderType: "centeredLarge", + _siteHeaderNavBarBackground: "DEFAULT", + _siteHeaderDisableBusinessName: true, + "--text-2": "#393838", + "--text-4": "#2b2a2a", + "--text-5": "#242323", + "--text2": "#6c6b6b", + "--text3": "#7e7e7e", + "--text4": "#919090", + "--text5": "#a3a3a3", + "--text6": "#b5b5b5", + "--secondary-1": "#cd533f", + "--secondary-2": "#b64a38", + "--secondary-3": "#a04031", + "--secondary-4": "#89372a", + "--secondary1": "#e76c59", + "--secondary2": "#e97d6b", + "--secondary3": "#ec8d7e", + "--secondary4": "#ef9d90", + "--secondary6": "#f4beb5", + "--secondary8": "#fadeda", + "--secondary9": "#fcefed", + "--outline-1": "#cdcccc", + "--outline-2": "#b6b6b6", + "--outline-4": "#898888", + "--outline2": "#e9e9e9", + "--surface1": "#fefaf9", + "--surface2": "#fdf5f4", + "--surface3": "#fdf0ee", + "--surface4": "#fcebe9", + "--status-inactive-1": "#878584", + "--status-inactive-2": "#787676", + "--status-inactive-3": "#696867", + "--status-inactive5": "#cbcac9", + "--status-inactive8": "#eaeae9", + "--status-inactive9": "#f5f4f4", + "--status-normal-2": "#1152a7", + "--status-normal-3": "#0f4792", + "--status-normal5": "#8ab3e8", + "--status-normal8": "#d0e0f6", + "--status-normal9": "#e8f0fa", + "--status-all-good-2": "#3e8516", + "--status-all-good-3": "#377413", + "--status-all-good4": "#95ca76", + "--status-all-good5": "#a7d38d", + "--status-all-good8": "#dcedd1", + "--status-all-good9": "#edf6e8", + "--status-warning-2": "#c0571e", + "--status-warning-3": "#a84c1b", + "--status-warning5": "#f8b693", + "--status-warning8": "#fce2d4", + "--status-warning9": "#fef0e9", + "--status-problem-2": "#ab2222", + "--status-problem-3": "#961e1e", + "--status-problem-4": "#801a1a", + "--status-problem3": "#e26b6b", + "--status-problem4": "#e68080", + "--status-problem5": "#eb9595", + "--status-problem6": "#efaaaa", + "--status-problem8": "#f7d5d5", + "--status-problem9": "#fbeaea", + "--primary-2": "#472417", + "--primary-3": "#3e1f14", + "--primary-4": "#351b11", + "--primary-6": "#24120c", + "--primary1": "#6a4234", + "--primary3": "#8b6c61", + "--primary4": "#9b8177", + "--primary5": "#ac968e", + "--primary6": "#bdaba5", + "--primary8": "#ded5d2", + "--background1": "#faf9f8", + "--background2": "#f5f2f1", + "--background3": "#f0eceb", + "--background4": "#ebe6e4", + "--background5": "#e6e0dd", + "--accent2": "#d89d35", + "--accent7": "#f0dab3", + "--on-secondary6": "#ffffff", + "--on-primary-1": "#e6e6e6", + "--on-primary-3": "#b3b3b3", + "--highlight-glue-1": "#66899c", + "--highlight-glue-3": "#4f6a79", + "--highlight-glue8": "#e3eaef", + "--highlight-teal-1": "#2ca0b8", + "--highlight-teal-3": "#227d8f", + "--highlight-teal8": "#d6f0f5", + "--highlight-yellow-1": "#debf21", + "--highlight-yellow-3": "#ad941a", + "--highlight-yellow8": "#fdf6d3", + "--highlight-golden-1": "#9e996a", + "--highlight-golden-3": "#7b7753", + "--highlight-golden8": "#efeee4", + "--highlight-purple-1": "#a656b3", + "--highlight-purple-3": "#81438b", + "--highlight-purple8": "#f1dff4" +}, { + label: "brown-dark", + + colorScheme: "dark", + "--primary": "#bdaba5", + "--secondary": "#f2aea2", + "--accent": "#e6c281", + "--text": Colors.grey, + "--outline": "#363636", + "--background": "#1a1a1a", + "--surface": "#1a1a1a", + "--on-primary": Colors.grey, + "--on-secondary": Colors.grey, + "--status-normal": "#8ab3e8", + "--status-all-good": "#a6d28d", + "--status-warning": "#f8b693", + "--status-problem": "#ea9595", + "--status-inactive": "#cac9c9", + "--highlight-glue": "#b8ccd6", + "--highlight-teal": "#98d8e6", + "--highlight-yellow": "#fbe992", + "--highlight-golden": "#d7d5bb", + "--highlight-purple": "#dcafe3", + "--nc-shadow": "0,0,0", + "--nc-on-shadow": "0,0,0", + "--nc-popup-dimming": "rgba(0,0,0,.6)", + "--nc-transparent": Colors.grey, + _creative: false, + _audioHaptics: false, + _audioHapticTick: "switch-on.mp3", + _audioHapticTickOff: "switch-off.mp3", + _audioHapticOpenOverlay: "pop.mp3", + _audioHapticError: "boop.mp3", + "--ff-primary": "Nunito", + "--fw-normal": "400", + "--fw-medium": "500", + "--fw-bold": "700", + _mixColorPos: [0,0,0,1], + _mixColorNeg: [255,255,255,1], + _siteHeaderType: null, + _siteHeaderNavBarBackground: "DEFAULT", + _siteHeaderDisableBusinessName: false, + "--text-2": "#f6f6f5", + "--text-4": "#f8f8f8", + "--text-5": "#fafaf9", + "--text2": "#c3c3c2", + "--text3": "#ababaa", + "--text4": "#929292", + "--text5": "#7a7a7a", + "--text6": "#626261", + "--secondary-1": "#f3b6ab", + "--secondary-2": "#f5beb5", + "--secondary-3": "#f6c6be", + "--secondary-4": "#f7cec7", + "--secondary1": "#da9d92", + "--secondary2": "#c28b82", + "--secondary3": "#a97a71", + "--secondary4": "#916861", + "--secondary6": "#614641", + "--secondary8": "#302320", + "--secondary9": "#181110", + "--outline-1": "#4a4a4a", + "--outline-2": "#5e5e5e", + "--outline-4": "#868686", + "--outline2": "#2b2b2b", + "--surface1": "#201e1e", + "--surface2": "#272322", + "--surface3": "#2d2726", + "--surface4": "#342c2a", + "--status-inactive-1": "#cfcece", + "--status-inactive-2": "#d5d4d4", + "--status-inactive-3": "#dad9d9", + "--status-inactive5": "#656565", + "--status-inactive8": "#282828", + "--status-inactive9": "#141414", + "--status-normal-2": "#a1c2ed", + "--status-normal-3": "#adcaef", + "--status-normal5": "#455a74", + "--status-normal8": "#1c242e", + "--status-normal9": "#0e1217", + "--status-all-good-2": "#b8dba4", + "--status-all-good-3": "#c1e0af", + "--status-all-good4": "#647e55", + "--status-all-good5": "#536947", + "--status-all-good8": "#212a1c", + "--status-all-good9": "#11150e", + "--status-warning-2": "#f9c5a9", + "--status-warning-3": "#faccb3", + "--status-warning5": "#7c5b4a", + "--status-warning8": "#32241d", + "--status-warning9": "#19120f", + "--status-problem-2": "#eeaaaa", + "--status-problem-3": "#f0b5b5", + "--status-problem-4": "#f2bfbf", + "--status-problem3": "#a46868", + "--status-problem4": "#8c5959", + "--status-problem5": "#754b4b", + "--status-problem6": "#5e3c3c", + "--status-problem8": "#2f1e1e", + "--status-problem9": "#170f0f", + "--primary-2": "#cabcb7", + "--primary-3": "#d1c4c0", + "--primary-4": "#d7cdc9", + "--primary-6": "#e5dddb", + "--primary1": "#aa9a95", + "--primary3": "#847873", + "--primary4": "#716763", + "--primary5": "#5f5653", + "--primary6": "#4c4442", + "--primary8": "#262221", + "--background1": "#1f1e1e", + "--background2": "#242322", + "--background3": "#292727", + "--background4": "#2e2b2b", + "--background5": "#32302f", + "--accent2": "#b89b67", + "--accent7": "#453a27", + "--on-secondary6": "#0d0d0d", + "--on-primary-1": "#373736", + "--on-primary-3": "#646463", + "--highlight-glue-1": "#bfd1da", + "--highlight-glue-3": "#cddbe2", + "--highlight-glue8": "#25292b", + "--highlight-teal-1": "#a2dce9", + "--highlight-teal-3": "#b7e4ee", + "--highlight-teal8": "#1e2b2e", + "--highlight-yellow-1": "#fbeb9d", + "--highlight-yellow-3": "#fcf0b3", + "--highlight-yellow8": "#322f1d", + "--highlight-golden-1": "#dbd9c2", + "--highlight-golden-3": "#e3e2cf", + "--highlight-golden8": "#2b2b25", + "--highlight-purple-1": "#e0b7e6", + "--highlight-purple-3": "#e7c7eb", + "--highlight-purple8": "#2c232d" +}]; diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_callExpr_nesting.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_callExpr_nesting.n4js.xt new file mode 100644 index 0000000000..ae95fb8caf --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_callExpr_nesting.n4js.xt @@ -0,0 +1,50 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest END_SETUP */ + + + +interface ~A { public j:J } +interface ~B { public i:I } +interface ~I { public x:string; } +interface ~J extends I { public y:string; } +const aa : A[] = []; + + + + + + +// XPECT noerrors --> +// XPECT type of 'oo1' --> Array +// XPECT type of '{i:a1.j}' --> ~Object with { i: J } +const oo1 = aa.map((a1) :B => ({i:a1.j} as B)); + +// XPECT noerrors --> +// XPECT type of 'oo2' --> Array +// XPECT type of '{i:a2.j}' --> ~Object with { i: J } +const oo2 = aa.map((a2) => ({i:a2.j} as B)); + +// XPECT noerrors --> +// XPECT type of 'oo3' --> Array +// XPECT type of '{i:a3.j}' --> ~Object with { i: I } +const oo3 = aa.map((a3) :B => ({i:a3.j})); + +// XPECT noerrors --> +// XPECT type of 'oo4' --> Array +// XPECT type of '{i:a4.j}' --> ~Object with { i: J } +const oo4 = aa.map((a4) => ({i:a4.j})) as B[]; + +// XPECT noerrors --> +// XPECT type of 'oo5' --> Array +// XPECT type of '{i:a5.j}' --> ~Object with { i: I } +const oo5 : B[] = aa.map((a5) => ({i:a5.j})); diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_cast.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_cast.n4js.xt new file mode 100644 index 0000000000..1d45a95685 --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_cast.n4js.xt @@ -0,0 +1,32 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest END_SETUP */ + + + +let a1 : Array = []; +let a2 : Array = []; +// XPECT noerrors --> +a1 = a2; +// XPECT noerrors --> +a2 = a1 as Array; + +// XPECT noerrors --> +// XPECT type of 'a1.filter((m) => m instanceof N4DataField)' --> Array +let r = a1.filter((m) => m instanceof N4DataField) as Array; + + + +// XPECT noerrors --> +// XPECT type of '[1, ""]' --> Array2 +let x = [1, ""] as any[]; +x; diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_concat.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_concat.n4js.xt new file mode 100644 index 0000000000..f4e24da8fb --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_concat.n4js.xt @@ -0,0 +1,24 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest END_SETUP */ + + +class Item { + public i: int; +} +function fItem() : Array<~Item> { + return []; +} +let arrItems : Array<~Item> = []; +// XPECT noerrors --> +// XPECT type of 'arrItems.concat(fItem())' --> Array<~Item> +arrItems = arrItems.concat(fItem()); diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_empty_specialcase.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_empty_specialcase.n4js.xt new file mode 100644 index 0000000000..e59a2aca07 --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_empty_specialcase.n4js.xt @@ -0,0 +1,23 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest END_SETUP */ + + + + +// XPECT noerrors --> +// XPECT type of '[].concat(1)' --> Array +const a : number[] = [].concat(1); + +// XPECT noerrors --> +// XPECT type of '[1].concat([])' --> Array +const b : number[] = [1].concat([]); diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_error_missing_prop.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_error_missing_prop.n4js.xt new file mode 100644 index 0000000000..f3b0493e26 --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_error_missing_prop.n4js.xt @@ -0,0 +1,27 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest END_SETUP */ + + + + + + +function fn(iter: Iterable): T? { + return null; +} +interface ~I { public cx1: int; public cx2: int } + +// XPECT noerrors --> +// XPECT type of '{ cx1 : fn([1]) }' --> ~Object with { cx1: int } +const cy = { cx1 : fn([1]) } as I +cy; diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_simple.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_simple.n4js.xt index 9372aadf6d..c5bd62b51e 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_simple.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ArrLit_simple.n4js.xt @@ -25,7 +25,7 @@ var c : C; // base cases -// XPECT type of '[ b, c ]' --> Array +// XPECT type of '[ b, c ]' --> Array2 var v01 = [ b, c ]; // XPECT type of '[ b, c ]' --> Array @@ -42,7 +42,7 @@ var v04 : Array = [ b, c ]; // with padding -// XPECT type of '[ ,,, b,,, c,,, ]' --> Array +// XPECT type of '[ ,,, b,,, c,,, ]' --> Array8 var v11 = [ ,,, b,,, c,,, ]; // XPECT type of '[ ,,, b,,, c,,, ]' --> Array @@ -58,7 +58,7 @@ var v14 : Array = [ ,,, b,,, c,,, ]; // ------------------------------------------------------------------ // with spread of a literal -// XPECT type of '[ b, ...[c] ]' --> Array +// XPECT type of '[ b, ...[c] ]' --> Array2 var v21 = [ b, ...[c] ]; // XPECT type of '[ b, ...[c] ]' --> Array @@ -81,9 +81,9 @@ class MyIterable { } let myIterableOfC: MyIterable; -// XPECT type of '[ b, ...getArrOfC() ]' --> Array +// XPECT type of '[ b, ...getArrOfC() ]' --> Array2 var v31a = [ b, ...getArrOfC() ]; -// XPECT type of '[ b, ...myIterableOfC ]' --> Array +// XPECT type of '[ b, ...myIterableOfC ]' --> Array2 var v31b = [ b, ...myIterableOfC ]; // XPECT type of '[ b, ...getArrOfC() ]' --> Array @@ -125,7 +125,7 @@ var v44 : Array = []; // the special handling applies only to IterableN!) -// XPECT type of '[ b, c ]' --> Array +// XPECT type of '[ b, c ]' --> Array2 var v51 = [ b, c ]; // XPECT type of '[ b, c ]' --> Array diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/CallExpr_union.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/CallExpr_union.n4js.xt new file mode 100644 index 0000000000..eb77a2584f --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/CallExpr_union.n4js.xt @@ -0,0 +1,22 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest END_SETUP */ + + +// XPECT noerrors --> + +function f(arg : Object|(string)=>void) {} + +f((s) => { + // XPECT type of 's' --> string + s; +}); diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/CondExpr.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/CondExpr.n4js.xt index 8af8ae95c8..c133accb0e 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/CondExpr.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/CondExpr.n4js.xt @@ -19,19 +19,26 @@ interface I { class J implements I { public mfj : number; } +class K implements I { + public mfj : number; +} let b : boolean = true; -// XPECT type of 'k1' --> ~Object with { i: ~I } +// XPECT type of '{i : new J()}' --> ~Object with { i: ~I } const k1 : ~Object with {i: ~I} = {i : new J()}; -// XPECT type of 'k2' --> ~Object with { i: ~I } +// XPECT type of 'b ? {i : new J()} : undefined' --> ~Object with { i: ~I } const k2 : ~Object with {i: ~I} = b ? {i : new J()} : undefined; -// XPECT type of 'k3' --> ~Object with { i: ~I } +// XPECT type of 'b ? {i : new J()} : null' --> ~Object with { i: ~I } const k3 : ~Object with {i: ~I} = b ? {i : new J()} : null; +// GH-2615 XPECT FIXME noerrors --> +// GH-2615 XPECT FIXME type of 'b ? {i : new J()} : {i : new K()}' --> ~Object with { i: ~I } +const k4 : ~Object with {i: ~I} = b ? {i : new J()} : {i : new K()}; + diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ObjLit_combined.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ObjLit_combined.n4js.xt index 4193872c5c..35257c5c42 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ObjLit_combined.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ObjLit_combined.n4js.xt @@ -40,7 +40,7 @@ fooMerge( foo2( foo2( fooOL2( { left: b, right: null } )))) fooMerge( foo2( foo2( fooOL2( { left: b, right: c } )))) -// XPECT type of '{ left: b, right: x }' --> ~Object with { left: union{B,X}; right: union{X,B} } +// XPECT type of '{ left: b, right: x }' --> ~Object with { left: union{B,X}; right: union{B,X} } fooMerge( foo2( foo2( fooOL2( { left: b, right: x } )))) diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ObjLit_quasi_optional.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ObjLit_quasi_optional.n4js.xt new file mode 100644 index 0000000000..e592b2e6e4 --- /dev/null +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/typesystem/polyExpressions/ObjLit_quasi_optional.n4js.xt @@ -0,0 +1,23 @@ +/* + * 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 + */ + +/* XPECT_SETUP org.eclipse.n4js.xpect.tests.N4jsXtTest END_SETUP */ + + + +// XPECT noerrors --> +class I { + public var0 = new Object(); + public var1: int +} +function f(a:~i~T=) :T {return null;} +// XPECT type of '{var1: undefined}' --> ~Object with { var1: int } +f({var1: undefined}) diff --git a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/types/StructuralTyping.n4js.xt b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/types/StructuralTyping.n4js.xt index 31961964ba..0ca0c7fac5 100644 --- a/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/types/StructuralTyping.n4js.xt +++ b/tests/org.eclipse.n4js.xpect.tests/xt-tests/validation/types/StructuralTyping.n4js.xt @@ -36,7 +36,7 @@ function i(d : ~D) {} n(new C()); //XPECT errors --> "C is not a structural subtype of ~I: missing setter or field y." at "new C()" f(new C()); -// XPECT errors --> "~Object with { x: number } is not a structural subtype of ~I: missing method foo." at "{x:10}" +// XPECT errors --> "~Object with { x: int } is not a structural subtype of ~I: missing method foo." at "{x:10}" f({x:10}); g({x:10}); // XPECT errors --> "D is not a subtype of I." at "new D()" diff --git a/version.json b/version.json index 31c4782284..1296080959 100644 --- a/version.json +++ b/version.json @@ -1,5 +1,5 @@ { "major": "0", - "minor": "36", + "minor": "37", "tag": "" } \ No newline at end of file From dd2c791d1f2f56000e97be1b4ed88d674b844821 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:24:22 +0200 Subject: [PATCH 23/26] Bump ip from 2.0.0 to 2.0.1 in /n4js-libs (#2616) Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1. - [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1) --- updated-dependencies: - dependency-name: ip dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- n4js-libs/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/n4js-libs/yarn.lock b/n4js-libs/yarn.lock index 56e7be32d3..05e8d4c616 100644 --- a/n4js-libs/yarn.lock +++ b/n4js-libs/yarn.lock @@ -2192,9 +2192,9 @@ inquirer@^8.2.4: wrap-ansi "^6.0.1" ip@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + version "2.0.1" + resolved "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105" + integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ== is-arrayish@^0.2.1: version "0.2.1" From 7fea72a42283f06193efdb4b7f3e129ea13c77ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:25:53 +0200 Subject: [PATCH 24/26] Bump follow-redirects in /n4js-libs/packages/n4js-cli (#2617) Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.3 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.3...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- n4js-libs/packages/n4js-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/n4js-libs/packages/n4js-cli/package.json b/n4js-libs/packages/n4js-cli/package.json index f293a8027a..3e11710934 100644 --- a/n4js-libs/packages/n4js-cli/package.json +++ b/n4js-libs/packages/n4js-cli/package.json @@ -29,7 +29,7 @@ "@types/node": "^16", "@types/debug": "4.1.12", "@types/npmlog": "7.0.0", - "follow-redirects": "1.15.3", + "follow-redirects": "1.15.6", "decompress": "4.2.1", "debug": "~4.3.4", "npmlog": "7.0.1", From a59e859681f2dcaf0f9733c7a61866e3991e61f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:27:05 +0200 Subject: [PATCH 25/26] Bump es5-ext from 0.10.62 to 0.10.64 in /n4js-tools/n4jsd-generator (#2619) Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64. - [Release notes](https://github.com/medikoo/es5-ext/releases) - [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md) - [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64) --- updated-dependencies: - dependency-name: es5-ext dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- n4js-tools/n4jsd-generator/yarn.lock | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/n4js-tools/n4jsd-generator/yarn.lock b/n4js-tools/n4jsd-generator/yarn.lock index 8181617845..41bf739747 100644 --- a/n4js-tools/n4jsd-generator/yarn.lock +++ b/n4js-tools/n4jsd-generator/yarn.lock @@ -294,13 +294,14 @@ end-of-stream@^1.0.0: dependencies: once "^1.4.0" -es5-ext@^0.10.12, es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: - version "0.10.62" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" - integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== +es5-ext@^0.10.12, es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.64" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714" + integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg== dependencies: es6-iterator "^2.0.3" es6-symbol "^3.1.3" + esniff "^2.0.1" next-tick "^1.1.0" es6-iterator@2, es6-iterator@^2.0.3: @@ -335,6 +336,16 @@ esm@3.2.25: resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== +esniff@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" + integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg== + dependencies: + d "^1.0.1" + es5-ext "^0.10.62" + event-emitter "^0.3.5" + type "^2.7.2" + esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" From f8f3fec818e46dde8e0ef1adb3e4ec97243dab64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:42:49 +0200 Subject: [PATCH 26/26] Bump es5-ext from 0.10.62 to 0.10.64 in /n4js-libs (#2618) Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64. - [Release notes](https://github.com/medikoo/es5-ext/releases) - [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md) - [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64) --- updated-dependencies: - dependency-name: es5-ext dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- n4js-libs/yarn.lock | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/n4js-libs/yarn.lock b/n4js-libs/yarn.lock index 05e8d4c616..7e3ffcc21f 100644 --- a/n4js-libs/yarn.lock +++ b/n4js-libs/yarn.lock @@ -1472,13 +1472,14 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es5-ext@^0.10.12, es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: - version "0.10.62" - resolved "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" - integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== +es5-ext@^0.10.12, es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.64" + resolved "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714" + integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg== dependencies: es6-iterator "^2.0.3" es6-symbol "^3.1.3" + esniff "^2.0.1" next-tick "^1.1.0" es6-iterator@2, es6-iterator@^2.0.3: @@ -1523,6 +1524,16 @@ escape-string-regexp@^1.0.5: resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== +esniff@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" + integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg== + dependencies: + d "^1.0.1" + es5-ext "^0.10.62" + event-emitter "^0.3.5" + type "^2.7.2" + esprima@^4.0.0: version "4.0.1" resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"