diff options
Diffstat (limited to 'plugins/org.eclipse.xtend')
168 files changed, 26419 insertions, 0 deletions
diff --git a/plugins/org.eclipse.xtend/.classpath b/plugins/org.eclipse.xtend/.classpath new file mode 100644 index 00000000..304e8618 --- /dev/null +++ b/plugins/org.eclipse.xtend/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/plugins/org.eclipse.xtend/.cvsignore b/plugins/org.eclipse.xtend/.cvsignore new file mode 100644 index 00000000..0850bc03 --- /dev/null +++ b/plugins/org.eclipse.xtend/.cvsignore @@ -0,0 +1,10 @@ +bin +*.jardesc +.antlr-eclipse +out +*.settings +temp.folder +@dot +build.xml +javaCompiler...args +oaw-core-plugins-4.0.0 diff --git a/plugins/org.eclipse.xtend/.project b/plugins/org.eclipse.xtend/.project new file mode 100644 index 00000000..d1a8c4b1 --- /dev/null +++ b/plugins/org.eclipse.xtend/.project @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.xtend</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.xtend.base.oawBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.antlr.eclipse.core.antlrnature</nature> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.xtend.base.oawNature</nature> + </natures> +</projectDescription> diff --git a/plugins/org.eclipse.xtend/META-INF/MANIFEST.MF b/plugins/org.eclipse.xtend/META-INF/MANIFEST.MF new file mode 100644 index 00000000..83bf96b1 --- /dev/null +++ b/plugins/org.eclipse.xtend/META-INF/MANIFEST.MF @@ -0,0 +1,34 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.eclipse.xtend +Bundle-Version: 0.7.0.qualifier +Bundle-Localization: plugin +Bundle-Vendor: %providerName +Require-Bundle: org.eclipse.emf.mwe.core, + org.apache.commons.logging, + org.antlr.runtime, + org.eclipse.emf.common +Export-Package: org.eclipse.internal.xtend.check.codeassist, + org.eclipse.internal.xtend.expression.ast, + org.eclipse.internal.xtend.expression.codeassist, + org.eclipse.internal.xtend.expression.debug, + org.eclipse.internal.xtend.expression.parser, + org.eclipse.internal.xtend.type.baseimpl, + org.eclipse.internal.xtend.type.baseimpl.types, + org.eclipse.internal.xtend.type.impl.java, + org.eclipse.internal.xtend.type.impl.java.beans, + org.eclipse.internal.xtend.type.impl.oawclassic, + org.eclipse.internal.xtend.util, + org.eclipse.internal.xtend.util.internal.icu, + org.eclipse.internal.xtend.xtend, + org.eclipse.internal.xtend.xtend.ast, + org.eclipse.internal.xtend.xtend.codeassist, + org.eclipse.internal.xtend.xtend.parser, + org.eclipse.internal.xtend.xtend.types, + org.eclipse.xtend, + org.eclipse.xtend.check, + org.eclipse.xtend.expression, + org.eclipse.xtend.typesystem +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Eclipse-BuddyPolicy: dependent diff --git a/plugins/org.eclipse.xtend/TODO.txt b/plugins/org.eclipse.xtend/TODO.txt new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/plugins/org.eclipse.xtend/TODO.txt diff --git a/plugins/org.eclipse.xtend/about.html b/plugins/org.eclipse.xtend/about.html new file mode 100644 index 00000000..c207d05a --- /dev/null +++ b/plugins/org.eclipse.xtend/about.html @@ -0,0 +1,33 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/> +<title>About</title> +</head> +<body lang="EN-US"> +<h2>About This Content</h2> + +<p>May 10, 2006</p> +<h3>License</h3> + +<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. +For purposes of the EPL, "Program" will mean the Content.</p> + +<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p> + +<h3>Source Code</h3> +<p>This plug-in contains source code zip files ("Source Zips") that correspond to binary content in other plug-ins. These Source Zips may be distributed under different license +agreements and/or notices. Details about these license agreements and notices are contained in "about.html" files ("Abouts") located in sub-directories in the +src/ directory of this plug-in. Such Abouts govern your use of the Source Zips in that directory, not the EPL.</p> + +</body> +</html>
\ No newline at end of file diff --git a/plugins/org.eclipse.xtend/about.ini b/plugins/org.eclipse.xtend/about.ini new file mode 100644 index 00000000..2143c4cc --- /dev/null +++ b/plugins/org.eclipse.xtend/about.ini @@ -0,0 +1,29 @@ +# about.ini +# contains information about a feature +# java.io.Properties file (ISO 8859-1 with "\" escapes) +# "%key" are externalized strings defined in about.properties +# This file does not need to be translated. + +# Property "aboutText" contains blurb for "About" dialog (translated) +aboutText=%blurb + +# Property "windowImage" contains path to window icon (16x16) +# needed for primary features only + +# Property "featureImage" contains path to feature image (32x32) +featureImage=eclipse32.png + +# Property "aboutImage" contains path to product image (500x330 or 115x164) +# needed for primary features only + +# Property "appName" contains name of the application (not translated) +# needed for primary features only + +# Property "welcomePage" contains path to welcome page (special XML-based format) +# optional + +# Property "welcomePerspective" contains the id of the perspective in which the +# welcome page is to be opened. +# optional + + diff --git a/plugins/org.eclipse.xtend/about.mappings b/plugins/org.eclipse.xtend/about.mappings new file mode 100644 index 00000000..a28390a7 --- /dev/null +++ b/plugins/org.eclipse.xtend/about.mappings @@ -0,0 +1,6 @@ +# about.mappings +# contains fill-ins for about.properties +# java.io.Properties file (ISO 8859-1 with "\" escapes) +# This file does not need to be translated. + +0=@build@ diff --git a/plugins/org.eclipse.xtend/about.properties b/plugins/org.eclipse.xtend/about.properties new file mode 100644 index 00000000..cad256ac --- /dev/null +++ b/plugins/org.eclipse.xtend/about.properties @@ -0,0 +1,24 @@ +############################################################################### +# Copyright (c) 2000, 2006 openArchitectureWare commiters and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# openArchitectureWare commiters - initial API and implementation +############################################################################### +# about.properties +# contains externalized strings for about.ini +# java.io.Properties file (ISO 8859-1 with "\" escapes) +# fill-ins are supplied by about.mappings +# This file should be translated. + +blurb=openArchitectureWare code generator\\n\\ +\n\ +Version: {featureVersion}\n\ +Build id: {0}\n\ +\n\ +(c) Copyright openArchitectureWare contributors and others 2000, 2007. All rights reserved.\n\ +Visit http://www.openArchitectureWare.org + diff --git a/plugins/org.eclipse.xtend/build.properties b/plugins/org.eclipse.xtend/build.properties new file mode 100644 index 00000000..42b9852a --- /dev/null +++ b/plugins/org.eclipse.xtend/build.properties @@ -0,0 +1,19 @@ +############################################################################### +# Copyright (c) 2005, 2006 committers of openArchitectureWare and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# committers of openArchitectureWare - initial API and implementation +############################################################################### +source.. = src/ +bin.includes = META-INF/,\ + .,\ + about.html,\ + about.ini,\ + about.properties,\ + about.mappings,\ + eclipse32.png,\ + plugin.properties diff --git a/plugins/org.eclipse.xtend/eclipse32.png b/plugins/org.eclipse.xtend/eclipse32.png Binary files differnew file mode 100644 index 00000000..ded4869b --- /dev/null +++ b/plugins/org.eclipse.xtend/eclipse32.png diff --git a/plugins/org.eclipse.xtend/plugin.properties b/plugins/org.eclipse.xtend/plugin.properties new file mode 100644 index 00000000..26d34f7a --- /dev/null +++ b/plugins/org.eclipse.xtend/plugin.properties @@ -0,0 +1,12 @@ +############################################################################### +# Copyright (c) 2000, 2006 openArchitectureWare commiters and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# openArchitectureWare commiters - initial API and implementation +############################################################################### +pluginName=openArchitectureWare core expressions +providerName=openArchitectureWare.org diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/check/codeassist/CheckFastAnalyzer.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/check/codeassist/CheckFastAnalyzer.java new file mode 100644 index 00000000..359f56bf --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/check/codeassist/CheckFastAnalyzer.java @@ -0,0 +1,137 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.check.codeassist; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.Stack; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.internal.xtend.expression.codeassist.LazyVar; +import org.eclipse.internal.xtend.xtend.codeassist.FastAnalyzer; +import org.eclipse.internal.xtend.xtend.codeassist.Partition; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.ExpressionFacade; +import org.eclipse.xtend.expression.Resource; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.ParameterizedType; +import org.eclipse.xtend.typesystem.Type; + +public class CheckFastAnalyzer { + + private final static Pattern VALIDATE_PATTERN = Pattern + .compile("context\\s+([\\[\\]:\\w\\]]+)\\s+[^;]*\\z"); + + private final static Pattern TYPEDECL_PATTERN = Pattern.compile("context\\s+[\\[\\]:\\w\\]]*\\z"); + + private CheckFastAnalyzer() { + } + + protected static boolean isTypeDeclaration(final String s) { + final Matcher m = TYPEDECL_PATTERN.matcher(s); + return m.find(); + } + + public final static Stack<Set<LazyVar>> computeStack(final String toAnalyze) { + final Matcher m = VALIDATE_PATTERN.matcher(toAnalyze); + final Stack<Set<LazyVar>> stack = new Stack<Set<LazyVar>>(); + if (!m.find()) + return stack; + final Set<LazyVar> vars = new HashSet<LazyVar>(); + stack.push(vars); + final LazyVar v = new LazyVar(); + v.typeName = m.group(1); + v.name = ExecutionContext.IMPLICIT_VARIABLE; + vars.add(v); + return stack; + } + + public final static Partition computePartition(final String str) { + if (FastAnalyzer.isInsideImport(str)) + return Partition.NAMESPACE_IMPORT; + + if (FastAnalyzer.isInsideExtensionImport(str)) + return Partition.EXTENSION_IMPORT; + + if (isTypeDeclaration(str)) + return Partition.TYPE_DECLARATION; + + final Stack<Set<LazyVar>> s = computeStack(str); + if (!s.isEmpty()) + return Partition.EXPRESSION; + + return Partition.DEFAULT; + } + + public final static ExecutionContext computeExecutionContext(final String str, ExecutionContext ctx) { + final Partition p = computePartition(str); + if (p == Partition.EXPRESSION || p == Partition.TYPE_DECLARATION) { + + final List<String> imports = FastAnalyzer.findImports(str); + final List<String> extensionImports = FastAnalyzer.findExtensions(str); + final Resource res = new Resource() { + + private String fqn; + + public String getFullyQualifiedName() { + return fqn; + } + + public void setFullyQualifiedName(String fqn) { + this.fqn = fqn; + } + + public String[] getImportedNamespaces() { + return imports.toArray(new String[imports.size()]); + } + + public String[] getImportedExtensions() { + return extensionImports.toArray(new String[extensionImports.size()]); + } + + }; + + ctx = ctx.cloneWithResource(res); + + for (final Iterator<Set<LazyVar>> iter = computeStack(str).iterator(); iter.hasNext();) { + final Set<LazyVar> vars = iter.next(); + for (final Iterator<LazyVar> iterator = vars.iterator(); iterator.hasNext();) { + final LazyVar v = iterator.next(); + Type vType = null; + if (v.typeName != null) { + vType = ctx.getTypeForName(v.typeName); + } else { + vType = new ExpressionFacade(ctx).analyze(v.expression, new HashSet<AnalysationIssue>()); + if (v.forEach) { + if (vType instanceof ParameterizedType) { + vType = ((ParameterizedType) vType).getInnerType(); + } else { + vType = null; + } + } + } + ctx = ctx.cloneWithVariable(new Variable(v.name, vType)); + } + } + } + return ctx; + + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/BooleanLiteral.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/BooleanLiteral.java new file mode 100644 index 00000000..2406e715 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/BooleanLiteral.java @@ -0,0 +1,41 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class BooleanLiteral extends Literal { + + public BooleanLiteral( final Identifier literalValue) { + super(literalValue); + } + + @Override + public Object evaluateInternal(final ExecutionContext ctx) { + return new Boolean(getLiteralValue().getValue()); + } + + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + return ctx.getBooleanType(); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/BooleanOperation.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/BooleanOperation.java new file mode 100644 index 00000000..f43febbc --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/BooleanOperation.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.EvaluationException; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +/** + * + */ +public class BooleanOperation extends Expression { + + private static final String IMPLIES = "implies"; + + private static final String OR = "||"; + + private static final String AND = "&&"; + + private Expression left; + + private Expression right; + + private Identifier operator; + + public BooleanOperation(final Identifier operator, final Expression e, + final Expression r) { + this.operator = operator; + left = e; + right = r; + } + + public Expression getLeft() { + return left; + } + + public Identifier getOperator() { + return operator; + } + + public Expression getRight() { + return right; + } + + @Override + protected Object evaluateInternal(final ExecutionContext ctx) { + final Boolean l = evaluateToBoolean(left, ctx); + if (l == null) + return ctx.handleNullEvaluation(this); + if (operator.getValue().equals(AND)) { + if (!l.booleanValue()) + return Boolean.FALSE; + final Boolean r = evaluateToBoolean(right, ctx); + if (r == null) + return ctx.handleNullEvaluation(this); + return Boolean.valueOf(l.booleanValue() && r.booleanValue()); + } else if (operator.getValue().equals(OR)) { + if (l.booleanValue()) + return Boolean.TRUE; + + final Boolean r = evaluateToBoolean(right, ctx); + if (r == null) + return ctx.handleNullEvaluation(this); + return Boolean.valueOf(l.booleanValue() || r.booleanValue()); + } else if (operator.getValue().equals(IMPLIES)) { + if (!l.booleanValue()) + return Boolean.TRUE; + Boolean b = evaluateToBoolean(right, ctx); + if (b== null) + return ctx.handleNullEvaluation(this); + return b; + } else + throw new EvaluationException("Unkown Boolean operator " + operator.getValue(), this, ctx); + } + + private Boolean evaluateToBoolean(final Expression expr, final ExecutionContext ctx) { + final Object l = expr.evaluate(ctx); + if (l == null) + return null; + if (!(l instanceof Boolean)) { + final Type t = ctx.getType(l); + throw new EvaluationException("Boolean expected but was " + t.getName(), expr, ctx); + } + final Boolean result = (Boolean) l; + return result; + } + + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + final Type l = left.analyze(ctx, issues); + final Type r = right.analyze(ctx, issues); + if (l == null || r == null) + return null; + + if (!ctx.getBooleanType().equals(l)) { + issues.add(new AnalysationIssue(AnalysationIssue.INCOMPATIBLE_TYPES, "Boolean expected! Found : " + + l.getName(), left)); + } + if (!ctx.getBooleanType().equals(r)) { + issues.add(new AnalysationIssue(AnalysationIssue.INCOMPATIBLE_TYPES, "Boolean expected! Found : " + + r.getName(), right)); + } + + return ctx.getBooleanType(); + } + + @Override + protected String toStringInternal() { + return left.toStringInternal() + operator.getValue() + right.toStringInternal(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Case.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Case.java new file mode 100644 index 00000000..3a6f71a2 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Case.java @@ -0,0 +1,45 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Bernd Kolb + */ +public class Case extends SyntaxElement { + private Expression condition; + + private Expression thenPart; + + public Case(final Expression condition, final Expression part) { + this.condition = condition; + thenPart = part; + } + + public Expression getCondition() { + return condition; + } + + public Expression getThenPart() { + return thenPart; + } + + @Override + public String toString() { + return "case " + condition.toString(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Cast.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Cast.java new file mode 100644 index 00000000..173819b6 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Cast.java @@ -0,0 +1,117 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.ParameterizedType; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Bernd Kolb + * + */ +public class Cast extends Expression { + + private Identifier type; + + private Expression target; + + public Cast(final Identifier type, final Expression target) { + this.type = type; + this.target = target; + } + + public Expression getTarget() { + return target; + } + + public Identifier getType() { + return type; + } + + @Override + public Object evaluateInternal(final ExecutionContext ctx) { + return getTarget().evaluate(ctx); + } + + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + final Type t = getTarget().analyze(ctx, issues); + + final Type toCast = findType(getType(), ctx, issues); + if (toCast == null) { + issues.add(new AnalysationIssue(AnalysationIssue.TYPE_NOT_FOUND, "Couldn't find type "+getType().getValue(), getType())); + return null; + } + if (t == null) + return null; + if (t instanceof ParameterizedType && toCast instanceof ParameterizedType) { + if (t.isAssignableFrom(toCast)) { + final Type innerType = getCastedType(((ParameterizedType) t).getInnerType(), + ((ParameterizedType) toCast).getInnerType(), ctx.getObjectType()); + if (innerType == null) { + issues.add(new AnalysationIssue(AnalysationIssue.INCOMPATIBLE_TYPES, "cannot cast from " + + t.toString() + " to " + toCast.toString(), this)); + return null; + } + return ((ParameterizedType) toCast).cloneWithInnerType(innerType); + } else if (toCast.isAssignableFrom(t)) { + final Type innerType = getCastedType(((ParameterizedType) t).getInnerType(), + ((ParameterizedType) toCast).getInnerType(), ctx.getObjectType()); + if (innerType == null) { + issues.add(new AnalysationIssue(AnalysationIssue.INCOMPATIBLE_TYPES, "cannot cast from " + + t.toString() + " to " + toCast.toString(), this)); + return null; + } + return ((ParameterizedType) t).cloneWithInnerType(innerType); + } else { + issues.add(new AnalysationIssue(AnalysationIssue.INCOMPATIBLE_TYPES, "cannot cast from " + t.toString() + + " to " + toCast.toString(), this)); + return null; + } + } else { + final Type rt = getCastedType(t, toCast, ctx.getObjectType()); + if (rt == null) { + issues.add(new AnalysationIssue(AnalysationIssue.INCOMPATIBLE_TYPES, "cannot cast from " + t.toString() + + " to " + toCast.toString(), this)); + } + return rt; + } + } + + private Type getCastedType(Type typeA, Type typeB, final Type objType) { + if (typeA == null) + typeA = objType; + + if (typeB == null) + typeB = objType; + + if (typeA.isAssignableFrom(typeB)) + return typeB; + else if (typeB.isAssignableFrom(typeA)) + return typeA; + return null; + } + + @Override + protected String toStringInternal() { + return "(" + type.getValue() + ")" + target.toString(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/ChainExpression.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/ChainExpression.java new file mode 100644 index 00000000..d0fb4f7b --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/ChainExpression.java @@ -0,0 +1,62 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Bernd Kolb + */ +public class ChainExpression extends Expression { + + private Expression first; + + private Expression next; + + public ChainExpression(final Expression first, final Expression next) { + this.first = first; + this.next = next; + } + + @Override + protected Object evaluateInternal(final ExecutionContext ctx) { + getFirst().evaluate(ctx); + return getNext().evaluate(ctx); + } + + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + getFirst().analyze(ctx, issues); + return getNext().analyze(ctx, issues); + } + + public Expression getFirst() { + return first; + } + + public Expression getNext() { + return next; + } + + @Override + protected String toStringInternal() { + return getFirst() + "->" + getNext(); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/CollectionExpression.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/CollectionExpression.java new file mode 100644 index 00000000..10e76e3a --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/CollectionExpression.java @@ -0,0 +1,261 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.internal.xtend.expression.parser.SyntaxConstants; +import org.eclipse.internal.xtend.type.baseimpl.BuiltinMetaModel; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.EvaluationException; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.ParameterizedType; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Bernd Kolb + */ +public class CollectionExpression extends FeatureCall { + + private Expression closure; + + private Identifier eleName; + + public CollectionExpression(final Identifier name, final Identifier eleName, final Expression closure) { + super(name,null); + this.eleName = eleName; + this.closure = closure; + } + + @Override + protected String toStringInternal() { + return super.toStringInternal() + "(" + (eleName != null ? eleName.getValue() + "|" : "") + closure + ")"; + } + + public Expression getClosure () { + return closure; + } + + @Override + public Object evaluateInternal(final ExecutionContext ctx) { + Object targetObj = null; + if (getTarget() == null) { + final Variable v = ctx.getVariable(ExecutionContext.IMPLICIT_VARIABLE); + if (v != null) { + targetObj = v.getValue(); + } + } else { + targetObj = getTarget().evaluate(ctx); + } + if (targetObj == null) + return ctx.handleNullEvaluation(this); + if (!(targetObj instanceof Collection)) { + throw new EvaluationException("Couldn't call '"+this.toString()+"' on an object of java type "+targetObj.getClass().getName(),this, ctx); + } + + if (getName().getValue().equals(SyntaxConstants.COLLECT)) + return executeCollect((Collection) targetObj, ctx); + else if (getName().getValue().equals(SyntaxConstants.SELECT)) + return executeSelect((Collection) targetObj, ctx); + else if (getName().getValue().equals(SyntaxConstants.SELECTFIRST)) + return executeSelectFirst((Collection) targetObj, ctx); + else if (getName().getValue().equals(SyntaxConstants.REJECT)) + return executeReject((Collection) targetObj, ctx); + else if (getName().getValue().equals(SyntaxConstants.EXISTS)) + return executeExists((Collection) targetObj, ctx); + else if (getName().getValue().equals(SyntaxConstants.NOT_EXISTS)) + return executeNotExists((Collection) targetObj, ctx); + else if (getName().getValue().equals(SyntaxConstants.FOR_ALL)) + return executeForAll((Collection) targetObj, ctx); + else if (getName().getValue().equals(SyntaxConstants.SORT_BY)) + return executeSortBy((Collection) targetObj, ctx); + else + throw new EvaluationException("Unkown collection operation : " + getName().getValue(), this, ctx); + + } + + private Object executeSortBy(Collection collection, final ExecutionContext ctx) { + List<Object> result = new ArrayList<Object>(); + result.addAll(collection); + Collections.sort(result, new Comparator<Object> () { + + public int compare(Object o1, Object o2) { + final Object a = closure.evaluate(ctx.cloneWithVariable(new Variable(getElementName(), o1))); + final Object b = closure.evaluate(ctx.cloneWithVariable(new Variable(getElementName(), o2))); + if (a==b) + return 0; + if (a==null) + return -1; + if (b==null) + return 1; + if (a instanceof Comparable) + return ((Comparable)a).compareTo(b); + return a.toString().compareTo(b.toString()); + }}); + return result; + } + + private Object executeForAll(final Collection collection, ExecutionContext ctx) { + for (final Iterator iter = collection.iterator(); iter.hasNext();) { + ctx = ctx.cloneWithVariable(new Variable(getElementName(), iter.next())); + final Object result = closure.evaluate(ctx); + if (!(result instanceof Boolean) || !((Boolean) result).booleanValue()) + return Boolean.FALSE; + } + return Boolean.TRUE; + } + + private Object executeExists(final Collection collection, ExecutionContext ctx) { + for (final Iterator iter = collection.iterator(); iter.hasNext();) { + ctx = ctx.cloneWithVariable(new Variable(getElementName(), iter.next())); + final Object result = closure.evaluate(ctx); + if (result instanceof Boolean && ((Boolean) result).booleanValue()) + return Boolean.TRUE; + } + return Boolean.FALSE; + } + + private Object executeNotExists(final Collection collection, ExecutionContext ctx) { + for (final Iterator iter = collection.iterator(); iter.hasNext();) { + ctx = ctx.cloneWithVariable(new Variable(getElementName(), iter.next())); + final Object result = closure.evaluate(ctx); + if (result instanceof Boolean && ((Boolean) result).booleanValue()) + return Boolean.FALSE; + } + return Boolean.TRUE; + } + + private Object executeReject(final Collection collection, ExecutionContext ctx) { + final Collection resultCol = new ArrayList(collection); + for (final Iterator iter = collection.iterator(); iter.hasNext();) { + final Object ele = iter.next(); + ctx = ctx.cloneWithVariable(new Variable(getElementName(), ele)); + final Object result = closure.evaluate(ctx); + if (result instanceof Boolean && ((Boolean) result).booleanValue()) { + resultCol.remove(ele); + } + } + return resultCol; + } + + private Object executeSelect(final Collection collection, ExecutionContext ctx) { + final Collection<Object> resultCol = new ArrayList<Object>(); + for (final Iterator iter = collection.iterator(); iter.hasNext();) { + final Object ele = iter.next(); + ctx = ctx.cloneWithVariable(new Variable(getElementName(), ele)); + final Object result = closure.evaluate(ctx); + if (result instanceof Boolean && ((Boolean) result).booleanValue()) { + resultCol.add(ele); + } + } + return resultCol; + } + + private Object executeSelectFirst(final Collection collection, ExecutionContext ctx) { + final Collection<Object> resultCol = new ArrayList<Object>(); + for (final Iterator iter = collection.iterator(); iter.hasNext();) { + final Object ele = iter.next(); + ctx = ctx.cloneWithVariable(new Variable(getElementName(), ele)); + final Object result = closure.evaluate(ctx); + if (result instanceof Boolean && ((Boolean) result).booleanValue()) { + resultCol.add(ele); + } + } + if ( resultCol.size() == 0 ) return null; + return resultCol.iterator().next(); + } + + private Object executeCollect(final Collection collection, ExecutionContext ctx) { + final Collection<Object> resultCol = new ArrayList<Object>(); + for (final Iterator iter = Collections.unmodifiableCollection(collection).iterator(); iter.hasNext();) { + final Object ele = iter.next(); + ctx = ctx.cloneWithVariable(new Variable(getElementName(), ele)); + resultCol.add(closure.evaluate(ctx)); + } + return resultCol; + } + + @Override + public Type analyze(ExecutionContext ctx, final Set<AnalysationIssue> issues) { + Type targetType = null; + if (getTarget() == null) { + final Variable v = ctx.getVariable(ExecutionContext.IMPLICIT_VARIABLE); + if (v != null) { + targetType = (Type) v.getValue(); + } + } else { + targetType = getTarget().analyze(ctx, issues); + } + if (targetType == null) + return null; + + if (!(targetType instanceof ParameterizedType)) { + issues.add(new AnalysationIssue(AnalysationIssue.INCOMPATIBLE_TYPES, "Collection type expected! was : " + + targetType, getTarget())); + return null; + } + + final Type innerType = ((ParameterizedType) targetType).getInnerType(); + Type result = null; + ctx = ctx.cloneWithVariable(new Variable(getElementName(), innerType)); + final Type closureType = closure.analyze(ctx, issues); + if (getName().getValue().equals(SyntaxConstants.COLLECT)) { + if (targetType.getName().startsWith(BuiltinMetaModel.SET)) + return ctx.getSetType(closureType); + else if (targetType.getName().startsWith(BuiltinMetaModel.LIST)) + return ctx.getListType(closureType); + else + return ctx.getCollectionType(closureType); + } else if (getName().getValue().equals(SyntaxConstants.SELECT) + || getName().getValue().equals(SyntaxConstants.REJECT) + ) { + return targetType; + } else if (getName().getValue().equals(SyntaxConstants.SELECTFIRST)) { + return innerType; + } else if (getName().getValue().equals(SyntaxConstants.SORT_BY)) { + return ctx.getListType(innerType); + }else if (getName().getValue().equals(SyntaxConstants.TYPE_SELECT)) { + if (closureType == null) + return null; + return ctx.getListType(closureType); + } else if (getName().getValue().equals(SyntaxConstants.EXISTS) + || getName().getValue().equals(SyntaxConstants.NOT_EXISTS) + || getName().getValue().equals(SyntaxConstants.FOR_ALL)) { + if (!ctx.getBooleanType().isAssignableFrom(closureType)) { + issues.add(new AnalysationIssue(AnalysationIssue.INCOMPATIBLE_TYPES, "Boolean type expected! was : " + + closureType, closure)); + } + result = ctx.getBooleanType(); + } else { + issues.add(new AnalysationIssue(AnalysationIssue.INTERNAL_ERROR, "Unknown operation : " + + getName().getValue(), this)); + } + return result; + } + + public String getElementName() { + return eleName != null ? eleName.getValue() : SyntaxConstants.DEFAULT_ELE_NAME; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/ConstructorCallExpression.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/ConstructorCallExpression.java new file mode 100644 index 00000000..a3d4045f --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/ConstructorCallExpression.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.EvaluationException; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Bernd Kolb + * + */ +public class ConstructorCallExpression extends Expression { + + private Identifier type; + + public ConstructorCallExpression(final Identifier type) { + this.type = type; + } + + public String getTypeName () { + return type.getValue(); + } + + @Override + protected Object evaluateInternal(final ExecutionContext ctx) { + final Type t = ctx.getTypeForName(type.getValue()); + if (t != null) + return t.newInstance(); + else + throw new EvaluationException("Couldn't find type " + type, this, ctx); + } + + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + final Type t = ctx.getTypeForName(type.getValue()); + if (t == null) { + issues.add(new AnalysationIssue(AnalysationIssue.TYPE_NOT_FOUND, "Type not found : " + type, type)); + } + // TODO add isAbstract to Type and check it here! + return t; + } + + @Override + protected String toStringInternal() { + return "new " + getTypeName(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/DeclaredParameter.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/DeclaredParameter.java new file mode 100644 index 00000000..9ae94774 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/DeclaredParameter.java @@ -0,0 +1,45 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class DeclaredParameter extends SyntaxElement { + + private Identifier type; + + private Identifier name; + + public DeclaredParameter(final Identifier type, + final Identifier name) { + this.type = type; + this.name = name; + } + + public Identifier getName() { + return name; + } + + public Identifier getType() { + return type; + } + + @Override + public String toString() { + return type.getValue() + " " + name.getValue(); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Expression.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Expression.java new file mode 100644 index 00000000..8d2d155d --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Expression.java @@ -0,0 +1,64 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.Analyzable; +import org.eclipse.xtend.expression.Evaluatable; +import org.eclipse.xtend.expression.EvaluationException; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Bernd Kolb + * + */ +public abstract class Expression extends SyntaxElement implements Analyzable, Evaluatable { + + + protected Type findType(final Identifier type, final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + final Type toCast = ctx.getTypeForName(type.getValue()); + if (toCast == null) { + issues.add(new AnalysationIssue(AnalysationIssue.TYPE_NOT_FOUND, type.getValue(), type)); + } + return toCast; + } + + public final Object evaluate(final ExecutionContext ctx) { + try { + Object evaluateInternal = evaluateInternal(ctx); + return evaluateInternal; + } catch (final EvaluationException ex) { + ctx.handleRuntimeException(ex, this, null); + return null; + } catch (final RuntimeException ex) { + EvaluationException evalex = new EvaluationException(ex.getMessage(),this, ctx); + ctx.handleRuntimeException(evalex, this, null); + return null; + } + } + + @Override + public final String toString() { + return toStringInternal(); + } + + protected abstract String toStringInternal(); + + protected abstract Object evaluateInternal(ExecutionContext ctx); + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/FeatureCall.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/FeatureCall.java new file mode 100644 index 00000000..ad3f922f --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/FeatureCall.java @@ -0,0 +1,274 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.internal.xtend.expression.parser.SyntaxConstants; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.EvaluationException; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.ParameterizedType; +import org.eclipse.xtend.typesystem.Property; +import org.eclipse.xtend.typesystem.StaticProperty; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Bernd Kolb + */ +public class FeatureCall extends Expression { + + private Expression target; + + private Identifier name; + + public FeatureCall(final Identifier name, final Expression target) { + this.target = target; + this.name = name; + } + + public Expression getTarget() { + return target; + } + + public void setTarget(final Expression target) { + this.target = target; + } + + public Identifier getName() { + return name; + } + + @Override + public String getNameString(ExecutionContext context){ + return name.getValue(); + } + + public StaticProperty getEnumLiteral(final ExecutionContext ctx) { + if (name.getValue().indexOf(SyntaxConstants.NS_DELIM) != -1) { + String typeName = name.getValue(); + typeName = typeName.substring(0, typeName + .lastIndexOf(SyntaxConstants.NS_DELIM)); + final Type type = ctx.getTypeForName(typeName); + if (type != null) { + final String litName = name.getValue().substring( + name.getValue().lastIndexOf(SyntaxConstants.NS_DELIM) + + SyntaxConstants.NS_DELIM.length()); + return type.getStaticProperty(litName); + } + } + return null; + } + + /** + * evaluates in the following order if (target==null) 1) enumeration literal + * 2) variable 3) implicit var (e.g. this) being everything but an empty + * list 4) type literal otherwise it's a property + * + * if the above doesn't match throw an error as long as target is no empty + * Collection + */ + @Override + public Object evaluateInternal(final ExecutionContext ctx) { + Object targetObj = null; + if (target == null) { + final StaticProperty staticProp = getEnumLiteral(ctx); + if (staticProp != null) + return staticProp.get(); + Variable var = ctx.getVariable(getName().getValue()); + if (var != null) + return var.getValue(); + + var = ctx.getVariable(ExecutionContext.IMPLICIT_VARIABLE); + if (var != null) { + targetObj = var.getValue(); + if (targetObj == null) + return ctx.handleNullEvaluation(this); + } + } else { + targetObj = getTarget().evaluate(ctx); + if (targetObj == null) + return ctx.handleNullEvaluation(this); + } + final String additionalMsg = ""; + if (targetObj != null) { + // Does the target object define a property with the feature name? + final Property p = ctx + .findProperty(getName().getValue(), targetObj); + if (p == null + && (targetObj instanceof Collection && !((Collection) targetObj) + .isEmpty())) { + return invokeOnInnerElements(ctx, targetObj, additionalMsg); + } + if (p != null) + return p.get(targetObj); + } + if (target == null) { + // type literal ? + final Type type = ctx.getTypeForName(getName().getValue()); + if (type != null) { + return type; + } + } + if (targetObj instanceof Collection + && ((Collection) targetObj).isEmpty()) { + return targetObj; + } + if (getName().getValue().indexOf(SyntaxConstants.NS_DELIM) != -1) + throw new EvaluationException( + "Couldn't find enum literal or type '" + + getName().getValue() + "'", this, ctx); + if (target == null) + throw new EvaluationException("Couldn't find type or property '" + + getName().getValue() + "'", this, ctx); + else + throw new EvaluationException("Couldn't find property '" + + getName().getValue() + "' for type " + + findType(targetObj, ctx).getName() + additionalMsg, this, + ctx); + } + + private Object invokeOnInnerElements(final ExecutionContext ctx, + Object targetObj, final String additionalMsg) { + final Collection col = (Collection) targetObj; + final List<Object> result = new ArrayList<Object>(); + for (final Iterator iter = col.iterator(); iter.hasNext() + && additionalMsg.length() == 0;) { + final Object element = iter.next(); + final Property prop = ctx.findProperty(getName().getValue(), + element); + if (prop == null) { + final Type type = ctx.getType(element); + throw new EvaluationException("Couldn't find property '" + + getName().getValue() + "' for inner type " + type + + "'", this, ctx); + } else { + final Object r = prop.get(element); + if (r instanceof Collection) { + result.addAll((Collection<?>) r); + } else { + result.add(r); + } + } + } + return result; + } + + /** + * analyzes in the following order if (target==null) 1) enumeration literal + * 2) variable 3) implicite var (e.g. this) 4) type literal + * + * otherwise it's a property + */ + public Type analyze(final ExecutionContext ctx, + final Set<AnalysationIssue> issues) { + Type targetType = null; + if (target == null) { + // enum literal + final StaticProperty staticProp = getEnumLiteral(ctx); + if (staticProp != null) + return staticProp.getReturnType(); + + // variable + Variable var = ctx.getVariable(getName().getValue()); + if (var != null) + return (Type) var.getValue(); + + // implicite variable 'this' + var = ctx.getVariable(ExecutionContext.IMPLICIT_VARIABLE); + if (var != null) { + targetType = (Type) var.getValue(); + } + + } else { + targetType = analyzeTarget(ctx, issues); + if (targetType == null) + return null; + } + + String additionalMsg = ""; + // simple property + if (targetType != null) { + Property p = targetType.getProperty(getName().getValue()); + if (p != null) + return p.getReturnType(); + + if (p == null && targetType instanceof ParameterizedType) { + final Type innerType = ((ParameterizedType) targetType) + .getInnerType(); + p = innerType.getProperty(getName().getValue()); + if (p != null) { + Type rt = p.getReturnType(); + if (rt instanceof ParameterizedType) { + rt = ((ParameterizedType) rt).getInnerType(); + } + return ctx.getListType(rt); + } + additionalMsg = " or inner type '" + innerType + "'"; + } + } + if (target == null) { + final Type type = ctx.getTypeForName(getName().getValue()); + if (type != null) + return ctx.getTypeType(); + } + + if (target == null) { + String txt = ""; + if (targetType != null) { + txt = targetType.getName() + " property, "; + } + issues.add(new AnalysationIssue(AnalysationIssue.FEATURE_NOT_FOUND, + "Unknown " + txt + + "variable, type or enumeration literal '" + + getName().getValue() + "'", this)); + return null; + } + + issues.add(new AnalysationIssue(AnalysationIssue.FEATURE_NOT_FOUND, + "Couldn't find property '" + getName().getValue() + + "' for type '" + targetType.getName() + "'" + + additionalMsg, this)); + return null; + + } + + protected Type analyzeTarget(final ExecutionContext ctx, + final Set<AnalysationIssue> issues) { + return getTarget().analyze(ctx, issues); + } + + protected Type findType(final Object value, final ExecutionContext ctx) { + final Type t = ctx.getType(value); + if (t == null) + throw new EvaluationException("Unkown object type : " + + value.getClass().getName(), this, ctx); + return t; + } + + @Override + protected String toStringInternal() { + return (getTarget() != null ? getTarget().toString() + "." : "") + + name.getValue(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/GlobalVarExpression.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/GlobalVarExpression.java new file mode 100644 index 00000000..f90e2e70 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/GlobalVarExpression.java @@ -0,0 +1,62 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Bernd Kolb + */ +public class GlobalVarExpression extends Expression { + private Log logger = LogFactory.getLog(getClass()); + private Identifier globalVarName; + + public GlobalVarExpression(final Identifier globalVarName) { + this.globalVarName = globalVarName; + } + + public String getVarName () { + return globalVarName.getValue(); + } + + @Override + public Object evaluateInternal(final ExecutionContext ctx) { + Variable o = ctx.getGlobalVariables().get(globalVarName.getValue()); + if (o==null) { + logger.warn("Global variable '"+globalVarName.getValue()+"' is null. Is it configured?"); + return null; + } + return o.getValue(); + } + + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + return ctx.getObjectType(); + } + + @Override + protected String toStringInternal() { + return "var "+globalVarName.getValue(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/ISyntaxElement.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/ISyntaxElement.java new file mode 100644 index 00000000..33033c8b --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/ISyntaxElement.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2005 - 2007 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.internal.xtend.expression.ast; + +import org.eclipse.xtend.expression.ExecutionContext; + +public interface ISyntaxElement { + public int getLine(); + + public int getEnd(); + + public int getStart(); + + public String getFileName(); + + public String getNameString(ExecutionContext context); + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Identifier.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Identifier.java new file mode 100644 index 00000000..f6573d71 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Identifier.java @@ -0,0 +1,67 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class Identifier extends SyntaxElement { + private String value; + private List<Identifier> follows = new ArrayList<Identifier>(); + + public Identifier(final String value) { + this.value = value; + } + + public Identifier append(final Identifier t) { + this.follows.add(t); + return this; + } + + private String fullVal = null; + + public String getValue() { + if (fullVal == null) { + StringBuffer buff = new StringBuffer(internalGetText()); + for (Identifier id : follows) { + buff.append(id.getValue()); + } + fullVal = buff.toString(); + } + return fullVal; + } + + private String internalGetText() { + if (value.startsWith("^")) + return value.substring(1); + return value; + } + + @Override + public int getEnd() { + if (!follows.isEmpty()) + return follows.get(follows.size() - 1).getEnd(); + return super.getEnd(); + } + + @Override + public String toString() { + return getValue(); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/IfExpression.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/IfExpression.java new file mode 100644 index 00000000..c0068156 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/IfExpression.java @@ -0,0 +1,97 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.EvaluationException; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Bernd Kolb + */ +public class IfExpression extends Expression { + + private Expression condition; + + private Expression thenPart; + + private Expression elsePart; + + public IfExpression(final Expression condition, + final Expression thenPart, final Expression elsePart) { + this.condition = condition; + this.thenPart = thenPart; + this.elsePart = elsePart; + } + + public Expression getCondition() { + return condition; + } + + public Expression getElsePart() { + return elsePart; + } + + public Expression getThenPart() { + return thenPart; + } + + @Override + public Object evaluateInternal(final ExecutionContext ctx) { + Object val = getCondition().evaluate(ctx); + if (val == null) + val = Boolean.FALSE; + + if (!(val instanceof Boolean)) + throw new EvaluationException("Boolean expected!", getCondition(), ctx); + + if (((Boolean) val).booleanValue()) + return getThenPart().evaluate(ctx); + else { + if (getElsePart()==null) + return null; + return getElsePart().evaluate(ctx); + } + } + + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + final Type conditionType = getCondition().analyze(ctx, issues); + if (conditionType != null && !conditionType.equals(ctx.getBooleanType())) { + issues.add(new AnalysationIssue(AnalysationIssue.INCOMPATIBLE_TYPES, "Boolean expected", getCondition())); + } + + final Type thenPartType = getThenPart().analyze(ctx, issues); + final Type elsePartType = getElsePart()!=null ? getElsePart().analyze(ctx, issues) : ctx.getVoidType(); + if (thenPartType == null || elsePartType == null) + return null; + if (thenPartType.isAssignableFrom(elsePartType)) + return elsePartType; + else if (elsePartType.isAssignableFrom(thenPartType)) + return thenPartType; + else + return ctx.getObjectType(); + } + + @Override + protected String toStringInternal() { + return "if "+condition.toString() + " then " + thenPart + (elsePart!=null ? " else " + elsePart : ""); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/IntegerLiteral.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/IntegerLiteral.java new file mode 100644 index 00000000..4f225968 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/IntegerLiteral.java @@ -0,0 +1,42 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class IntegerLiteral extends Literal { + + public IntegerLiteral(final Identifier literalValue) { + super(literalValue); + } + + @Override + public Object evaluateInternal(final ExecutionContext ctx) { + return new Long(getLiteralValue().getValue()); + } + + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + return ctx.getIntegerType(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/LetExpression.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/LetExpression.java new file mode 100644 index 00000000..934cc75a --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/LetExpression.java @@ -0,0 +1,76 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Bernd Kolb + */ +public class LetExpression extends Expression { + + private Expression varExpression; + + private Expression targetExpression; + + private Identifier varName; + + public LetExpression(final Identifier varName, + final Expression varExpression, final Expression target) { + this.varName = varName; + this.varExpression = varExpression; + targetExpression = target; + } + + public Expression getVarExpression () { + return varExpression; + } + + public Expression getTargetExpression () { + return targetExpression; + } + + public String getName () { + return varName.getValue(); + } + + @Override + public Object evaluateInternal(ExecutionContext ctx) { + final Object o = varExpression.evaluate(ctx); + ctx = ctx.cloneWithVariable(new Variable(varName.getValue(), o)); + return targetExpression.evaluate(ctx); + } + + public Type analyze(ExecutionContext ctx, final Set<AnalysationIssue> issues) { + final Type t = varExpression.analyze(ctx, issues); + if (t == null) + return null; + ctx = ctx.cloneWithVariable(new Variable(varName.getValue(), t)); + return targetExpression.analyze(ctx, issues); + } + + @Override + protected String toStringInternal() { + return "let " + varName + "=" + varExpression + " : " + targetExpression; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/ListLiteral.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/ListLiteral.java new file mode 100644 index 00000000..e9db0366 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/ListLiteral.java @@ -0,0 +1,89 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Bernd Kolb + */ +public class ListLiteral extends Expression { + + private Expression[] elements; + + public ListLiteral(final Expression[] contents) { + elements = contents; + } + + public Expression[] getElements() { + return elements; + } + + public List<Expression> getElementsAsList () { + return Arrays.asList(elements); + } + + @Override + public Object evaluateInternal(final ExecutionContext ctx) { + final List<Object> col = new ArrayList<Object>(); + final Expression[] params = getElements(); + for (int i = 0; i < params.length; i++) { + col.add(params[i].evaluate(ctx)); + } + return col; + } + + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + Type t = null; + for (int i = 0; i < elements.length; i++) { + final Expression element = elements[i]; + final Type exprType = element.analyze(ctx, issues); + if (exprType == null) + return null; + if (t == null || exprType.isAssignableFrom(t)) { + t = exprType; + } + } + return ctx.getListType(t); + } + + @Override + protected String toStringInternal() { + return "{" + expressionsToString() + "}"; + } + + private String expressionsToString() { + String r = ""; + for (int i = 0; i < elements.length; i++) { + r += elements[i].toString(); + if (i + 1 < elements.length) { + r += ","; + } + + } + return r; + } + + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Literal.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Literal.java new file mode 100644 index 00000000..413321e2 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/Literal.java @@ -0,0 +1,39 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +/** + * @author Bernd Kolb + * + */ +public abstract class Literal extends Expression { + + private Identifier literalValue; + + public Literal(final Identifier literalValue) { + this.literalValue = literalValue; + } + + public Identifier getLiteralValue() { + return literalValue; + } + + @Override + protected String toStringInternal() { + return literalValue.toString(); + } + + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/NullLiteral.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/NullLiteral.java new file mode 100644 index 00000000..6d3421c4 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/NullLiteral.java @@ -0,0 +1,42 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class NullLiteral extends Literal { + + public NullLiteral(final Identifier literalValue) { + super(literalValue); + } + + @Override + public Object evaluateInternal(final ExecutionContext ctx) { + return null; + } + + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + return ctx.getVoidType(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/OperationCall.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/OperationCall.java new file mode 100644 index 00000000..9e95dc8a --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/OperationCall.java @@ -0,0 +1,357 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.internal.xtend.util.ProfileCollector; +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.EvaluationException; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.Operation; +import org.eclipse.xtend.typesystem.ParameterizedType; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Bernd Kolb + */ +public class OperationCall extends FeatureCall { + + private Expression[] params; + + public OperationCall(final Identifier name, final Expression target, final Expression... params) { + super(name, target); + this.params = params; + } + + public Expression[] getParams() { + return params; + } + + public List<Expression> getParamsAsList() { + return Arrays.asList(params); + } + + @Override + public Object evaluateInternal(final ExecutionContext ctx) { + // evaluate from left to right + // first the target + Object targetObj = null; + if (getTarget()!=null) { + targetObj = getTarget().evaluate(ctx); + } + // then the parameters in the defined order + final Object[] evaluatedParams = new Object[getParams().length]; + if (getParams().length > 0) { + for (int i = 0; i < getParams().length; i++) { + evaluatedParams[i] = getParams()[i].evaluate(ctx); + } + } + + if (getTarget() == null) { + // extension + final Extension f = ctx.getExtension(getName().getValue(), evaluatedParams); + if (f != null) { + ProfileCollector.getInstance().enter(f.toString()); + try { + return evaluate(f, evaluatedParams, ctx); + } catch (EvaluationException e) { + e.addStackElement(this, ctx); + throw e; + } finally { + ProfileCollector.getInstance().leave(); + } + } + + // implicite + final Variable var = ctx.getVariable(ExecutionContext.IMPLICIT_VARIABLE); + if (var == null) + throw new EvaluationException("Couldn't find extension '" + getName().getValue() + getParamTypes(evaluatedParams, ctx) + "'!", this, ctx); + targetObj = var.getValue(); + } + + // operation + Operation op = ctx.findOperation(getName().getValue(), targetObj, evaluatedParams); + if (op != null) + return evaluate(op, targetObj, evaluatedParams, ctx); + // extension as members + Object[] ps = new Object[evaluatedParams.length + 1]; + ps[0] = targetObj; + System.arraycopy(evaluatedParams, 0, ps, 1, evaluatedParams.length); + Extension f = ctx.getExtension(getName().getValue(), ps); + if (f != null) { + try { + ProfileCollector.getInstance().enter(f.toString()); + return evaluate(f, ps, ctx); + } catch (EvaluationException e) { + e.addStackElement(this, ctx); + throw e; + } finally { + ProfileCollector.getInstance().leave(); + } + } + + if (targetObj instanceof Collection) { + final List<Object> result = new ArrayList<Object>(); + final Collection<?> col = (Collection<?>) targetObj; + for (final Iterator<?> iter = col.iterator(); iter.hasNext();) { + final Object element = iter.next(); + // operation + op = ctx.findOperation(getName().getValue(), element, evaluatedParams); + if (op != null) { + final Object r = evaluate(op, element, evaluatedParams, ctx); + if (r instanceof Collection) { + result.addAll((Collection<?>) r); + } else { + result.add(r); + } + } else { + // extension as members + ps = new Object[evaluatedParams.length + 1]; + ps[0] = element; + System.arraycopy(evaluatedParams, 0, ps, 1, evaluatedParams.length); + f = ctx.getExtension(getName().getValue(), ps); + if (f != null) { + Object r = null; + try { + r = evaluate(f, ps, ctx); + } catch (EvaluationException e) { + e.addStackElement(this, ctx); + throw e; + } + if (r instanceof Collection) { + result.addAll((Collection<?>) r); + } else { + result.add(r); + } + } else + throw new EvaluationException("Couldn't find operation '" + getName().getValue() + getParamTypes(evaluatedParams, ctx) + "' for " + + ctx.getType(targetObj).getName() + "!", this, ctx); + } + } + return result; + } + + if (targetObj != null && f == null && op == null) + throw new EvaluationException("Couldn't find operation '" + getName().getValue() + getParamTypes(evaluatedParams, ctx) + "' for " + + ctx.getType(targetObj).getName() + ".", this, ctx); + return ctx.handleNullEvaluation(this); + + } + + private String getParamTypes(final Object[] params2, final ExecutionContext ctx) { + final StringBuffer buff = new StringBuffer("("); + for (int i = 0; i < params2.length; i++) { + final Type type = ctx.getType(params2[i]); + buff.append(type.getName()); + if (i + 1 < params2.length) { + buff.append(","); + } + } + return buff.append(")").toString(); + } + + @Override + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + final Type[] paramTypes = new Type[getParams().length]; + if (getParams().length > 0) { + for (int i = 0; i < getParams().length; i++) { + paramTypes[i] = getParams()[i].analyze(ctx, issues); + if (paramTypes[i] == null) + return null; + } + } + + // extension + Type targetType = null; + if (getTarget() == null) { + Extension f = null; + try { + f = ctx.getExtensionForTypes(getName().getValue(), paramTypes); + } catch (final Exception e) { + issues.add(new AnalysationIssue(AnalysationIssue.INTERNAL_ERROR, "Error parsing extensions : " + e.getMessage(), this)); + } + if (f != null) + return f.getReturnType(paramTypes, ctx, issues); + final Variable var = ctx.getVariable(ExecutionContext.IMPLICIT_VARIABLE); + if (var != null) { + targetType = (Type) var.getValue(); + } else { + issues.add(new AnalysationIssue(AnalysationIssue.FEATURE_NOT_FOUND, "Couldn't find extensions : " + toString(), this)); + } + } else { + targetType = getTarget().analyze(ctx, issues); + } + if (targetType == null) + return null; + // operation + Operation op = targetType.getOperation(getName().getValue(), paramTypes); + if (op != null) + return op.getReturnType(targetType, paramTypes); + // extension as members + final int issueSize = issues.size(); + Type rt = getExtensionsReturnType(ctx, issues, paramTypes, targetType); + if (rt != null) + return rt; + else if (issueSize < issues.size()) + return null; + String additionalMsg = ""; + if (targetType instanceof ParameterizedType) { + final Type innerType = ((ParameterizedType) targetType).getInnerType(); + op = innerType.getOperation(getName().getValue(), paramTypes); + if (op != null) { + rt = op.getReturnType(); + if (rt instanceof ParameterizedType) { + rt = ((ParameterizedType) rt).getInnerType(); + } + return ctx.getListType(rt); + } + rt = getExtensionsReturnType(ctx, issues, paramTypes, innerType); + if (rt != null) { + if (rt instanceof ParameterizedType) { + rt = ((ParameterizedType) rt).getInnerType(); + } + return ctx.getListType(rt); + } + additionalMsg = " or type '" + innerType + "'"; + } + + issues.add(new AnalysationIssue(AnalysationIssue.FEATURE_NOT_FOUND, "Couldn't find operation '" + getName().getValue() + + getParamsString(paramTypes) + "' for type '" + targetType.getName() + "'" + additionalMsg, this)); + return null; + + } + + private Type getExtensionsReturnType(final ExecutionContext ctx, final Set<AnalysationIssue> issues, final Type[] paramTypes, + final Type targetType) { + final Type[] pts = new Type[paramTypes.length + 1]; + pts[0] = targetType; + System.arraycopy(paramTypes, 0, pts, 1, paramTypes.length); + Extension f = null; + try { + f = ctx.getExtensionForTypes(getName().getValue(), pts); + } catch (final Exception e) { + issues.add(new AnalysationIssue(AnalysationIssue.INTERNAL_ERROR, "Error parsing extensions : " + e.getMessage(), this)); + } + if (f != null) { + final Set<AnalysationIssue> temp = new HashSet<AnalysationIssue>(); + final Type rt = f.getReturnType(pts, ctx, temp); + if (rt == null) { + issues.add(new AnalysationIssue(AnalysationIssue.INTERNAL_ERROR, "couldn't resolve return type for extension " + f + "! Errors : " + + temp.toString(), this)); + } + return rt; + } else if (getTarget() == null) { // try without implicite this + try { + f = ctx.getExtensionForTypes(getName().getValue(), paramTypes); + } catch (final Exception e) { + issues.add(new AnalysationIssue(AnalysationIssue.INTERNAL_ERROR, "Error parsing extensions : " + e.getMessage(), this)); + } + if (f != null) { + final Set<AnalysationIssue> temp = new HashSet<AnalysationIssue>(); + final Type rt = f.getReturnType(pts, ctx, temp); + if (rt == null) { + issues.add(new AnalysationIssue(AnalysationIssue.INTERNAL_ERROR, "couldn't resolve return type for extension " + f + + "! Errors : " + temp.toString(), this)); + } + return rt; + } + } + return null; + } + + private String getParamsString(final Type[] paramTypes) { + final StringBuffer buff = new StringBuffer("("); + for (int i = 0; i < paramTypes.length; i++) { + final Type type = paramTypes[i]; + buff.append(type.getName()); + if (i + 1 < paramTypes.length) { + buff.append(","); + } + } + return buff.append(")").toString(); + } + + @Override + protected String toStringInternal() { + return (getTarget() != null ? getTarget().toStringInternal() + "." : "") + getName() + getParamsExpressionString(getParams()); + } + + @Override + public String getNameString(ExecutionContext context) { + final StringBuffer buff = new StringBuffer(); + buff.append(getName().getValue()); + buff.append("("); + if (params.length > 0) + if (context != null) + buff.append(getParamTypesString(context)); + else + // TODO: CK low: Get parameter types from OawModelManager for Breakpoints + buff.append(".."); + return buff.append(")").toString(); + } + + private String getParamTypesString(ExecutionContext context) { + final ExecutionContext ctx = context.cloneWithoutMonitor(); + final StringBuffer buff = new StringBuffer(); + for (int i = 0; i < getParams().length; i++) { + Type type = ctx.getType(params[i].evaluate(ctx)); + String name = type.getName(); + int pos = name.lastIndexOf("::"); + if (pos < 0) + buff.append(name); + else + buff.append(name.substring(pos + 2)); + if (i + 1 < params.length) + buff.append(","); + } + return buff.toString(); + } + + private String getParamsExpressionString(final Expression[] params2) { + final StringBuffer buff = new StringBuffer("("); + for (int i = 0; i < params2.length; i++) { + buff.append(params2[i]); + if (i + 1 < params2.length) { + buff.append(","); + } + } + return buff.append(")").toString(); + } + + private Object evaluate(Extension ext, Object[] params, ExecutionContext ctx) { + ctx.preTask(this); + Object result = ext.evaluate(params, ctx); + ctx.postTask(this); + return result; + } + + private Object evaluate(Operation op, Object targetObj, Object[] params, ExecutionContext ctx) { + ctx.preTask(this); + Object result = op.evaluate(targetObj, params); + ctx.postTask(this); + return result; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/RealLiteral.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/RealLiteral.java new file mode 100644 index 00000000..50f4039b --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/RealLiteral.java @@ -0,0 +1,42 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class RealLiteral extends Literal { + + public RealLiteral(final Identifier literalValue) { + super(literalValue); + } + + @Override + protected Object evaluateInternal(final ExecutionContext ctx) { + return new Double(getLiteralValue().getValue()); + } + + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + return ctx.getRealType(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/StringLiteral.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/StringLiteral.java new file mode 100644 index 00000000..1d548e5c --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/StringLiteral.java @@ -0,0 +1,47 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Set; + +import org.eclipse.internal.xtend.util.StringHelper; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class StringLiteral extends Literal { + + public StringLiteral(final Identifier literalValue) { + super(literalValue); + } + + @Override + public Object evaluateInternal(final ExecutionContext ctx) { + return getValue(); + } + + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + return ctx.getStringType(); + } + + public String getValue() { + return StringHelper.strip(StringHelper.unescape(getLiteralValue().getValue()), 1, 1); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/SwitchExpression.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/SwitchExpression.java new file mode 100644 index 00000000..aac61f6c --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/SwitchExpression.java @@ -0,0 +1,107 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Bernd Kolb + */ +public class SwitchExpression extends Expression { + + private Expression switchExpr = null; + + private Expression defaultExpr = null; + + private List<Case> cases = null; + + public SwitchExpression(final Expression switchExpr, + final List<Case> cases, final Expression defaultExpr) { + this.switchExpr = switchExpr; + this.cases = cases; + this.defaultExpr = defaultExpr; + } + + @Override + protected Object evaluateInternal(final ExecutionContext ctx) { + Object switchVal = Boolean.TRUE; + if (switchExpr != null) + switchVal = switchExpr.evaluate(ctx); + for (final Iterator<Case> iter = cases.iterator(); iter.hasNext();) { + final Case c = iter.next(); + final Object caseCondVal = c.getCondition().evaluate(ctx); + if ((switchVal != null && switchVal.equals(caseCondVal)) || switchVal == caseCondVal) + return c.getThenPart().evaluate(ctx); + } + return defaultExpr.evaluate(ctx); + } + + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + Type condType = ctx.getBooleanType(); + if (switchExpr != null) + condType = switchExpr.analyze(ctx, issues); + if (condType == null) + return null; + Type returnType = defaultExpr.analyze(ctx, issues); + if (returnType == null) + return null; + for (final Iterator<Case> iter = cases.iterator(); iter.hasNext();) { + final Case c = iter.next(); + final Type caseCondType = c.getCondition().analyze(ctx, issues); + if (caseCondType != null) { + if (!condType.isAssignableFrom(caseCondType)) { + issues.add(new AnalysationIssue(AnalysationIssue.INCOMPATIBLE_TYPES, condType.getName() + + " expected!", c.getCondition())); + } + } + final Type caseThenType = c.getThenPart().analyze(ctx, issues); + if (caseThenType != null) { + if (!returnType.isAssignableFrom(caseThenType)) { + if (caseThenType.isAssignableFrom(returnType)) { + returnType = caseThenType; + } else { + returnType = ctx.getObjectType(); + } + } + } + } + return returnType; + } + + public List<Case> getCases() { + return cases; + } + + public Expression getDefaultExpr() { + return defaultExpr; + } + + public Expression getSwitchExpr() { + return switchExpr; + } + + @Override + protected String toStringInternal() { + return "switch " + switchExpr.toStringInternal() ; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/SyntaxElement.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/SyntaxElement.java new file mode 100644 index 00000000..f47eb309 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/SyntaxElement.java @@ -0,0 +1,66 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import org.eclipse.xtend.expression.ExecutionContext; + +public abstract class SyntaxElement implements ISyntaxElement { + protected int start; + + protected int end; + + protected int line; + + public SyntaxElement() { + } + + public void setEnd(int end) { + this.end = end; + } + + public void setLine(int line) { + this.line = line; + } + + public void setStart(int start) { + this.start = start; + } + + public int getLine() { + return line; + } + + public int getEnd() { + return end; + } + + public int getStart() { + return start; + } + + private String fileName; + + public void setFileName(final String fileName) { + this.fileName = fileName; + } + + public String getFileName() { + return fileName; + } + + public String getNameString(ExecutionContext context) { + return toString(); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/TypeSelectExpression.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/TypeSelectExpression.java new file mode 100644 index 00000000..35cb263e --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/TypeSelectExpression.java @@ -0,0 +1,114 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.ast; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; + +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.EvaluationException; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.ParameterizedType; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Bernd Kolb + */ +public class TypeSelectExpression extends FeatureCall { + + private Identifier typeLiteral; + + public TypeSelectExpression(final Identifier opName, final Identifier typeLiteral) { + super(opName, null); + this.typeLiteral = typeLiteral; + } + + public String getTypeName () { + return typeLiteral.getValue(); + } + + @Override + protected String toStringInternal() { + return super.toStringInternal() + "(" + typeLiteral + ")"; + } + + @Override + public Object evaluateInternal(final ExecutionContext ctx) { + Object targetObj = null; + if (getTarget() == null) { + final Variable v = ctx.getVariable(ExecutionContext.IMPLICIT_VARIABLE); + if (v != null) + targetObj = v.getValue(); + } else { + targetObj = getTarget().evaluate(ctx); + } + if (targetObj == null) + return ctx.handleNullEvaluation(this); + if (!(targetObj instanceof Collection)) { + + } + + return executeTypeSelect((Collection<?>) targetObj, ctx); + } + + private Object executeTypeSelect(final Collection<?> collection, final ExecutionContext ctx) { + final Collection<Object> resultCol = new ArrayList<Object>(); + final Type t = ctx.getTypeForName(typeLiteral.getValue()); + if (t == null) + throw new EvaluationException("Unkown type '" + typeLiteral + "'", typeLiteral, ctx); + for (final Iterator<?> iter = collection.iterator(); iter.hasNext();) { + final Object ele = iter.next(); + if (ele!=null && t.isAssignableFrom(ctx.getType(ele))) { + resultCol.add(ele); + } + } + return resultCol; + } + + @Override + public Type analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + Type targetType = null; + if (getTarget() == null) { + final Variable v = ctx.getVariable(ExecutionContext.IMPLICIT_VARIABLE); + if (v != null) + targetType = (Type) v.getValue(); + } else { + targetType = getTarget().analyze(ctx, issues); + } + if (targetType == null) + return null; + + if (!(targetType instanceof ParameterizedType)) { + issues.add(new AnalysationIssue(AnalysationIssue.INCOMPATIBLE_TYPES, "Collection type expected! was : " + + targetType, getTarget())); + return null; + } + + final Type closureType = ctx.getTypeForName(typeLiteral.getValue()); + if (closureType == null) { + issues.add(new AnalysationIssue(AnalysationIssue.TYPE_NOT_FOUND, "Couldn't find type " + typeLiteral, + typeLiteral)); + return null; + } + + return ctx.getListType(closureType); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/CharacterScanner.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/CharacterScanner.java new file mode 100644 index 00000000..76d02355 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/CharacterScanner.java @@ -0,0 +1,59 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.codeassist; + +public class CharacterScanner { + public final static int BOUNDS = -1; + + private String internal; + + private int offset = 0; + + public CharacterScanner(final String internal) { + this.internal = internal; + } + + public boolean goTo(final int offset) { + if (offset < 0 || offset >= internal.length()) + return false; + this.offset = offset; + return true; + } + + public int read() { + if (offset >= internal.length()) + return BOUNDS; + return internal.charAt(offset++); + } + + public int unread() { + if (offset > 0) + return BOUNDS; + return internal.charAt(offset--); + } + + public String getString() { + return internal; + } + + public int offset() { + return offset; + } + + public char currentChar() { + return internal.charAt(offset); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ExpressionProposalComputer.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ExpressionProposalComputer.java new file mode 100644 index 00000000..71109871 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ExpressionProposalComputer.java @@ -0,0 +1,481 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.codeassist; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.antlr.runtime.CommonToken; +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.internal.xtend.xtend.parser.XtendLexer; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.ExpressionFacade; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.Callable; +import org.eclipse.xtend.typesystem.Operation; +import org.eclipse.xtend.typesystem.ParameterizedType; +import org.eclipse.xtend.typesystem.Property; +import org.eclipse.xtend.typesystem.StaticProperty; +import org.eclipse.xtend.typesystem.Type; + +public class ExpressionProposalComputer implements ProposalComputer { + + private final static Set<String> operators = new HashSet<String>(); + static { + operators.add("&&"); + operators.add("/"); + operators.add("."); + operators.add("=="); + operators.add(">="); + operators.add(">"); + operators.add("<="); + operators.add("<"); + operators.add("-"); + operators.add("%"); + operators.add("*"); + operators.add("!="); + operators.add("!"); + operators.add("||"); + operators.add("+"); + } + + private final static Set<String> stopper = new HashSet<String>(); + static { + stopper.add("("); + stopper.add(":"); + stopper.add("?"); + stopper.add("|"); + stopper.add("{"); + stopper.add(","); + } + + private final static Set<String> methodNames = new HashSet<String>(); + static { + methodNames.add("collect"); + methodNames.add("exists"); + methodNames.add("notExists"); + methodNames.add("forAll"); + methodNames.add("reject"); + methodNames.add("select"); + methodNames.add("selectFirst"); + methodNames.add("sortBy"); + methodNames.add("typeSelect"); + } + + private final static Set<String> operands = new HashSet<String>(); + static { + operands.add("collect"); + operands.add("exists"); + operands.add("notExists"); + operands.add("false"); + operands.add("forAll"); + operands.add("null"); + operands.add("reject"); + operands.add("select"); + operands.add("sortBy"); + operands.add("selectFirst"); + operands.add("true"); + operands.add("typeSelect"); + } + + private final static Map<String, String> blockTokens = new HashMap<String, String>(); + static { + blockTokens.put("(",")"); + blockTokens.put("{","}"); + } + + private static final Pattern QUALIFIED_NAME = Pattern.compile("\\W*(.*)(?:::\\w*)$"); + + public ExpressionProposalComputer() { + } + + /** + * @param ctx + * @return + */ + public List<Object> computeProposals(final String txt, ExecutionContext ctx, final ProposalFactory factory) { + final String[] s = computePrefixAndTargetExpression(txt); + final String prefix = s[0]; + final String expressionString = s[1]; + ctx = computeExecutionContext(txt, ctx); + final List<Object> proposals = new ArrayList<Object>(); + + if (prefix.length() > 0 && expressionString == null) { + proposals.addAll(new TypeProposalComputer().computeProposals(txt, ctx, factory)); + } + + Type implicitVariableType = null; + if (expressionString != null) { + final Set<AnalysationIssue> issues = new HashSet<AnalysationIssue>(); + implicitVariableType = new ExpressionFacade(ctx).analyze(expressionString, issues); + if (implicitVariableType == null) + return Collections.emptyList(); + } + if (implicitVariableType == null) { + // variables + final Map<String, Variable> vars = ctx.getVisibleVariables(); + for (final Iterator<String> iter = vars.keySet().iterator(); iter.hasNext();) { + final String varName = iter.next(); + if (varName.toLowerCase().startsWith(prefix.toLowerCase())) { + final Object o = ctx.getVariable(varName).getValue(); + proposals.add(factory.createVariableProposal(varName, (Type) o, prefix)); + } + } + + // members and extensions on implicit variable (this) + final Variable implicitVariable = ctx.getVariable(ExecutionContext.IMPLICIT_VARIABLE); + if (implicitVariable != null) { + implicitVariableType = (Type) implicitVariable.getValue(); + proposals.addAll(getAllMemberProposals(implicitVariableType, prefix, ctx, factory)); + for (StaticProperty p : implicitVariableType.getAllStaticProperties()) { + if (p.getName().startsWith(prefix)) { + proposals.add(factory.createStaticPropertyProposal((StaticProperty) p, prefix, false)); + } + } + } + + final Set<? extends Extension> exts = ctx.getAllExtensions(); + for (Extension extension : exts) { + if (extension.getName().toLowerCase().startsWith(prefix.toLowerCase())) { + boolean skip = false; + if (extension.getParameterTypes().size() >= 1) { + Type firstParameterType = extension.getParameterTypes().get(0); + + if (implicitVariable != null) { + implicitVariableType = (Type) implicitVariable.getValue(); + if (implicitVariableType.isAssignableFrom(firstParameterType) + || firstParameterType.isAssignableFrom(implicitVariableType)) { + skip = true; + System.out.println("SKIP"); + } + } + } + if (!skip) { + System.out.println("NOSKIP"); + proposals.add(factory.createExtensionProposal(extension, prefix)); + } + } + } + + // Static properties + Matcher m = QUALIFIED_NAME.matcher(txt); + if (m.matches()) { + String typeName = m.group(1); + implicitVariableType = ctx.getTypeForName(typeName); + if (implicitVariableType!=null) { + for (StaticProperty p : implicitVariableType.getAllStaticProperties()) { + if (p.getName().startsWith(prefix)) { + proposals.add(factory.createStaticPropertyProposal((StaticProperty) p, prefix, false)); + } + } + } + } + } else { + // members and extensions on targetType + proposals.addAll(getAllMemberProposals(implicitVariableType, prefix, ctx, factory)); + } + return proposals; + } + + private final static Pattern COL_OP = Pattern + .compile("((select|collect|exists|notExists|reject|forEach|sortBy)\\s*\\(\\s*(\\w+)\\s*\\|)|(\\()|(\\))"); + + private final static Pattern LET = Pattern.compile(".*let\\s*(\\w+)\\s*=\\s*([^:]+):([^:]*)"); + + public final static ExecutionContext computeExecutionContext(final String txt, ExecutionContext ctx) { + final Stack<LazyVar> vars = new Stack<LazyVar>(); + Matcher m = LET.matcher(txt); + while (m.find()) { + final LazyVar v = new LazyVar(); + v.name = m.group(1); + v.forEach = false; + v.expression = m.group(2).trim(); + vars.push(v); + } + m = COL_OP.matcher(txt); + while (m.find()) { + if (m.group(1) != null) { + final String[] s = computePrefixAndTargetExpression(txt.substring(0, m.start())); + final String expressionString = s[1]; + final LazyVar v = new LazyVar(); + v.name = m.group(3); + v.forEach = true; + v.expression = expressionString; + vars.push(v); + } else if (m.group(4) != null) { + vars.push(null); + } else if (m.group(5) != null) { + vars.pop(); + } else + throw new IllegalStateException("Match:" + m.group()); + } + for (final Iterator<LazyVar> iter = vars.iterator(); iter.hasNext();) { + final LazyVar v = iter.next(); + if (v != null) { + Type targetType = null; + final String expressionString = v.expression; + if (expressionString == null) { + final Variable var = ctx.getVariable(ExecutionContext.IMPLICIT_VARIABLE); + if (var != null) { + if (var.getValue() instanceof ParameterizedType) { + targetType = ((ParameterizedType) var.getValue()).getInnerType(); + } + } + } else { + targetType = new ExpressionFacade(ctx).analyze(expressionString, new HashSet<AnalysationIssue>()); + if (v.forEach) { + if (targetType instanceof ParameterizedType) { + targetType = ((ParameterizedType) targetType).getInnerType(); + } else { + targetType = null; + } + } + } + + if (targetType != null) { + ctx = ctx.cloneWithVariable(new Variable(v.name, targetType)); + } + } + } + return ctx; + } + + /** + * Computes the list of proposals for a type. These proposals are: + * <ol> + * <li>Owned features of the type: {@link Property}, {@link StaticProperty} or {@link Operation}. + * <li>Extensions whose first parameter is of type <code>targetType</code> + * <li>For parametrized types all features of the parameter type + * </ol> + * + * @param targetType Type to search for proposals + * @param prefix A prefix the proposals must match + * @param ctx Current execution context + * @param factory Factory to use for proposal creation + * @return All proposals matching <code>prefix</code> for <code>targetType</code> + */ + private final static List<Object> getAllMemberProposals(Type targetType, final String prefix, final ExecutionContext ctx, + final ProposalFactory factory) { + final List<Object> result = new ArrayList<Object>(); + if (targetType != null) { + Set<? extends Callable> s = targetType.getAllFeatures(); + for (final Callable f : s) { + if (f.getName().toLowerCase().startsWith(prefix.toLowerCase())) { + if (f instanceof Property) { + result.add(factory.createPropertyProposal((Property) f, prefix, false)); + } else if (f instanceof Operation) { + if (Character.isJavaIdentifierStart(f.getName().charAt(0))) { + result.add(factory.createOperationProposal((Operation) f, prefix, false)); + } + } + } + } + + // get all extensions whose first parameter is compatible with 'targetType' + Set<? extends Extension> extensions = ctx.getAllExtensions(); + for (Extension extension : extensions) { + if (extension.getName().toLowerCase().startsWith(prefix.toLowerCase())) { + if (extension.getParameterTypes().size() >= 1) { + Type firstParameterType = extension.getParameterTypes().get(0); + if (targetType.equals(firstParameterType)) { + result.add(factory.createExtensionOnMemberPositionProposal(extension, prefix, false)); + } + } + } + } + if (targetType instanceof ParameterizedType) { + result.addAll(getAllCollectionOperations(prefix, factory)); + targetType = ((ParameterizedType) targetType).getInnerType(); + s = targetType.getAllFeatures(); + for (final Callable f : s) { + if (f.getName().toLowerCase().startsWith(prefix.toLowerCase())) { + if (f instanceof Property) { + result.add(factory.createPropertyProposal((Property) f, prefix, true)); + } else if (f instanceof Operation) { + if (Character.isJavaIdentifierStart(f.getName().charAt(0))) { + result.add(factory.createOperationProposal((Operation) f, prefix, true)); + } + } + } + } + extensions = ctx.getAllExtensions(); + for (final Extension e : extensions) { + if (e.getName().toLowerCase().startsWith(prefix.toLowerCase()) && e.getParameterTypes().size() >= 1 + && e.getParameterTypes().get(0).isAssignableFrom(targetType)) { + result.add(factory.createExtensionOnMemberPositionProposal(e, prefix, true)); + } + } + } + } + return result; + } + + private static List<Object> getAllCollectionOperations(final String prefix, final ProposalFactory f) { + final List<Object> result = new ArrayList<Object>(); + final String marked = "expression-with-e"; + + String s = "select(e|" + marked + ")"; + if (s.startsWith(prefix)) + result.add(f.createCollectionSpecificOperationProposal(s, s, prefix, s.indexOf(marked), marked.length())); + + s = "reject(e|" + marked + ")"; + if (s.startsWith(prefix)) + result.add(f.createCollectionSpecificOperationProposal(s, s, prefix, s.indexOf(marked), marked.length())); + + s = "selectFirst(e|" + marked + ")"; + if (s.startsWith(prefix)) + result.add(f.createCollectionSpecificOperationProposal(s, s, prefix, s.indexOf(marked), marked.length())); + + s = "collect(e|" + marked + ")"; + if (s.startsWith(prefix)) + result.add(f.createCollectionSpecificOperationProposal(s, s, prefix, s.indexOf(marked), marked.length())); + + s = "exists(e|" + marked + ")"; + if (s.startsWith(prefix)) + result.add(f.createCollectionSpecificOperationProposal(s, s, prefix, s.indexOf(marked), marked.length())); + + s = "notExists(e|" + marked + ")"; + if (s.startsWith(prefix)) + result.add(f.createCollectionSpecificOperationProposal(s, s, prefix, s.indexOf(marked), marked.length())); + + s = "forAll(e|" + marked + ")"; + if (s.startsWith(prefix)) + result.add(f.createCollectionSpecificOperationProposal(s, s, prefix, s.indexOf(marked), marked.length())); + + s = "sortBy(e|" + marked + ")"; + if (s.startsWith(prefix)) + result.add(f.createCollectionSpecificOperationProposal(s, s, prefix, s.indexOf(marked), marked.length())); + + s = "typeSelect(Type)"; + if (s.startsWith(prefix)) + result.add(f.createCollectionSpecificOperationProposal(s, s, prefix, s.indexOf("Type"), "Type".length())); + + return result; + } + + /** + * @param ctx + * @return + */ + public final static String[] computePrefixAndTargetExpression(final String str) { + final ReverseScanner scanner = new ReverseScanner(str); + String prefix = ""; + final String expr = null; + + try { + CommonToken t = scanner.previousToken(); + if (t != null) { + // prefix consists of identifier parts + if (!Character.isWhitespace(str.charAt(str.length() - 1))) { + if (Character.isJavaIdentifierStart(t.getText().charAt(0))) { + prefix = t.getText(); + t = scanner.previousToken(); // go to operator + } + } + + final int exprEnd = scanner.getOffset(); + // if t is a dot there is a target expression + if (t != null && ".".equals(t.getText())) { + boolean lastWasOperator = true; + boolean stop = false; + while (!stop && (t = scanner.previousToken()) != null) { + if (isOperand(t)) { + if (lastWasOperator) { + lastWasOperator = false; + } else { // two operands in sequence -> stopper! + scanner.nextToken(); + stop = true; + } + } else if (".".equals(t.getText())) { + if (!lastWasOperator) { + lastWasOperator = true; + } else + // errorneous expression + return new String[] { prefix, expr }; + } else if (isBlockCloser(t) && lastWasOperator) { + lastWasOperator = false; + final Stack<CommonToken> s = new Stack<CommonToken>(); + s.push(t); + while (!s.isEmpty()) { + final CommonToken temp = scanner.previousToken(); + if (temp == null) + return new String[] { prefix, expr }; + if (temp.getType() == t.getType()) { + s.push(temp); + } else if (isOpposite(temp, t)) { + s.pop(); + } + } + if (")".equals(t.getText())) { + // we have an unambigous syntax here + // a.method(with.param) + // but also + // anIdentifier + // (another.parenthesized.expressions) + final CommonToken previousToken = scanner.previousToken(); + if (!isMethodName(previousToken)) { + scanner.nextToken(); + } + } + } else { + scanner.nextToken(); // go one forward + stop = true; + } + } + return new String[] { prefix, str.substring(scanner.getOffset(), exprEnd).trim() }; + } + } + return new String[] { prefix, expr }; + } catch (final Exception e) { + return new String[] { prefix, expr }; + } + } + + private final static boolean isMethodName(final CommonToken token) { + if (token != null) { + return token.getType() == XtendLexer.Identifier || methodNames.contains(token.getText()); + } else { + return false; + } + } + + private final static boolean isOpposite(final CommonToken left, final CommonToken right) { + final String temp = blockTokens.get(left.getText()); + if (temp==null) + return false; + return temp != null && right.getText().equals(temp); + } + + private final static boolean isBlockCloser(final CommonToken t) { + return blockTokens.values().contains(t.getText()); + } + + private final static boolean isOperand(final CommonToken t) { + return t.getType() == XtendLexer.Identifier || + t.getType() == XtendLexer.IntLiteral || + t.getType() == XtendLexer.StringLiteral || operands.contains(t.getText()); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ExtensionImportProposalComputer.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ExtensionImportProposalComputer.java new file mode 100644 index 00000000..c00515eb --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ExtensionImportProposalComputer.java @@ -0,0 +1,42 @@ +package org.eclipse.internal.xtend.expression.codeassist; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.xtend.expression.ExecutionContext; + +public class ExtensionImportProposalComputer { + private final static Pattern p = Pattern.compile("extension\\s+([\\w\\:]*)\\z", Pattern.CASE_INSENSITIVE); + + protected Pattern getPattern() { + return p; + } + + public List<Object> computeProposals(String part, ExecutionContext ctx, ProposalFactory factory, Set<String> extensionFileNames) { + String prefix = computePrefix(part); + List result = new ArrayList(); + if (prefix==null) + return result; + for (String s : extensionFileNames) { + if (s.startsWith(prefix)) + result.add(factory.createExtensionImportProposal(s, s, prefix, s.length(), 0)); + } + return result; + } + + protected String computePrefix(String part) { + Matcher m = getPattern().matcher(part); + if (m.find()) { + return m.group(1); + } + return null; + } + + public String test__computePrefix(String part){ + return computePrefix(part); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/LazyVar.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/LazyVar.java new file mode 100644 index 00000000..a9a7337a --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/LazyVar.java @@ -0,0 +1,25 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.codeassist; + +public class LazyVar { + public String name; + + public String typeName; + + public String expression; + + public boolean forEach = false; +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/Proposal.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/Proposal.java new file mode 100644 index 00000000..0f579874 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/Proposal.java @@ -0,0 +1,23 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.codeassist; + +public interface Proposal { + public String getDisplayString(); + + public String getInsertString(); + + public String getPrefix(); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ProposalComputer.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ProposalComputer.java new file mode 100644 index 00000000..34e5d508 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ProposalComputer.java @@ -0,0 +1,23 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.codeassist; + +import java.util.List; + +import org.eclipse.xtend.expression.ExecutionContext; + +public interface ProposalComputer { + public List<Object> computeProposals(String txt, ExecutionContext ctx, ProposalFactory factory); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ProposalFactory.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ProposalFactory.java new file mode 100644 index 00000000..ec14717d --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ProposalFactory.java @@ -0,0 +1,62 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.codeassist; + +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.xtend.typesystem.Operation; +import org.eclipse.xtend.typesystem.Property; +import org.eclipse.xtend.typesystem.StaticProperty; +import org.eclipse.xtend.typesystem.Type; + +public interface ProposalFactory { + public Object createPropertyProposal(Property p, String prefix, boolean onCollection); + + /** + * Creates an proposal for a static property + * @param p The property for which a proposal should be created + * @param prefix Current evaluation text prefix + * @param onCollection <code>true</code>: Proposal is computed on a collection + * @return A proposal for the content assist + */ + public Object createStaticPropertyProposal(StaticProperty p, String prefix, boolean onCollection); + + public Object createOperationProposal(Operation p, String prefix, boolean onCollection); + + public Object createCollectionSpecificOperationProposal(String insertString, String displayString, String prefix, + int cursor, int marked); + + public Object createDefinitionProposal(final String insertStr, final String displayStr, final String prefix); + + public Object createExtensionProposal(Extension p, String prefix); + + public Object createExtensionOnMemberPositionProposal(Extension p, String prefix, boolean onCollection); + + public Object createVariableProposal(String name, Type t, String prefix); + + public Object createTypeProposal(String insertString, Type type, String prefix); + + public Object createNamespaceProposal(final String insertStr, final String displayStr, final String prefix); + + public Object createStatementProposal(String insertString, String displayString, String prefix, int cursor, + int marked); + + public Object createStatementProposal(String insertString, String displayString, String prefix); + + public Object createKeywordProposal(String insertString, String displayString, String prefix); + + public Object createExtensionImportProposal(final String insertStr, final String displayStr, final String prefix, + final int cursor, final int marked); + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ProposalFactoryDefaultImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ProposalFactoryDefaultImpl.java new file mode 100644 index 00000000..a1299b7d --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ProposalFactoryDefaultImpl.java @@ -0,0 +1,86 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.codeassist; + +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.Operation; +import org.eclipse.xtend.typesystem.Property; +import org.eclipse.xtend.typesystem.StaticProperty; +import org.eclipse.xtend.typesystem.Type; + +public class ProposalFactoryDefaultImpl implements ProposalFactory { + + public Object createPropertyProposal(final Property p, final String prefix, final boolean onCollection) { + return new ProposalImpl(prefix, p.getName(), p.toString(), p); + } + + public Object createStaticPropertyProposal(final StaticProperty p, final String prefix, final boolean onCollection) { + return new ProposalImpl(prefix, p.getName(), p.toString(), p); + } + + public Object createOperationProposal(final Operation p, final String prefix, final boolean onCollection) { + return new ProposalImpl(prefix, p.getName(), p.toString(), p); + } + + public Object createExtensionOnMemberPositionProposal(final Extension p, final String prefix, + final boolean onCollection) { + return new ProposalImpl(prefix, p.getName(), p.toString(), p); + } + + public Object createCollectionSpecificOperationProposal(final String insertString, final String displayString, + final String prefix, final int cursor, final int marked) { + return new ProposalImpl(prefix, insertString, displayString, displayString); + } + + public Object createExtensionProposal(final Extension p, final String prefix) { + return new ProposalImpl(prefix, p.getName(), p.toString(), p); + } + + public Object createVariableProposal(final String name, final Type t, final String prefix) { + return new ProposalImpl(prefix, name, name, new Variable(name, t)); + } + + public Object createTypeProposal(final String insertString, final Type type, final String prefix) { + return new ProposalImpl(prefix, insertString, type.getName(), type); + } + + public Object createStatementProposal(final String insertString, final String displayString, final String prefix, + final int cursor, final int marked) { + return new ProposalImpl(prefix, insertString, displayString, displayString); + } + + public Object createStatementProposal(final String insertString, final String displayString, final String prefix) { + return new ProposalImpl(prefix, insertString, displayString, displayString); + } + + public Object createKeywordProposal(final String insertString, final String displayString, final String prefix) { + return new ProposalImpl(prefix, insertString, displayString, displayString); + } + + public Object createExtensionImportProposal(String insertStr, String displayStr, String prefix, int cursor, + int marked) { + return new ProposalImpl(prefix, insertStr, displayStr, displayStr); + } + + public Object createNamespaceProposal(String insertStr, String displayStr, String prefix) { + return new ProposalImpl(prefix, insertStr, displayStr, displayStr); + } + + public Object createDefinitionProposal(String insertStr, String displayStr, String prefix) { + return new ProposalImpl(prefix, insertStr, displayStr, displayStr); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ProposalImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ProposalImpl.java new file mode 100644 index 00000000..0d09d960 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ProposalImpl.java @@ -0,0 +1,48 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.codeassist; + +public class ProposalImpl implements Proposal { + private String prefix; + + private Object proposedElement; + + private String insertString; + + private String displayString; + + public ProposalImpl(final String prefix, final String insertString, final String displayString, final Object element) { + this.prefix = prefix; + proposedElement = element; + this.insertString = insertString; + this.displayString = displayString; + } + + public String getPrefix() { + return prefix; + } + + public Object getProposedElement() { + return proposedElement; + } + + public String getDisplayString() { + return displayString; + } + + public String getInsertString() { + return insertString; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ReverseScanner.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ReverseScanner.java new file mode 100644 index 00000000..e5997ff2 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/ReverseScanner.java @@ -0,0 +1,72 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.codeassist; + +import java.util.ArrayList; +import java.util.List; + +import org.antlr.runtime.ANTLRStringStream; +import org.antlr.runtime.CommonToken; +import org.antlr.runtime.CommonTokenStream; +import org.eclipse.internal.xtend.xtend.parser.XtendLexer; + +public class ReverseScanner { + + private int index; + + private List<CommonToken> tokens = new ArrayList<CommonToken>(); + + public ReverseScanner(final String s) { + CommonTokenStream stream = new CommonTokenStream(new XtendLexer( + new ANTLRStringStream(s))); + CommonToken ct = null; + tokens.add(null); + while ((ct = (CommonToken) stream.LT(1)).getType() != XtendLexer.EOF) { + tokens.add(ct); + stream.consume(); + } + tokens.add(null); + index = lastIndex(); + } + + private int lastIndex() { + return tokens.size()-1; + } + + public CommonToken previousToken() { + return tokens.get(decrement()); + } + + private int decrement() { + return index==0?0:--index; + } + + public CommonToken nextToken() { + return tokens.get(increment()); + } + + private int increment() { + return index==lastIndex()?lastIndex():++index; + } + + public int getOffset() { + if (index == 0) + return 0; + if (index == lastIndex()) + return tokens.get(lastIndex()-1).getStopIndex()+1; + return tokens.get(index).getStartIndex(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/TypeProposalComputer.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/TypeProposalComputer.java new file mode 100644 index 00000000..22db8822 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/codeassist/TypeProposalComputer.java @@ -0,0 +1,58 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.codeassist; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.TypeNameUtil; +import org.eclipse.xtend.typesystem.Type; + +public class TypeProposalComputer implements ProposalComputer { + + public List<Object> computeProposals(final String txt, final ExecutionContext ctx, final ProposalFactory factory) { + final String prefix = findPrefix(txt); + final Type[] types = ctx.findTypesForPrefix(prefix); + final List<Object> result = new ArrayList<Object>(); + List<String> namespaces = Arrays.asList(ctx.currentResource().getImportedNamespaces()); + for (int i = 0; i < types.length; i++) { + final Type type = types[i]; + String insertString = type.getName(); + if (insertString.startsWith(prefix)) { + result.add(factory.createTypeProposal(insertString, type, prefix)); + } else { + String simpleName = TypeNameUtil.getSimpleName(insertString); + if (simpleName.startsWith(prefix) && namespaces.contains(TypeNameUtil.getPackage(insertString))) { + result.add(factory.createTypeProposal(simpleName, type, prefix)); + } + } + } + return result; + } + + public String findPrefix(final String txt) { + final StringBuffer result = new StringBuffer(); + int i = txt.length() - 1; + char c = txt.charAt(i); + while (i > 0 && (Character.isJavaIdentifierStart(c) || c == ':')) { + result.append(c); + c = txt.charAt(--i); + } + return result.reverse().toString(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/BaseSpecialTreatment.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/BaseSpecialTreatment.java new file mode 100644 index 00000000..b8e953d1 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/BaseSpecialTreatment.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2005 - 2007 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.internal.xtend.expression.debug; + +import org.eclipse.emf.mwe.core.debug.model.SyntaxElement; +import org.eclipse.internal.xtend.expression.ast.ISyntaxElement; +import org.eclipse.xtend.expression.ExecutionContext; + +/** + * Base class for all special treatments for element adapters. + * + * @author Clemens Kadura (zAJKa) + */ +public abstract class BaseSpecialTreatment { + + public boolean shallNotSuspend(Object element, int flag, ExecutionContext context) { + return false; + } + + public void adaptSyntaxElement(SyntaxElement to, Object element) { + // empty implementation + } + + /** + * add syntax element specific content to the element name that will be shown in Launch view + * @param se the syntax element + * @param context the execution context + * @return the special text to add to the name + */ + public String adaptElementName(ISyntaxElement se, ExecutionContext context){ + return ""; + } + + public ISyntaxElement getSpecialEndSyntaxElement(ISyntaxElement se){ + return null; + } + + public int getElementNameLength(ISyntaxElement se) { + return -1; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/EvaluatedElementWrapper.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/EvaluatedElementWrapper.java new file mode 100644 index 00000000..77625c26 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/EvaluatedElementWrapper.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2005 - 2007 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.internal.xtend.expression.debug; + +import org.eclipse.internal.xtend.expression.ast.ISyntaxElement; +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; + +/** + * Wrapper for a SyntaxElement to mark it evaluated for breakpoints. + * + * @author Clemens Kadura (zAJKa) + */ +public class EvaluatedElementWrapper extends SyntaxElement { + + private final ISyntaxElement element; + + public EvaluatedElementWrapper(ISyntaxElement element) { + this.element = element; + } + + public ISyntaxElement getElement() { + return element; + } + + @Override + public int getLine() { + return element.getLine(); + } + + @Override + public int getEnd() { + return element.getEnd(); + } + + @Override + public int getStart() { + return element.getStart(); + } + + @Override + public String getFileName() { + return element.getFileName(); + } + + @Override + public String toString() { + return element.toString(); + } + + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/ExpressionElementAdapter.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/ExpressionElementAdapter.java new file mode 100644 index 00000000..fe71a2d9 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/ExpressionElementAdapter.java @@ -0,0 +1,278 @@ +/******************************************************************************* + * Copyright (c) 2005 - 2007 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.internal.xtend.expression.debug; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import org.eclipse.emf.mwe.core.debug.model.NameValuePair; +import org.eclipse.emf.mwe.core.debug.model.SyntaxElement; +import org.eclipse.emf.mwe.core.debug.processing.ElementAdapter; +import org.eclipse.internal.xtend.expression.ast.ChainExpression; +import org.eclipse.internal.xtend.expression.ast.Expression; +import org.eclipse.internal.xtend.expression.ast.FeatureCall; +import org.eclipse.internal.xtend.expression.ast.Literal; +import org.eclipse.internal.xtend.expression.ast.OperationCall; +import org.eclipse.internal.xtend.type.baseimpl.PolymorphicResolver; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.AbstractTypeImpl; +import org.eclipse.xtend.typesystem.Callable; +import org.eclipse.xtend.typesystem.Property; +import org.eclipse.xtend.typesystem.Type; + +/** + * The IElementAdapter implementation for expressions. + * + * @author Bernd Kolb + * @author Clemens Kadura (zAJKa) + */ +public class ExpressionElementAdapter implements ElementAdapter { + + public static final String TYPE = "expression"; + + protected ExecutionContext context; + + protected ExpressionModelPresentation pres; + + protected Set<BaseSpecialTreatment> specials = new HashSet<BaseSpecialTreatment>(); + + // ------------------------------------------------------------------------- + + public ExpressionElementAdapter() { + specials.add(new NoResourceSpecial()); + pres = new ExpressionModelPresentation(specials); + } + + // ------------------------------------------------------------------------- + + public ExecutionContext getContext() { + return context; + } + + public void setContext(Object context) { + this.context = (ExecutionContext) context; + } + + public String getAdapterType() { + return TYPE; + } + + // ------------------------------------------------------------------------- + + public boolean canHandle(Object element) { + if (element instanceof Expression) + return true; + if (element instanceof SyntaxElement) { + SyntaxElement se = (SyntaxElement) element; + return se.resource.endsWith(".ext"); + } + return false; + } + + public boolean shallHandle(Object element) { + return element instanceof OperationCall && ((OperationCall) element).getName().getValue().length() > 2; + } + + public boolean shallSuspend(Object element, int flag) { + boolean result = true; + for (BaseSpecialTreatment special : specials) + result &= !(special.shallNotSuspend(element, flag, context)); + return result; + } + + public SyntaxElement createElementTO(Object element) { + SyntaxElement to = pres.getStartPresentation((org.eclipse.internal.xtend.expression.ast.SyntaxElement) element, context); + for (BaseSpecialTreatment special : specials) + special.adaptSyntaxElement(to, element); + return to; + } + + public boolean isSurroundingElement(Object element) { + return false; + } + + public SyntaxElement createEndElementTO(Object element) { + // TODO: CK: low: decide where end location is available and set it here + return pres.getEndPresentation((org.eclipse.internal.xtend.expression.ast.SyntaxElement) element, context); + } + + public String getVariableDetailRep(Object element) { + return pres.getStringRep(element); + } + + public String getVariableSimpleRep(Object element) { + return pres.getVariableSimpleRep(element, context); + } + + public boolean checkVariableHasMembers(Object element) { + if (element instanceof Collection) + return !((Collection<?>) element).isEmpty(); + if (element instanceof Type) { + Type t = (Type) element; + return t.getAllProperties().size() > 0; + } + return context.getType(element).getAllProperties().size() > 0; + } + + public List<NameValuePair> getVariables(Object element) { + if (element instanceof ChainExpression || element instanceof Literal) { + return Collections.EMPTY_LIST; + } + if (element instanceof OperationCall) { + ArrayList<NameValuePair> result = getAllVisibleVariables(); + + Map<String, Variable> visibleVariables = context.getVisibleVariables(); + + Expression[] params = ((OperationCall) element).getParams(); + for (Expression expression : params) { + if (expression instanceof FeatureCall && !(expression instanceof OperationCall)) { + FeatureCall fc = (FeatureCall) expression; + if (!visibleVariables.containsKey(fc.toString())) { + result.addAll(evaluateFeatureCall(fc)); + } + } + } + + Expression target = ((OperationCall) element).getTarget(); + if (target instanceof FeatureCall && !(target instanceof OperationCall)) { + if (!visibleVariables.containsKey(target.toString())) { + FeatureCall fc = (FeatureCall) target; + result.addAll(evaluateFeatureCall(fc)); + } + + } + + return result; + } + if (element instanceof FeatureCall) { + return evaluateFeatureCall((FeatureCall) element); + } + if (element instanceof Collection) { + List<NameValuePair> result = new ArrayList<NameValuePair>(); + Collection col = (Collection) element; + int i = 0; + for (Object object : col) { + result.add(new NameValuePair("[" + i + "]", object)); + i++; + } + return result; + } + Type type = context.getType(element); + return getAllPropertiesFor(type, element); + } + + public Object findElement(SyntaxElement se, Object actual, int flag) { + if (actual == null) + return null; + if (actual instanceof OperationCall) { + OperationCall op = (OperationCall) actual; + int start = pres.getStart(op); + if (se.resource.endsWith(pres.getStringRep(op.getFileName())) && se.start == start) + return actual; + } + return null; + } + + // ------------------------------------------------------------------------- + + protected ArrayList<NameValuePair> getAllVisibleVariables() { + ArrayList<NameValuePair> result = new ArrayList<NameValuePair>(); + Map<String, Variable> visibleVariables = context.getVisibleVariables(); + + for (Entry<String, Variable> nameValuePair : visibleVariables.entrySet()) { + result.add(new NameValuePair(nameValuePair.getKey(), nameValuePair.getValue().getValue())); + } + return result; + } + + private List<NameValuePair> evaluateFeatureCall(FeatureCall fc) { + return getEvalResultProperties(fc.toString(), fc.evaluate(context.cloneWithoutMonitor())); + } + + private List<NameValuePair> getEvalResultProperties(String prefix, Object evaluate) { + ArrayList<NameValuePair> result = new ArrayList<NameValuePair>(); + if (evaluate instanceof Collection) { + result.add(new NameValuePair(prefix, evaluate)); + return result; + } + Type type = context.getType(evaluate); + return getAllPropertiesFor(type, evaluate); + } + + // Hint: We don't use the AbstractTypeImpl collection of all properties, because it collects methods with the + // same name from superclasses twice. We take only the most specialized method here (as in Java) + // Is this a bug or intended that way in AbstractTypeImpl? (TODO: ask Sven or Arno) + private List<NameValuePair> getAllPropertiesFor(Type type, Object element) { + ArrayList<NameValuePair> result = new ArrayList<NameValuePair>(); + + for (Property p : getAllProperties(type)) { + String name = p.getName(); + if (!(name.equals("wait") || name.startsWith("notify"))) { + Object value = null; + try { + value = p.get(element); + } catch (Exception e) { + value = "Error: " + e.getMessage(); + } + if (value != null) { + result.add(new NameValuePair(name, value)); + } + } + } + return result; + } + + // ------------------------------------------------------------------------- + // see AbstractTypeImpl + + private final Map<Type, Map<String, Callable>> typeCache = new HashMap<Type, Map<String, Callable>>(); + + private Set<? extends Property> getAllProperties(Type type) { + return PolymorphicResolver.select(getAllFeatures(type), Property.class); + } + + public final Set<Callable> getAllFeatures(Type type) { + Map<String, Callable> allFeatures; + if (typeCache.containsKey(type)) + allFeatures = typeCache.get(type); + else { + allFeatures = new HashMap<String, Callable>(); + Callable[] contribs = ((AbstractTypeImpl) type).getContributedFeatures(); + addIfNotExist(allFeatures, Arrays.asList(contribs)); + for (Type superType : type.getSuperTypes()) { + if (superType != null) + addIfNotExist(allFeatures, getAllFeatures(superType)); + } + typeCache.put(type, allFeatures); + } + Set<Callable> result = new HashSet<Callable>(); + result.addAll(allFeatures.values()); + return result; + } + + private void addIfNotExist(Map<String, Callable> all, Collection<Callable> more) { + for (Callable one : more) { + String name = one.getName(); + if (!all.containsKey(name)) + all.put(name, one); + } + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/ExpressionModelPresentation.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/ExpressionModelPresentation.java new file mode 100644 index 00000000..00b3fa53 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/ExpressionModelPresentation.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2005 - 2007 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.internal.xtend.expression.debug; + +import java.util.Set; + +import org.eclipse.emf.mwe.core.debug.model.SyntaxElement; +import org.eclipse.internal.xtend.expression.ast.FeatureCall; +import org.eclipse.internal.xtend.expression.ast.ISyntaxElement; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.ExpressionFacade; +import org.eclipse.xtend.expression.Variable; + +/** + * This class is responsible for all presentation topics for expressions in the debugger views. + * + * @author Clemens Kadura (zAJKa) + */ +public class ExpressionModelPresentation { + + protected Set<BaseSpecialTreatment> specials; + + // ------------------------------------------------------------------------- + + public ExpressionModelPresentation(Set<BaseSpecialTreatment> specials) { + this.specials = specials; + } + + // ------------------------------------------------------------------------- + + public SyntaxElement getStartPresentation(ISyntaxElement se, ExecutionContext context) { + SyntaxElement to = new SyntaxElement(); + + to.containerName = getContainerName(se); + to.elementName = se.getNameString(context); + to.resource = getResource(se); + to.start = getStart(se); + to.end = se.getEnd(); + to.line = se.getLine(); + return to; + } + + public SyntaxElement getEndPresentation(ISyntaxElement se, ExecutionContext context) { + return getStartPresentation(se, context); + } + + public String getVariableSimpleRep(Object element, ExecutionContext context) { + if (element == null) + return "null"; + if (element instanceof String) + return (String) element; + return (String) new ExpressionFacade(context.cloneWithVariable(new Variable("this", element))).evaluate("metaType.name"); + } + + // ------------------------------------------------------------------------- + + public int getStart(ISyntaxElement se) { + if (se instanceof FeatureCall) + return ((FeatureCall) se).getName().getStart(); + return se.getStart(); + } + + public int getStartingEndPosition(ISyntaxElement se) { + return se.getEnd(); + } + + // ------------------------------------------------------------------------- + + protected String getContainerName(ISyntaxElement se) { + return getTemplateName(se); + } + + protected String getTemplateName(ISyntaxElement se) { + String fileName = se.getFileName(); + if (fileName == null) + return ""; + return fileName.substring(fileName.lastIndexOf('/') + 1, fileName.length() - 4); + } + + protected String getResource(ISyntaxElement se) { + if (se.getFileName() == null) + return ""; + return se.getFileName(); + } + + public String getStringRep(Object element) { + if (element == null) + return "null"; + return element.toString(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/NoResourceSpecial.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/NoResourceSpecial.java new file mode 100644 index 00000000..94ad4a33 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/debug/NoResourceSpecial.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2005 - 2007 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.internal.xtend.expression.debug; + +import org.eclipse.emf.mwe.core.debug.model.SyntaxElement; +import org.eclipse.emf.mwe.core.debug.processing.EventHandler; +import org.eclipse.xtend.expression.ExecutionContext; + +/** + * Adapter to handle statements that don't have an associated resource. (mainly the initial one) + * + * @author Clemens Kadura (zAJKa) + */ +public class NoResourceSpecial extends BaseSpecialTreatment { + + /** + * Don't suspend for normal frame, if the element has no resource (virtual ones) + * + * @see org.eclipse.internal.xtend.expression.debug.BaseSpecialTreatment#shallNotSuspend(java.lang.Object, int) + */ + @Override + public boolean shallNotSuspend(Object element, int flag, ExecutionContext ctx) { + return flag == EventHandler.NORMAL_FRAME && !hasResource(element); + } + + /** + * Don't show frame in Launch view, if the element has no resource (virtual ones) + * + * @see org.eclipse.internal.xtend.expression.debug.BaseSpecialTreatment#adaptSyntaxElementTO(org.eclipse.internal.xtend.debug.model.SyntaxElement, + * java.lang.Object) + */ + @Override + public void adaptSyntaxElement(SyntaxElement to, Object element) { + if (!hasResource(element)) + to.visible = false; + } + + // ------------------------------------------------------------------------- + + private boolean hasResource(Object element) { + return getClass().getResource("/" + ((org.eclipse.internal.xtend.expression.ast.SyntaxElement) element).getFileName()) != null; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/parser/ExpressionFactory.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/parser/ExpressionFactory.java new file mode 100644 index 00000000..c63f63af --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/parser/ExpressionFactory.java @@ -0,0 +1,201 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.parser; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.internal.xtend.expression.ast.BooleanLiteral; +import org.eclipse.internal.xtend.expression.ast.BooleanOperation; +import org.eclipse.internal.xtend.expression.ast.Case; +import org.eclipse.internal.xtend.expression.ast.Cast; +import org.eclipse.internal.xtend.expression.ast.ChainExpression; +import org.eclipse.internal.xtend.expression.ast.CollectionExpression; +import org.eclipse.internal.xtend.expression.ast.ConstructorCallExpression; +import org.eclipse.internal.xtend.expression.ast.DeclaredParameter; +import org.eclipse.internal.xtend.expression.ast.Expression; +import org.eclipse.internal.xtend.expression.ast.FeatureCall; +import org.eclipse.internal.xtend.expression.ast.GlobalVarExpression; +import org.eclipse.internal.xtend.expression.ast.Identifier; +import org.eclipse.internal.xtend.expression.ast.IfExpression; +import org.eclipse.internal.xtend.expression.ast.IntegerLiteral; +import org.eclipse.internal.xtend.expression.ast.LetExpression; +import org.eclipse.internal.xtend.expression.ast.ListLiteral; +import org.eclipse.internal.xtend.expression.ast.NullLiteral; +import org.eclipse.internal.xtend.expression.ast.OperationCall; +import org.eclipse.internal.xtend.expression.ast.RealLiteral; +import org.eclipse.internal.xtend.expression.ast.StringLiteral; +import org.eclipse.internal.xtend.expression.ast.SwitchExpression; +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; +import org.eclipse.internal.xtend.expression.ast.TypeSelectExpression; +import org.eclipse.internal.xtend.xtend.ast.ExtensionFile; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class ExpressionFactory { + + private String fileName; + + public ExpressionFactory(final String string) { + fileName = string; + } + + public ExpressionFactory() { + fileName = "nofile"; + } + + public Identifier createIdentifier(String text) { + return handle(new Identifier(text)); + } + + public StringLiteral createStringLiteral(final Identifier t) { + return handle(new StringLiteral(t)); + } + + public IntegerLiteral createIntegerLiteral(final Identifier t) { + return handle(new IntegerLiteral(t)); + } + + public BooleanLiteral createBooleanLiteral(final Identifier t) { + return handle(new BooleanLiteral(t)); + } + + public NullLiteral createNullLiteral(final Identifier t) { + return handle(new NullLiteral(t)); + } + + public ListLiteral createListLiteral(List<Expression> paramExpr) { + if (paramExpr == null) + paramExpr = new ArrayList<Expression>(); + return handle(new ListLiteral(paramExpr + .toArray(new Expression[paramExpr.size()]))); + } + + public FeatureCall createFeatureCall(final Identifier name, + final Expression target) { + return handle(new FeatureCall(name, target)); + } + + public OperationCall createOperationCall(final Identifier name, + final Expression singleParam) { + return handle(new OperationCall(name, singleParam)); + } + + public OperationCall createOperationCall(final Identifier name, + List<Expression> parameterExpressions) { + if (parameterExpressions == null) + parameterExpressions = new ArrayList<Expression>(); + final Expression[] params = parameterExpressions + .toArray(new Expression[parameterExpressions.size()]); + return handle(new OperationCall(name, null, params)); + } + + public Expression createBinaryOperation(Identifier name, Expression left, + Expression right) { + return handle(new OperationCall(name, left, right)); + } + + public IfExpression createIf(final Expression cond, final Expression then, + final Expression elseExpr) { + return handle(new IfExpression(cond, then, elseExpr)); + } + + public CollectionExpression createCollectionExpression( + final Identifier opName, final Identifier elementName, + final Expression closure) { + return handle(new CollectionExpression(opName, + elementName, closure)); + } + + public DeclaredParameter createDeclaredParameter(final Identifier type, + final Identifier name) { + return handle(new DeclaredParameter(type, name)); + } + + public Expression createCast(final Identifier t, final Expression e) { + return handle(new Cast(t, e)); + } + + protected <T extends SyntaxElement> T handle(final T expr) { + expr.setFileName(fileName); + return expr; + } + protected SyntaxElement handle(final ExtensionFile expr) { + expr.setFileName(fileName); + expr.setFullyQualifiedName(fileName); + return expr; + } + + public Case createCase(final Expression cond, final Expression then) { + return handle(new Case(cond, then)); + } + + public SwitchExpression createSwitchExpression(final Expression switchExpr, + final List<Case> cases, final Expression defaultExpr) { + return handle(new SwitchExpression(switchExpr, + nonNull(cases), defaultExpr)); + } + + public ChainExpression createChainExpression(final Expression head, + final Expression next) { + return handle(new ChainExpression(head, next)); + } + + public RealLiteral createRealLiteral(final Identifier lit) { + return handle(new RealLiteral(lit)); + } + + public FeatureCall createTypeSelectExpression(final Identifier id, + final Identifier ident) { + return handle(new TypeSelectExpression(id, ident)); + } + + public BooleanOperation createBooleanOperation(final Identifier name, + final Expression e, final Expression r) { + return handle(new BooleanOperation(name, e, r)); + } + + public LetExpression createLetExpression(final Identifier v, + final Expression varExpr, final Expression target) { + return handle(new LetExpression(v, varExpr, target)); + } + + public Expression createConstructorCall(final Identifier type) { + return handle(new ConstructorCallExpression( + type)); + } + + public GlobalVarExpression createGlobalVarExpression(Identifier name) { + return handle(new GlobalVarExpression(name)); + } + + public Expression createParanthesizedExpression(Expression x) { + return x; // TODO create an AST element (when needed) + } + + protected <T> List<T> nonNull(List<T> l) { + if (l == null) + return new ArrayList<T>(); + for (Iterator<T> iter = l.iterator(); iter.hasNext();) { + Object x = (Object) iter.next(); + if (x==null) + iter.remove(); + } + return l; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/parser/SyntaxConstants.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/parser/SyntaxConstants.java new file mode 100644 index 00000000..a45a3dbc --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/parser/SyntaxConstants.java @@ -0,0 +1,44 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.expression.parser; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Markus Voelter + */ +public interface SyntaxConstants { + public final static String NS_DELIM = "::"; + + public static final String COLLECT = "collect"; + + public static final String SELECT = "select"; + + public static final String SELECTFIRST = "selectFirst"; + + public static final String REJECT = "reject"; + + public static final String EXISTS = "exists"; + + public static final String NOT_EXISTS = "notExists"; + + public static final String FOR_ALL = "forAll"; + + public static final String SORT_BY = "sortBy"; + + public static final String DEFAULT_ELE_NAME = "element"; + + public static final String TYPE_SELECT = "typeSelect"; +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/BuiltinMetaModel.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/BuiltinMetaModel.java new file mode 100644 index 00000000..3dde82e5 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/BuiltinMetaModel.java @@ -0,0 +1,331 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2007 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl; + +import java.math.BigDecimal; +import java.math.BigInteger; +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.internal.xtend.expression.parser.SyntaxConstants; +import org.eclipse.internal.xtend.type.baseimpl.types.BooleanTypeImpl; +import org.eclipse.internal.xtend.type.baseimpl.types.CollectionTypeImpl; +import org.eclipse.internal.xtend.type.baseimpl.types.FeatureTypeImpl; +import org.eclipse.internal.xtend.type.baseimpl.types.IntegerTypeImpl; +import org.eclipse.internal.xtend.type.baseimpl.types.ListTypeImpl; +import org.eclipse.internal.xtend.type.baseimpl.types.ObjectTypeImpl; +import org.eclipse.internal.xtend.type.baseimpl.types.OperationTypeImpl; +import org.eclipse.internal.xtend.type.baseimpl.types.PropertyTypeImpl; +import org.eclipse.internal.xtend.type.baseimpl.types.RealTypeImpl; +import org.eclipse.internal.xtend.type.baseimpl.types.SetTypeImpl; +import org.eclipse.internal.xtend.type.baseimpl.types.StaticPropertyTypeImpl; +import org.eclipse.internal.xtend.type.baseimpl.types.StringTypeImpl; +import org.eclipse.internal.xtend.type.baseimpl.types.TypeTypeImpl; +import org.eclipse.internal.xtend.type.baseimpl.types.VoidType; +import org.eclipse.internal.xtend.util.Cache; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.MetaModel; +import org.eclipse.xtend.typesystem.ParameterizedType; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public final class BuiltinMetaModel implements MetaModel { + + public static final String OBJECT = "Object"; + + // Datatypes + public final static String STRING = "String"; + + public final static String BOOLEAN = "Boolean"; + + public final static String INTEGER = "Integer"; + + public final static String REAL = "Real"; + + // Collection types + public final static String COLLECTION = "Collection"; + + public final static String SET = "Set"; + + public final static String LIST = "List"; + + // reflection layer types + public static final String TYPE = "oaw::Type"; + + public static final String FEATURE = "oaw::Feature"; + + public static final String PROPERTY = "oaw::Property"; + + public static final String OPERATION = "oaw::Operation"; + + private static final String STATIC_PROPERTY = "oaw::StaticProperty"; + + public static final String VOID = "Void"; + + // singleton instances + private Type stringType = null; + + private Type booleanType = null; + + private Type integerType = null; + + private Type realType = null; + + private Type objectType = null; + + private Type typeType = null; + + private Type featureType = null; + + private Type propertyType = null; + + private Type operationType = null; + + private Type staticPropertyType = null; + + private Type voidType = null; + + private final Map<String, Type> _builtinTypes = new HashMap<String, Type>(); + + private TypeSystem typeSystem; + + public TypeSystem getTypeSystem() { + return typeSystem; + } + + public BuiltinMetaModel(final TypeSystem typeSystem) { + this.typeSystem = typeSystem; + + stringType = new StringTypeImpl(getTypeSystem(), BuiltinMetaModel.STRING); + + booleanType = new BooleanTypeImpl(getTypeSystem(), BuiltinMetaModel.BOOLEAN); + + integerType = new IntegerTypeImpl(getTypeSystem(), BuiltinMetaModel.INTEGER); + + realType = new RealTypeImpl(getTypeSystem(), BuiltinMetaModel.REAL); + + objectType = new ObjectTypeImpl(getTypeSystem(), BuiltinMetaModel.OBJECT); + + typeType = new TypeTypeImpl(getTypeSystem(), BuiltinMetaModel.TYPE); + + featureType = new FeatureTypeImpl(getTypeSystem(), BuiltinMetaModel.FEATURE); + + propertyType = new PropertyTypeImpl(getTypeSystem(), BuiltinMetaModel.PROPERTY); + + staticPropertyType = new StaticPropertyTypeImpl(getTypeSystem(), BuiltinMetaModel.STATIC_PROPERTY); + + operationType = new OperationTypeImpl(getTypeSystem(), BuiltinMetaModel.OPERATION); + + voidType = new VoidType(getTypeSystem(), BuiltinMetaModel.VOID); + + _builtinTypes.put(BuiltinMetaModel.OBJECT, objectType); + _builtinTypes.put(convert(Object.class.getName()), objectType); + + _builtinTypes.put(BuiltinMetaModel.VOID, voidType); + + _builtinTypes.put(BuiltinMetaModel.STRING, stringType); + _builtinTypes.put(convert(String.class.getName()), stringType); + _builtinTypes.put(convert(StringBuffer.class.getName()), stringType); + _builtinTypes.put(Character.TYPE.getName(), stringType); + _builtinTypes.put(convert(Character.class.getName()), stringType); + + _builtinTypes.put(BuiltinMetaModel.BOOLEAN, booleanType); + _builtinTypes.put(Boolean.TYPE.getName(), booleanType); + _builtinTypes.put(convert(Boolean.class.getName()), booleanType); + + _builtinTypes.put(BuiltinMetaModel.INTEGER, integerType); + _builtinTypes.put(Integer.TYPE.getName(), integerType); + _builtinTypes.put(convert(Integer.class.getName()), integerType); + _builtinTypes.put(convert(Long.class.getName()), integerType); + _builtinTypes.put(convert(Short.class.getName()), integerType); + _builtinTypes.put(convert(Byte.class.getName()), integerType); + _builtinTypes.put(convert(BigInteger.class.getName()), integerType); + + _builtinTypes.put(BuiltinMetaModel.REAL, realType); + _builtinTypes.put(Double.TYPE.getName(), realType); + _builtinTypes.put(convert(Double.class.getName()), realType); + _builtinTypes.put(convert(Float.class.getName()), realType); + _builtinTypes.put(convert(BigDecimal.class.getName()), realType); + + _builtinTypes.put(BuiltinMetaModel.TYPE, typeType); + _builtinTypes.put(BuiltinMetaModel.FEATURE, featureType); + _builtinTypes.put(BuiltinMetaModel.PROPERTY, propertyType); + _builtinTypes.put(BuiltinMetaModel.OPERATION, operationType); + _builtinTypes.put(BuiltinMetaModel.STATIC_PROPERTY, staticPropertyType); + + _builtinTypes.put(BuiltinMetaModel.COLLECTION, getCollectionType(objectType)); + _builtinTypes.put(Collection.class.getName(), getCollectionType(objectType)); + _builtinTypes.put(convert(Collection.class.getName()), getCollectionType(objectType)); + _builtinTypes.put(BuiltinMetaModel.SET, getSetType(objectType)); + _builtinTypes.put(Set.class.getName(), getSetType(objectType)); + _builtinTypes.put(convert(Set.class.getName()), getSetType(objectType)); + _builtinTypes.put(BuiltinMetaModel.LIST, getListType(objectType)); + _builtinTypes.put(List.class.getName(), getListType(objectType)); + _builtinTypes.put(convert(List.class.getName()), getListType(objectType)); + + _knownTypes = new HashSet<Type>(_builtinTypes.values()); + } + + public String getName() { + return "built-in"; + } + + public final Type getObjectType() { + return objectType; + } + + public final Type getBooleanType() { + return booleanType; + } + + public final Type getIntegerType() { + return integerType; + } + + public Type getRealType() { + return realType; + } + + public final Type getStringType() { + return stringType; + } + + public final Type getTypeType() { + return typeType; + } + + public final Type getFeatureType() { + return featureType; + } + + public final Type getPropertyType() { + return propertyType; + } + + public final Type getOperationType() { + return operationType; + } + + public Type getStaticPropertyType() { + return staticPropertyType; + } + + public final ParameterizedType getCollectionType(final Type innerType) { + return new CollectionTypeImpl(innerType, getTypeSystem(), BuiltinMetaModel.COLLECTION); + } + + public final ParameterizedType getListType(final Type innerType) { + return new ListTypeImpl(innerType, getTypeSystem(), BuiltinMetaModel.LIST); + } + + public final ParameterizedType getSetType(final Type innerType) { + return new SetTypeImpl(innerType, getTypeSystem(), BuiltinMetaModel.SET); + } + + private final Cache<Object, Type> typeCache = new Cache<Object, Type>() { + + @Override + protected Type createNew(Object obj) { + if (obj == null) { + return getVoidType(); + } + if (obj instanceof Set) { + return getSetType(null); + } + if (obj instanceof List) { + return getListType(null); + } + if (obj instanceof Collection) { + return getCollectionType(null); + } + // datatypes + if (stringType.isInstance(obj)) { + return stringType; + } + if (integerType.isInstance(obj)) { + return integerType; + } + if (booleanType.isInstance(obj)) { + return booleanType; + } + if (realType.isInstance(obj)) { + return realType; + } + if (typeType.isInstance(obj)) { + return typeType; + } + if (propertyType.isInstance(obj)) { + return propertyType; + } + if (operationType.isInstance(obj)) { + return operationType; + } + if (staticPropertyType.isInstance(obj)) { + return staticPropertyType; + } + + return objectType; + } + }; + + public Type getType(final Object obj) { + return typeCache.get(obj); + } + + public Type getTypeForName(final String typeName) { + return _builtinTypes.get(typeName); + } + + HashSet<Type> _knownTypes; + public Set<Type> getKnownTypes() { + return _knownTypes; + } + + private final static String convert(final String javaclassname) { + final StringBuffer sb = new StringBuffer(); + for (int i = 0; i < javaclassname.length(); i++) { + final char c = javaclassname.charAt(i); + if (c == '.') { + sb.append(SyntaxConstants.NS_DELIM); + } else { + sb.append(c); + } + } + return sb.toString(); + } + + public Type getVoidType() { + return voidType; + } + + public void setTypeSystem(final TypeSystem typeSystem) { + if (typeSystem != null) { + this.typeSystem = typeSystem; + } + } + + public Set<String> getNamespaces() { + // TODO: provide real implementation + return new HashSet<String>(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/FeatureImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/FeatureImpl.java new file mode 100644 index 00000000..d589bc4c --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/FeatureImpl.java @@ -0,0 +1,49 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl; + +import org.eclipse.xtend.typesystem.Callable; +import org.eclipse.xtend.typesystem.Type; + +public abstract class FeatureImpl implements Callable { + + private String name; + + private Type returnType; + + public FeatureImpl(final String name, final Type returnType) { + this.name = name; + this.returnType = returnType; + } + + public String getName() { + return name; + } + + public Type getReturnType() { + return returnType; + } + + @Override + public String toString() { + return returnType.toString() + " " + name; + } + + @Override + public abstract boolean equals(Object obj); + + @Override + public abstract int hashCode(); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/OperationImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/OperationImpl.java new file mode 100644 index 00000000..9f73242c --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/OperationImpl.java @@ -0,0 +1,126 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.xtend.typesystem.Operation; +import org.eclipse.xtend.typesystem.Type; + +public abstract class OperationImpl extends FeatureImpl implements Operation { + + private List<Type> paramTypes; + + private Type owner; + + public OperationImpl(final Type owner, final String name, final Type returnType, final Type... paramTypes) { + super(name, returnType); + this.paramTypes = paramTypes == null ? new ArrayList() : Arrays.asList(paramTypes); + this.owner = owner; + } + + public final Object evaluate(final Object target, final Object[] params) { + try { + return evaluateInternal(target, params); + } catch (final NullPointerException e) { + if (target == null) + return null; + else + throw e; + } + } + + protected abstract Object evaluateInternal(Object target, Object[] params); + + public Type getOwner() { + return owner; + } + + public List<Type> getParameterTypes() { + return paramTypes; + } + + public Type getReturnType(final Type targetType, final Type[] paramTpes) { + return getReturnType(); + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) + return false; + if (this == obj) + return true; + if (obj instanceof Operation) { + final Operation op = (Operation) obj; + boolean equals = getOwner().equals(op.getOwner()) && getName().equals(op.getName()) + && getParameterTypes().size() == op.getParameterTypes().size(); + + if (equals) { + final List<Type> typesA = getParameterTypes(); + final List<Type> typesB = op.getParameterTypes(); + for (int i = 0; i < typesA.size() && equals; i++) { + final Type a = typesA.get(i); + final Type b = typesB.get(i); + equals = equals && a.equals(b); + } + } + return equals; + } + return false; + } + + private int hashCode = 0; + + @Override + public int hashCode() { + if (hashCode == 0) { + hashCode = 17; + hashCode = hashCode * 37 + owner.hashCode(); + hashCode = hashCode * 37 + getName().hashCode(); + for (int i = 0; i < paramTypes.size(); i++) { + hashCode = hashCode * 37 + paramTypes.get(i).hashCode(); + } + } + return hashCode; + } + + @Override + public String toString() { + final StringBuffer buff = new StringBuffer(); + if (getReturnType() != null) { + buff.append(getReturnType().toString()); + } else { + buff.append("void"); + } + buff.append(" ").append(getOwner().toString()); + buff.append(".").append(getName()).append("("); + + for (int i = 0, x = getParameterTypes().size(); i < x; i++) { + final Type paramType = getParameterTypes().get(i); + buff.append(paramType.toString()); + if (i + 1 < x) { + buff.append(","); + } + } + buff.append(")"); + return buff.toString(); + } + + public String getDocumentation() { + return ""; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/PolymorphicResolver.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/PolymorphicResolver.java new file mode 100644 index 00000000..b5aaa36a --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/PolymorphicResolver.java @@ -0,0 +1,131 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.xtend.typesystem.Callable; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Operation; +import org.eclipse.xtend.typesystem.ParameterizedCallable; +import org.eclipse.xtend.typesystem.Property; +import org.eclipse.xtend.typesystem.StaticProperty; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class PolymorphicResolver { + + public final static Operation getOperation(final Set<? extends Callable> features, final String name, final Type targetType, + final List<? extends Type> paramTypes) { + final List<Type> allParams = new ArrayList<Type>(); + allParams.add(targetType); + allParams.addAll(paramTypes); + return (Operation) getFeature(features, Operation.class, name, allParams); + } + + public final static Property getProperty(final Set<? extends Callable> features, final String name, final Type targetType) { + final List<Type> allParams = new ArrayList<Type>(); + allParams.add(targetType); + return (Property) getFeature(features, Property.class, name, allParams); + } + + public static StaticProperty getStaticProperty(final Set<? extends Callable> features, final String name, final Type targetType) { + final List<Type> allParams = new ArrayList<Type>(); + allParams.add(targetType); + return (StaticProperty) getFeature(features, StaticProperty.class, name, allParams); + } + + public final static Extension getExtension(final Set<? extends Callable> features, final String name, final List<Type> paramTypes) { + return (Extension) getFeature(features, Extension.class, name, paramTypes); + } + + public final static Callable getCallable(final Set<? extends Callable> callables, final String name, final List<Type> paramTypes) { + return getFeature(callables, Callable.class, name, paramTypes); + } + + public static <T> Set<T> select(final Set<? extends Callable> features, final Class<T> type) { + final Set<T> result = new HashSet<T>(); + for (Callable callable : features) { + if (type.isInstance(callable)) { + result.add((T) callable); + } + } + return result; + } + + public final static Callable getFeature(final Set<? extends Callable> features, final Class type, final String name, + final List<? extends Type> paramTypes) { + final List<Callable> possFeatures = new ArrayList<Callable>(); + for (Callable feature : features) { + if (type.isInstance(feature) && feature.getName().equals(name)) { + final List<? extends Type> featureParamTypes = getParamTypes(feature); + if (featureParamTypes.size() == paramTypes.size() && typesComparator.compare(featureParamTypes, paramTypes) >= 0) { + possFeatures.add(feature); + } + } + } + + if (possFeatures.size() == 1) + return possFeatures.get(0); + else if (possFeatures.isEmpty()) + return null; + else { + // sort features by specialization + Collections.sort(possFeatures, paramFeatureComparator); + if (paramFeatureComparator.compare(possFeatures.get(1), possFeatures.get(0)) > 0) { + return possFeatures.get(0); + } + + for (Callable callable : possFeatures) { + if (callable instanceof Extension) { + throw new RuntimeException("Ambiguous operations " + possFeatures.get(0).toString() + " and " + possFeatures.get(1).toString() + + " for param types " + paramTypes); + } + } + return possFeatures.get(0); + + } + } + + private static final Comparator<Callable> paramFeatureComparator = new Comparator<Callable>() { + + public int compare(Callable o1, Callable o2) { + return typesComparator.compare(getParamTypes(o1), getParamTypes(o2)); + } + }; + + static List<? extends Type> getParamTypes(final Callable feature) { + final List<Type> result = new ArrayList<Type>(); + if (feature instanceof Feature) { + result.add(((Feature) feature).getOwner()); + } + if (feature instanceof ParameterizedCallable) { + result.addAll(((ParameterizedCallable) feature).getParameterTypes()); + } + return result; + } + + public final static Comparator<List<? extends Type>> typesComparator = new TypesComparator(); + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/PropertyImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/PropertyImpl.java new file mode 100644 index 00000000..cb688932 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/PropertyImpl.java @@ -0,0 +1,74 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl; + +import org.eclipse.xtend.typesystem.Property; +import org.eclipse.xtend.typesystem.Type; + +public abstract class PropertyImpl extends FeatureImpl implements Property { + + private Type owner; + + public PropertyImpl(final Type owner, final String name, final Type returnType) { + super(name, returnType); + this.owner = owner; + } + + public Type getOwner() { + return owner; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) + return false; + if (this == obj) + return true; + if (obj instanceof Property) { + final Property op = (Property) obj; + return getReturnType().equals(op.getReturnType()) && getName().equals(op.getName()); + } + return false; + } + + private int hashCode = 0; + + @Override + public int hashCode() { + if (hashCode == 0) { + hashCode = 17; + hashCode = 37 * hashCode + getName().hashCode(); + hashCode = 37 * hashCode + getReturnType().hashCode(); + } + return hashCode; + } + + @Override + public String toString() { + final StringBuffer buff = new StringBuffer(); + buff.append(getReturnType().toString()); + buff.append(" ").append(getOwner().toString()); + buff.append(".").append(getName()); + return buff.toString(); + } + + public String getDocumentation() { + return ""; + } + + public void set(final Object target, final Object newValue) { + throw new UnsupportedOperationException("setting of property " + getName() + " not upported!"); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/StaticPropertyImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/StaticPropertyImpl.java new file mode 100644 index 00000000..8f4a7faa --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/StaticPropertyImpl.java @@ -0,0 +1,63 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl; + +import org.eclipse.xtend.typesystem.StaticProperty; +import org.eclipse.xtend.typesystem.Type; + +public abstract class StaticPropertyImpl extends FeatureImpl implements StaticProperty { + + private Type owner; + + public StaticPropertyImpl(final Type owner, final String name, final Type returnType) { + super(name, returnType); + this.owner = owner; + } + + public Type getOwner() { + return owner; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) + return false; + if (this == obj) + return true; + if (obj instanceof StaticProperty) { + final StaticProperty op = (StaticProperty) obj; + return getOwner().equals(op.getOwner()) && getName().equals(op.getName()); + } + return false; + } + + @Override + public int hashCode() { + return getName().hashCode(); + } + + @Override + public String toString() { + final StringBuffer buff = new StringBuffer(); + buff.append(getReturnType().toString()); + buff.append(" ").append(getOwner().toString()); + buff.append("#").append(getName()); + return buff.toString(); + } + + public String getDocumentation() { + return ""; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/TypesComparator.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/TypesComparator.java new file mode 100644 index 00000000..cab28f39 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/TypesComparator.java @@ -0,0 +1,52 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl; + +import java.util.Comparator; +import java.util.List; + +import org.eclipse.xtend.typesystem.Type; + +public final class TypesComparator implements Comparator<List<? extends Type>> { + /** + * + * returns -1 if the second list of types is not assignable to the first + * list of types returns 0 if the second list of types exactly matches the + * first list of types returns 1 if the second list of types is assignable + * to the first list of types + */ + public int compare(final List<? extends Type> types1, final List<? extends Type> types2) { + if (types1 == null || types2 == null) + throw new NullPointerException(); + if (types1.size() != types2.size()) + return -1; + boolean directMatch = true; + for (int i = 0, x = types1.size(); i < x; i++) { + final Type type1 = types1.get(i); + final Type type2 = types2.get(i); + if (type1.isAssignableFrom(type2)) { + if (!type1.equals(type2)) { + directMatch = false; + } + } else + return -1; + } + if (directMatch) + return 0; + else + return 1; + } + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/BooleanTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/BooleanTypeImpl.java new file mode 100644 index 00000000..e43d13c6 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/BooleanTypeImpl.java @@ -0,0 +1,65 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.util.Collections; +import java.util.Set; + +import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Type; + +public final class BooleanTypeImpl extends BuiltinBaseType implements Type { + public BooleanTypeImpl(final TypeSystem ts, final String name) { + super(ts, name); + } + + public boolean isInstance(final Object o) { + return o instanceof Boolean; + } + + @Override + public Object convert(final Object src, final Class targetType) { + if (targetType == Boolean.class || targetType == Boolean.TYPE) + return src; + return super.convert(src, targetType); + } + + public Object newInstance() { + return Boolean.FALSE; + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[] { + new OperationImpl(this, "!",BooleanTypeImpl.this) { + @Override + public Object evaluateInternal(final Object target, + final Object[] params) { + return target == null ? null : new Boolean(!((Boolean) target) + .booleanValue()); + } + } + + }; + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.singleton(getTypeSystem().getObjectType()); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/BuiltinBaseType.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/BuiltinBaseType.java new file mode 100644 index 00000000..63bd9c84 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/BuiltinBaseType.java @@ -0,0 +1,26 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.AbstractTypeImpl; + +public abstract class BuiltinBaseType extends AbstractTypeImpl { + + public BuiltinBaseType(final TypeSystem ts, final String name) { + super(ts, name); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/CollectionTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/CollectionTypeImpl.java new file mode 100644 index 00000000..000b9495 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/CollectionTypeImpl.java @@ -0,0 +1,330 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; +import org.eclipse.internal.xtend.type.baseimpl.PropertyImpl; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.ParameterizedType; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class CollectionTypeImpl extends BuiltinBaseType implements ParameterizedType { + private Type innerType; + + public CollectionTypeImpl(final Type innerType, final TypeSystem ts, final String name) { + super(ts, name); + this.innerType = innerType; + } + + public Type getInnerType() { + return innerType; + } + + public ParameterizedType cloneWithInnerType(final Type innerType) { + return (ParameterizedType) getTypeSystem().getCollectionType(innerType); + } + + @Override + protected boolean internalIsAssignableFrom(final Type t) { + return super.internalIsAssignableFrom(t); + } + + public boolean isInstance(final Object o) { + return o instanceof Collection; + } + + public Object newInstance() { + return new ArrayList<Object>(); + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[] { + new OperationImpl(this, "toList", getTypeSystem().getListType(getInnerType())) { + + @Override + public String getDocumentation() { + return "converts this collection to List"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return new ArrayList<Object>(((Collection<?>) target)); + } + + @Override + public Type getReturnType(final Type targetType, final Type[] paramTypes) { + if (!(targetType instanceof ParameterizedType)) + return getReturnType(); + final TypeSystem ts = getTypeSystem(); + return ts.getListType(((ParameterizedType) targetType).getInnerType()); + } + }, + + new OperationImpl(this, "toSet", getTypeSystem().getSetType(getInnerType())) { + + @Override + public String getDocumentation() { + return "converts this collection to Set"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return new java.util.HashSet<Object>((Collection<?>) target); + } + + @Override + public Type getReturnType(final Type targetType, final Type[] paramTypes) { + if (!(targetType instanceof ParameterizedType)) + return getReturnType(); + final TypeSystem ts = getTypeSystem(); + return ts.getSetType(((ParameterizedType) targetType).getInnerType()); + } + }, + + new OperationImpl(this, "toString", getTypeSystem().getStringType(), getTypeSystem() + .getStringType() ) { + + @Override + public String getDocumentation() { + return "concatenates each contained element (using toString()), separated by the specified String."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + final StringBuffer buff = new StringBuffer(); + for (final Iterator<?> iter = ((Collection<?>) target).iterator(); iter.hasNext();) { + buff.append(iter.next().toString()); + if (iter.hasNext()) { + buff.append(params[0].toString()); + } + } + return buff.toString(); + } + }, + + new PropertyImpl(this, "size", getTypeSystem().getIntegerType()) { + + @Override + public String getDocumentation() { + return "returns the size of this Collection"; + } + + public Object get(final Object target) { + return new Long(((Collection<?>) target).size()); + } + }, + + new PropertyImpl(this, "isEmpty", getTypeSystem().getBooleanType()) { + + @Override + public String getDocumentation() { + return "returns true if this Collection is empty"; + } + + public Object get(final Object target) { + return new Boolean(((Collection<?>) target).size() == 0); + } + }, + + new OperationImpl(this, "add", this, getInnerType() ) { + + @Override + public String getDocumentation() { + return "adds an element to the Collection (modifies it!). returns this Collection."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + ((Collection<Object>) target).add(params[0]); + return target; + } + }, + + new OperationImpl(this, "addAll", this, getTypeSystem().getCollectionType( + getInnerType()) ) { + + @Override + public String getDocumentation() { + return "adds all elements to the Collection (modifies it!). returns this Collection."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + ((Collection<?>) target).addAll((Collection) params[0]); + return target; + } + }, + + new OperationImpl(this, "contains", getTypeSystem().getBooleanType(), getTypeSystem() + .getObjectType() ) { + + @Override + public String getDocumentation() { + return "returns true if this collection contains the specified object. otherwise false. returns this Collection."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return Boolean.valueOf(((Collection) target).contains(params[0])); + } + }, + + new OperationImpl(this, "containsAll", getTypeSystem().getBooleanType(), getTypeSystem() + .getCollectionType(getTypeSystem().getObjectType()) ) { + + @Override + public String getDocumentation() { + return "returns true if this collection contains each element contained in the specified collection. otherwise false. returns this Collection."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return Boolean.valueOf(((Collection) target).containsAll((Collection) params[0])); + } + }, + + new OperationImpl(this, "remove", this, getTypeSystem().getObjectType() ) { + + @Override + public String getDocumentation() { + return "removes the specified element from this Collection if contained (modifies it!). returns this Collection."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + ((Collection) target).remove(params[0]); + return target; + } + }, + + new OperationImpl(this, "removeAll", this, getTypeSystem().getObjectType() ) { + + @Override + public String getDocumentation() { + return "removes all elements contained in the specified collection from this Collection if contained (modifies it!). returns this Collection."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + ((Collection) target).removeAll((Collection) params[0]); + return target; + } + }, + + new OperationImpl(this, "union", getTypeSystem().getSetType(getInnerType()), + getTypeSystem().getCollectionType(getTypeSystem().getObjectType())) { + + @Override + public String getDocumentation() { + return "returns a new Set, containing all elements from this and the specified Collection"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + final Set r = new HashSet((Collection) target); + r.addAll((Collection) params[0]); + return r; + } + }, + + new OperationImpl(this, "without", getTypeSystem().getSetType(getInnerType()), + getTypeSystem().getCollectionType(getTypeSystem().getObjectType()) ) { + + @Override + public String getDocumentation() { + return "returns a new Set, containing all elements from this Collection without the elements from specified Collection"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + final Set r = new HashSet((Collection) target); + r.removeAll((Collection) params[0]); + return r; + } + }, + + new OperationImpl(this, "intersect", getTypeSystem().getSetType(getInnerType()), + getTypeSystem().getCollectionType(getTypeSystem().getObjectType()) ) { + + @Override + public String getDocumentation() { + return "returns a new Set, containing only the elements contained in this and the specified Collection"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + final Set r = new HashSet((Collection) target); + r.retainAll((Collection) params[0]); + return r; + } + }, + + new OperationImpl(this, "flatten", getTypeSystem().getListType(getTypeSystem().getObjectType()), + new Type[0]) { + + @Override + public String getDocumentation() { + return "returns a flatten List."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return flattenRec((Collection) target); + } + + public List<Object> flattenRec(final Collection col) { + final List<Object> result = new ArrayList<Object>(); + for (final Object element : col) { + if (element instanceof Collection) { + result.addAll(flattenRec((Collection) element)); + } else { + result.add(element); + } + } + return result; + } + } + + }; + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.singleton(getTypeSystem().getObjectType()); + } + + @Override + public String toString() { + String s = getName(); + if (innerType != null) { + s += "[" + innerType + "]"; + } + return s; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/FeatureTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/FeatureTypeImpl.java new file mode 100644 index 00000000..b72ce71f --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/FeatureTypeImpl.java @@ -0,0 +1,93 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.util.Collections; +import java.util.Set; + +import org.eclipse.internal.xtend.type.baseimpl.PropertyImpl; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class FeatureTypeImpl extends BuiltinBaseType implements Type { + + public FeatureTypeImpl(final TypeSystem ts, final String name) { + super(ts, name); + } + + public boolean isInstance(final Object o) { + return o instanceof Feature; + } + + public Object newInstance() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAbstract() { + return true; + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.singleton(getTypeSystem().getObjectType()); + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[] { new PropertyImpl(this, "name", getTypeSystem().getStringType()) { + public Object get(final Object target) { + return ((Feature) target).getName(); + } + + @Override + public void set(final Object target, final Object val) { + throw new UnsupportedOperationException("property name is unsettable!"); + } + + }, new PropertyImpl(this, "returnType", getTypeSystem().getTypeType()) { + public Object get(final Object target) { + return ((Feature) target).getReturnType(); + } + + @Override + public void set(final Object target, final Object val) { + throw new UnsupportedOperationException("property name is unsettable!"); + } + + }, new PropertyImpl(this, "owner", getTypeSystem().getTypeType()) { + public Object get(final Object target) { + return ((Feature) target).getOwner(); + } + + @Override + public void set(final Object target, final Object val) { + throw new UnsupportedOperationException("property name is unsettable!"); + } + + }, new PropertyImpl(this, "documentation", getTypeSystem().getStringType()) { + + public Object get(final Object target) { + return ((Feature) target).getDocumentation(); + } + } }; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/IntegerTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/IntegerTypeImpl.java new file mode 100644 index 00000000..66587484 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/IntegerTypeImpl.java @@ -0,0 +1,274 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Type; + +public final class IntegerTypeImpl extends BuiltinBaseType implements Type { + + public IntegerTypeImpl(final TypeSystem ts, final String name) { + super(ts, name); + } + + public boolean isInstance(final Object o) { + return o instanceof Integer || o instanceof BigInteger || o instanceof Byte || o instanceof Long + || o instanceof Short; + } + + public Object newInstance() { + return new Long(-1); + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[] { + new OperationImpl(this, "+", IntegerTypeImpl.this, new Type[] { IntegerTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (params[0] == null) + return null; + return new Long(((Number) target).longValue() + ((Number) params[0]).longValue()); + } + }, + new OperationImpl(this, "-", IntegerTypeImpl.this, new Type[] { IntegerTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (params[0] == null) + return null; + return new Long(((Number) target).longValue() - ((Number) params[0]).longValue()); + } + }, + new OperationImpl(this, "-", IntegerTypeImpl.this, new Type[] {}) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return new Long(((Number) target).longValue() * -1l); + } + }, + new OperationImpl(this, "*", IntegerTypeImpl.this, new Type[] { IntegerTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (params[0] == null) + return null; + + return new Long(((Number) target).longValue() * ((Number) params[0]).longValue()); + } + }, + new OperationImpl(this, "/", IntegerTypeImpl.this, new Type[] { IntegerTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (params[0] == null) + return null; + + return new Long(((Number) target).longValue() / ((Number) params[0]).longValue()); + } + }, + new OperationImpl(this, "==", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return new Boolean(target == params[0]); + + try { + return toLong(target).equals(toLong(params[0])); + } + catch (Exception exc) { + if (target instanceof Number && params[0] instanceof Number) + return ((Number) target).doubleValue() == ((Number) params[0]).doubleValue(); + + return false; + } + } + + }, + new OperationImpl(this, "!=", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return params[0] != null; + + try { + return ! toLong(target).equals(toLong(params[0])); + } + catch (Exception exc) { + if (target instanceof Number && params[0] instanceof Number) + return ((Number) target).doubleValue() != ((Number) params[0]).doubleValue(); + + return true; + } + } + }, + new OperationImpl(this, ">", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return Boolean.FALSE; + if (params[0] == null) + return Boolean.FALSE; + + try { + return ((Comparable<Long>) toLong(target)).compareTo(toLong(params[0])) > 0; + } + catch (Exception exc) { + return ((Number) target).doubleValue() > ((Number) params[0]).doubleValue(); + } + } + }, + new OperationImpl(this, ">=", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return params[0] == null ? Boolean.TRUE : Boolean.FALSE; + if (params[0] == null) + return Boolean.FALSE; + + try { + return ((Comparable<Long>) toLong(target)).compareTo(toLong(params[0])) >= 0; + } + catch (Exception exc) { + return ((Number) target).doubleValue() >= ((Number) params[0]).doubleValue(); + } + } + }, + new OperationImpl(this, "<", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return Boolean.FALSE; + if (params[0] == null) + return Boolean.FALSE; + + try { + return ((Comparable<Long>) toLong(target)).compareTo(toLong(params[0])) < 0; + } + catch (Exception exc) { + return ((Number) target).doubleValue() < ((Number) params[0]).doubleValue(); + } + } + }, + new OperationImpl(this, "<=", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return params[0] == null ? Boolean.TRUE : Boolean.FALSE; + if (params[0] == null) + return Boolean.FALSE; + + try { + return ((Comparable<Long>) toLong(target)).compareTo(toLong(params[0])) <= 0; + } + catch (Exception exc) { + return ((Number) target).doubleValue() <= ((Number) params[0]).doubleValue(); + } + } + }, new OperationImpl(this, "upTo", getTypeSystem().getListType(this), new Type[] { this }) { + + @Override + public String getDocumentation() { + return "returns a List of Integers starting with the value of the target expression, up to" + + "the value of the specified Integer, incremented by one.<br/>" + + "e.g. '1.upTo(5)' evaluates to {1,2,3,4,5}"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + final List<Long> result = new ArrayList<Long>(); + long l1 = toLong(target).longValue(); + final long l2 = toLong(params[0]).longValue(); + + while (l1 <= l2) { + result.add(new Long(l1)); + l1++; + } + return result; + } + }, new OperationImpl(this, "upTo", getTypeSystem().getListType(this), new Type[] { this, this }) { + + @Override + public String getDocumentation() { + return "returns a List of Integers starting with the value of the target expression, up to" + + "the value of the first paramter, incremented by the second parameter.<br/>" + + "e.g. '1.upTo(10, 2)' evaluates to {1,3,5,7,9}"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + final List<Long> result = new ArrayList<Long>(); + long l1 = toLong(target).longValue(); + final long l2 = toLong(params[0]).longValue(); + final long l3 = toLong(params[1]).longValue(); + + while (l1 <= l2) { + result.add(new Long(l1)); + l1 = l1 + l3; + } + return result; + } + } }; + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.singleton(getTypeSystem().getRealType()); + } + + Long toLong(final Object o) { + if (o == null) + return null; + + if (o instanceof Integer) + return new Long(((Integer) o).longValue()); + else if (o instanceof BigInteger) + return new Long(((BigInteger) o).longValue()); + else if (o instanceof Byte) + return new Long(((Byte) o).longValue()); + else if (o instanceof Long) + return (Long) o; + else if (o instanceof Short) + return new Long(((Short) o).longValue()); + throw new IllegalArgumentException(o.getClass().getName() + " not supported"); + } + + @Override + public Object convert(final Object src, final Class<?> targetType) { + final Long l = toLong(src); + if (targetType.isAssignableFrom(Integer.class) || targetType.isAssignableFrom(Integer.TYPE)) + return new Integer(l.intValue()); + else if (targetType.isAssignableFrom(BigInteger.class)) + return BigInteger.valueOf(l.longValue()); + else if (targetType.isAssignableFrom(Byte.class) || targetType.isAssignableFrom(Byte.TYPE)) + return new Byte(l.byteValue()); + else if (targetType.isAssignableFrom(Long.class) || targetType.isAssignableFrom(Long.TYPE)) + return src; + else if (targetType.isAssignableFrom(Short.class) || targetType.isAssignableFrom(Short.TYPE)) + return new Short(l.shortValue()); + return super.convert(src, targetType); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/ListTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/ListTypeImpl.java new file mode 100644 index 00000000..84bae2dc --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/ListTypeImpl.java @@ -0,0 +1,131 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.ParameterizedType; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class ListTypeImpl extends CollectionTypeImpl implements Type { + + public ListTypeImpl(final Type innerType, final TypeSystem ts, final String name) { + super(innerType, ts, name); + } + + @Override + public boolean isInstance(final Object o) { + return o instanceof List; + } + + @Override + public Object newInstance() { + return new ArrayList<Object>(); + } + + @Override + public ParameterizedType cloneWithInnerType(final Type innerType) { + return (ParameterizedType) getTypeSystem().getListType(innerType); + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[] { new OperationImpl(this, "get", getInnerType(), new Type[] { getTypeSystem().getIntegerType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return ((List<?>) target).get(((Number) params[0]).intValue()); + } + }, new OperationImpl(this, "indexOf", getTypeSystem().getIntegerType(), new Type[] { getTypeSystem().getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return new Long(((List<?>) target).indexOf(params[0])); + } + }, new OperationImpl(this, "first", getInnerType(), new Type[0]) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target instanceof List) { + List<?> l = (List<?>) target; + if (l.size() > 0) + return l.get(0); + } + return null; + } + }, new OperationImpl(this, "reverse", getInnerType(), new Type[0]) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target instanceof List) { + List<?> l = new ArrayList ((List<?>) target); + Collections.reverse(l); + return l; + } + return null; + } + }, new OperationImpl(this, "last", getInnerType(), new Type[0]) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target instanceof List) { + List<?> l = (List<?>) target; + if (l.size() > 0) + return l.get(l.size() - 1); + } + return null; + } + }, new OperationImpl(this, "withoutFirst", this, new Type[0]) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target instanceof List) { + List l = (List) target; + List r = new ArrayList(); + for (int i = 1; i < l.size(); i++) { + r.add(l.get(i)); + } + return r; + } + return null; + } + }, new OperationImpl(this, "withoutLast", this, new Type[0]) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target instanceof List) { + List l = (List) target; + List r = new ArrayList(); + for (int i = 0; i < l.size() - 1; i++) { + r.add(l.get(i)); + } + return r; + } + return null; + } + } + + }; + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.singleton(getTypeSystem().getCollectionType(getInnerType())); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/ObjectTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/ObjectTypeImpl.java new file mode 100644 index 00000000..7c991035 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/ObjectTypeImpl.java @@ -0,0 +1,151 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.util.Collections; +import java.util.Set; + +import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; +import org.eclipse.internal.xtend.type.baseimpl.PropertyImpl; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Operation; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class ObjectTypeImpl extends BuiltinBaseType implements Type { + + public ObjectTypeImpl(final TypeSystem ts, final String name) { + super(ts, name); + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[] { + new OperationImpl(this, "==", getTypeSystem().getBooleanType(), new Type[] { ObjectTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return new Boolean(target == params[0]); + return new Boolean(target.equals(params[0])); + } + }, new OperationImpl(this, "!=", getTypeSystem().getBooleanType(), new Type[] { ObjectTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return new Boolean(target != params[0]); + return new Boolean(!target.equals(params[0])); + } + }, new OperationImpl(this, ">", getTypeSystem().getBooleanType(), new Type[] { ObjectTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return Boolean.FALSE; + if (params[0] == null) + return Boolean.FALSE; + return new Boolean(((Comparable<Object>) target).compareTo(params[0]) > 0); + } + }, new OperationImpl(this, ">=", getTypeSystem().getBooleanType(), new Type[] { ObjectTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return params[0] == null ? Boolean.TRUE : Boolean.FALSE; + if (params[0] == null) + return Boolean.FALSE; + return new Boolean(((Comparable<Object>) target).compareTo(params[0]) >= 0); + } + }, new OperationImpl(this, "<", getTypeSystem().getBooleanType(), new Type[] { ObjectTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return Boolean.FALSE; + if (params[0] == null) + return Boolean.FALSE; + return new Boolean(((Comparable<Object>) target).compareTo(params[0]) < 0); + } + }, new OperationImpl(this, "<=", getTypeSystem().getBooleanType(), new Type[] { ObjectTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return params[0] == null ? Boolean.TRUE : Boolean.FALSE; + if (params[0] == null) + return Boolean.FALSE; + return new Boolean(((Comparable<Object>) target).compareTo(params[0]) <= 0); + } + }, new PropertyImpl(this, "metaType", getTypeSystem().getTypeType()) { + @Override + public String getDocumentation() { + return "returns this object's meta type."; + } + + public Object get(final Object target) { + return getTypeSystem().getType(target); + } + }, new OperationImpl(this, "toString", getTypeSystem().getStringType()) { + @Override + public String getDocumentation() { + return "returns the String representation of this object. (Calling Java's toString() method)"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return target != null ? target.toString() : "null"; + } + }, new OperationImpl(this, "compareTo", getTypeSystem().getIntegerType(), new Type[] { this }) { + @Override + public String getDocumentation() { + return "Compares this object with the specified object for order. Returns a negative " + + "integer, zero, or a positive integer as this object is less than, equal to, " + + "or greater than the specified object."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return params[0] == null ? new Long(0) : new Long(-1); + if (params[0] == null) + return new Long(1); + if (target instanceof Comparable) + return new Long(((Comparable<Object>) target).compareTo(params[0])); + else { + final TypeSystem ts = getTypeSystem(); + Operation op = ts.findOperation("toString", target, null); + final String s1 = (String) op.evaluate(target, null); + op = ts.findOperation("toString", params[0], null); + final String s2 = (String) op.evaluate(params[0], null); + ; + return new Long(s1.compareTo(s2)); + } + } + } }; + } + + public boolean isInstance(final Object o) { + return true; + } + + public Object newInstance() { + return new Object(); + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.EMPTY_SET; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/OperationTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/OperationTypeImpl.java new file mode 100644 index 00000000..2968a90f --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/OperationTypeImpl.java @@ -0,0 +1,75 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Operation; +import org.eclipse.xtend.typesystem.Type; + +public final class OperationTypeImpl extends FeatureTypeImpl implements Type { + + public OperationTypeImpl(final TypeSystem ts, final String name) { + super(ts, name); + } + + @Override + public boolean isInstance(final Object o) { + return o instanceof Operation; + } + + @Override + public Object newInstance() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAbstract() { + return true; + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.singleton(getTypeSystem().getFeatureType()); + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[] { + new OperationImpl(this, "evaluate", getTypeSystem().getObjectType(), + getTypeSystem().getObjectType(), getTypeSystem().getListType(null)) { + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return ((Operation) target).evaluate(target, ((List<?>) params[0]).toArray()); + } + + }, + new OperationImpl(this, "getParameterTypes", + getTypeSystem().getListType(getTypeSystem().getTypeType())) { + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return ((Operation) target).getParameterTypes(); + } + + } }; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/PropertyTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/PropertyTypeImpl.java new file mode 100644 index 00000000..5504c8a6 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/PropertyTypeImpl.java @@ -0,0 +1,71 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.util.Collections; +import java.util.Set; + +import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Property; +import org.eclipse.xtend.typesystem.Type; + +public final class PropertyTypeImpl extends BuiltinBaseType { + + public PropertyTypeImpl(final TypeSystem ts, final String name) { + super(ts, name); + } + + public boolean isInstance(final Object o) { + return o instanceof Property; + } + + public Object newInstance() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAbstract() { + return true; + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.singleton(getTypeSystem().getFeatureType()); + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[] { + new OperationImpl(this, "get", getTypeSystem().getObjectType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return ((Property) target).get(params[0]); + } + }, + new OperationImpl(this, "set", getTypeSystem().getVoidType(), new Type[] { + getTypeSystem().getObjectType(), getTypeSystem().getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + ((Property) target).set(params[0], params[1]); + return null; + } + } + + }; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/RealTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/RealTypeImpl.java new file mode 100644 index 00000000..3dc450fd --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/RealTypeImpl.java @@ -0,0 +1,193 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.math.BigDecimal; +import java.util.Collections; +import java.util.Set; + +import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class RealTypeImpl extends BuiltinBaseType implements Type { + + public RealTypeImpl(final TypeSystem ts, final String name) { + super(ts, name); + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[] { + new OperationImpl(this, "+", RealTypeImpl.this, new Type[] { RealTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (params[0] == null) + return null; + + return new Double(((Number) target).doubleValue() + ((Number) params[0]).doubleValue()); + } + }, + new OperationImpl(this, "-", RealTypeImpl.this, new Type[] { RealTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (params[0] == null) + return null; + + return new Double(((Number) target).doubleValue() - ((Number) params[0]).doubleValue()); + } + }, + new OperationImpl(this, "-", RealTypeImpl.this, new Type[] {}) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return new Double(((Number) target).doubleValue() * -1.0d); + } + }, + new OperationImpl(this, "*", RealTypeImpl.this, new Type[] { RealTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (params[0] == null) + return null; + + return new Double(((Number) target).doubleValue() * ((Number) params[0]).doubleValue()); + } + }, + new OperationImpl(this, "/", RealTypeImpl.this, new Type[] { RealTypeImpl.this }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (params[0] == null) + return null; + + return new Double(((Number) target).doubleValue() / ((Number) params[0]).doubleValue()); + } + }, + new OperationImpl(this, "==", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return new Boolean(target == params[0]); + + try { + return toDouble(target).equals(toDouble(params[0])); + } + catch (Exception exc) { + return false; + } + } + + }, + new OperationImpl(this, "!=", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return new Boolean(target != params[0]); + + try { + return !toDouble(target).equals(toDouble(params[0])); + } + catch (Exception exc) { + return true; + } + } + }, + new OperationImpl(this, ">", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return Boolean.FALSE; + if (params[0] == null) + return Boolean.FALSE; + return new Boolean(((Comparable<Double>) toDouble(target)).compareTo(toDouble(params[0])) > 0); + } + }, + new OperationImpl(this, ">=", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return params[0] == null ? Boolean.TRUE : Boolean.FALSE; + if (params[0] == null) + return Boolean.FALSE; + return new Boolean(((Comparable<Double>) toDouble(target)).compareTo(toDouble(params[0])) >= 0); + } + }, + new OperationImpl(this, "<", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return Boolean.FALSE; + if (params[0] == null) + return Boolean.FALSE; + return new Boolean(((Comparable<Double>) toDouble(target)).compareTo(toDouble(params[0])) < 0); + } + }, + new OperationImpl(this, "<=", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + if (target == null) + return params[0] == null ? Boolean.TRUE : Boolean.FALSE; + if (params[0] == null) + return Boolean.FALSE; + return new Boolean(((Comparable<Double>) toDouble(target)).compareTo(toDouble(params[0])) <= 0); + } + } }; + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.singleton(getTypeSystem().getObjectType()); + } + + public boolean isInstance(final Object o) { + return o instanceof Double || o instanceof Float || o instanceof BigDecimal; + } + + public Object newInstance() { + return new Double(1); + } + + private Double toDouble(final Object o) { + if (o == null) + return null; + + if (o instanceof Number) + return ((Number) o).doubleValue(); + + throw new IllegalArgumentException(o.getClass().getName() + " not supported"); + } + + @Override + public Object convert(final Object src, final Class<?> targetType) { + final Double l = toDouble(src); + if (targetType.isAssignableFrom(Double.class) || targetType.isAssignableFrom(Double.TYPE)) + return l; + else if (targetType.isAssignableFrom(Float.class) || targetType.isAssignableFrom(Float.TYPE)) + return new Float(l.doubleValue()); + else if (targetType.isAssignableFrom(BigDecimal.class)) + return new BigDecimal(l.doubleValue()); + return super.convert(src, targetType); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/SetTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/SetTypeImpl.java new file mode 100644 index 00000000..e7ef743a --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/SetTypeImpl.java @@ -0,0 +1,61 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.ParameterizedType; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class SetTypeImpl extends CollectionTypeImpl { + + public SetTypeImpl(final Type innerType, final TypeSystem ts, final String name) { + super(innerType, ts, name); + } + + @Override + public boolean isInstance(final Object o) { + return o instanceof Set; + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[] {}; + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.singleton(getTypeSystem().getCollectionType(getInnerType())); + } + + @Override + public Object newInstance() { + return new HashSet<Object>(); + } + + @Override + public ParameterizedType cloneWithInnerType(final Type innerType) { + return (ParameterizedType) getTypeSystem().getSetType(innerType); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/StaticPropertyTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/StaticPropertyTypeImpl.java new file mode 100644 index 00000000..81ea4f58 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/StaticPropertyTypeImpl.java @@ -0,0 +1,65 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.util.Collections; +import java.util.Set; + +import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.StaticProperty; +import org.eclipse.xtend.typesystem.Type; + +public final class StaticPropertyTypeImpl extends BuiltinBaseType { + + public StaticPropertyTypeImpl(final TypeSystem ts, final String name) { + super(ts, name); + } + + public boolean isInstance(final Object o) { + return o instanceof StaticProperty; + } + + public Object newInstance() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAbstract() { + return true; + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.singleton(getTypeSystem().getFeatureType()); + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[] { new OperationImpl(this, "get", getTypeSystem().getObjectType(), new Type[] {}) { + + @Override + public String getDocumentation() { + return "returns the static value"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return ((StaticProperty) target).get(); + } + } }; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/StringTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/StringTypeImpl.java new file mode 100644 index 00000000..0e77973e --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/StringTypeImpl.java @@ -0,0 +1,333 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; +import org.eclipse.internal.xtend.type.baseimpl.PropertyImpl; +import org.eclipse.internal.xtend.util.StringHelper; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class StringTypeImpl extends BuiltinBaseType implements Type { + final Log log = LogFactory.getLog(getClass()); + + public StringTypeImpl(final TypeSystem ts, final String name) { + super(ts, name); + } + + public boolean isInstance(final Object o) { + return o instanceof String || o instanceof StringBuffer || o instanceof Character; + } + + public Object newInstance() { + return ""; + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[] { + new PropertyImpl(this, "length", getTypeSystem().getIntegerType()) { + + @Override + public String getDocumentation() { + return "the length of this string"; + } + + public Object get(final Object target) { + return new Long(target.toString().length()); + } + }, + + new OperationImpl(this, "+", getTypeSystem().getStringType(), new Type[] { getTypeSystem() + .getObjectType() }) { + + @Override + public String getDocumentation() { + return "concatenates two strings"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return target.toString() + params[0]; + } + }, + + new OperationImpl(this, "startsWith", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getStringType() }) { + + @Override + public String getDocumentation() { + return "Tests if this string starts with the specified prefix."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + final String token = (String) params[0]; + return new Boolean(target.toString().startsWith(token)); + } + }, + new OperationImpl(this, "contains", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getStringType() }) { + + @Override + public String getDocumentation() { + return "Tests if this string contains substring."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + final String token = (String) params[0]; + return new Boolean(target.toString().indexOf(token) >= 0); + } + }, + new OperationImpl(this, "endsWith", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getStringType() }) { + + @Override + public String getDocumentation() { + return "Tests if this string ends with the specified prefix."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + final String token = (String) params[0]; + return new Boolean(target.toString().endsWith(token)); + } + }, + new OperationImpl(this, "subString", getTypeSystem().getStringType(), new Type[] { getTypeSystem() + .getIntegerType(),getTypeSystem().getIntegerType() }) { + + @Override + public String getDocumentation() { + return "Tests if this string ends with the specified prefix."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + final Number from = (Number) params[0]; + final Number to = (Number) params[1]; + return target.toString().substring(from.intValue(),to.intValue()); + } + }, + + new OperationImpl(this, "toUpperCase", getTypeSystem().getStringType(), new Type[] {}) { + + @Override + public String getDocumentation() { + return "Converts all of the characters in this String to upper" + + " case using the rules of the default locale (from Java)"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return target.toString().toUpperCase(); + } + }, + + new OperationImpl(this, "toLowerCase", getTypeSystem().getStringType(), new Type[] {}) { + @Override + public String getDocumentation() { + return "Converts all of the characters in this String to lower" + + " case using the rules of the default locale (from Java)"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return target.toString().toLowerCase(); + } + }, + + new OperationImpl(this, "toFirstUpper", getTypeSystem().getStringType(), new Type[] {}) { + @Override + public String getDocumentation() { + return "Converts the first character in this String to upper" + + " case using the rules of the default locale (from Java)"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return StringHelper.firstUpper(target.toString()); + } + }, + + new OperationImpl(this, "toFirstLower", getTypeSystem().getStringType(), new Type[] {}) { + @Override + public String getDocumentation() { + return "Converts the first character in this String to lower" + + " case using the rules of the default locale (from Java)"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return StringHelper.firstLower(target.toString()); + } + }, + + new OperationImpl(this, "toCharList", getTypeSystem().getListType(getTypeSystem().getStringType()), + new Type[] {}) { + + @Override + public String getDocumentation() { + return "splits this String into a List[String] containing Strings of length 1"; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + final String txt = target.toString(); + final List<String> result = new ArrayList<String>(); + final char[] chars = txt.toCharArray(); + for (int i = 0; i < chars.length; i++) { + result.add(String.valueOf(chars[i])); + } + return result; + } + }, + + new OperationImpl(this, "replaceAll", getTypeSystem().getStringType(), new Type[] { + getTypeSystem().getStringType(), getTypeSystem().getStringType() }) { + + @Override + public String getDocumentation() { + return "Replaces each substring of this string that matches the given " + + "regular expression with the given replacement."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return target.toString().replaceAll(params[0].toString(), params[1].toString()); + } + }, + + new OperationImpl(this, "replaceFirst", getTypeSystem().getStringType(), new Type[] { + getTypeSystem().getStringType(), getTypeSystem().getStringType() }) { + + @Override + public String getDocumentation() { + return "Replaces the first substring of this string that matches the given" + + " regular expression with the given replacement."; + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return target.toString().replaceFirst(params[0].toString(), params[1].toString()); + } + }, + + new OperationImpl(this, "split", getTypeSystem().getListType(getTypeSystem().getStringType()), + new Type[] { getTypeSystem().getStringType() }) { + + @Override + public String getDocumentation() { + return "Splits this string around matches of the given regular expression (from Java 1.4)"; + + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return new ArrayList<String>(Arrays.asList(target.toString().split(params[0].toString()))); + } + }, + + new OperationImpl(this, "matches", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getStringType() }) { + + @Override + public String getDocumentation() { + return "Tells whether or not this string matches the given regular expression. (from Java 1.4)"; + + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return Boolean.valueOf(((String) target).matches((String) params[0])); + } + }, + + new OperationImpl(this, "trim", getTypeSystem().getStringType(), new Type[] {}) { + + @Override + public String getDocumentation() { + return "Returns a copy of the string, with leading and trailing whitespace omitted. (from Java 1.4)"; + + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return ((String) target).trim(); + } + }, + + new OperationImpl(this, "asInteger", getTypeSystem().getIntegerType(), new Type[] {}) { + + @Override + public String getDocumentation() { + return "Returns an Integer object holding the value of the specified String (from Java 1.5)"; + + } + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + try { + return Integer.valueOf((String) target); + } catch (NumberFormatException nfe) { + log.error("'asInteger' on '"+target+"' returned null!"); + return null; + } + } + } + + }; + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.singleton(getTypeSystem().getObjectType()); + } + + private String toString(final Object o) { + if (o == null) + return null; + if (isInstance(o)) + return o.toString(); + throw new IllegalArgumentException(o.getClass().getName() + " not supported"); + } + + @Override + public Object convert(final Object src, final Class targetType) { + final String s = toString(src); + if (targetType.isAssignableFrom(String.class)) + return s; + else if (targetType.isAssignableFrom(Character.class) || targetType.isAssignableFrom(Character.TYPE)) { + if (s.length() == 1) + return new Character(s.charAt(0)); + } else if (targetType.isAssignableFrom(StringBuffer.class)) + return new StringBuffer(s); + return super.convert(src, targetType); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/TypeTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/TypeTypeImpl.java new file mode 100644 index 00000000..1e20f735 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/TypeTypeImpl.java @@ -0,0 +1,190 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; +import org.eclipse.internal.xtend.type.baseimpl.PropertyImpl; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class TypeTypeImpl extends BuiltinBaseType { + + public TypeTypeImpl(final TypeSystem ts, final String name) { + super(ts, name); + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.singleton(getTypeSystem().getObjectType()); + } + + public boolean isInstance(final Object o) { + return o instanceof Type; + } + + public Object newInstance() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAbstract() { + return true; + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[] { + new PropertyImpl(this, "name", getTypeSystem().getStringType()) { + public Object get(final Object target) { + final Type t = (Type) target; + return t.getName(); + } + + @Override + public void set(final Object target, final Object val) { + throw new UnsupportedOperationException("unsettable!"); + } + + }, + + new PropertyImpl(this, "superTypes", getTypeSystem().getSetType(getTypeSystem().getTypeType())) { + public Object get(final Object target) { + return ((Type) target).getSuperTypes(); + } + + @Override + public void set(final Object target, final Object val) { + throw new UnsupportedOperationException("unsettable!"); + } + }, + + new PropertyImpl(this, "allFeatures", getTypeSystem().getSetType(getTypeSystem().getFeatureType())) { + public Object get(final Object target) { + return ((Type) target).getAllFeatures(); + } + + @Override + public void set(final Object target, final Object val) { + throw new UnsupportedOperationException("unsettable!"); + } + }, + + new PropertyImpl(this, "allProperties", getTypeSystem().getSetType(getTypeSystem().getPropertyType())) { + public Object get(final Object target) { + return ((Type) target).getAllProperties(); + } + + @Override + public void set(final Object target, final Object val) { + throw new UnsupportedOperationException("unsettable!"); + } + }, + new PropertyImpl(this, "allOperations", getTypeSystem().getSetType(getTypeSystem().getOperationType())) { + public Object get(final Object target) { + return ((Type) target).getAllOperations(); + } + + @Override + public void set(final Object target, final Object val) { + throw new UnsupportedOperationException("unsettable!"); + } + }, + + new PropertyImpl(this, "allStaticProperties", getTypeSystem().getSetType( + getTypeSystem().getStaticPropertyType())) { + public Object get(final Object target) { + return ((Type) target).getAllStaticProperties(); + } + + @Override + public void set(final Object target, final Object val) { + throw new UnsupportedOperationException("unsettable!"); + } + }, + new OperationImpl(this, "getFeature", getTypeSystem().getFeatureType(), new Type[] { + getTypeSystem().getStringType(), getTypeSystem().getListType(null) }) { + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + final List l = (List) params[1]; + final Type[] ta = (Type[]) l.toArray(new Type[l.size()]); + return ((Type) target).getFeature((String) params[0], ta); + } + }, + + new OperationImpl(this, "getProperty", getTypeSystem().getPropertyType(), new Type[] { getTypeSystem() + .getStringType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return ((Type) target).getProperty((String) params[0]); + } + }, + + new OperationImpl(this, "getOperation", getTypeSystem().getOperationType(), new Type[] { + getTypeSystem().getStringType(), getTypeSystem().getListType(null) }) { + + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + final List l = (List) params[1]; + final Type[] ta = (Type[]) l.toArray(new Type[l.size()]); + return ((Type) target).getOperation((String) params[0], ta); + } + }, + + new OperationImpl(this, "getStaticProperty", getTypeSystem().getStaticPropertyType(), + new Type[] { getTypeSystem().getStringType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return ((Type) target).getStaticProperty((String) params[0]); + } + }, + + new OperationImpl(this, "newInstance", getTypeSystem().getObjectType(), new Type[0]) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return ((Type) target).newInstance(); + } + }, + new OperationImpl(this, "isInstance", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getObjectType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return new Boolean(((Type) target).isInstance(params[0])); + } + }, new OperationImpl(this, "isAssignableFrom", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() + .getTypeType() }) { + @Override + public Object evaluateInternal(final Object target, final Object[] params) { + return ((Type) target).isAssignableFrom((Type) params[0]); + } + }, new PropertyImpl(this, "documentation", getTypeSystem().getStringType()) { + + public Object get(final Object target) { + return ((Type) target).getDocumentation(); + } + } + + }; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/VoidType.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/VoidType.java new file mode 100644 index 00000000..c17502f7 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/VoidType.java @@ -0,0 +1,63 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.baseimpl.types; + +import java.util.Collections; +import java.util.Set; + +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.AbstractTypeImpl; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class VoidType extends AbstractTypeImpl implements Type { + + public VoidType(final TypeSystem ts, final String name) { + super(ts, name); + } + + @Override + public Feature[] getContributedFeatures() { + return new Feature[0]; + } + + public boolean isInstance(final Object o) { + return o == null; + } + + public Object newInstance() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAbstract() { + return true; + } + + @Override + public Set<Type> getSuperTypes() { + return Collections.singleton(getTypeSystem().getObjectType()); + } + + @Override + public String getDocumentation() { + return "Void is used as an undefined type. It's only instance is the null reference."; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaBeansMetaModel.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaBeansMetaModel.java new file mode 100644 index 00000000..d373aa65 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaBeansMetaModel.java @@ -0,0 +1,10 @@ +package org.eclipse.internal.xtend.type.impl.java; + +import org.eclipse.internal.xtend.type.impl.java.beans.JavaBeansStrategy; + + +public class JavaBeansMetaModel extends JavaMetaModel { + public JavaBeansMetaModel () { + setTypeStrategy(new JavaBeansStrategy ()); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaMetaModel.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaMetaModel.java new file mode 100644 index 00000000..10530811 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaMetaModel.java @@ -0,0 +1,160 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.impl.java; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.mwe.core.resources.ResourceLoaderFactory; +import org.eclipse.internal.xtend.expression.parser.SyntaxConstants; +import org.eclipse.internal.xtend.type.impl.java.beans.JavaBeansStrategy; +import org.eclipse.internal.xtend.util.Cache; +import org.eclipse.xtend.expression.TypeNameUtil; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.MetaModel; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class JavaMetaModel implements MetaModel, TypeFinder { + private String _name = null; + + private JavaTypeStrategy _strategy; + + private TypeSystem typeSystem; + + public TypeSystem getTypeSystem() { + return typeSystem; + } + + public void setTypeSystem(final TypeSystem typeSystem) { + if (typeSystem != null) { + this.typeSystem = typeSystem; + } + } + + public JavaMetaModel() { + _strategy = new JavaBeansStrategy(); + } + + public JavaMetaModel(final String name, final JavaTypeStrategy strategy) { + _name = name; + _strategy = strategy; + } + + private final Cache<Class<?>, Type> cache = new Cache<Class<? extends Object>, Type>() { + @Override + protected Type createNew(Class<?> clazz) { + JavaTypeImpl impl = new JavaTypeImpl(JavaMetaModel.this, clazz, getName(clazz), _strategy); + if (List.class.isAssignableFrom(clazz)) { + return typeSystem.getListType(typeSystem.getObjectType()); + } else if (Set.class.isAssignableFrom(clazz)) { + return typeSystem.getSetType(typeSystem.getObjectType()); + } else if (Collection.class.isAssignableFrom(clazz)) { + return typeSystem.getCollectionType(typeSystem.getObjectType()); + } + return impl; + } + }; + + private String getName(final Class<?> class1) { + return TypeNameUtil.getName(class1); + } + + private final Class<? extends JavaMetaModel> NOCLASS = getClass(); + + private final Cache<String, Class<?>> classCache = new Cache<String, Class<? extends Object>>() { + @Override + protected Class<?> createNew(String typeName) { + // try to load the requested class by its name + final String classname = typeName.replaceAll(SyntaxConstants.NS_DELIM, "."); + try { + Class<?> loadedClass = ResourceLoaderFactory.createResourceLoader().loadClass(classname); + return loadedClass == null ? NOCLASS : loadedClass; + } catch (Exception e1) { + // FIXME: This catch block should really be removed - the + // built-in ResosurceLoader implementation + // never throws an exception, and contributed implementations + // should comply to this contract + return NOCLASS; + } + } + }; + + public Type builtinAwareGetTypeForName(final String typeName) { + Type type = typeSystem.getTypeForName(typeName); + if (type == null) { + type = getTypeForName(typeName); + } + return type; + } + + public Type getTypeForName(final String typeName) { + final Class<?> clazz = classCache.get(typeName); + if (clazz == NOCLASS) { + return null; + } + return getTypeForClass(clazz); + } + + public Type builtinAwareGetType(final Object obj) { + Type type = typeSystem.getType(obj); + if (type == null) { + type = getType(obj); + } + return type; + } + + public Type getType(final Object obj) { + if (obj == null) { + return null; + } + return getTypeForClass(obj.getClass()); + } + + public Type builtinAwareGetTypeForClass(final Class<?> clazz) { + Type type = typeSystem.getTypeForName(getName(clazz)); + if (type == null) { + type = getTypeForClass(clazz); + } + return type; + } + + public Type getTypeForClass(final Class<?> clazz) { + return cache.get(clazz); + } + + public Set<Type> getKnownTypes() { + final Collection<Type> col = cache.getValues(); + return (Set<Type>) (col instanceof Set ? col : new HashSet<Type>(col)); + } + + public String getName() { + return _name; + } + + public void setTypeStrategy(final JavaTypeStrategy strategy) { + _strategy = strategy; + } + + public Set<String> getNamespaces() { + // TODO: provide real implementation + return new HashSet<String>(); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaOperationImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaOperationImpl.java new file mode 100644 index 00000000..127452c8 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaOperationImpl.java @@ -0,0 +1,57 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.impl.java; + +import java.lang.reflect.Method; +import java.util.Arrays; + +import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; +import org.eclipse.xtend.typesystem.Operation; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge + * @author Arno Haase + */ +public class JavaOperationImpl extends OperationImpl implements Operation { + + private Method method; + + public JavaOperationImpl(final Type owner, final String name, final Type type, final Type[] parameterTypes, + final Method method) { + super(owner, name, type, parameterTypes); + this.method = method; + } + + @Override + public Object evaluateInternal(Object target, final Object[] params) { + try { + target = getOwner().convert(target, method.getDeclaringClass()); + if (params != null) { + for (int i = 0; i < params.length; i++) { + params[i] = getParameterTypes().get(i).convert(params[i], method.getParameterTypes()[i]); + } + } + final Object resultRaw = method.invoke(target, params); + if (resultRaw != null && resultRaw.getClass().isArray()) { + return Arrays.asList ((Object[]) resultRaw); + } + return resultRaw; + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaPropertyImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaPropertyImpl.java new file mode 100644 index 00000000..2403c0fe --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaPropertyImpl.java @@ -0,0 +1,64 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.impl.java; + +import java.lang.reflect.Method; +import java.util.Arrays; + +import org.eclipse.internal.xtend.type.baseimpl.PropertyImpl; +import org.eclipse.xtend.typesystem.Property; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge + * @author Arno Haase + */ +public class JavaPropertyImpl extends PropertyImpl implements Property { + + private Method readMethod; + + private Method writeMethod; + + public JavaPropertyImpl(final Type owner, final String name, final Type returnType, final Method readMethod, + final Method writeMethod) { + super(owner, name, returnType); + this.readMethod = readMethod; + this.writeMethod = writeMethod; + } + + public Object get(final Object target) { + try { + final Object resultRaw = readMethod.invoke(target, (Object[])null); + if (resultRaw != null && resultRaw.getClass().isArray()) { + return Arrays.asList ((Object[]) resultRaw); + } + return resultRaw; + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void set(final Object target, final Object newValue) { + if (writeMethod == null) + throw new UnsupportedOperationException("Property " + getName() + " is not writable!"); + try { + writeMethod.invoke(target, new Object[] { newValue }); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaStaticPropertyImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaStaticPropertyImpl.java new file mode 100644 index 00000000..ba031879 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaStaticPropertyImpl.java @@ -0,0 +1,42 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.impl.java; + +import java.lang.reflect.Field; + +import org.eclipse.internal.xtend.type.baseimpl.StaticPropertyImpl; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class JavaStaticPropertyImpl extends StaticPropertyImpl { + + private Field field; + + public JavaStaticPropertyImpl(final Type owner, final String name, final Type returnType, final Field field) { + super(owner, name, returnType); + this.field = field; + } + + public Object get() { + try { + return field.get(null); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } +}
\ No newline at end of file diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaTypeImpl.java new file mode 100644 index 00000000..376febc0 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaTypeImpl.java @@ -0,0 +1,116 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.impl.java; + +import java.lang.reflect.Modifier; +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.xtend.typesystem.AbstractTypeImpl; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge + * @author Arno Haase + */ +public class JavaTypeImpl extends AbstractTypeImpl implements Type { + + private final static Log log = LogFactory.getLog(JavaTypeImpl.class); + + private Class<?> clazz; + + private Set<Type> superTypes = null; + + private Feature[] features = null; + + private JavaTypeStrategy strategy = null; + + private JavaMetaModel metamodel = null; + + public JavaTypeImpl(final JavaMetaModel meta, final Class<?> clazz, final String name, final JavaTypeStrategy strategy) { + super(meta.getTypeSystem(), name); + this.clazz = clazz; + metamodel = meta; + this.strategy = strategy; + } + + @Override + public Feature[] getContributedFeatures() { + if (features == null) { + features = strategy.getFeatures(metamodel, clazz, this); + } + return features; + } + + @Override + public Set<Type> getSuperTypes() { + if (superTypes == null) { + final Set<Type> result = new HashSet<Type>(); + if (clazz.getSuperclass() != null && !clazz.getSuperclass().equals(Object.class)) { + final Type beanType = metamodel.builtinAwareGetTypeForClass(clazz.getSuperclass()); + if (beanType != null) { + result.add(beanType); + } + } + final Class[] interfaces = clazz.getInterfaces(); + for (int i = 0; i < interfaces.length; i++) { + final Type beanType = metamodel.builtinAwareGetTypeForClass(interfaces[i]); + if (beanType != null) { + result.add(beanType); + } + } + if (result.isEmpty()) { + result.add(metamodel.getTypeSystem().getObjectType()); + } + superTypes = result; + } + return superTypes; + } + + public boolean isInstance(final Object o) { + return clazz.isInstance(o); + } + + @Override + protected boolean internalIsAssignableFrom(final Type t) { + if (t instanceof JavaTypeImpl) + return clazz.isAssignableFrom(((JavaTypeImpl) t).clazz); + return false; + } + + public Object newInstance() { + try { + return clazz.newInstance(); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public boolean isAbstract() { + try { + return clazz.getConstructor(new Class[0]) == null || Modifier.isAbstract (clazz.getModifiers()); + } catch (final SecurityException e) { + log.error(e.getMessage(), e); + } catch (final NoSuchMethodException e) { + log.error(e.getMessage(), e); + } + return true; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaTypeStrategy.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaTypeStrategy.java new file mode 100644 index 00000000..39abf2a6 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/JavaTypeStrategy.java @@ -0,0 +1,26 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.impl.java; + +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface JavaTypeStrategy { + public Feature[] getFeatures(TypeFinder typeFinder, Class<?> clazz, Type owner); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/TypeFinder.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/TypeFinder.java new file mode 100644 index 00000000..ec7a9677 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/TypeFinder.java @@ -0,0 +1,29 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.impl.java; + +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface TypeFinder { + public Type builtinAwareGetTypeForName(String typeName); + + public Type builtinAwareGetType(Object obj); + + public Type builtinAwareGetTypeForClass(Class<?> obj); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/beans/JavaBeansStrategy.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/beans/JavaBeansStrategy.java new file mode 100644 index 00000000..29f61104 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/java/beans/JavaBeansStrategy.java @@ -0,0 +1,211 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.impl.java.beans; + +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.internal.xtend.type.baseimpl.FeatureImpl; +import org.eclipse.internal.xtend.type.baseimpl.StaticPropertyImpl; +import org.eclipse.internal.xtend.type.impl.java.JavaOperationImpl; +import org.eclipse.internal.xtend.type.impl.java.JavaPropertyImpl; +import org.eclipse.internal.xtend.type.impl.java.JavaStaticPropertyImpl; +import org.eclipse.internal.xtend.type.impl.java.JavaTypeStrategy; +import org.eclipse.internal.xtend.type.impl.java.TypeFinder; +import org.eclipse.internal.xtend.util.StringHelper; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Karsten Thoms (bugfixing, documentation) + * @author Bernd Kolb + */ +public class JavaBeansStrategy implements JavaTypeStrategy { + + private static Map<Class<?>, PropertyDescriptor[]> propertyDescCache = new HashMap<Class<?>, PropertyDescriptor[]>(); + + /** + * Collect all features provided by a Java Class: + * <ul> + * <li> Properties + * <li> Declared public methods + * <li> Static fields + * <li> Java5 enumeration literals for defined enum types + * </ul> + */ + public Feature[] getFeatures(final TypeFinder typeFinder, final Class clazz, final Type t) { + final List<FeatureImpl> result = new ArrayList<FeatureImpl>(); + + final Set<Method> usedMethods = new HashSet<Method>(); + + PropertyDescriptor[] pdArr; + if ( propertyDescCache.containsKey(clazz)) { + pdArr = propertyDescCache.get(clazz); + }else { + try { + pdArr = Introspector.getBeanInfo(clazz).getPropertyDescriptors(); + } catch (IntrospectionException e1) { + pdArr = new PropertyDescriptor[0]; + } + propertyDescCache.put(clazz, pdArr); + } + for (int i = 0; i < pdArr.length; i++) { + final PropertyDescriptor pd = pdArr[i]; + final Method m = pd.getReadMethod() != null ? pd.getReadMethod() : pd.getWriteMethod(); + if (m != null && clazz.equals(m.getDeclaringClass())) { + // remember the getter method for this property; we do not need + // to add this feature as an operation, too. + String propName = pd.getName(); + if (pd.getReadMethod() != null) { + usedMethods.add(pd.getReadMethod()); + } + result.add(new JavaPropertyImpl(t, propName, typeFinder.builtinAwareGetTypeForClass(pd.getPropertyType()), pd.getReadMethod(), pd + .getWriteMethod())); + } + } + + final Method[] meths = clazz.getDeclaredMethods(); + for (int i = 0; i < meths.length; i++) { + final Method method = meths[i]; + if (Modifier.isPublic(method.getModifiers()) && !usedMethods.contains(method)) { + // leave the accessor methods in: they don't hurt, and this way + // we can e.g. call "set" methods + try { + // special handling for accessor method for boolean + // properties, whose return type is + // the wrapper type 'Boolean' (not 'boolean') + if (isNonStandardBooleanProperty(method)) { + handleNonStandardBooleanProperty(typeFinder, t, result, pdArr, method); + } else { + Type returnType = typeFinder.builtinAwareGetTypeForClass(method.getReturnType()); + result.add(new JavaOperationImpl(t, method.getName(), returnType, createTypes(method.getParameterTypes(), typeFinder), method)); + } + } catch (final RuntimeException e) { + // ignore + } + } + } + + // staticProps + final Field[] fields = clazz.getFields(); + for (int i = 0; i < fields.length; i++) { + final Field field = fields[i]; + final int mod = field.getModifiers(); + if (Modifier.isPublic(mod) && Modifier.isStatic(mod) && Modifier.isFinal(mod)) { + result.add(new JavaStaticPropertyImpl(t, field.getName(), typeFinder.builtinAwareGetTypeForClass(field.getType()), field)); + } + } + + // Java 5 enums + final Object[] enumValues = clazz.getEnumConstants(); + if (enumValues != null) { + for (Object o : enumValues) { + final Enum<?> curEnum = (Enum<?>) o; + result.add(new StaticPropertyImpl(t, curEnum.name(), t) { + public Object get() { + return curEnum; + } + }); + } + } + + return result.toArray(new Feature[result.size()]); + } + + /** + * Tests if this method is a getter for boolean property (beginning with + * 'is') whose return type is of the wrapper type 'java.lang.Boolean'. + * JavaBeans won't recognize this as an accessor method for a property. + * + * @param method + * The method to check + * @return <code>true</code>: the method begins with 'is', the return + * type is 'java.lang.Boolean' and the method has no arguments. + */ + private boolean isNonStandardBooleanProperty(final Method method) { + return method.getName().startsWith("is") && method.getReturnType().getName().equals(Boolean.class.getName()) && method.getParameterTypes().length == 0; + } + + /** + * Adds a JavaPropertyImpl to the list of features for properties of type + * 'java.lang.Boolean', which has a getter method beginning with 'is'. + * <p> + * If this non-standard property has a setter method than it was already + * added as a JavaProperty. But this instance is immutable, so the original + * has to be removed and another one be added. + * + * @param typeFinder + * Helper to resolve the Built-In type 'oaw::Boolean' + * @param t + * The type for which the property is defined + * @param result + * The original feature list. + * @param pdArr + * Property descriptors of the class + * @param method + * The method to handle + */ + private void handleNonStandardBooleanProperty(final TypeFinder typeFinder, final Type t, final List<FeatureImpl> result, final PropertyDescriptor[] pdArr, + final Method method) { + // extract the property name + String propName = method.getName().substring(2); + if (propName.length() > 1 && propName.matches("\\p{Upper}\\p{Lower}.*")) { + propName = StringHelper.firstLower(propName); + } + + // search the property definition which has the setter method + JavaPropertyImpl setMethod = null; + Method writeMethod = null; + for (FeatureImpl feature : result) { + if (feature.getName().equals(propName)) { + setMethod = (JavaPropertyImpl) feature; + for (PropertyDescriptor pd : pdArr) { + if (pd.getName().equals(propName)) { + writeMethod = pd.getWriteMethod(); + break; + } + } + break; + } + } + if (setMethod != null) + result.remove(setMethod); + JavaPropertyImpl prop = new JavaPropertyImpl(t, propName, typeFinder.builtinAwareGetTypeForClass(Boolean.class), method, writeMethod); + result.add(prop); + } + + protected Type[] createTypes(final Class<?>[] parameterTypes, final TypeFinder tf) { + final Type[] result = new Type[parameterTypes.length]; + for (int i = 0; i < parameterTypes.length; i++) { + result[i] = tf.builtinAwareGetTypeForClass(parameterTypes[i]); + if (result[i] == null) + throw new NullPointerException(); + } + return result; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/oawclassic/OAWClassicStrategy.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/oawclassic/OAWClassicStrategy.java new file mode 100644 index 00000000..bc0ab525 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/impl/oawclassic/OAWClassicStrategy.java @@ -0,0 +1,81 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.type.impl.oawclassic; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.internal.xtend.type.baseimpl.FeatureImpl; +import org.eclipse.internal.xtend.type.impl.java.JavaOperationImpl; +import org.eclipse.internal.xtend.type.impl.java.JavaPropertyImpl; +import org.eclipse.internal.xtend.type.impl.java.JavaTypeStrategy; +import org.eclipse.internal.xtend.type.impl.java.TypeFinder; +import org.eclipse.internal.xtend.util.StringHelper; +import org.eclipse.xtend.typesystem.Feature; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class OAWClassicStrategy implements JavaTypeStrategy { + + private boolean convertPropertiesToLowerCase = true; + + private boolean isOAWClassicGetter(final Method method) { + if (method.getParameterTypes().length == 0) + return true; + return false; + } + + public Feature[] getFeatures(final TypeFinder typeFinder, final Class clazz, final Type owner) { + final List<FeatureImpl> result = new ArrayList<FeatureImpl>(); + final Method[] methods = clazz.getMethods(); + for (int i = 0; i < methods.length; i++) { + final Method method = methods[i]; + if (isOAWClassicGetter(method)) { + final Method getterMethod = method; + final Method setterMethod = null; + String propName = method.getName(); + if (convertPropertiesToLowerCase) { + propName = StringHelper.firstLower(propName); + } + result.add(new JavaPropertyImpl(owner, propName, typeFinder.builtinAwareGetTypeForClass(clazz), + getterMethod, setterMethod)); + } else { + final Type rt = typeFinder.builtinAwareGetTypeForClass(method.getReturnType()); + if (rt != null) { + final Type[] params = new Type[method.getParameterTypes().length]; + boolean nullParam = false; + for (int j = 0; j < params.length && !nullParam; j++) { + params[j] = typeFinder.builtinAwareGetTypeForClass(method.getParameterTypes()[j]); + nullParam = params[j] == null; + } + if (!nullParam) { + result.add(new JavaOperationImpl(owner, method.getName(), rt, params, method)); + } + } + } + + } + return result.toArray(new Feature[result.size()]); + } + + public void setConvertPropertiesToLowerCase(final boolean bool) { + convertPropertiesToLowerCase = bool; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/Cache.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/Cache.java new file mode 100644 index 00000000..5d6f886c --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/Cache.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.internal.xtend.util; + +import java.util.Collection; +import java.util.HashMap; + +public abstract class Cache<K, V> { + + protected abstract V createNew(K arg0); + + private final HashMap<K, V> internal = new HashMap<K, V>(); + + public V get(final K key) { + if (internal.containsKey(key)) + return internal.get(key); + final V r = createNew(key); + internal.put(key, r); + return r; + } + + public Collection<V> getValues() { + return internal.values(); + } + + /** + * Clears the cache. + * + * @since 4.2 + */ + public void clear() { + internal.clear(); + } + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/DoubleKeyCache.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/DoubleKeyCache.java new file mode 100644 index 00000000..e1910f3f --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/DoubleKeyCache.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.internal.xtend.util; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +public abstract class DoubleKeyCache<K1, K2, V> { + + protected abstract V createNew(K1 key1, K2 key2); + + private final Map <Pair <K1, K2>, V> internal = new HashMap <Pair <K1, K2>, V>(); + + public V get (K1 key1, K2 key2) { + final Pair<K1, K2> key = new Pair <K1, K2> (key1, key2); + + if (internal.containsKey (key)) + return internal.get (key); + final V r = createNew (key1, key2); + internal.put(key, r); + return r; + } + + public Collection<V> getValues() { + return internal.values(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/EncodingDetector.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/EncodingDetector.java new file mode 100644 index 00000000..774a5c00 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/EncodingDetector.java @@ -0,0 +1,51 @@ +package org.eclipse.internal.xtend.util; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.nio.charset.Charset; + +import org.eclipse.internal.xtend.util.internal.icu.CharsetDetector; +import org.eclipse.internal.xtend.util.internal.icu.CharsetMatch; + +/** + * This class helps detecting the encoding of some resource by scanning the first bytes from it. + * @author Karsten Thoms + * @since 4.2 + */ +public class EncodingDetector { + public static Charset detectEncoding (BufferedInputStream in) throws IOException { + // Read some bytes from the stream + in.mark(65); + byte[] buf = new byte[64]; + in.read(buf); + // reset the stream + in.reset(); + return detectEncoding(buf); + } + + public static Charset detectEncoding (byte[] sample) { + Charset encoding = null; + // Special handling for Xpand files on Mac: Try to detect + // the opening Guillemot bracket for MacRoman encoding + for (int i=0; i<sample.length; i++) { + if (sample[i]==-57) { // opening Guillemot bracket + encoding = Charset.forName("MacRoman"); + break; + } + } + // Use com.ibm.icu for autodetection + if (encoding==null) { + CharsetDetector det = new CharsetDetector(); + det.setText(sample); + CharsetMatch match = det.detect(); + if (match!=null) { + encoding = Charset.forName(match.getName()); + } else { + // fallback: Use System encoding + encoding = Charset.forName(System.getProperty("file.encoding")); + } + } + return encoding; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/HigherOrder.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/HigherOrder.java new file mode 100644 index 00000000..8bcf64bf --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/HigherOrder.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.internal.xtend.util; + +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.internal.xtend.type.impl.java.JavaMetaModel; +import org.eclipse.internal.xtend.type.impl.java.beans.JavaBeansStrategy; +import org.eclipse.xtend.expression.ExecutionContextImpl; +import org.eclipse.xtend.expression.ExpressionFacade; + +public class HigherOrder { + public static <T> Collection<T> select(Collection<T> col, String closure) { + return (Collection<T>) facade().evaluate("x.select("+closure+")", Collections.singletonMap("x", col)); + } + + public static <T> Collection<?> collect(Collection<T> col, String closure) { + return (Collection<?>) facade().evaluate("x.collect("+closure+")", Collections.singletonMap("x", col)); + } + + public static <T> boolean exists(Collection<T> col, String closure) { + return (Boolean) facade().evaluate("x.select("+closure+")", Collections.singletonMap("x", col)); + } + + public static <T> boolean forAll(Collection<T> col, String closure) { + return (Boolean)facade().evaluate("x.select("+closure+")", Collections.singletonMap("x", col)); + } + + public static <T> T first(Collection<T> col, String closure) { + Collection<T> re = (Collection<T>) facade().evaluate("x.select("+closure+")", Collections.singletonMap("x", col)); + if (re!=null && re.size()>0) { + return re.iterator().next(); + } + return null; + } + + + + private static ExpressionFacade facade() { + ExecutionContextImpl ctx = new ExecutionContextImpl(); + ctx.registerMetaModel(new JavaMetaModel("java",new JavaBeansStrategy())); + ExpressionFacade ef = new ExpressionFacade(ctx); + return ef; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/Pair.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/Pair.java new file mode 100644 index 00000000..48ff0002 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/Pair.java @@ -0,0 +1,76 @@ +package org.eclipse.internal.xtend.util; + +import java.io.Serializable; + +/** + * This class provides combines two objects into one, giving them appropriate + * equals and hashCode methods. + * + * @author Arno Haase + */ +public class Pair<T1, T2> implements Serializable, Cloneable { + private static final long serialVersionUID = 5892226218172864652L; + + private T1 _first; + + private T2 _second; + + public Pair() { + } + + public Pair(T1 first, T2 second) { + _first = first; + _second = second; + } + + public T1 getFirst() { + return _first; + } + + public void setFirst(T1 first) { + _first = first; + } + + public T2 getSecond() { + return _second; + } + + public void setSecond(T2 second) { + _second = second; + } + + public String toString() { + return "Pair [" + _first + ", " + _second + "]"; + } + + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof Pair)) + return false; + + final Pair<?, ?> pair = (Pair<?, ?>) o; + + if (_first != null ? !_first.equals(pair._first) : pair._first != null) + return false; + if (_second != null ? !_second.equals(pair._second) : pair._second != null) + return false; + + return true; + } + + public int hashCode() { + int result; + result = (_first != null ? _first.hashCode() : 0); + result = 29 * result + (_second != null ? _second.hashCode() : 0); + return result; + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new InternalError("Should not be thrown: " + e); + } + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/ProfileCollector.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/ProfileCollector.java new file mode 100644 index 00000000..4449c032 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/ProfileCollector.java @@ -0,0 +1,185 @@ +package org.eclipse.internal.xtend.util; + +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +/** + * This class serves as a ThreadLocal collector for profiling information. + * + * @author arno + * + */ +public class ProfileCollector { + private ProfileCollector () {} + private static final ThreadLocal<ProfileCollector> _instance = new ThreadLocal<ProfileCollector>() { + protected ProfileCollector initialValue() { + return new ProfileCollector(); + }; + }; + + private PrintWriter _out; + private final Stack<Triplet<String, Long, Long>> _contextStack = new Stack<Triplet<String, Long, Long>>(); + private final Map<String, ProfileEntry> _profile = new HashMap<String, ProfileEntry>(); + + public static ProfileCollector getInstance () { + return _instance.get(); + } + + + /** + * This method tells the ProfileCollector to perform detailed logging and store it in the Writer passed + * as a parameter. + */ + public void setDetailedLoggingWriter (OutputStream out) { + try { + _out = new PrintWriter (new OutputStreamWriter (out, "utf-8")); + + _out.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); + _out.println("<m2t-profile>"); + } + catch (UnsupportedEncodingException exc) {} + } + + /** + * This method must be called by the application to indicate that logging is finished. Once this method + * was called, enter() and leave() must not be called. + */ + public void finish () { + if (_out != null) { + _out.println ("</m2t-profile>"); + _out.flush(); + _out = null; + } + } + + public Collection<ProfileEntry> getProfile () { + return _profile.values(); + } + + public void enter (String context) { + _contextStack.push (new Triplet<String, Long, Long>(context, System.currentTimeMillis(), 0L)); + if (_out != null) + _out.println("<call context=\"" + context + "\">"); + } + + /** + * the leave() method does not need to be passed the context because it keeps a stack of all contexts and + * pops the topmost. + * + */ + public void leave () { + final Triplet<String, Long, Long> entry = _contextStack.pop(); + final long duration = System.currentTimeMillis() - entry.getSecond(); + final long timeInChildren = entry.getThird(); + + if (! _contextStack.isEmpty()) { + // add this duration to the "duration in children" field of the parent + final Triplet<String, Long, Long> parent = _contextStack.peek(); + parent.setThird(parent.getThird() + duration); + } + + if (_profile.containsKey(entry.getFirst())) { + _profile.get(entry.getFirst()).registerCall(duration, duration - timeInChildren); + } + else { + _profile.put (entry.getFirst(), new ProfileEntry (entry.getFirst(), duration, duration - timeInChildren)); + } + + if (_out != null) { + _out.println ("<duration millis=\"" + duration + "\"/>"); + _out.println ("</call>"); + } + } + + @Override + public String toString() { + final StringBuilder result = new StringBuilder (); + + result.append ("context\tnum\ttotal\tnet\tmin\tnet\tmax\tnet\n"); + + for (ProfileEntry e: _profile.values()) { + result.append (e.getContextName() + "\t" + e.getNumCalls() + "\t" + e.getTotalTimeGross() + "\t" + e.getTotalTimeNet() + "\t" + e.getMinTimeGross() + "\t" + e.getMinTimeNet() + "\t" + e.getMaxTimeGross() + "\t" + e.getMaxTimeNet() + "\n"); + } + + return result.toString(); + } + + public static class ProfileEntry { + private final String _contextName; + private int _numCalls = 1; + private long _totalTimeGross; + private long _totalTimeNet; + private long _minTimeGross; + private long _minTimeNet; + private long _maxTimeGross; + private long _maxTimeNet; + + public ProfileEntry (String contextName, long grossDuration, long netDuration) { + _contextName = contextName; + + _totalTimeGross += grossDuration; + _totalTimeNet += netDuration; + + _minTimeGross = grossDuration; + _maxTimeGross = grossDuration; + _minTimeNet = netDuration; + _maxTimeNet = netDuration; + } + + public void registerCall (long grossDuration, long netDuration) { + _numCalls++; + + _totalTimeGross += grossDuration; + _totalTimeNet += netDuration; + + if (grossDuration < _minTimeGross) + _minTimeGross = grossDuration; + if (grossDuration > _maxTimeGross) + _maxTimeGross = grossDuration; + if (netDuration < _minTimeNet) + _minTimeNet = netDuration; + if (netDuration > _maxTimeNet) + _maxTimeNet = netDuration; + } + + public String getContextName() { + return _contextName; + } + + public long getMaxTimeGross() { + return _maxTimeGross; + } + + public long getMaxTimeNet() { + return _maxTimeNet; + } + + public long getMinTimeGross() { + return _minTimeGross; + } + + public long getMinTimeNet() { + return _minTimeNet; + } + + public int getNumCalls() { + return _numCalls; + } + + public long getTotalTimeGross() { + return _totalTimeGross; + } + + public long getTotalTimeNet() { + return _totalTimeNet; + } + } +} + + diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/StringHelper.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/StringHelper.java new file mode 100644 index 00000000..2b75fc42 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/StringHelper.java @@ -0,0 +1,273 @@ +package org.eclipse.internal.xtend.util; + +import java.text.DateFormat; +import java.text.NumberFormat; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; + +/** + * This class is a collection of helper functions for string handling. + * + * @author Arno Haase + */ +public class StringHelper { + private static final NumberFormat _numFormat = NumberFormat.getNumberInstance(); + + /** + * formats a number using the default locale settings. + */ + public static String prettyPrint(long num) { + return _numFormat.format(num); + } + + /** + * formats a number using the default locale settings. + */ + public static String prettyPrint(Number num) { + return _numFormat.format(num); + } + + /** + * formats a date using the default locale settings. + */ + public static String prettyPrint(Date date) { + return DateFormat.getDateTimeInstance().format(date); + } + + /** + * returns a new string in which one search string is replaced by another. + */ + public static String replace(String src, String search, String replace) { + if (src == null) + return src; + if (search == null || search.length() == 0) + throw new IllegalArgumentException("Search string must not be empty"); + + String result = src; + int ind = 0; + while ((ind = result.indexOf(search, ind)) >= 0) { + result = result.substring(0, ind) + replace + result.substring(ind + search.length()); + ind += replace.length(); + } + + return result; + } + + /** + * replaces special characters that affect formatting with non-formatting + * character sequences. + * <ul> + * <li> \ -> \\ + * <li> <tab> -> \t + * <li> <CR> -> \r + * <li> <Newline> -> \n + * </ul> + */ + public static String escape(String src) { + String result = replace(src, "\\", "\\\\"); + result = replace(result, "\t", "\\t"); + result = replace(result, "\r", "\\r"); + result = replace(result, "\n", "\\n"); + result = replace(result, "\"", "\\\""); + + return result; + } + + /** + * undoes the operations of <code>escape</code> + */ + public static String unescape(String src) { + if (src == null) + return null; + + final StringBuffer result = new StringBuffer(); + for (int i = 0; i < src.length(); i++) { + final char curChar = src.charAt(i); + + if (curChar != '\\') { + result.append(curChar); + continue; + } + // increment i to skip to the character after '\\' + i++; + if (i >= src.length()) + throw new IllegalArgumentException("String ends with '\\'"); + + result.append(unescapeChar(src.charAt(i))); + } + + return result.toString(); + } + + private static char unescapeChar(char escapedChar) { + switch (escapedChar) { + case '\\': + return '\\'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case '"': + return '"'; + } + throw new IllegalArgumentException("unsupported string format: '\\" + escapedChar + "' is not supported."); + } + + /** + * truncates a string regardless of its length. This method is a workaround + * for a shortcoming of String.substring (int, int) that is unable to handle + * the case where the number of characters would extend beyond the end of + * the string. + */ + public static String truncate(String str, int maxLen) { + if (str == null || str.length() < maxLen) + return str; + if (maxLen < 0) + return ""; + return str.substring(0, maxLen); + } + + /** + * same as String.substring, except that this version handles the case + * robustly when the index is out of bounds. + */ + public static String substring(String str, int beginIndex) { + if (str == null) + return null; + if (beginIndex < 0) + return str; + if (beginIndex >= str.length()) + return ""; + + return str.substring(beginIndex); + } + + /** + * same as String.substring, except that this version handles the case + * robustly when one or both of the indexes is out of bounds. + */ + public static String substring(String str, int beginIndex, int endIndex) { + if (str == null) + return null; + if (beginIndex > endIndex) + return ""; + if (beginIndex < 0) + beginIndex = 0; + if (endIndex > str.length()) + endIndex = str.length(); + + return str.substring(beginIndex, endIndex); + } + + /** + * removes a number of characters from the beginning and the end of a string + */ + public static String strip(String s, int numStart, int numEnd) { + if (s == null) + return s; + + return substring(s, numStart, s.length() - numEnd); + } + + /** + * returns the number of occurrences of a character in a string + */ + public static int numMatches(String s, char ch) { + if (s == null) + return 0; + + int result = 0; + for (int i = 0; i < s.length(); i++) + if (s.charAt(i) == ch) + result++; + + return result; + } + + /** + * returns the number of occurrences of a substring in a string + */ + public static int numMatches(String s, String search) { + if (s == null || search == null || "".equals(s) || "".equals(search)) + return 0; + + int result = 0; + int curIndex = 0; + while (true) { + curIndex = s.indexOf(search, curIndex); + if (curIndex == -1) + break; + + curIndex++; + result++; + } + return result; + } + + /** + * tests if a string starts with any one of a collection of prefixes + */ + public static boolean startsWithAny(String str, Collection<String> prefixes) { + if (str == null) + return false; + + for (Iterator<String> iter = prefixes.iterator(); iter.hasNext();) { + if (str.startsWith(iter.next())) + return true; + } + return false; + } + + /** + * tests if a string starts with any one of a collection of prefixes + */ + public static boolean startsWithAny(String str, String[] prefixes) { + if (str == null) + return false; + + for (int i = 0; i < prefixes.length; i++) { + if (str.startsWith(prefixes[i])) + return true; + } + return false; + } + + /** + * tests if a string ends with any one of a collection of prefixes + */ + public static boolean endsWithAny(String str, Collection<String> prefixes) { + if (str == null) + return false; + + for (Iterator<String> iter = prefixes.iterator(); iter.hasNext();) { + if (str.endsWith(iter.next())) + return true; + } + return false; + } + + /** + * tests if a string ends with any one of a collection of prefixes + */ + public static boolean endsWithAny(String str, String[] prefixes) { + if (str == null) + return false; + + for (int i = 0; i < prefixes.length; i++) { + if (str.endsWith(prefixes[i])) + return true; + } + return false; + } + + public static String firstUpper(String str) { + return str.substring(0, 1).toUpperCase().concat(str.substring(1)); + } + + public static String firstLower(String str) { + return str.substring(0, 1).toLowerCase().concat(str.substring(1)); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/TripleKeyCache.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/TripleKeyCache.java new file mode 100644 index 00000000..1a86df32 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/TripleKeyCache.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.internal.xtend.util; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +public abstract class TripleKeyCache<K1, K2, K3, V> { + + protected abstract V createNew(K1 key1, K2 key2, K3 key3); + + private final Map <Triplet <K1, K2, K3>, V> internal = new HashMap <Triplet <K1, K2, K3>, V>(); + + public V get (K1 key1, K2 key2, K3 key3) { + final Triplet <K1, K2, K3> key = new Triplet <K1, K2, K3> (key1, key2, key3); + + if (internal.containsKey (key)) + return internal.get (key); + final V r = createNew (key1, key2, key3); + internal.put(key, r); + return r; + } + + public Collection<V> getValues() { + return internal.values(); + } +} + diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/Triplet.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/Triplet.java new file mode 100644 index 00000000..e36aeea1 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/Triplet.java @@ -0,0 +1,87 @@ +package org.eclipse.internal.xtend.util; + +import java.io.Serializable; + +/** + * This class provides combines three objects into one, giving them appropriate + * equals and hashCode methods. + * + * @author Arno Haase + */ +public class Triplet<T1, T2, T3> implements Serializable, Cloneable { + private static final long serialVersionUID = -3721045730655830208L; + + private T1 _first; + + private T2 _second; + + private T3 _third; + + public Triplet(T1 first, T2 second, T3 third) { + _first = first; + _second = second; + _third = third; + } + + public T1 getFirst() { + return _first; + } + + public T2 getSecond() { + return _second; + } + + public T3 getThird() { + return _third; + } + + public void setFirst(T1 first) { + _first = first; + } + + public void setSecond(T2 second) { + _second = second; + } + + public void setThird(T3 third) { + _third = third; + } + + public String toString() { + return "Triplet [" + _first + ", " + _second + ", " + _third + "]"; + } + + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof Triplet)) + return false; + + final Triplet<?, ?, ?> triplet = (Triplet<?, ?, ?>) o; + + if (_first != null ? !_first.equals(triplet._first) : triplet._first != null) + return false; + if (_second != null ? !_second.equals(triplet._second) : triplet._second != null) + return false; + if (_third != null ? !_third.equals(triplet._third) : triplet._third != null) + return false; + + return true; + } + + public int hashCode() { + int result; + result = (_first != null ? _first.hashCode() : 0); + result = 29 * result + (_second != null ? _second.hashCode() : 0); + result = 29 * result + (_third != null ? _third.hashCode() : 0); + return result; + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new InternalError("Should not be thrown: " + e); + } + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetDetector.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetDetector.java new file mode 100644 index 00000000..2b0a650e --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetDetector.java @@ -0,0 +1,568 @@ +package org.eclipse.internal.xtend.util.internal.icu; +/** +This code was taken from the com.ibm.icu library (3.6.1). We needed to copy it to have not +a dependency to this large library only the need of charset recognition. +(KTH 2007-07-30) + +The com.ibm.icu library is published under Eclipse Public License V1.0. +*/ +/** +******************************************************************************* +* Copyright (C) 2005-2006, International Business Machines Corporation and * +* others. All Rights Reserved. * +******************************************************************************* +*/ + +import java.io.InputStream; +import java.io.Reader; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Arrays; +import java.util.Iterator; + + +/** + * <code>CharsetDetector</code> provides a facility for detecting the + * charset or encoding of character data in an unknown format. + * The input data can either be from an input stream or an array of bytes. + * The result of the detection operation is a list of possibly matching + * charsets, or, for simple use, you can just ask for a Java Reader that + * will will work over the input data. + * <p/> + * Character set detection is at best an imprecise operation. The detection + * process will attempt to identify the charset that best matches the characteristics + * of the byte data, but the process is partly statistical in nature, and + * the results can not be guaranteed to always be correct. + * <p/> + * For best accuracy in charset detection, the input data should be primarily + * in a single language, and a minimum of a few hundred bytes worth of plain text + * in the language are needed. The detection process will attempt to + * ignore html or xml style markup that could otherwise obscure the content. + * <p/> + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ +public class CharsetDetector { + +// Question: Should we have getters corresponding to the setters for inut text +// and declared encoding? + +// A thought: If we were to create our own type of Java Reader, we could defer +// figuring out an actual charset for data that starts out with too much English +// only ASCII until the user actually read through to something that didn't look +// like 7 bit English. If nothing else ever appeared, we would never need to +// actually choose the "real" charset. All assuming that the application just +// wants the data, and doesn't care about a char set name. + + /** + * Constructor + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public CharsetDetector() { + } + + /** + * Set the declared encoding for charset detection. + * The declared encoding of an input text is an encoding obtained + * from an http header or xml declaration or similar source that + * can be provided as additional information to the charset detector. + * A match between a declared encoding and a possible detected encoding + * will raise the quality of that detected encoding by a small delta, + * and will also appear as a "reason" for the match. + * <p/> + * A declared encoding that is incompatible with the input data being + * analyzed will not be added to the list of possible encodings. + * + * @param encoding The declared encoding + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public CharsetDetector setDeclaredEncoding(String encoding) { + fDeclaredEncoding = encoding; + return this; + } + + /** + * Set the input text (byte) data whose charset is to be detected. + * + * @param in the input text of unknown encoding + * + * @return This CharsetDetector + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public CharsetDetector setText(byte [] in) { + fRawInput = in; + fRawLength = in.length; + + MungeInput(); + + return this; + } + + private static final int kBufSize = 8000; + + /** + * Set the input text (byte) data whose charset is to be detected. + * <p/> + * The input stream that supplies the character data must have markSupported() + * == true; the charset detection process will read a small amount of data, + * then return the stream to its original position via + * the InputStream.reset() operation. The exact amount that will + * be read depends on the characteristics of the data itself. + * + * @param in the input text of unknown encoding + * + * @return This CharsetDetector + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + + public CharsetDetector setText(InputStream in) throws IOException { + fInputStream = in; + fInputStream.mark(kBufSize); + fRawInput = new byte[kBufSize]; // Always make a new buffer because the + // previous one may have come from the caller, + // in which case we can't touch it. + fRawLength = 0; + int remainingLength = kBufSize; + while (remainingLength > 0 ) { + // read() may give data in smallish chunks, esp. for remote sources. Hence, this loop. + int bytesRead = fInputStream.read(fRawInput, fRawLength, remainingLength); + if (bytesRead <= 0) { + break; + } + fRawLength += bytesRead; + remainingLength -= bytesRead; + } + fInputStream.reset(); + + MungeInput(); // Strip html markup, collect byte stats. + return this; + } + + + /** + * Return the charset that best matches the supplied input data. + * + * Note though, that because the detection + * only looks at the start of the input data, + * there is a possibility that the returned charset will fail to handle + * the full set of input data. + * <p/> + * Raise an exception if + * <ul> + * <li>no charset appears to match the data.</li> + * <li>no input text has been provided</li> + * </ul> + * + * @return a CharsetMatch object representing the best matching charset, or + * <code>null</code> if there are no matches. + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public CharsetMatch detect() { +// TODO: A better implementation would be to copy the detect loop from +// detectAll(), and cut it short as soon as a match with a high confidence +// is found. This is something to be done later, after things are otherwise +// working. + CharsetMatch matches[] = detectAll(); + + if (matches == null || matches.length == 0) { + return null; + } + + return matches[0]; + } + + /** + * Return an array of all charsets that appear to be plausible + * matches with the input data. The array is ordered with the + * best quality match first. + * <p/> + * Raise an exception if + * <ul> + * <li>no charsets appear to match the input data.</li> + * <li>no input text has been provided</li> + * </ul> + * + * @return An array of CharsetMatch objects representing possibly matching charsets. + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public CharsetMatch[] detectAll() { + CharsetRecognizer csr; + int i; + int detectResults; + int confidence; + ArrayList matches = new ArrayList(); + + // Iterate over all possible charsets, remember all that + // give a match quality > 0. + for (i=0; i<fCSRecognizers.size(); i++) { + csr = (CharsetRecognizer)fCSRecognizers.get(i); + detectResults = csr.match(this); + confidence = detectResults & 0x000000ff; + if (confidence > 0) { + CharsetMatch m = new CharsetMatch(this, csr, confidence); + matches.add(m); + } + } + Collections.sort(matches); // CharsetMatch compares on confidence + Collections.reverse(matches); // Put best match first. + CharsetMatch [] resultArray = new CharsetMatch[matches.size()]; + resultArray = (CharsetMatch[]) matches.toArray(resultArray); + return resultArray; + } + + + /** + * Autodetect the charset of an inputStream, and return a Java Reader + * to access the converted input data. + * <p/> + * This is a convenience method that is equivalent to + * <code>this.setDeclaredEncoding(declaredEncoding).setText(in).detect().getReader();</code> + * <p/> + * For the input stream that supplies the character data, markSupported() + * must be true; the charset detection will read a small amount of data, + * then return the stream to its original position via + * the InputStream.reset() operation. The exact amount that will + * be read depends on the characteristics of the data itself. + *<p/> + * Raise an exception if no charsets appear to match the input data. + * + * @param in The source of the byte data in the unknown charset. + * + * @param declaredEncoding A declared encoding for the data, if available, + * or null or an empty string if none is available. + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public Reader getReader(InputStream in, String declaredEncoding) { + fDeclaredEncoding = declaredEncoding; + + try { + setText(in); + + CharsetMatch match = detect(); + + if (match == null) { + return null; + } + + return match.getReader(); + } catch (IOException e) { + return null; + } + } + + /** + * Autodetect the charset of an inputStream, and return a String + * containing the converted input data. + * <p/> + * This is a convenience method that is equivalent to + * <code>this.setDeclaredEncoding(declaredEncoding).setText(in).detect().getString();</code> + *<p/> + * Raise an exception if no charsets appear to match the input data. + * + * @param in The source of the byte data in the unknown charset. + * + * @param declaredEncoding A declared encoding for the data, if available, + * or null or an empty string if none is available. + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public String getString(byte[] in, String declaredEncoding) + { + fDeclaredEncoding = declaredEncoding; + + try { + setText(in); + + CharsetMatch match = detect(); + + if (match == null) { + return null; + } + + return match.getString(-1); + } catch (IOException e) { + return null; + } + } + + + /** + * Get the names of all char sets that can be recognized by the char set detector. + * + * @return an array of the names of all charsets that can be recognized + * by the charset detector. + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public static String[] getAllDetectableCharsets() { + return fCharsetNames; + } + + /** + * Test whether or not input filtering is enabled. + * + * @return <code>true</code> if input text will be filtered. + * + * @see #enableInputFilter + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public boolean inputFilterEnabled() + { + return fStripTags; + } + + /** + * Enable filtering of input text. If filtering is enabled, + * text within angle brackets ("<" and ">") will be removed + * before detection. + * + * @param filter <code>true</code> to enable input text filtering. + * + * @return The previous setting. + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public boolean enableInputFilter(boolean filter) + { + boolean previous = fStripTags; + + fStripTags = filter; + + return previous; + } + + /** + * MungeInput - after getting a set of raw input data to be analyzed, preprocess + * it by removing what appears to be html markup. + * + * @internal + */ + private void MungeInput() { + int srci = 0; + int dsti = 0; + byte b; + boolean inMarkup = false; + int openTags = 0; + int badTags = 0; + + // + // html / xml markup stripping. + // quick and dirty, not 100% accurate, but hopefully good enough, statistically. + // discard everything within < brackets > + // Count how many total '<' and illegal (nested) '<' occur, so we can make some + // guess as to whether the input was actually marked up at all. + if (fStripTags) { + for (srci = 0; srci < fRawLength && dsti < fInputBytes.length; srci++) { + b = fRawInput[srci]; + if (b == (byte)'<') { + if (inMarkup) { + badTags++; + } + inMarkup = true; + openTags++; + } + + if (! inMarkup) { + fInputBytes[dsti++] = b; + } + + if (b == (byte)'>') { + inMarkup = false; + } + } + + fInputLen = dsti; + } + + // + // If it looks like this input wasn't marked up, or if it looks like it's + // essentially nothing but markup abandon the markup stripping. + // Detection will have to work on the unstripped input. + // + if (openTags<5 || openTags/5 < badTags || + (fInputLen < 100 && fRawLength>600)) { + int limit = fRawLength; + + if (limit > kBufSize) { + limit = kBufSize; + } + + for (srci=0; srci<limit; srci++) { + fInputBytes[srci] = fRawInput[srci]; + } + fInputLen = srci; + } + + // + // Tally up the byte occurence statistics. + // These are available for use by the various detectors. + // + Arrays.fill(fByteStats, (short)0); + for (srci=0; srci<fInputLen; srci++) { + int val = fInputBytes[srci] & 0x00ff; + fByteStats[val]++; + } + + fC1Bytes = false; + for (int i = 0x80; i <= 0x9F; i += 1) { + if (fByteStats[i] != 0) { + fC1Bytes = true; + break; + } + } + } + + /** + * The following items are accessed by individual CharsetRecongizers during + * the recognition process + * + * @internal + */ + byte[] fInputBytes = // The text to be checked. Markup will have been + new byte[kBufSize]; // removed if appropriate. + + int fInputLen; // Length of the byte data in fInputText. + + short fByteStats[] = // byte frequency statistics for the input text. + new short[256]; // Value is percent, not absolute. + // Value is rounded up, so zero really means zero occurences. + + boolean fC1Bytes = // True if any bytes in the range 0x80 - 0x9F are in the input; + false; + + String fDeclaredEncoding; + + + + // + // Stuff private to CharsetDetector + // + byte[] fRawInput; // Original, untouched input bytes. + // If user gave us a byte array, this is it. + // If user gave us a stream, it's read to a + // buffer here. + int fRawLength; // Length of data in fRawInput array. + + InputStream fInputStream; // User's input stream, or null if the user + // gave us a byte array. + + boolean fStripTags = // If true, setText() will strip tags from input text. + false; + + + /** + * List of recognizers for all charsets known to the implementation. + * + * @internal + */ + private static ArrayList fCSRecognizers = createRecognizers(); + private static String [] fCharsetNames; + + /** + * Create the singleton instances of the CharsetRecognizer classes + * <p> + * Customized by oAW; see https://bugs.eclipse.org/bugs/show_bug.cgi?id=203919 + * @internal + */ + private static ArrayList createRecognizers() { + ArrayList<CharsetRecognizer> recognizers = new ArrayList<CharsetRecognizer>(); + + // :TRICKY: The sequence of Recognizers is built in reverse order of their + // generality. When detecting a charset, we use the charset with the + // highest scorig rate. If there are multiple charsets with the same + // scoring, the last one that fits best is used. + + recognizers.add(new CharsetRecog_mbcs.CharsetRecog_sjis()); + recognizers.add(new CharsetRecog_2022.CharsetRecog_2022JP()); + recognizers.add(new CharsetRecog_2022.CharsetRecog_2022CN()); + recognizers.add(new CharsetRecog_2022.CharsetRecog_2022KR()); + recognizers.add(new CharsetRecog_mbcs.CharsetRecog_euc.CharsetRecog_gb_18030()); + recognizers.add(new CharsetRecog_mbcs.CharsetRecog_euc.CharsetRecog_euc_jp()); + recognizers.add(new CharsetRecog_mbcs.CharsetRecog_euc.CharsetRecog_euc_kr()); + recognizers.add(new CharsetRecog_mbcs.CharsetRecog_big5()); + + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_1_da()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_1_de()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_1_en()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_1_es()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_1_fr()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_1_it()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_1_nl()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_1_no()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_1_pt()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_1_sv()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_2_cs()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_2_hu()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_2_pl()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_2_ro()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_5_ru()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_6_ar()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_7_el()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_8_I_he()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_8_he()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_windows_1251()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_windows_1256()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_KOI8_R()); + recognizers.add(new CharsetRecog_sbcs.CharsetRecog_8859_9_tr()); + + recognizers.add(new CharsetRecog_Unicode.CharsetRecog_UTF_32_BE()); + recognizers.add(new CharsetRecog_Unicode.CharsetRecog_UTF_32_LE()); + recognizers.add(new CharsetRecog_Unicode.CharsetRecog_UTF_16_BE()); + recognizers.add(new CharsetRecog_Unicode.CharsetRecog_UTF_16_LE()); + + recognizers.add(new CharsetRecog_UTF8()); + + // Remove all Recognizers from this list which have unsupported character codes + // in the current java runtime to avoid later problems with matching but unsupported + // charsets. + for (Iterator<CharsetRecognizer> iter = recognizers.iterator(); iter.hasNext();) { + CharsetRecognizer recognizer = iter.next(); + try { + Charset.forName(recognizer.getName()); + } + catch (UnsupportedCharsetException ex) { + iter.remove(); + } + } + + // Create an array of all charset names, as a side effect. + // Needed for the getAllDetectableCharsets() API. + String[] charsetNames = new String [recognizers.size()]; + int out = 0; + + for (int i = 0; i < recognizers.size(); i++) { + String name = ((CharsetRecognizer)recognizers.get(i)).getName(); + + if (out == 0 || ! name.equals(charsetNames[out - 1])) { + charsetNames[out++] = name; + } + } + + fCharsetNames = new String[out]; + System.arraycopy(charsetNames, 0, fCharsetNames, 0, out); + + return recognizers; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetMatch.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetMatch.java new file mode 100644 index 00000000..37278da0 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetMatch.java @@ -0,0 +1,286 @@ +package org.eclipse.internal.xtend.util.internal.icu; +/** +This code was taken from the com.ibm.icu library (3.6.1). We needed to copy it to have not +a dependency to this large library only the need of charset recognition. +(KTH 2007-07-30) + +The com.ibm.icu library is published under Eclipse Public License V1.0. + */ + +/** +******************************************************************************* +* Copyright (C) 2005-2006, International Business Machines Corporation and * +* others. All Rights Reserved. * +******************************************************************************* +*/ + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + + +/** + * This class represents a charset that has been identified by a CharsetDetector + * as a possible encoding for a set of input data. From an instance of this + * class, you can ask for a confidence level in the charset identification, + * or for Java Reader or String to access the original byte data in Unicode form. + * <p/> + * Instances of this class are created only by CharsetDetectors. + * <p/> + * Note: this class has a natural ordering that is inconsistent with equals. + * The natural ordering is based on the match confidence value. + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ +public class CharsetMatch implements Comparable { + + + /** + * Create a java.io.Reader for reading the Unicode character data corresponding + * to the original byte data supplied to the Charset detect operation. + * <p/> + * CAUTION: if the source of the byte data was an InputStream, a Reader + * can be created for only one matching char set using this method. If more + * than one charset needs to be tried, the caller will need to reset + * the InputStream and create InputStreamReaders itself, based on the charset name. + * + * @return the Reader for the Unicode character data. + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public Reader getReader() { + InputStream inputStream = fInputStream; + + if (inputStream == null) { + inputStream = new ByteArrayInputStream(fRawInput, 0, fRawLength); + } + + try { + inputStream.reset(); + return new InputStreamReader(inputStream, getName()); + } catch (IOException e) { + return null; + } + } + + /** + * Create a Java String from Unicode character data corresponding + * to the original byte data supplied to the Charset detect operation. + * + * @return a String created from the converted input data. + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public String getString() throws java.io.IOException { + return getString(-1); + + } + + /** + * Create a Java String from Unicode character data corresponding + * to the original byte data supplied to the Charset detect operation. + * The length of the returned string is limited to the specified size; + * the string will be trunctated to this length if necessary. A limit value of + * zero or less is ignored, and treated as no limit. + * + * @param maxLength The maximium length of the String to be created when the + * source of the data is an input stream, or -1 for + * unlimited length. + * @return a String created from the converted input data. + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public String getString(int maxLength) throws java.io.IOException { + String result = null; + if (fInputStream != null) { + StringBuffer sb = new StringBuffer(); + char[] buffer = new char[1024]; + Reader reader = getReader(); + int max = maxLength < 0? Integer.MAX_VALUE : maxLength; + int bytesRead = 0; + + while ((bytesRead = reader.read(buffer, 0, Math.min(max, 1024))) >= 0) { + sb.append(buffer, 0, bytesRead); + max -= bytesRead; + } + + reader.close(); + + return sb.toString(); + } else { + result = new String(fRawInput, getName()); + } + return result; + + } + + /** + * Get an indication of the confidence in the charset detected. + * Confidence values range from 0-100, with larger numbers indicating + * a better match of the input data to the characteristics of the + * charset. + * + * @return the confidence in the charset match + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public int getConfidence() { + return fConfidence; + } + + + /** + * Bit flag indicating the match is based on the the encoding scheme. + * + * @see #getMatchType + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + static public final int ENCODING_SCHEME = 1; + + /** + * Bit flag indicating the match is based on the presence of a BOM. + * + * @see #getMatchType + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + static public final int BOM = 2; + + /** + * Bit flag indicating he match is based on the declared encoding. + * + * @see #getMatchType + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + static public final int DECLARED_ENCODING = 4; + + /** + * Bit flag indicating the match is based on language statistics. + * + * @see #getMatchType + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + static public final int LANG_STATISTICS = 8; + + /** + * Return flags indicating what it was about the input data + * that caused this charset to be considered as a possible match. + * The result is a bitfield containing zero or more of the flags + * ENCODING_SCHEME, BOM, DECLARED_ENCODING, and LANG_STATISTICS. + * A result of zero means no information is available. + * <p> + * Note: currently, this method always returns zero. + * <p> + * + * @return the type of match found for this charset. + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public int getMatchType() { +// TODO: create a list of enum-like constants for common combinations of types of matches. + return 0; + } + + /** + * Get the name of the detected charset. + * The name will be one that can be used with other APIs on the + * platform that accept charset names. It is the "Canonical name" + * as defined by the class java.nio.charset.Charset; for + * charsets that are registered with the IANA charset registry, + * this is the MIME-preferred registerd name. + * + * @see java.nio.charset.Charset + * @see java.io.InputStreamReader + * + * @return The name of the charset. + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public String getName() { + return fRecognizer.getName(); + } + + /** + * Get the ISO code for the language of the detected charset. + * + * @return The ISO code for the language or <code>null</code> if the language cannot be determined. + * + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public String getLanguage() { + return fRecognizer.getLanguage(); + } + + + /** + * Compare to other CharsetMatch objects. + * Comparison is based on the match confidence value, which + * allows CharsetDetector.detectAll() to order its results. + * + * @param o the CharsetMatch object to compare against. + * @return a negative integer, zero, or a positive integer as the + * confidence level of this CharsetMatch + * is less than, equal to, or greater than that of + * the argument. + * @throws ClassCastException if the argument is not a CharsetMatch. + * @draft ICU 3.4 + * @provisional This API might change or be removed in a future release. + */ + public int compareTo (Object o) { + CharsetMatch other = (CharsetMatch)o; + int compareResult = 0; + if (this.fConfidence > other.fConfidence) { + compareResult = 1; + } else if (this.fConfidence < other.fConfidence) { + compareResult = -1; + } + return compareResult; + } + + /** + * Constructor. Implementation internal + * + * @internal + */ + CharsetMatch(CharsetDetector det, CharsetRecognizer rec, int conf) { + fRecognizer = rec; + fConfidence = conf; + + // The references to the original aplication input data must be copied out + // of the charset recognizer to here, in case the application resets the + // recognizer before using this CharsetMatch. + if (det.fInputStream == null) { + // We only want the existing input byte data if it came straight from the user, + // not if is just the head of a stream. + fRawInput = det.fRawInput; + fRawLength = det.fRawLength; + } + fInputStream = det.fInputStream; + } + + + // + // Private Data + // + private int fConfidence; + private CharsetRecognizer fRecognizer; + private byte[] fRawInput = null; // Original, untouched input bytes. + // If user gave us a byte array, this is it. + private int fRawLength; // Length of data in fRawInput array. + + private InputStream fInputStream = null; // User's input stream, or null if the user + // gave us a byte array. +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_2022.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_2022.java new file mode 100644 index 00000000..8f7ed015 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_2022.java @@ -0,0 +1,170 @@ +package org.eclipse.internal.xtend.util.internal.icu; +/** +This code was taken from the com.ibm.icu library (3.6.1). We needed to copy it to have not +a dependency to this large library only the need of charset recognition. +(KTH 2007-07-30) + +The com.ibm.icu library is published under Eclipse Public License V1.0. + */ + +/* +******************************************************************************* +* Copyright (C) 2005, International Business Machines Corporation and * +* others. All Rights Reserved. * +******************************************************************************* +*/ + +/** + * class CharsetRecog_2022 part of the ICU charset detection imlementation. + * This is a superclass for the individual detectors for + * each of the detectable members of the ISO 2022 family + * of encodings. + * + * The separate classes are nested within this class. + * + * @internal + */ +abstract class CharsetRecog_2022 extends CharsetRecognizer { + + + /** + * Matching function shared among the 2022 detectors JP, CN and KR + * Counts up the number of legal an unrecognized escape sequences in + * the sample of text, and computes a score based on the total number & + * the proportion that fit the encoding. + * + * + * @param text the byte buffer containing text to analyse + * @param textLen the size of the text in the byte. + * @param escapeSequences the byte escape sequences to test for. + * @return match quality, in the range of 0-100. + */ + int match(byte [] text, int textLen, byte [][] escapeSequences) { + int i, j; + int escN; + int hits = 0; + int misses = 0; + int shifts = 0; + int quality; + scanInput: + for (i=0; i<textLen; i++) { + if (text[i] == 0x1b) { + checkEscapes: + for (escN=0; escN<escapeSequences.length; escN++) { + byte [] seq = escapeSequences[escN]; + + for (j=1; j<seq.length; j++) { + if (seq[j] != text[i+j]) { + continue checkEscapes; + } + } + + hits++; + i += seq.length-1; + continue scanInput; + } + + misses++; + } + + if (text[i] == 0x0e || text[i] == 0x0f) { + // Shift in/out + shifts++; + } + } + + if (hits == 0) { + return 0; + } + + // + // Initial quality is based on relative proportion of recongized vs. + // unrecognized escape sequences. + // All good: quality = 100; + // half or less good: quality = 0; + // linear inbetween. + quality = (100*hits - 100*misses) / (hits + misses); + + // Back off quality if there were too few escape sequences seen. + // Include shifts in this computation, so that KR does not get penalized + // for having only a single Escape sequence, but many shifts. + if (hits+shifts < 5) { + quality -= (5-(hits+shifts))*10; + } + + if (quality < 0) { + quality = 0; + } + return quality; + } + + + + + static class CharsetRecog_2022JP extends CharsetRecog_2022 { + private byte [] [] escapeSequences = { + {0x1b, 0x24, 0x28, 0x43}, // KS X 1001:1992 + {0x1b, 0x24, 0x28, 0x44}, // JIS X 212-1990 + {0x1b, 0x24, 0x40}, // JIS C 6226-1978 + {0x1b, 0x24, 0x41}, // GB 2312-80 + {0x1b, 0x24, 0x42}, // JIS X 208-1983 + {0x1b, 0x26, 0x40}, // JIS X 208 1990, 1997 + {0x1b, 0x28, 0x42}, // ASCII + {0x1b, 0x28, 0x48}, // JIS-Roman + {0x1b, 0x28, 0x49}, // Half-width katakana + {0x1b, 0x28, 0x4a}, // JIS-Roman + {0x1b, 0x2e, 0x41}, // ISO 8859-1 + {0x1b, 0x2e, 0x46} // ISO 8859-7 + }; + + String getName() { + return "ISO-2022-JP"; + } + + int match(CharsetDetector det) { + return match(det.fInputBytes, det.fInputLen, escapeSequences); + } + } + + static class CharsetRecog_2022KR extends CharsetRecog_2022 { + private byte [] [] escapeSequences = { + {0x1b, 0x24, 0x29, 0x43} + }; + + String getName() { + return "ISO-2022-KR"; + } + + int match(CharsetDetector det) { + return match(det.fInputBytes, det.fInputLen, escapeSequences); + } + + } + + static class CharsetRecog_2022CN extends CharsetRecog_2022 { + private byte [] [] escapeSequences = { + {0x1b, 0x24, 0x29, 0x41}, // GB 2312-80 + {0x1b, 0x24, 0x29, 0x47}, // CNS 11643-1992 Plane 1 + {0x1b, 0x24, 0x2A, 0x48}, // CNS 11643-1992 Plane 2 + {0x1b, 0x24, 0x29, 0x45}, // ISO-IR-165 + {0x1b, 0x24, 0x2B, 0x49}, // CNS 11643-1992 Plane 3 + {0x1b, 0x24, 0x2B, 0x4A}, // CNS 11643-1992 Plane 4 + {0x1b, 0x24, 0x2B, 0x4B}, // CNS 11643-1992 Plane 5 + {0x1b, 0x24, 0x2B, 0x4C}, // CNS 11643-1992 Plane 6 + {0x1b, 0x24, 0x2B, 0x4D}, // CNS 11643-1992 Plane 7 + {0x1b, 0x4e}, // SS2 + {0x1b, 0x4f}, // SS3 + }; + + String getName() { + return "ISO-2022-CN"; + } + + + int match(CharsetDetector det) { + return match(det.fInputBytes, det.fInputLen, escapeSequences); + } + } + +} + diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_UTF8.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_UTF8.java new file mode 100644 index 00000000..e513a371 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_UTF8.java @@ -0,0 +1,107 @@ +package org.eclipse.internal.xtend.util.internal.icu; +/** +This code was taken from the com.ibm.icu library (3.6.1). We needed to copy it to have not +a dependency to this large library only the need of charset recognition. +(KTH 2007-07-30) + +The com.ibm.icu library is published under Eclipse Public License V1.0. + */ + +/** +******************************************************************************* +* Copyright (C) 2005, International Business Machines Corporation and * +* others. All Rights Reserved. * +******************************************************************************* +*/ + +/** + * Charset recognizer for UTF-8 + * + * @internal + */ +class CharsetRecog_UTF8 extends CharsetRecognizer { + + String getName() { + return "UTF-8"; + } + + /* (non-Javadoc) + * @see com.ibm.icu.text.CharsetRecognizer#match(com.ibm.icu.text.CharsetDetector) + */ + int match(CharsetDetector det) { + boolean hasBOM = false; + int numValid = 0; + int numInvalid = 0; + byte input[] = det.fRawInput; + int i; + int trailBytes = 0; + int confidence; + + if (det.fRawLength >= 3 && + input[0]==0xef && input[1]==0xbb & input[2]==0xbf) { + hasBOM = true; + } + + // Scan for multi-byte sequences + for (i=0; i<det.fRawLength; i++) { + int b = input[i]; + if ((b & 0x80) == 0) { + continue; // ASCII + } + + // Hi bit on char found. Figure out how long the sequence should be + if ((b & 0x0e0) == 0x0c0) { + trailBytes = 1; + } else if ((b & 0x0f0) == 0x0e0) { + trailBytes = 2; + } else if ((b & 0x0f8) == 0xf0) { + trailBytes = 3; + } else { + numInvalid++; + if (numInvalid > 5) { + break; + } + trailBytes = 0; + } + + // Verify that we've got the right number of trail bytes in the sequence + for (;;) { + i++; + if (i>=det.fRawLength) { + break; + } + b = input[i]; + if ((b & 0xc0) != 0x080) { + numInvalid++; + break; + } + if (--trailBytes == 0) { + numValid++; + break; + } + } + + } + + // Cook up some sort of confidence score, based on presense of a BOM + // and the existence of valid and/or invalid multi-byte sequences. + confidence = 0; + if (hasBOM && numInvalid==0) { + confidence = 100; + } else if (hasBOM && numValid > numInvalid*10) { + confidence = 80; + } else if (numValid > 3 && numInvalid == 0) { + confidence = 100; + } else if (numValid > 0 && numInvalid == 0) { + confidence = 80; + } else if (numValid == 0 && numInvalid == 0) { + // Plain ASCII. + confidence = 10; + } else if (numValid > numInvalid*10) { + // Probably corruput utf-8 data. Valid sequences aren't likely by chance. + confidence = 25; + } + return confidence; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_Unicode.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_Unicode.java new file mode 100644 index 00000000..cb0725b1 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_Unicode.java @@ -0,0 +1,153 @@ +package org.eclipse.internal.xtend.util.internal.icu; +/** +This code was taken from the com.ibm.icu library (3.6.1). We needed to copy it to have not +a dependency to this large library only the need of charset recognition. +(KTH 2007-07-30) + +The com.ibm.icu library is published under Eclipse Public License V1.0. + */ + +/* + ******************************************************************************* + * Copyright (C) 1996-2006, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + * + */ + +/** + * This class matches UTF-16 and UTF-32, both big- and little-endian. The + * BOM will be used if it is present. + * + * @internal + */ +abstract class CharsetRecog_Unicode extends CharsetRecognizer { + + /* (non-Javadoc) + * @see com.ibm.icu.text.CharsetRecognizer#getName() + */ + abstract String getName(); + + /* (non-Javadoc) + * @see com.ibm.icu.text.CharsetRecognizer#match(com.ibm.icu.text.CharsetDetector) + */ + abstract int match(CharsetDetector det); + + static class CharsetRecog_UTF_16_BE extends CharsetRecog_Unicode + { + String getName() + { + return "UTF-16BE"; + } + + int match(CharsetDetector det) + { + byte[] input = det.fRawInput; + + if ((input[0] & 0xFF) == 0xFE && (input[1] & 0xFF) == 0xFF) { + return 100; + } + + // TODO: Do some statastics to check for unsigned UTF-16BE + return 0; + } + } + + static class CharsetRecog_UTF_16_LE extends CharsetRecog_Unicode + { + String getName() + { + return "UTF-16LE"; + } + + int match(CharsetDetector det) + { + byte[] input = det.fRawInput; + + if ((input[0] & 0xFF) == 0xFF && (input[1] & 0xFF) == 0xFE && (input[2] != 0x00 || input[3] != 0x00)) { + return 100; + } + + // TODO: Do some statastics to check for unsigned UTF-16LE + return 0; + } + } + + static abstract class CharsetRecog_UTF_32 extends CharsetRecog_Unicode + { + abstract int getChar(byte[] input, int index); + + abstract String getName(); + + int match(CharsetDetector det) + { + byte[] input = det.fRawInput; + int limit = (det.fRawLength / 4) * 4; + int numValid = 0; + int numInvalid = 0; + boolean hasBOM = false; + int confidence = 0; + + if (getChar(input, 0) == 0x0000FEFF) { + hasBOM = true; + } + + for(int i = 0; i < limit; i += 4) { + int ch = getChar(input, i); + + if (ch < 0 || ch >= 0x10FFFF || (ch >= 0xD800 && ch <= 0xDFFF)) { + numInvalid += 1; + } else { + numValid += 1; + } + } + + + // Cook up some sort of confidence score, based on presense of a BOM + // and the existence of valid and/or invalid multi-byte sequences. + if (hasBOM && numInvalid==0) { + confidence = 100; + } else if (hasBOM && numValid > numInvalid*10) { + confidence = 80; + } else if (numValid > 3 && numInvalid == 0) { + confidence = 100; + } else if (numValid > 0 && numInvalid == 0) { + confidence = 80; + } else if (numValid > numInvalid*10) { + // Probably corruput UTF-32BE data. Valid sequences aren't likely by chance. + confidence = 25; + } + + return confidence; + } + } + + static class CharsetRecog_UTF_32_BE extends CharsetRecog_UTF_32 + { + int getChar(byte[] input, int index) + { + return (input[index + 0] & 0xFF) << 24 | (input[index + 1] & 0xFF) << 16 | + (input[index + 2] & 0xFF) << 8 | (input[index + 3] & 0xFF); + } + + String getName() + { + return "UTF-32BE"; + } + } + + + static class CharsetRecog_UTF_32_LE extends CharsetRecog_UTF_32 + { + int getChar(byte[] input, int index) + { + return (input[index + 3] & 0xFF) << 24 | (input[index + 2] & 0xFF) << 16 | + (input[index + 1] & 0xFF) << 8 | (input[index + 0] & 0xFF); + } + + String getName() + { + return "UTF-32LE"; + } + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_mbcs.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_mbcs.java new file mode 100644 index 00000000..59306e5e --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_mbcs.java @@ -0,0 +1,539 @@ +package org.eclipse.internal.xtend.util.internal.icu; +/** +This code was taken from the com.ibm.icu library (3.6.1). We needed to copy it to have not +a dependency to this large library only the need of charset recognition. +(KTH 2007-07-30) + +The com.ibm.icu library is published under Eclipse Public License V1.0. + */ + +/* + **************************************************************************** + * Copyright (C) 2005-2006, International Business Machines Corporation and * + * others. All Rights Reserved. * + **************************************************************************** + * + */ + +import java.util.Arrays; + +/** + * CharsetRecognizer implemenation for Asian - double or multi-byte - charsets. + * Match is determined mostly by the input data adhering to the + * encoding scheme for the charset, and, optionally, + * frequency-of-occurence of characters. + * <p/> + * Instances of this class are singletons, one per encoding + * being recognized. They are created in the main + * CharsetDetector class and kept in the global list of available + * encodings to be checked. The specific encoding being recognized + * is determined by subclass. + * + * @internal + */ +abstract class CharsetRecog_mbcs extends CharsetRecognizer { + + /** + * Get the IANA name of this charset. + * @return the charset name. + */ + abstract String getName() ; + + + /** + * Test the match of this charset with the input text data + * which is obtained via the CharsetDetector object. + * + * @param det The CharsetDetector, which contains the input text + * to be checked for being in this charset. + * @return Two values packed into one int (Damn java, anyhow) + * <br/> + * bits 0-7: the match confidence, ranging from 0-100 + * <br/> + * bits 8-15: The match reason, an enum-like value. + */ + int match(CharsetDetector det, int [] commonChars) { + int singleByteCharCount = 0; + int doubleByteCharCount = 0; + int commonCharCount = 0; + int badCharCount = 0; + int totalCharCount = 0; + int confidence = 0; + iteratedChar iter = new iteratedChar(); + + detectBlock: { + for (iter.reset(); nextChar(iter, det);) { + totalCharCount++; + if (iter.error) { + badCharCount++; + } else { + + if (iter.charValue <= 0xff) { + singleByteCharCount++; + } else { + doubleByteCharCount++; + if (commonChars != null) { + if (Arrays.binarySearch(commonChars, iter.charValue) >= 0) { + commonCharCount++; + } + } + } + } + if (badCharCount >= 2 && badCharCount*5 >= doubleByteCharCount) { + // Bail out early if the byte data is not matching the encoding scheme. + break detectBlock; + } + } + + if (doubleByteCharCount <= 10 && badCharCount== 0) { + // Not many multi-byte chars. + // ASCII or ISO file? It's probably not our encoding, + // but is not incompatible with our encoding, so don't give it a zero. + confidence = 10; + break detectBlock; + } + + // + // No match if there are too many characters that don't fit the encoding scheme. + // (should we have zero tolerance for these?) + // + if (doubleByteCharCount < 20*badCharCount) { + confidence = 0; + break detectBlock; + } + + if (commonChars == null) { + // We have no statistics on frequently occuring characters. + // Assess confidence purely on having a reasonable number of + // multi-byte characters (the more the better + confidence = 30 + doubleByteCharCount - 20*badCharCount; + if (confidence > 100) { + confidence = 100; + } + }else { + // + // Frequency of occurence statistics exist. + // + double maxVal = Math.log((float)doubleByteCharCount / 4); + double scaleFactor = 90.0 / maxVal; + confidence = (int)(Math.log(commonCharCount+1) * scaleFactor + 10); + confidence = Math.min(confidence, 100); + } + } // end of detectBlock: + + return confidence; + } + + // "Character" iterated character class. + // Recognizers for specific mbcs encodings make their "characters" available + // by providing a nextChar() function that fills in an instance of iteratedChar + // with the next char from the input. + // The returned characters are not converted to Unicode, but remain as the raw + // bytes (concatenated into an int) from the codepage data. + // + // For Asian charsets, use the raw input rather than the input that has been + // stripped of markup. Detection only considers multi-byte chars, effectively + // stripping markup anyway, and double byte chars do occur in markup too. + // + static class iteratedChar { + int charValue = 0; // 1-4 bytes from the raw input data + int index = 0; + int nextIndex = 0; + boolean error = false; + boolean done = false; + + void reset() { + charValue = 0; + index = -1; + nextIndex = 0; + error = false; + done = false; + } + + int nextByte(CharsetDetector det) { + if (nextIndex >= det.fRawLength) { + done = true; + return -1; + } + int byteValue = (int)det.fRawInput[nextIndex++] & 0x00ff; + return byteValue; + } + } + + /** + * Get the next character (however many bytes it is) from the input data + * Subclasses for specific charset encodings must implement this function + * to get characters according to the rules of their encoding scheme. + * + * This function is not a method of class iteratedChar only because + * that would require a lot of extra derived classes, which is awkward. + * @param it The iteratedChar "struct" into which the returned char is placed. + * @param det The charset detector, which is needed to get at the input byte data + * being iterated over. + * @return True if a character was returned, false at end of input. + */ + abstract boolean nextChar(iteratedChar it, CharsetDetector det); + + + + + + /** + * Shift-JIS charset recognizer. + * + */ + static class CharsetRecog_sjis extends CharsetRecog_mbcs { + static int [] commonChars = + // TODO: This set of data comes from the character frequency- + // of-occurence analysis tool. The data needs to be moved + // into a resource and loaded from there. + {0x8140, 0x8141, 0x8142, 0x8145, 0x815b, 0x8169, 0x816a, 0x8175, 0x8176, 0x82a0, + 0x82a2, 0x82a4, 0x82a9, 0x82aa, 0x82ab, 0x82ad, 0x82af, 0x82b1, 0x82b3, 0x82b5, + 0x82b7, 0x82bd, 0x82be, 0x82c1, 0x82c4, 0x82c5, 0x82c6, 0x82c8, 0x82c9, 0x82cc, + 0x82cd, 0x82dc, 0x82e0, 0x82e7, 0x82e8, 0x82e9, 0x82ea, 0x82f0, 0x82f1, 0x8341, + 0x8343, 0x834e, 0x834f, 0x8358, 0x835e, 0x8362, 0x8367, 0x8375, 0x8376, 0x8389, + 0x838a, 0x838b, 0x838d, 0x8393, 0x8e96, 0x93fa, 0x95aa}; + + boolean nextChar(iteratedChar it, CharsetDetector det) { + it.index = it.nextIndex; + it.error = false; + int firstByte; + firstByte = it.charValue = it.nextByte(det); + if (firstByte < 0) { + return false; + } + + if (firstByte <= 0x7f || (firstByte>0xa0 && firstByte<=0xdf)) { + return true; + } + + int secondByte = it.nextByte(det); + if (secondByte < 0) { + return false; + } + it.charValue = (firstByte << 8) | secondByte; + if (! ((secondByte>=0x40 && secondByte<=0x7f) || (secondByte>=0x80 && secondByte<=0xff))) { + // Illegal second byte value. + it.error = true; + } + return true; + } + + int match(CharsetDetector det) { + return match(det, commonChars); + } + + String getName() { + return "Shift_JIS"; + } + + public String getLanguage() + { + return "ja"; + } + + + } + + + /** + * Big5 charset recognizer. + * + */ + static class CharsetRecog_big5 extends CharsetRecog_mbcs { + static int [] commonChars = + // TODO: This set of data comes from the character frequency- + // of-occurence analysis tool. The data needs to be moved + // into a resource and loaded from there. + {0xa140, 0xa141, 0xa142, 0xa143, 0xa147, 0xa149, 0xa175, 0xa176, 0xa440, 0xa446, + 0xa447, 0xa448, 0xa451, 0xa454, 0xa457, 0xa464, 0xa46a, 0xa46c, 0xa477, 0xa4a3, + 0xa4a4, 0xa4a7, 0xa4c1, 0xa4ce, 0xa4d1, 0xa4df, 0xa4e8, 0xa4fd, 0xa540, 0xa548, + 0xa558, 0xa569, 0xa5cd, 0xa5e7, 0xa657, 0xa661, 0xa662, 0xa668, 0xa670, 0xa6a8, + 0xa6b3, 0xa6b9, 0xa6d3, 0xa6db, 0xa6e6, 0xa6f2, 0xa740, 0xa751, 0xa759, 0xa7da, + 0xa8a3, 0xa8a5, 0xa8ad, 0xa8d1, 0xa8d3, 0xa8e4, 0xa8fc, 0xa9c0, 0xa9d2, 0xa9f3, + 0xaa6b, 0xaaba, 0xaabe, 0xaacc, 0xaafc, 0xac47, 0xac4f, 0xacb0, 0xacd2, 0xad59, + 0xaec9, 0xafe0, 0xb0ea, 0xb16f, 0xb2b3, 0xb2c4, 0xb36f, 0xb44c, 0xb44e, 0xb54c, + 0xb5a5, 0xb5bd, 0xb5d0, 0xb5d8, 0xb671, 0xb7ed, 0xb867, 0xb944, 0xbad8, 0xbb44, + 0xbba1, 0xbdd1, 0xc2c4, 0xc3b9, 0xc440, 0xc45f}; + + boolean nextChar(iteratedChar it, CharsetDetector det) { + it.index = it.nextIndex; + it.error = false; + int firstByte; + firstByte = it.charValue = it.nextByte(det); + if (firstByte < 0) { + return false; + } + + if (firstByte <= 0x7f || firstByte==0xff) { + // single byte character. + return true; + } + + int secondByte = it.nextByte(det); + if (secondByte < 0) { + return false; + } + it.charValue = (it.charValue << 8) | secondByte; + + if (secondByte < 0x40 || + secondByte ==0x7f || + secondByte == 0xff) { + it.error = true; + } + return true; + } + + int match(CharsetDetector det) { + return match(det, commonChars); + } + + String getName() { + return "Big5"; + } + + + public String getLanguage() + { + return "zh"; + } + } + + + /** + * EUC charset recognizers. One abstract class that provides the common function + * for getting the next character according to the EUC encoding scheme, + * and nested derived classes for EUC_KR, EUC_JP, EUC_CN. + * + */ + abstract static class CharsetRecog_euc extends CharsetRecog_mbcs { + + /* + * (non-Javadoc) + * Get the next character value for EUC based encodings. + * Character "value" is simply the raw bytes that make up the character + * packed into an int. + */ + boolean nextChar(iteratedChar it, CharsetDetector det) { + it.index = it.nextIndex; + it.error = false; + int firstByte = 0; + int secondByte = 0; + int thirdByte = 0; + //int fourthByte = 0; + + buildChar: { + firstByte = it.charValue = it.nextByte(det); + if (firstByte < 0) { + // Ran off the end of the input data + it.done = true; + break buildChar; + } + if (firstByte <= 0x8d) { + // single byte char + break buildChar; + } + + secondByte = it.nextByte(det); + it.charValue = (it.charValue << 8) | secondByte; + + if (firstByte >= 0xA1 && firstByte <= 0xfe) { + // Two byte Char + if (secondByte < 0xa1) { + it.error = true; + } + break buildChar; + } + if (firstByte == 0x8e) { + // Code Set 2. + // In EUC-JP, total char size is 2 bytes, only one byte of actual char value. + // In EUC-TW, total char size is 4 bytes, three bytes contribute to char value. + // We don't know which we've got. + // Treat it like EUC-JP. If the data really was EUC-TW, the following two + // bytes will look like a well formed 2 byte char. + if (secondByte < 0xa1) { + it.error = true; + } + break buildChar; + } + + if (firstByte == 0x8f) { + // Code set 3. + // Three byte total char size, two bytes of actual char value. + thirdByte = it.nextByte(det); + it.charValue = (it.charValue << 8) | thirdByte; + if (thirdByte < 0xa1) { + it.error = true; + } + } + } + + return (it.done == false); + } + + /** + * The charset recognize for EUC-JP. A singleton instance of this class + * is created and kept by the public CharsetDetector class + */ + static class CharsetRecog_euc_jp extends CharsetRecog_euc { + static int [] commonChars = + // TODO: This set of data comes from the character frequency- + // of-occurence analysis tool. The data needs to be moved + // into a resource and loaded from there. + {0xa1a1, 0xa1a2, 0xa1a3, 0xa1a6, 0xa1bc, 0xa1ca, 0xa1cb, 0xa1d6, 0xa1d7, 0xa4a2, + 0xa4a4, 0xa4a6, 0xa4a8, 0xa4aa, 0xa4ab, 0xa4ac, 0xa4ad, 0xa4af, 0xa4b1, 0xa4b3, + 0xa4b5, 0xa4b7, 0xa4b9, 0xa4bb, 0xa4bd, 0xa4bf, 0xa4c0, 0xa4c1, 0xa4c3, 0xa4c4, + 0xa4c6, 0xa4c7, 0xa4c8, 0xa4c9, 0xa4ca, 0xa4cb, 0xa4ce, 0xa4cf, 0xa4d0, 0xa4de, + 0xa4df, 0xa4e1, 0xa4e2, 0xa4e4, 0xa4e8, 0xa4e9, 0xa4ea, 0xa4eb, 0xa4ec, 0xa4ef, + 0xa4f2, 0xa4f3, 0xa5a2, 0xa5a3, 0xa5a4, 0xa5a6, 0xa5a7, 0xa5aa, 0xa5ad, 0xa5af, + 0xa5b0, 0xa5b3, 0xa5b5, 0xa5b7, 0xa5b8, 0xa5b9, 0xa5bf, 0xa5c3, 0xa5c6, 0xa5c7, + 0xa5c8, 0xa5c9, 0xa5cb, 0xa5d0, 0xa5d5, 0xa5d6, 0xa5d7, 0xa5de, 0xa5e0, 0xa5e1, + 0xa5e5, 0xa5e9, 0xa5ea, 0xa5eb, 0xa5ec, 0xa5ed, 0xa5f3, 0xb8a9, 0xb9d4, 0xbaee, + 0xbbc8, 0xbef0, 0xbfb7, 0xc4ea, 0xc6fc, 0xc7bd, 0xcab8, 0xcaf3, 0xcbdc, 0xcdd1}; + String getName() { + return "EUC-JP"; + } + + int match(CharsetDetector det) { + return match(det, commonChars); + } + + public String getLanguage() + { + return "ja"; + } + } + + /** + * The charset recognize for EUC-KR. A singleton instance of this class + * is created and kept by the public CharsetDetector class + */ + static class CharsetRecog_euc_kr extends CharsetRecog_euc { + static int [] commonChars = + // TODO: This set of data comes from the character frequency- + // of-occurence analysis tool. The data needs to be moved + // into a resource and loaded from there. + {0xb0a1, 0xb0b3, 0xb0c5, 0xb0cd, 0xb0d4, 0xb0e6, 0xb0ed, 0xb0f8, 0xb0fa, 0xb0fc, + 0xb1b8, 0xb1b9, 0xb1c7, 0xb1d7, 0xb1e2, 0xb3aa, 0xb3bb, 0xb4c2, 0xb4cf, 0xb4d9, + 0xb4eb, 0xb5a5, 0xb5b5, 0xb5bf, 0xb5c7, 0xb5e9, 0xb6f3, 0xb7af, 0xb7c2, 0xb7ce, + 0xb8a6, 0xb8ae, 0xb8b6, 0xb8b8, 0xb8bb, 0xb8e9, 0xb9ab, 0xb9ae, 0xb9cc, 0xb9ce, + 0xb9fd, 0xbab8, 0xbace, 0xbad0, 0xbaf1, 0xbbe7, 0xbbf3, 0xbbfd, 0xbcad, 0xbcba, + 0xbcd2, 0xbcf6, 0xbdba, 0xbdc0, 0xbdc3, 0xbdc5, 0xbec6, 0xbec8, 0xbedf, 0xbeee, + 0xbef8, 0xbefa, 0xbfa1, 0xbfa9, 0xbfc0, 0xbfe4, 0xbfeb, 0xbfec, 0xbff8, 0xc0a7, + 0xc0af, 0xc0b8, 0xc0ba, 0xc0bb, 0xc0bd, 0xc0c7, 0xc0cc, 0xc0ce, 0xc0cf, 0xc0d6, + 0xc0da, 0xc0e5, 0xc0fb, 0xc0fc, 0xc1a4, 0xc1a6, 0xc1b6, 0xc1d6, 0xc1df, 0xc1f6, + 0xc1f8, 0xc4a1, 0xc5cd, 0xc6ae, 0xc7cf, 0xc7d1, 0xc7d2, 0xc7d8, 0xc7e5, 0xc8ad}; + + String getName() { + return "EUC-KR"; + } + + int match(CharsetDetector det) { + return match(det, commonChars); + } + + public String getLanguage() + { + return "ko"; + } + } + } + + /** + * + * GB-18030 recognizer. Uses simplified Chinese statistics. + * + */ + static class CharsetRecog_gb_18030 extends CharsetRecog_mbcs { + + /* + * (non-Javadoc) + * Get the next character value for EUC based encodings. + * Character "value" is simply the raw bytes that make up the character + * packed into an int. + */ + boolean nextChar(iteratedChar it, CharsetDetector det) { + it.index = it.nextIndex; + it.error = false; + int firstByte = 0; + int secondByte = 0; + int thirdByte = 0; + int fourthByte = 0; + + buildChar: { + firstByte = it.charValue = it.nextByte(det); + + if (firstByte < 0) { + // Ran off the end of the input data + it.done = true; + break buildChar; + } + + if (firstByte <= 0x80) { + // single byte char + break buildChar; + } + + secondByte = it.nextByte(det); + it.charValue = (it.charValue << 8) | secondByte; + + if (firstByte >= 0x81 && firstByte <= 0xFE) { + // Two byte Char + if ((secondByte >= 0x40 && secondByte <= 0x7E) || (secondByte >=80 && secondByte <=0xFE)) { + break buildChar; + } + + // Four byte char + if (secondByte >= 0x30 && secondByte <= 0x39) { + thirdByte = it.nextByte(det); + + if (thirdByte >= 0x81 && thirdByte <= 0xFE) { + fourthByte = it.nextByte(det); + + if (fourthByte >= 0x30 && fourthByte <= 0x39) { + it.charValue = (it.charValue << 16) | (thirdByte << 8) | fourthByte; + break buildChar; + } + } + } + + it.error = true; + break buildChar; + } + } + + return (it.done == false); + } + + static int [] commonChars = + // TODO: This set of data comes from the character frequency- + // of-occurence analysis tool. The data needs to be moved + // into a resource and loaded from there. + {0xa1a1, 0xa1a2, 0xa1a3, 0xa1a4, 0xa1b0, 0xa1b1, 0xa1f1, 0xa1f3, 0xa3a1, 0xa3ac, + 0xa3ba, 0xb1a8, 0xb1b8, 0xb1be, 0xb2bb, 0xb3c9, 0xb3f6, 0xb4f3, 0xb5bd, 0xb5c4, + 0xb5e3, 0xb6af, 0xb6d4, 0xb6e0, 0xb7a2, 0xb7a8, 0xb7bd, 0xb7d6, 0xb7dd, 0xb8b4, + 0xb8df, 0xb8f6, 0xb9ab, 0xb9c9, 0xb9d8, 0xb9fa, 0xb9fd, 0xbacd, 0xbba7, 0xbbd6, + 0xbbe1, 0xbbfa, 0xbcbc, 0xbcdb, 0xbcfe, 0xbdcc, 0xbecd, 0xbedd, 0xbfb4, 0xbfc6, + 0xbfc9, 0xc0b4, 0xc0ed, 0xc1cb, 0xc2db, 0xc3c7, 0xc4dc, 0xc4ea, 0xc5cc, 0xc6f7, + 0xc7f8, 0xc8ab, 0xc8cb, 0xc8d5, 0xc8e7, 0xc9cf, 0xc9fa, 0xcab1, 0xcab5, 0xcac7, + 0xcad0, 0xcad6, 0xcaf5, 0xcafd, 0xccec, 0xcdf8, 0xceaa, 0xcec4, 0xced2, 0xcee5, + 0xcfb5, 0xcfc2, 0xcfd6, 0xd0c2, 0xd0c5, 0xd0d0, 0xd0d4, 0xd1a7, 0xd2aa, 0xd2b2, + 0xd2b5, 0xd2bb, 0xd2d4, 0xd3c3, 0xd3d0, 0xd3fd, 0xd4c2, 0xd4da, 0xd5e2, 0xd6d0}; + + + String getName() { + return "GB18030"; + } + + int match(CharsetDetector det) { + return match(det, commonChars); + } + + public String getLanguage() + { + return "zh"; + } + } + + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_sbcs.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_sbcs.java new file mode 100644 index 00000000..1da7721c --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecog_sbcs.java @@ -0,0 +1,1061 @@ +package org.eclipse.internal.xtend.util.internal.icu; +/** +This code was taken from the com.ibm.icu library (3.6.1). We needed to copy it to have not +a dependency to this large library only the need of charset recognition. +(KTH 2007-07-30) + +The com.ibm.icu library is published under Eclipse Public License V1.0. + */ + +/* + **************************************************************************** + * Copyright (C) 2005-2006, International Business Machines Corporation and * + * others. All Rights Reserved. * + ************************************************************************** * + * + */ + +/** + * This class recognizes single-byte encodings. Because the encoding scheme is so + * simple, language statistics are used to do the matching. + * + * @internal + */ +abstract class CharsetRecog_sbcs extends CharsetRecognizer { + + /* (non-Javadoc) + * @see com.ibm.icu.text.CharsetRecognizer#getName() + */ + abstract String getName(); + + /* (non-Javadoc) + * @see com.ibm.icu.text.CharsetRecognizer#match(com.ibm.icu.text.CharsetDetector) + */ + abstract int match(CharsetDetector det); + + static class NGramParser + { + @SuppressWarnings("unused") + private static final int N_GRAM_SIZE = 3; + private static final int N_GRAM_MASK = 0xFFFFFF; + + private int byteIndex = 0; + private int ngram = 0; + + private int[] ngramList; + private byte[] byteMap; + + private int ngramCount; + private int hitCount; + + public NGramParser(int[] theNgramList, byte[] theByteMap) + { + ngramList = theNgramList; + byteMap = theByteMap; + + ngram = 0; + + ngramCount = hitCount = 0; + } + + /* + * Binary search for value in table, which must have exactly 64 entries. + */ + private static int search(int[] table, int value) + { + int index = 0; + + if (table[index + 32] <= value) { + index += 32; + } + + if (table[index + 16] <= value) { + index += 16; + } + + if (table[index + 8] <= value) { + index += 8; + } + + if (table[index + 4] <= value) { + index += 4; + } + + if (table[index + 2] <= value) { + index += 2; + } + + if (table[index + 1] <= value) { + index += 1; + } + + if (table[index] > value) { + index -= 1; + } + + if (index < 0 || table[index] != value) { + return -1; + } + + return index; + } + + private void lookup(int thisNgram) + { + ngramCount += 1; + + if (search(ngramList, thisNgram) >= 0) { + hitCount += 1; + } + + } + + private void addByte(int b) + { + ngram = ((ngram << 8) + (b & 0xFF)) & N_GRAM_MASK; + lookup(ngram); + } + + private int nextByte(CharsetDetector det) + { + if (byteIndex >= det.fInputLen) { + return -1; + } + + return det.fInputBytes[byteIndex++] & 0xFF; + } + + public int parse(CharsetDetector det) + { + int b; + boolean ignoreSpace = false; + + while ((b = nextByte(det)) >= 0) { + byte mb = byteMap[b]; + + // TODO: 0x20 might not be a space in all character sets... + if (mb != 0) { + if (!(mb == 0x20 && ignoreSpace)) { + addByte(mb); + } + + ignoreSpace = (mb == 0x20); + } + } + + // TODO: Is this OK? The buffer could have ended in the middle of a word... + addByte(0x20); + + double rawPercent = (double) hitCount / (double) ngramCount; + +// if (rawPercent <= 2.0) { +// return 0; +// } + + // TODO - This is a bit of a hack to take care of a case + // were we were getting a confidence of 135... + if (rawPercent > 0.33) { + return 98; + } + + return (int) (rawPercent * 300.0); + } + } + + protected boolean haveC1Bytes = false; + + int match(CharsetDetector det, int[] ngrams, byte[] byteMap) + { + NGramParser parser = new NGramParser(ngrams, byteMap); + + haveC1Bytes = det.fC1Bytes; + + return parser.parse(det); + } + + abstract static class CharsetRecog_8859_1 extends CharsetRecog_sbcs + { + protected static byte[] byteMap = { + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x00, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0xAA, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0xB5, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0xBA, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0xF0, (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0x20, + (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB, (byte) 0xFC, (byte) 0xFD, (byte) 0xFE, (byte) 0xDF, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0xF0, (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0x20, + (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB, (byte) 0xFC, (byte) 0xFD, (byte) 0xFE, (byte) 0xFF, + }; + + public String getName() + { + return haveC1Bytes? "windows-1252" : "ISO-8859-1"; + } + } + + static class CharsetRecog_8859_1_da extends CharsetRecog_8859_1 + { + private static int[] ngrams = { + 0x206166, 0x206174, 0x206465, 0x20656E, 0x206572, 0x20666F, 0x206861, 0x206920, 0x206D65, 0x206F67, 0x2070E5, 0x207369, 0x207374, 0x207469, 0x207669, 0x616620, + 0x616E20, 0x616E64, 0x617220, 0x617420, 0x646520, 0x64656E, 0x646572, 0x646574, 0x652073, 0x656420, 0x656465, 0x656E20, 0x656E64, 0x657220, 0x657265, 0x657320, + 0x657420, 0x666F72, 0x676520, 0x67656E, 0x676572, 0x696765, 0x696C20, 0x696E67, 0x6B6520, 0x6B6B65, 0x6C6572, 0x6C6967, 0x6C6C65, 0x6D6564, 0x6E6465, 0x6E6520, + 0x6E6720, 0x6E6765, 0x6F6720, 0x6F6D20, 0x6F7220, 0x70E520, 0x722064, 0x722065, 0x722073, 0x726520, 0x737465, 0x742073, 0x746520, 0x746572, 0x74696C, 0x766572, + }; + + public String getLanguage() + { + return "da"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_8859_1_de extends CharsetRecog_8859_1 + { + private static int[] ngrams = { + 0x20616E, 0x206175, 0x206265, 0x206461, 0x206465, 0x206469, 0x206569, 0x206765, 0x206861, 0x20696E, 0x206D69, 0x207363, 0x207365, 0x20756E, 0x207665, 0x20766F, + 0x207765, 0x207A75, 0x626572, 0x636820, 0x636865, 0x636874, 0x646173, 0x64656E, 0x646572, 0x646965, 0x652064, 0x652073, 0x65696E, 0x656974, 0x656E20, 0x657220, + 0x657320, 0x67656E, 0x68656E, 0x687420, 0x696368, 0x696520, 0x696E20, 0x696E65, 0x697420, 0x6C6963, 0x6C6C65, 0x6E2061, 0x6E2064, 0x6E2073, 0x6E6420, 0x6E6465, + 0x6E6520, 0x6E6720, 0x6E6765, 0x6E7465, 0x722064, 0x726465, 0x726569, 0x736368, 0x737465, 0x742064, 0x746520, 0x74656E, 0x746572, 0x756E64, 0x756E67, 0x766572, + }; + + public String getLanguage() + { + return "de"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_8859_1_en extends CharsetRecog_8859_1 + { + private static int[] ngrams = { + 0x206120, 0x20616E, 0x206265, 0x20636F, 0x20666F, 0x206861, 0x206865, 0x20696E, 0x206D61, 0x206F66, 0x207072, 0x207265, 0x207361, 0x207374, 0x207468, 0x20746F, + 0x207768, 0x616964, 0x616C20, 0x616E20, 0x616E64, 0x617320, 0x617420, 0x617465, 0x617469, 0x642061, 0x642074, 0x652061, 0x652073, 0x652074, 0x656420, 0x656E74, + 0x657220, 0x657320, 0x666F72, 0x686174, 0x686520, 0x686572, 0x696420, 0x696E20, 0x696E67, 0x696F6E, 0x697320, 0x6E2061, 0x6E2074, 0x6E6420, 0x6E6720, 0x6E7420, + 0x6F6620, 0x6F6E20, 0x6F7220, 0x726520, 0x727320, 0x732061, 0x732074, 0x736169, 0x737420, 0x742074, 0x746572, 0x746861, 0x746865, 0x74696F, 0x746F20, 0x747320, + }; + + public String getLanguage() + { + return "en"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_8859_1_es extends CharsetRecog_8859_1 + { + private static int[] ngrams = { + 0x206120, 0x206361, 0x20636F, 0x206465, 0x20656C, 0x20656E, 0x206573, 0x20696E, 0x206C61, 0x206C6F, 0x207061, 0x20706F, 0x207072, 0x207175, 0x207265, 0x207365, + 0x20756E, 0x207920, 0x612063, 0x612064, 0x612065, 0x61206C, 0x612070, 0x616369, 0x61646F, 0x616C20, 0x617220, 0x617320, 0x6369F3, 0x636F6E, 0x646520, 0x64656C, + 0x646F20, 0x652064, 0x652065, 0x65206C, 0x656C20, 0x656E20, 0x656E74, 0x657320, 0x657374, 0x69656E, 0x69F36E, 0x6C6120, 0x6C6F73, 0x6E2065, 0x6E7465, 0x6F2064, + 0x6F2065, 0x6F6E20, 0x6F7220, 0x6F7320, 0x706172, 0x717565, 0x726120, 0x726573, 0x732064, 0x732065, 0x732070, 0x736520, 0x746520, 0x746F20, 0x756520, 0xF36E20, + }; + + public String getLanguage() + { + return "es"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_8859_1_fr extends CharsetRecog_8859_1 + { + private static int[] ngrams = { + 0x206175, 0x20636F, 0x206461, 0x206465, 0x206475, 0x20656E, 0x206574, 0x206C61, 0x206C65, 0x207061, 0x20706F, 0x207072, 0x207175, 0x207365, 0x20736F, 0x20756E, + 0x20E020, 0x616E74, 0x617469, 0x636520, 0x636F6E, 0x646520, 0x646573, 0x647520, 0x652061, 0x652063, 0x652064, 0x652065, 0x65206C, 0x652070, 0x652073, 0x656E20, + 0x656E74, 0x657220, 0x657320, 0x657420, 0x657572, 0x696F6E, 0x697320, 0x697420, 0x6C6120, 0x6C6520, 0x6C6573, 0x6D656E, 0x6E2064, 0x6E6520, 0x6E7320, 0x6E7420, + 0x6F6E20, 0x6F6E74, 0x6F7572, 0x717565, 0x72206C, 0x726520, 0x732061, 0x732064, 0x732065, 0x73206C, 0x732070, 0x742064, 0x746520, 0x74696F, 0x756520, 0x757220, + }; + + public String getLanguage() + { + return "fr"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_8859_1_it extends CharsetRecog_8859_1 + { + private static int[] ngrams = { + 0x20616C, 0x206368, 0x20636F, 0x206465, 0x206469, 0x206520, 0x20696C, 0x20696E, 0x206C61, 0x207065, 0x207072, 0x20756E, 0x612063, 0x612064, 0x612070, 0x612073, + 0x61746F, 0x636865, 0x636F6E, 0x64656C, 0x646920, 0x652061, 0x652063, 0x652064, 0x652069, 0x65206C, 0x652070, 0x652073, 0x656C20, 0x656C6C, 0x656E74, 0x657220, + 0x686520, 0x692061, 0x692063, 0x692064, 0x692073, 0x696120, 0x696C20, 0x696E20, 0x696F6E, 0x6C6120, 0x6C6520, 0x6C6920, 0x6C6C61, 0x6E6520, 0x6E6920, 0x6E6F20, + 0x6E7465, 0x6F2061, 0x6F2064, 0x6F2069, 0x6F2073, 0x6F6E20, 0x6F6E65, 0x706572, 0x726120, 0x726520, 0x736920, 0x746120, 0x746520, 0x746920, 0x746F20, 0x7A696F, + }; + + public String getLanguage() + { + return "it"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_8859_1_nl extends CharsetRecog_8859_1 + { + private static int[] ngrams = { + 0x20616C, 0x206265, 0x206461, 0x206465, 0x206469, 0x206565, 0x20656E, 0x206765, 0x206865, 0x20696E, 0x206D61, 0x206D65, 0x206F70, 0x207465, 0x207661, 0x207665, + 0x20766F, 0x207765, 0x207A69, 0x61616E, 0x616172, 0x616E20, 0x616E64, 0x617220, 0x617420, 0x636874, 0x646520, 0x64656E, 0x646572, 0x652062, 0x652076, 0x65656E, + 0x656572, 0x656E20, 0x657220, 0x657273, 0x657420, 0x67656E, 0x686574, 0x696520, 0x696E20, 0x696E67, 0x697320, 0x6E2062, 0x6E2064, 0x6E2065, 0x6E2068, 0x6E206F, + 0x6E2076, 0x6E6465, 0x6E6720, 0x6F6E64, 0x6F6F72, 0x6F7020, 0x6F7220, 0x736368, 0x737465, 0x742064, 0x746520, 0x74656E, 0x746572, 0x76616E, 0x766572, 0x766F6F, + }; + + public String getLanguage() + { + return "nl"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_8859_1_no extends CharsetRecog_8859_1 + { + private static int[] ngrams = { + 0x206174, 0x206176, 0x206465, 0x20656E, 0x206572, 0x20666F, 0x206861, 0x206920, 0x206D65, 0x206F67, 0x2070E5, 0x207365, 0x20736B, 0x20736F, 0x207374, 0x207469, + 0x207669, 0x20E520, 0x616E64, 0x617220, 0x617420, 0x646520, 0x64656E, 0x646574, 0x652073, 0x656420, 0x656E20, 0x656E65, 0x657220, 0x657265, 0x657420, 0x657474, + 0x666F72, 0x67656E, 0x696B6B, 0x696C20, 0x696E67, 0x6B6520, 0x6B6B65, 0x6C6520, 0x6C6C65, 0x6D6564, 0x6D656E, 0x6E2073, 0x6E6520, 0x6E6720, 0x6E6765, 0x6E6E65, + 0x6F6720, 0x6F6D20, 0x6F7220, 0x70E520, 0x722073, 0x726520, 0x736F6D, 0x737465, 0x742073, 0x746520, 0x74656E, 0x746572, 0x74696C, 0x747420, 0x747465, 0x766572, + }; + + public String getLanguage() + { + return "no"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_8859_1_pt extends CharsetRecog_8859_1 + { + private static int[] ngrams = { + 0x206120, 0x20636F, 0x206461, 0x206465, 0x20646F, 0x206520, 0x206573, 0x206D61, 0x206E6F, 0x206F20, 0x207061, 0x20706F, 0x207072, 0x207175, 0x207265, 0x207365, + 0x20756D, 0x612061, 0x612063, 0x612064, 0x612070, 0x616465, 0x61646F, 0x616C20, 0x617220, 0x617261, 0x617320, 0x636F6D, 0x636F6E, 0x646120, 0x646520, 0x646F20, + 0x646F73, 0x652061, 0x652064, 0x656D20, 0x656E74, 0x657320, 0x657374, 0x696120, 0x696361, 0x6D656E, 0x6E7465, 0x6E746F, 0x6F2061, 0x6F2063, 0x6F2064, 0x6F2065, + 0x6F2070, 0x6F7320, 0x706172, 0x717565, 0x726120, 0x726573, 0x732061, 0x732064, 0x732065, 0x732070, 0x737461, 0x746520, 0x746F20, 0x756520, 0xE36F20, 0xE7E36F, + }; + + public String getLanguage() + { + return "pt"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_8859_1_sv extends CharsetRecog_8859_1 + { + private static int[] ngrams = { + 0x206174, 0x206176, 0x206465, 0x20656E, 0x2066F6, 0x206861, 0x206920, 0x20696E, 0x206B6F, 0x206D65, 0x206F63, 0x2070E5, 0x20736B, 0x20736F, 0x207374, 0x207469, + 0x207661, 0x207669, 0x20E472, 0x616465, 0x616E20, 0x616E64, 0x617220, 0x617474, 0x636820, 0x646520, 0x64656E, 0x646572, 0x646574, 0x656420, 0x656E20, 0x657220, + 0x657420, 0x66F672, 0x67656E, 0x696C6C, 0x696E67, 0x6B6120, 0x6C6C20, 0x6D6564, 0x6E2073, 0x6E6120, 0x6E6465, 0x6E6720, 0x6E6765, 0x6E696E, 0x6F6368, 0x6F6D20, + 0x6F6E20, 0x70E520, 0x722061, 0x722073, 0x726120, 0x736B61, 0x736F6D, 0x742073, 0x746120, 0x746520, 0x746572, 0x74696C, 0x747420, 0x766172, 0xE47220, 0xF67220, + }; + + public String getLanguage() + { + return "sv"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + abstract static class CharsetRecog_8859_2 extends CharsetRecog_sbcs + { + protected static byte[] byteMap = { + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x00, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0xB1, (byte) 0x20, (byte) 0xB3, (byte) 0x20, (byte) 0xB5, (byte) 0xB6, (byte) 0x20, + (byte) 0x20, (byte) 0xB9, (byte) 0xBA, (byte) 0xBB, (byte) 0xBC, (byte) 0x20, (byte) 0xBE, (byte) 0xBF, + (byte) 0x20, (byte) 0xB1, (byte) 0x20, (byte) 0xB3, (byte) 0x20, (byte) 0xB5, (byte) 0xB6, (byte) 0xB7, + (byte) 0x20, (byte) 0xB9, (byte) 0xBA, (byte) 0xBB, (byte) 0xBC, (byte) 0x20, (byte) 0xBE, (byte) 0xBF, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0xF0, (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0x20, + (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB, (byte) 0xFC, (byte) 0xFD, (byte) 0xFE, (byte) 0xDF, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0xF0, (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0x20, + (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB, (byte) 0xFC, (byte) 0xFD, (byte) 0xFE, (byte) 0x20, + }; + + public String getName() + { + return haveC1Bytes? "windows-1250" : "ISO-8859-2"; + } + } + + static class CharsetRecog_8859_2_cs extends CharsetRecog_8859_2 + { + private static int[] ngrams = { + 0x206120, 0x206279, 0x20646F, 0x206A65, 0x206E61, 0x206E65, 0x206F20, 0x206F64, 0x20706F, 0x207072, 0x2070F8, 0x20726F, 0x207365, 0x20736F, 0x207374, 0x20746F, + 0x207620, 0x207679, 0x207A61, 0x612070, 0x636520, 0x636820, 0x652070, 0x652073, 0x652076, 0x656D20, 0x656EED, 0x686F20, 0x686F64, 0x697374, 0x6A6520, 0x6B7465, + 0x6C6520, 0x6C6920, 0x6E6120, 0x6EE920, 0x6EEC20, 0x6EED20, 0x6F2070, 0x6F646E, 0x6F6A69, 0x6F7374, 0x6F7520, 0x6F7661, 0x706F64, 0x706F6A, 0x70726F, 0x70F865, + 0x736520, 0x736F75, 0x737461, 0x737469, 0x73746E, 0x746572, 0x746EED, 0x746F20, 0x752070, 0xBE6520, 0xE16EED, 0xE9686F, 0xED2070, 0xED2073, 0xED6D20, 0xF86564, + }; + + public String getLanguage() + { + return "cs"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_8859_2_hu extends CharsetRecog_8859_2 + { + private static int[] ngrams = { + 0x206120, 0x20617A, 0x206265, 0x206567, 0x20656C, 0x206665, 0x206861, 0x20686F, 0x206973, 0x206B65, 0x206B69, 0x206BF6, 0x206C65, 0x206D61, 0x206D65, 0x206D69, + 0x206E65, 0x20737A, 0x207465, 0x20E973, 0x612061, 0x61206B, 0x61206D, 0x612073, 0x616B20, 0x616E20, 0x617A20, 0x62616E, 0x62656E, 0x656779, 0x656B20, 0x656C20, + 0x656C65, 0x656D20, 0x656E20, 0x657265, 0x657420, 0x657465, 0x657474, 0x677920, 0x686F67, 0x696E74, 0x697320, 0x6B2061, 0x6BF67A, 0x6D6567, 0x6D696E, 0x6E2061, + 0x6E616B, 0x6E656B, 0x6E656D, 0x6E7420, 0x6F6779, 0x732061, 0x737A65, 0x737A74, 0x737AE1, 0x73E967, 0x742061, 0x747420, 0x74E173, 0x7A6572, 0xE16E20, 0xE97320, + }; + + public String getLanguage() + { + return "hu"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_8859_2_pl extends CharsetRecog_8859_2 + { + private static int[] ngrams = { + 0x20637A, 0x20646F, 0x206920, 0x206A65, 0x206B6F, 0x206D61, 0x206D69, 0x206E61, 0x206E69, 0x206F64, 0x20706F, 0x207072, 0x207369, 0x207720, 0x207769, 0x207779, + 0x207A20, 0x207A61, 0x612070, 0x612077, 0x616E69, 0x636820, 0x637A65, 0x637A79, 0x646F20, 0x647A69, 0x652070, 0x652073, 0x652077, 0x65207A, 0x65676F, 0x656A20, + 0x656D20, 0x656E69, 0x676F20, 0x696120, 0x696520, 0x69656A, 0x6B6120, 0x6B6920, 0x6B6965, 0x6D6965, 0x6E6120, 0x6E6961, 0x6E6965, 0x6F2070, 0x6F7761, 0x6F7769, + 0x706F6C, 0x707261, 0x70726F, 0x70727A, 0x727A65, 0x727A79, 0x7369EA, 0x736B69, 0x737461, 0x776965, 0x796368, 0x796D20, 0x7A6520, 0x7A6965, 0x7A7920, 0xF37720, + }; + + public String getLanguage() + { + return "pl"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_8859_2_ro extends CharsetRecog_8859_2 + { + private static int[] ngrams = { + 0x206120, 0x206163, 0x206361, 0x206365, 0x20636F, 0x206375, 0x206465, 0x206469, 0x206C61, 0x206D61, 0x207065, 0x207072, 0x207365, 0x2073E3, 0x20756E, 0x20BA69, + 0x20EE6E, 0x612063, 0x612064, 0x617265, 0x617420, 0x617465, 0x617520, 0x636172, 0x636F6E, 0x637520, 0x63E320, 0x646520, 0x652061, 0x652063, 0x652064, 0x652070, + 0x652073, 0x656120, 0x656920, 0x656C65, 0x656E74, 0x657374, 0x692061, 0x692063, 0x692064, 0x692070, 0x696520, 0x696920, 0x696E20, 0x6C6120, 0x6C6520, 0x6C6F72, + 0x6C7569, 0x6E6520, 0x6E7472, 0x6F7220, 0x70656E, 0x726520, 0x726561, 0x727520, 0x73E320, 0x746520, 0x747275, 0x74E320, 0x756920, 0x756C20, 0xBA6920, 0xEE6E20, + }; + + public String getLanguage() + { + return "ro"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + abstract static class CharsetRecog_8859_5 extends CharsetRecog_sbcs + { + protected static byte[] byteMap = { + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x00, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, + (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB, (byte) 0xFC, (byte) 0x20, (byte) 0xFE, (byte) 0xFF, + (byte) 0xD0, (byte) 0xD1, (byte) 0xD2, (byte) 0xD3, (byte) 0xD4, (byte) 0xD5, (byte) 0xD6, (byte) 0xD7, + (byte) 0xD8, (byte) 0xD9, (byte) 0xDA, (byte) 0xDB, (byte) 0xDC, (byte) 0xDD, (byte) 0xDE, (byte) 0xDF, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0xD0, (byte) 0xD1, (byte) 0xD2, (byte) 0xD3, (byte) 0xD4, (byte) 0xD5, (byte) 0xD6, (byte) 0xD7, + (byte) 0xD8, (byte) 0xD9, (byte) 0xDA, (byte) 0xDB, (byte) 0xDC, (byte) 0xDD, (byte) 0xDE, (byte) 0xDF, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0x20, (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, + (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB, (byte) 0xFC, (byte) 0x20, (byte) 0xFE, (byte) 0xFF, + }; + + public String getName() + { + return "ISO-8859-5"; + } + } + + static class CharsetRecog_8859_5_ru extends CharsetRecog_8859_5 + { + private static int[] ngrams = { + 0x20D220, 0x20D2DE, 0x20D4DE, 0x20D7D0, 0x20D820, 0x20DAD0, 0x20DADE, 0x20DDD0, 0x20DDD5, 0x20DED1, 0x20DFDE, 0x20DFE0, 0x20E0D0, 0x20E1DE, 0x20E1E2, 0x20E2DE, + 0x20E7E2, 0x20EDE2, 0xD0DDD8, 0xD0E2EC, 0xD3DE20, 0xD5DBEC, 0xD5DDD8, 0xD5E1E2, 0xD5E220, 0xD820DF, 0xD8D520, 0xD8D820, 0xD8EF20, 0xDBD5DD, 0xDBD820, 0xDBECDD, + 0xDDD020, 0xDDD520, 0xDDD8D5, 0xDDD8EF, 0xDDDE20, 0xDDDED2, 0xDE20D2, 0xDE20DF, 0xDE20E1, 0xDED220, 0xDED2D0, 0xDED3DE, 0xDED920, 0xDEDBEC, 0xDEDC20, 0xDEE1E2, + 0xDFDEDB, 0xDFE0D5, 0xDFE0D8, 0xDFE0DE, 0xE0D0D2, 0xE0D5D4, 0xE1E2D0, 0xE1E2D2, 0xE1E2D8, 0xE1EF20, 0xE2D5DB, 0xE2DE20, 0xE2DEE0, 0xE2EC20, 0xE7E2DE, 0xEBE520, + }; + + public String getLanguage() + { + return "ru"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + abstract static class CharsetRecog_8859_6 extends CharsetRecog_sbcs + { + protected static byte[] byteMap = { + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x00, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0xC1, (byte) 0xC2, (byte) 0xC3, (byte) 0xC4, (byte) 0xC5, (byte) 0xC6, (byte) 0xC7, + (byte) 0xC8, (byte) 0xC9, (byte) 0xCA, (byte) 0xCB, (byte) 0xCC, (byte) 0xCD, (byte) 0xCE, (byte) 0xCF, + (byte) 0xD0, (byte) 0xD1, (byte) 0xD2, (byte) 0xD3, (byte) 0xD4, (byte) 0xD5, (byte) 0xD6, (byte) 0xD7, + (byte) 0xD8, (byte) 0xD9, (byte) 0xDA, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + }; + + public String getName() + { + return "ISO-8859-6"; + } + } + + static class CharsetRecog_8859_6_ar extends CharsetRecog_8859_6 + { + private static int[] ngrams = { + 0x20C7E4, 0x20C7E6, 0x20C8C7, 0x20D9E4, 0x20E1EA, 0x20E4E4, 0x20E5E6, 0x20E8C7, 0xC720C7, 0xC7C120, 0xC7CA20, 0xC7D120, 0xC7E420, 0xC7E4C3, 0xC7E4C7, 0xC7E4C8, + 0xC7E4CA, 0xC7E4CC, 0xC7E4CD, 0xC7E4CF, 0xC7E4D3, 0xC7E4D9, 0xC7E4E2, 0xC7E4E5, 0xC7E4E8, 0xC7E4EA, 0xC7E520, 0xC7E620, 0xC7E6CA, 0xC820C7, 0xC920C7, 0xC920E1, + 0xC920E4, 0xC920E5, 0xC920E8, 0xCA20C7, 0xCF20C7, 0xCFC920, 0xD120C7, 0xD1C920, 0xD320C7, 0xD920C7, 0xD9E4E9, 0xE1EA20, 0xE420C7, 0xE4C920, 0xE4E920, 0xE4EA20, + 0xE520C7, 0xE5C720, 0xE5C920, 0xE5E620, 0xE620C7, 0xE720C7, 0xE7C720, 0xE8C7E4, 0xE8E620, 0xE920C7, 0xEA20C7, 0xEA20E5, 0xEA20E8, 0xEAC920, 0xEAD120, 0xEAE620, + }; + + public String getLanguage() + { + return "ar"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + abstract static class CharsetRecog_8859_7 extends CharsetRecog_sbcs + { + protected static byte[] byteMap = { + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x00, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0xA1, (byte) 0xA2, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0xDC, (byte) 0x20, + (byte) 0xDD, (byte) 0xDE, (byte) 0xDF, (byte) 0x20, (byte) 0xFC, (byte) 0x20, (byte) 0xFD, (byte) 0xFE, + (byte) 0xC0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0xF0, (byte) 0xF1, (byte) 0x20, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, + (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB, (byte) 0xDC, (byte) 0xDD, (byte) 0xDE, (byte) 0xDF, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0xF0, (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, + (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB, (byte) 0xFC, (byte) 0xFD, (byte) 0xFE, (byte) 0x20, + }; + + public String getName() + { + return haveC1Bytes? "windows-1253" : "ISO-8859-7"; + } + } + + static class CharsetRecog_8859_7_el extends CharsetRecog_8859_7 + { + private static int[] ngrams = { + 0x20E1ED, 0x20E1F0, 0x20E3E9, 0x20E4E9, 0x20E5F0, 0x20E720, 0x20EAE1, 0x20ECE5, 0x20EDE1, 0x20EF20, 0x20F0E1, 0x20F0EF, 0x20F0F1, 0x20F3F4, 0x20F3F5, 0x20F4E7, + 0x20F4EF, 0xDFE120, 0xE120E1, 0xE120F4, 0xE1E920, 0xE1ED20, 0xE1F0FC, 0xE1F220, 0xE3E9E1, 0xE5E920, 0xE5F220, 0xE720F4, 0xE7ED20, 0xE7F220, 0xE920F4, 0xE9E120, + 0xE9EADE, 0xE9F220, 0xEAE1E9, 0xEAE1F4, 0xECE520, 0xED20E1, 0xED20E5, 0xED20F0, 0xEDE120, 0xEFF220, 0xEFF520, 0xF0EFF5, 0xF0F1EF, 0xF0FC20, 0xF220E1, 0xF220E5, + 0xF220EA, 0xF220F0, 0xF220F4, 0xF3E520, 0xF3E720, 0xF3F4EF, 0xF4E120, 0xF4E1E9, 0xF4E7ED, 0xF4E7F2, 0xF4E9EA, 0xF4EF20, 0xF4EFF5, 0xF4F9ED, 0xF9ED20, 0xFEED20, + }; + + public String getLanguage() + { + return "el"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + abstract static class CharsetRecog_8859_8 extends CharsetRecog_sbcs + { + protected static byte[] byteMap = { + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x00, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0xB5, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0xF0, (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, + (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + }; + + public String getName() + { + return haveC1Bytes? "windows-1255" : "ISO-8859-8"; + } + } + + static class CharsetRecog_8859_8_I_he extends CharsetRecog_8859_8 + { + private static int[] ngrams = { + 0x20E0E5, 0x20E0E7, 0x20E0E9, 0x20E0FA, 0x20E1E9, 0x20E1EE, 0x20E4E0, 0x20E4E5, 0x20E4E9, 0x20E4EE, 0x20E4F2, 0x20E4F9, 0x20E4FA, 0x20ECE0, 0x20ECE4, 0x20EEE0, + 0x20F2EC, 0x20F9EC, 0xE0FA20, 0xE420E0, 0xE420E1, 0xE420E4, 0xE420EC, 0xE420EE, 0xE420F9, 0xE4E5E0, 0xE5E020, 0xE5ED20, 0xE5EF20, 0xE5F820, 0xE5FA20, 0xE920E4, + 0xE9E420, 0xE9E5FA, 0xE9E9ED, 0xE9ED20, 0xE9EF20, 0xE9F820, 0xE9FA20, 0xEC20E0, 0xEC20E4, 0xECE020, 0xECE420, 0xED20E0, 0xED20E1, 0xED20E4, 0xED20EC, 0xED20EE, + 0xED20F9, 0xEEE420, 0xEF20E4, 0xF0E420, 0xF0E920, 0xF0E9ED, 0xF2EC20, 0xF820E4, 0xF8E9ED, 0xF9EC20, 0xFA20E0, 0xFA20E1, 0xFA20E4, 0xFA20EC, 0xFA20EE, 0xFA20F9, + }; + + public String getName() + { + return haveC1Bytes? "windows-1255" : /*"ISO-8859-8-I"*/ "ISO-8859-8"; + } + + public String getLanguage() + { + return "he"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_8859_8_he extends CharsetRecog_8859_8 + { + private static int[] ngrams = { + 0x20E0E5, 0x20E0EC, 0x20E4E9, 0x20E4EC, 0x20E4EE, 0x20E4F0, 0x20E9F0, 0x20ECF2, 0x20ECF9, 0x20EDE5, 0x20EDE9, 0x20EFE5, 0x20EFE9, 0x20F8E5, 0x20F8E9, 0x20FAE0, + 0x20FAE5, 0x20FAE9, 0xE020E4, 0xE020EC, 0xE020ED, 0xE020FA, 0xE0E420, 0xE0E5E4, 0xE0EC20, 0xE0EE20, 0xE120E4, 0xE120ED, 0xE120FA, 0xE420E4, 0xE420E9, 0xE420EC, + 0xE420ED, 0xE420EF, 0xE420F8, 0xE420FA, 0xE4EC20, 0xE5E020, 0xE5E420, 0xE7E020, 0xE9E020, 0xE9E120, 0xE9E420, 0xEC20E4, 0xEC20ED, 0xEC20FA, 0xECF220, 0xECF920, + 0xEDE9E9, 0xEDE9F0, 0xEDE9F8, 0xEE20E4, 0xEE20ED, 0xEE20FA, 0xEEE120, 0xEEE420, 0xF2E420, 0xF920E4, 0xF920ED, 0xF920FA, 0xF9E420, 0xFAE020, 0xFAE420, 0xFAE5E9, + }; + + public String getLanguage() + { + return "he"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + abstract static class CharsetRecog_8859_9 extends CharsetRecog_sbcs + { + protected static byte[] byteMap = { + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x00, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0xAA, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0xB5, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0xBA, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0xF0, (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0x20, + (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB, (byte) 0xFC, (byte) 0x69, (byte) 0xFE, (byte) 0xDF, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0xF0, (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0x20, + (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB, (byte) 0xFC, (byte) 0xFD, (byte) 0xFE, (byte) 0xFF, + }; + + public String getName() + { + return haveC1Bytes? "windows-1254" : "ISO-8859-9"; + } + } + + static class CharsetRecog_8859_9_tr extends CharsetRecog_8859_9 + { + private static int[] ngrams = { + 0x206261, 0x206269, 0x206275, 0x206461, 0x206465, 0x206765, 0x206861, 0x20696C, 0x206B61, 0x206B6F, 0x206D61, 0x206F6C, 0x207361, 0x207461, 0x207665, 0x207961, + 0x612062, 0x616B20, 0x616C61, 0x616D61, 0x616E20, 0x616EFD, 0x617220, 0x617261, 0x6172FD, 0x6173FD, 0x617961, 0x626972, 0x646120, 0x646520, 0x646920, 0x652062, + 0x65206B, 0x656469, 0x656E20, 0x657220, 0x657269, 0x657369, 0x696C65, 0x696E20, 0x696E69, 0x697220, 0x6C616E, 0x6C6172, 0x6C6520, 0x6C6572, 0x6E2061, 0x6E2062, + 0x6E206B, 0x6E6461, 0x6E6465, 0x6E6520, 0x6E6920, 0x6E696E, 0x6EFD20, 0x72696E, 0x72FD6E, 0x766520, 0x796120, 0x796F72, 0xFD6E20, 0xFD6E64, 0xFD6EFD, 0xFDF0FD, + }; + + public String getLanguage() + { + return "tr"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_windows_1251 extends CharsetRecog_sbcs + { + private static int[] ngrams = { + 0x20E220, 0x20E2EE, 0x20E4EE, 0x20E7E0, 0x20E820, 0x20EAE0, 0x20EAEE, 0x20EDE0, 0x20EDE5, 0x20EEE1, 0x20EFEE, 0x20EFF0, 0x20F0E0, 0x20F1EE, 0x20F1F2, 0x20F2EE, + 0x20F7F2, 0x20FDF2, 0xE0EDE8, 0xE0F2FC, 0xE3EE20, 0xE5EBFC, 0xE5EDE8, 0xE5F1F2, 0xE5F220, 0xE820EF, 0xE8E520, 0xE8E820, 0xE8FF20, 0xEBE5ED, 0xEBE820, 0xEBFCED, + 0xEDE020, 0xEDE520, 0xEDE8E5, 0xEDE8FF, 0xEDEE20, 0xEDEEE2, 0xEE20E2, 0xEE20EF, 0xEE20F1, 0xEEE220, 0xEEE2E0, 0xEEE3EE, 0xEEE920, 0xEEEBFC, 0xEEEC20, 0xEEF1F2, + 0xEFEEEB, 0xEFF0E5, 0xEFF0E8, 0xEFF0EE, 0xF0E0E2, 0xF0E5E4, 0xF1F2E0, 0xF1F2E2, 0xF1F2E8, 0xF1FF20, 0xF2E5EB, 0xF2EE20, 0xF2EEF0, 0xF2FC20, 0xF7F2EE, 0xFBF520, + }; + + private static byte[] byteMap = { + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x00, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x90, (byte) 0x83, (byte) 0x20, (byte) 0x83, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x9A, (byte) 0x20, (byte) 0x9C, (byte) 0x9D, (byte) 0x9E, (byte) 0x9F, + (byte) 0x90, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x9A, (byte) 0x20, (byte) 0x9C, (byte) 0x9D, (byte) 0x9E, (byte) 0x9F, + (byte) 0x20, (byte) 0xA2, (byte) 0xA2, (byte) 0xBC, (byte) 0x20, (byte) 0xB4, (byte) 0x20, (byte) 0x20, + (byte) 0xB8, (byte) 0x20, (byte) 0xBA, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0xBF, + (byte) 0x20, (byte) 0x20, (byte) 0xB3, (byte) 0xB3, (byte) 0xB4, (byte) 0xB5, (byte) 0x20, (byte) 0x20, + (byte) 0xB8, (byte) 0x20, (byte) 0xBA, (byte) 0x20, (byte) 0xBC, (byte) 0xBE, (byte) 0xBE, (byte) 0xBF, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0xF0, (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, + (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB, (byte) 0xFC, (byte) 0xFD, (byte) 0xFE, (byte) 0xFF, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0xF0, (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, + (byte) 0xF8, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB, (byte) 0xFC, (byte) 0xFD, (byte) 0xFE, (byte) 0xFF, + }; + + public String getName() + { + return "windows-1251"; + } + + public String getLanguage() + { + return "ru"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_windows_1256 extends CharsetRecog_sbcs + { + private static int[] ngrams = { + 0x20C7E1, 0x20C7E4, 0x20C8C7, 0x20DAE1, 0x20DDED, 0x20E1E1, 0x20E3E4, 0x20E6C7, 0xC720C7, 0xC7C120, 0xC7CA20, 0xC7D120, 0xC7E120, 0xC7E1C3, 0xC7E1C7, 0xC7E1C8, + 0xC7E1CA, 0xC7E1CC, 0xC7E1CD, 0xC7E1CF, 0xC7E1D3, 0xC7E1DA, 0xC7E1DE, 0xC7E1E3, 0xC7E1E6, 0xC7E1ED, 0xC7E320, 0xC7E420, 0xC7E4CA, 0xC820C7, 0xC920C7, 0xC920DD, + 0xC920E1, 0xC920E3, 0xC920E6, 0xCA20C7, 0xCF20C7, 0xCFC920, 0xD120C7, 0xD1C920, 0xD320C7, 0xDA20C7, 0xDAE1EC, 0xDDED20, 0xE120C7, 0xE1C920, 0xE1EC20, 0xE1ED20, + 0xE320C7, 0xE3C720, 0xE3C920, 0xE3E420, 0xE420C7, 0xE520C7, 0xE5C720, 0xE6C7E1, 0xE6E420, 0xEC20C7, 0xED20C7, 0xED20E3, 0xED20E6, 0xEDC920, 0xEDD120, 0xEDE420, + }; + + private static byte[] byteMap = { + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x00, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x81, (byte) 0x20, (byte) 0x83, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x88, (byte) 0x20, (byte) 0x8A, (byte) 0x20, (byte) 0x9C, (byte) 0x8D, (byte) 0x8E, (byte) 0x8F, + (byte) 0x90, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x98, (byte) 0x20, (byte) 0x9A, (byte) 0x20, (byte) 0x9C, (byte) 0x20, (byte) 0x20, (byte) 0x9F, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0xAA, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0xB5, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0xC0, (byte) 0xC1, (byte) 0xC2, (byte) 0xC3, (byte) 0xC4, (byte) 0xC5, (byte) 0xC6, (byte) 0xC7, + (byte) 0xC8, (byte) 0xC9, (byte) 0xCA, (byte) 0xCB, (byte) 0xCC, (byte) 0xCD, (byte) 0xCE, (byte) 0xCF, + (byte) 0xD0, (byte) 0xD1, (byte) 0xD2, (byte) 0xD3, (byte) 0xD4, (byte) 0xD5, (byte) 0xD6, (byte) 0x20, + (byte) 0xD8, (byte) 0xD9, (byte) 0xDA, (byte) 0xDB, (byte) 0xDC, (byte) 0xDD, (byte) 0xDE, (byte) 0xDF, + (byte) 0xE0, (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, + (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC, (byte) 0xED, (byte) 0xEE, (byte) 0xEF, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0xF4, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0xF9, (byte) 0x20, (byte) 0xFB, (byte) 0xFC, (byte) 0x20, (byte) 0x20, (byte) 0xFF, + }; + + public String getName() + { + return "windows-1256"; + } + + public String getLanguage() + { + return "ar"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } + + static class CharsetRecog_KOI8_R extends CharsetRecog_sbcs + { + private static int[] ngrams = { + 0x20C4CF, 0x20C920, 0x20CBC1, 0x20CBCF, 0x20CEC1, 0x20CEC5, 0x20CFC2, 0x20D0CF, 0x20D0D2, 0x20D2C1, 0x20D3CF, 0x20D3D4, 0x20D4CF, 0x20D720, 0x20D7CF, 0x20DAC1, + 0x20DCD4, 0x20DED4, 0xC1CEC9, 0xC1D4D8, 0xC5CCD8, 0xC5CEC9, 0xC5D3D4, 0xC5D420, 0xC7CF20, 0xC920D0, 0xC9C520, 0xC9C920, 0xC9D120, 0xCCC5CE, 0xCCC920, 0xCCD8CE, + 0xCEC120, 0xCEC520, 0xCEC9C5, 0xCEC9D1, 0xCECF20, 0xCECFD7, 0xCF20D0, 0xCF20D3, 0xCF20D7, 0xCFC7CF, 0xCFCA20, 0xCFCCD8, 0xCFCD20, 0xCFD3D4, 0xCFD720, 0xCFD7C1, + 0xD0CFCC, 0xD0D2C5, 0xD0D2C9, 0xD0D2CF, 0xD2C1D7, 0xD2C5C4, 0xD3D120, 0xD3D4C1, 0xD3D4C9, 0xD3D4D7, 0xD4C5CC, 0xD4CF20, 0xD4CFD2, 0xD4D820, 0xD9C820, 0xDED4CF, + }; + + private static byte[] byteMap = { + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x00, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, + (byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x6B, (byte) 0x6C, (byte) 0x6D, (byte) 0x6E, (byte) 0x6F, + (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, + (byte) 0x78, (byte) 0x79, (byte) 0x7A, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0xA3, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0xA3, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x20, + (byte) 0xC0, (byte) 0xC1, (byte) 0xC2, (byte) 0xC3, (byte) 0xC4, (byte) 0xC5, (byte) 0xC6, (byte) 0xC7, + (byte) 0xC8, (byte) 0xC9, (byte) 0xCA, (byte) 0xCB, (byte) 0xCC, (byte) 0xCD, (byte) 0xCE, (byte) 0xCF, + (byte) 0xD0, (byte) 0xD1, (byte) 0xD2, (byte) 0xD3, (byte) 0xD4, (byte) 0xD5, (byte) 0xD6, (byte) 0xD7, + (byte) 0xD8, (byte) 0xD9, (byte) 0xDA, (byte) 0xDB, (byte) 0xDC, (byte) 0xDD, (byte) 0xDE, (byte) 0xDF, + (byte) 0xC0, (byte) 0xC1, (byte) 0xC2, (byte) 0xC3, (byte) 0xC4, (byte) 0xC5, (byte) 0xC6, (byte) 0xC7, + (byte) 0xC8, (byte) 0xC9, (byte) 0xCA, (byte) 0xCB, (byte) 0xCC, (byte) 0xCD, (byte) 0xCE, (byte) 0xCF, + (byte) 0xD0, (byte) 0xD1, (byte) 0xD2, (byte) 0xD3, (byte) 0xD4, (byte) 0xD5, (byte) 0xD6, (byte) 0xD7, + (byte) 0xD8, (byte) 0xD9, (byte) 0xDA, (byte) 0xDB, (byte) 0xDC, (byte) 0xDD, (byte) 0xDE, (byte) 0xDF, + }; + + public String getName() + { + return "KOI8-R"; + } + + public String getLanguage() + { + return "ru"; + } + + public int match(CharsetDetector det) + { + return match(det, ngrams, byteMap); + } + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecognizer.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecognizer.java new file mode 100644 index 00000000..c29d6e50 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/util/internal/icu/CharsetRecognizer.java @@ -0,0 +1,63 @@ +package org.eclipse.internal.xtend.util.internal.icu; +/** +This code was taken from the com.ibm.icu library (3.6.1). We needed to copy it to have not +a dependency to this large library only the need of charset recognition. +(KTH 2007-07-30) + +The com.ibm.icu library is published under Eclipse Public License V1.0. + */ + +/** +******************************************************************************* +* Copyright (C) 2005, International Business Machines Corporation and * +* others. All Rights Reserved. * +******************************************************************************* +*/ + +/** + * Abstract class for recognizing a single charset. + * Part of the implementation of ICU's CharsetDetector. + * + * Each specific charset that can be recognized will have an instance + * of some subclass of this class. All interaction between the overall + * CharsetDetector and the stuff specific to an individual charset happens + * via the interface provided here. + * + * Instances of CharsetDetector DO NOT have or maintain + * state pertaining to a specific match or detect operation. + * The WILL be shared by multiple instances of CharsetDetector. + * They encapsulate const charset-specific information. + * + * @internal + */ +abstract class CharsetRecognizer { + /** + * Get the IANA name of this charset. + * @return the charset name. + */ + abstract String getName(); + + /** + * Get the ISO language code for this charset. + * @return the language code, or <code>null</code> if the language cannot be determined. + */ + public String getLanguage() + { + return null; + } + + /** + * Test the match of this charset with the input text data + * which is obtained via the CharsetDetector object. + * + * @param det The CharsetDetector, which contains the input text + * to be checked for being in this charset. + * @return Two values packed into one int (Damn java, anyhow) + * <br/> + * bits 0-7: the match confidence, ranging from 0-100 + * <br/> + * bits 8-15: The match reason, an enum-like value. + */ + abstract int match(CharsetDetector det); + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/XtendAdvice.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/XtendAdvice.java new file mode 100644 index 00000000..45ecf802 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/XtendAdvice.java @@ -0,0 +1,55 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.xtend; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.mwe.core.WorkflowComponent; +import org.eclipse.emf.mwe.core.ao.AbstractWorkflowAdvice; +import org.eclipse.emf.mwe.core.issues.Issues; +import org.eclipse.xtend.XtendComponent; + +public class XtendAdvice extends AbstractWorkflowAdvice { + + private List<String> extensionAdvices = new ArrayList<String>(); + + public void addExtensionAdvices(String extensionAdvices) { + this.extensionAdvices.add( extensionAdvices ); + } + + public void addExtensionAdvice(String extensionAdvices) { + this.extensionAdvices.add( extensionAdvices ); + } + + @Override + public void weave(WorkflowComponent c, Issues issues) { + if ( !(c instanceof XtendComponent) ) { + issues.addError(this, "advice target is not an XtendComponent."); + } else { + XtendComponent xc = (XtendComponent)c; + for (String advice : extensionAdvices) { + xc.addExtensionAdvice(advice); + } + } + } + + @Override + public String getLogMessage() { + return "extensionAdvices: "+buildList( extensionAdvices ); + } + + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/XtendFile.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/XtendFile.java new file mode 100644 index 00000000..e563ea99 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/XtendFile.java @@ -0,0 +1,44 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.xtend; + +import java.util.List; +import java.util.Set; + +import org.eclipse.internal.xtend.xtend.ast.Around; +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.Resource; +import org.eclipse.xtend.expression.ResourceManager; + +public interface XtendFile extends Resource { + + public static final String FILE_EXTENSION = "ext"; + + List<Extension> getExtensions(); + + List<Around> getArounds(); + + List<Extension> getPublicExtensions(ResourceManager resourceManager,ExecutionContext ctx); + + /** + * This method is public only for technical reasons - do not call directly! + */ + List<Extension> getPublicExtensions(ResourceManager resourceManager, ExecutionContext ctx, Set<String> flowoverCache); + + void analyze(ExecutionContext ctx, Set<AnalysationIssue> issues); + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/XtendResourceParser.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/XtendResourceParser.java new file mode 100644 index 00000000..693c3a6d --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/XtendResourceParser.java @@ -0,0 +1,31 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.xtend; + +import java.io.Reader; + +import org.eclipse.internal.xtend.xtend.parser.ParseFacade; +import org.eclipse.xtend.expression.Resource; +import org.eclipse.xtend.expression.ResourceParser; + + + +public class XtendResourceParser implements ResourceParser { + + public Resource parse(final Reader in, final String fileName) { + return ParseFacade.file(in, fileName); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/AbstractExtension.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/AbstractExtension.java new file mode 100644 index 00000000..34cc3bec --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/AbstractExtension.java @@ -0,0 +1,316 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.xtend.ast; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.internal.xtend.expression.ast.DeclaredParameter; +import org.eclipse.internal.xtend.expression.ast.Identifier; +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.EvaluationException; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.Type; + +public abstract class AbstractExtension extends SyntaxElement implements Extension { + + private Identifier name; + + private List<DeclaredParameter> formalParameters; + + protected ExtensionFile file; + + protected boolean cached = false; + + private boolean isPrivate = false; + + public AbstractExtension( final Identifier name, + final Identifier returnType, final List<DeclaredParameter> formalParameters, final boolean cached, final boolean isPrivate) { + this.name = name; + this.formalParameters = formalParameters; + this.returnType = returnType; + this.cached = cached; + this.isPrivate = isPrivate; + } + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#getFormalParameters() + */ + public List<DeclaredParameter> getFormalParameters() { + return formalParameters; + } + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#getName() + */ + public String getName() { + return name.getValue(); + } + + public Identifier getNameIdentifier() { + return name; + } + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#getReturnType(org.eclipse.internal.xtend.type.Type[], org.eclipse.internal.xtend.expression.ExecutionContext, java.util.Set) + */ + public final Type getReturnType(final Type[] parameters, ExecutionContext ctx, final Set<AnalysationIssue> issues) { + ctx = ctx.cloneWithResource(getExtensionFile()); + return internalGetReturnType(parameters, ctx, issues); + } + + protected abstract Type internalGetReturnType(Type[] parameters, ExecutionContext ctx, Set<AnalysationIssue> issues); + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#analyze(org.eclipse.internal.xtend.expression.ExecutionContext, java.util.Set) + */ + public final void analyze(ExecutionContext ctx, final Set<AnalysationIssue> issues) { + final List<DeclaredParameter> params = getFormalParameters(); + final Set<String> usedNames = new HashSet<String>(); + for (final Iterator<DeclaredParameter> iter = params.iterator(); iter.hasNext();) { + final DeclaredParameter p = iter.next(); + final Type pt = ctx.getTypeForName(p.getType().getValue()); + if (pt == null) { + issues.add(new AnalysationIssue(AnalysationIssue.TYPE_NOT_FOUND, "Type not found: " + + p.getType().getValue(), p.getType())); + } + if (!usedNames.add(p.getName().getValue())) { + issues.add(new AnalysationIssue(AnalysationIssue.SYNTAX_ERROR, "Duplicate parameter name: " + + p.getName().getValue(), p.getName())); + } + ctx = ctx.cloneWithVariable(new Variable(p.getName().getValue(), pt)); + } + if (returnType != null) { + final Type pt = ctx.getTypeForName(returnType.getValue()); + if (pt == null) { + issues.add(new AnalysationIssue(AnalysationIssue.TYPE_NOT_FOUND, "Type not found: " + + returnType.getValue(), returnType)); + } + } + try { + analyzeInternal(ctx, issues); + } catch (RuntimeException ex) { + ctx.handleRuntimeException(ex, this, null); + } + } + + protected abstract void analyzeInternal(ExecutionContext ctx, Set<AnalysationIssue> issues); + + private final Map<List<Object>, Object> cache = new HashMap<List<Object>, Object>(); + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#evaluate(java.lang.Object[], org.eclipse.internal.xtend.expression.ExecutionContext) + */ + public Object evaluate(final Object[] parameters, ExecutionContext ctx) { + try { + if (cached) { + final List<Object> l = Arrays.asList(parameters); + if (cache.containsKey(l)) + return cache.get(l); + } + if (getExtensionFile() == null) + throw new IllegalStateException("No containing file!"); + ctx = ctx.cloneWithResource(getExtensionFile()); + final Object result = evaluateInternal(parameters, ctx); + if (cached) { + cache.put(Arrays.asList(parameters), result); + } + return result; + } catch (RuntimeException ex) { + ctx.handleRuntimeException(ex, this, null); + } + return null; + } + + public final void setExtensionFile(final ExtensionFile f) { + file = f; + } + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#getExtensionFile() + */ + public ExtensionFile getExtensionFile() { + return file; + } + + protected abstract Object evaluateInternal(Object[] parameters, ExecutionContext ctx); + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#getParameterNames() + */ + public List<String> getParameterNames() { + final List<String> names = new ArrayList<String>(); + for (final Iterator<DeclaredParameter> iter = getFormalParameters().iterator(); iter.hasNext();) { + names.add(iter.next().getName().getValue()); + } + return names; + } + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#init(org.eclipse.internal.xtend.expression.ExecutionContext) + */ + public void init(final ExecutionContext ctx) { + if (parameterTypes == null) { + try { + parameterTypes = new ArrayList<Type>(); + for (final Iterator<DeclaredParameter> iter = getFormalParameters().iterator(); iter.hasNext();) { + final String name = iter.next().getType().getValue(); + final Type t = ctx.getTypeForName(name); + if (t == null) + throw new EvaluationException("Couldn't resolve type for '" + name + + "'. Did you forget to configure the corresponding metamodel?", this, ctx); + parameterTypes.add(t); + } + } catch (final RuntimeException e) { + parameterTypes = null; + throw e; + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#getReturnType() + */ + public Type getReturnType() { + throw new UnsupportedOperationException(); + } + + private List<Type> parameterTypes = null; + + protected Identifier returnType; + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#getParameterTypes() + */ + public List<Type> getParameterTypes() { + return parameterTypes; + } + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#getReturnTypeIdentifier() + */ + public Identifier getReturnTypeIdentifier() { + return returnType; + } + + private String _stringRepresentation = null; + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#toString() + */ + @Override + public String toString() { + if (_stringRepresentation == null) { + _stringRepresentation = (returnType != null ? returnType.getValue() + " " : "") + getName() + "(" + paramsToString() + ")"; + } + + return _stringRepresentation; + } + + private String _outlineRepresentation = null; + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#toOutlineString() + */ + public String toOutlineString() { + if (_outlineRepresentation == null) { + _outlineRepresentation = getName() + "(" + paramsToOutlineString() + ")" + (returnType != null ? ": "+returnType.getValue() : "") ; + } + return _outlineRepresentation; + } + + private String paramsToString() { + final StringBuffer buff = new StringBuffer(); + for (final Iterator<DeclaredParameter> iter = getFormalParameters().iterator(); iter.hasNext();) { + final DeclaredParameter element = iter.next(); + buff.append(element.getType() + " " + element.getName()); + if (iter.hasNext()) { + buff.append(","); + } + } + return buff.toString(); + } + + private String paramsToOutlineString() { + final StringBuffer buff = new StringBuffer(); + for (final Iterator<DeclaredParameter> iter = getFormalParameters().iterator(); iter.hasNext();) { + final DeclaredParameter element = iter.next(); + buff.append(element.getName()); + if (iter.hasNext()) { + buff.append(", "); + } + } + return buff.toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#isPrivate() + */ + public boolean isPrivate() { + return isPrivate; + } + + /* (non-Javadoc) + * @see org.eclipse.internal.xtend.xtend.ast.Extension#isCached() + */ + public boolean isCached () { + return cached; + } + + public String getQualifiedName() { + return getExtensionFile().getFullyQualifiedName()+"::"+getName(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getName() == null) ? 0 : getName().hashCode()); + result = prime * result + ((parameterTypes == null) ? 0 : parameterTypes.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final AbstractExtension other = (AbstractExtension) obj; + if (getName() == null) { + if (other.getName() != null) + return false; + } else if (!getName().equals(other.getName())) + return false; + if (parameterTypes == null) { + if (other.parameterTypes != null) + return false; + } else if (!parameterTypes.equals(other.parameterTypes)) + return false; + return true; + } + + + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/Around.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/Around.java new file mode 100644 index 00000000..bc55ee2c --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/Around.java @@ -0,0 +1,109 @@ +package org.eclipse.internal.xtend.xtend.ast; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.internal.xtend.expression.ast.DeclaredParameter; +import org.eclipse.internal.xtend.expression.ast.Expression; +import org.eclipse.internal.xtend.expression.ast.Identifier; +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; +import org.eclipse.internal.xtend.xtend.XtendFile; +import org.eclipse.internal.xtend.xtend.types.AdviceContextType; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.Type; + +public class Around extends SyntaxElement { + + public static final String CONTEXT_PARAM_NAME = "ctx"; + private Identifier pointcut; + private List<DeclaredParameter> params; + private boolean wildparams; + private Expression expression; + + public Around(Identifier pointcut, List<DeclaredParameter> params, boolean wildparams, Expression expr) { + this.pointcut = pointcut; + this.params = params; + this.wildparams = wildparams; + this.expression = expr; + } + + public Identifier getPointCut() { + return pointcut; + } + + public boolean isWildparams() { + return wildparams; + } + + public Expression getExpression() { + return expression; + } + + public List<DeclaredParameter> getParams() { + return params; + } + + private XtendFile parent = null; + private Pattern p; + public void setParent(XtendFile parent) { + this.parent = parent; + } + + public XtendFile getParent() { + return parent; + } + + public List<Type> getParamTypes(ExecutionContext ctx) { + ctx = ctx.cloneWithResource(getParent()); + List<Type> result = new ArrayList<Type>(); + for (DeclaredParameter p : getParams()) { + result.add(ctx.getTypeForName(p.getType().getValue())); + } + return result; + } + + public boolean nameMatches(String fqn) { + if (p == null) { + p = Pattern.compile(pointcut.getValue().replaceAll("\\*", ".*")); + } + final Matcher m = p.matcher(fqn); + return m.matches(); + } + + public void analyze(ExecutionContext ctx, final Set<AnalysationIssue> issues) { + ctx = ctx.cloneWithoutVariables(); + ctx = ctx.cloneWithResource(getParent()); + for (DeclaredParameter p : getParams()) { + final String name = p.getName().getValue(); + if (name.equals(CONTEXT_PARAM_NAME)) + issues.add(new AnalysationIssue(AnalysationIssue.SYNTAX_ERROR,"The variable name 'ctx' is not allowed here!",p.getName())); + final Type t = ctx.getTypeForName(p.getType().getValue()); + ctx = ctx.cloneWithVariable(new Variable(name, t)); + } + ctx = ctx.cloneWithVariable(new Variable(CONTEXT_PARAM_NAME,ctx.getTypeForName(AdviceContextType.TYPE_NAME))); + expression.analyze(ctx, issues); + } + + @Override + public String toString() { + return " around "+pointcut+"("+paramsToString()+(isWildparams()?" * ":"")+") from "+getParent().getFullyQualifiedName(); + } + + private String paramsToString() { + StringBuffer b = new StringBuffer(""); + for (Iterator<DeclaredParameter> iter = getParams().iterator();iter.hasNext();) { + DeclaredParameter p = iter.next(); + b.append(p.getType()+" "+p.getName()); + if (iter.hasNext()) + b.append(","); + } + return b.toString(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/Check.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/Check.java new file mode 100644 index 00000000..161911eb --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/Check.java @@ -0,0 +1,197 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.xtend.ast; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; + +import org.eclipse.emf.mwe.core.issues.Issues; +import org.eclipse.internal.xtend.expression.ast.Expression; +import org.eclipse.internal.xtend.expression.ast.Identifier; +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.EvaluationException; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.Type; + +public class Check extends SyntaxElement { + + private Identifier type; + + private boolean errorSeverity = true; + + private Expression msg; + + private Expression constraint; + + private Expression guard; + + public Check(final Identifier type, final Expression guard, final boolean errorSeverity, + final Expression msg, final Expression constraint) { + this.type = type; + this.guard = guard; + this.errorSeverity = errorSeverity; + this.msg = msg; + this.constraint = constraint; + } + + public final void analyze(ExecutionContext ctx, final Set<AnalysationIssue> issues) { + final Type toCheck = ctx.getTypeForName(type.getValue()); + if (toCheck == null) { + issues + .add(new AnalysationIssue(AnalysationIssue.TYPE_NOT_FOUND, "Type not found: " + type.getValue(), + this)); + return; + } + ctx = ctx.cloneWithVariable(new Variable(ExecutionContext.IMPLICIT_VARIABLE, toCheck)); + if (guard != null) { + Type guardType = null; + try { + guardType = guard.analyze(ctx, issues); + } catch (RuntimeException ex) { + ctx.handleRuntimeException(ex, this, null); + } + if (guardType == null) + return; + if (!guardType.equals(ctx.getBooleanType())) { + issues.add(new AnalysationIssue(AnalysationIssue.TYPE_NOT_FOUND, "Boolean expected! (is " + + guardType.getName() + ")", guard)); + } + } + + Type constraintType = null; + try { + constraintType = constraint.analyze(ctx, issues); + } catch (RuntimeException ex) { + ctx.handleRuntimeException(ex, this, null); + } + if (constraintType == null) + return; + if (!constraintType.equals(ctx.getBooleanType())) { + issues.add(new AnalysationIssue(AnalysationIssue.TYPE_NOT_FOUND, "Boolean expected! (is " + + constraintType.getName() + ")", constraint)); + } + + try { + msg.analyze(ctx, issues); + } catch (RuntimeException ex) { + ctx.handleRuntimeException(ex, this, null); + } + } + + /** + * Executes the check. + * @param ctx The current execution context + * @param colToCheck Collection of objects on which the check is evaluated + * @param issues Errors and warnings are reported to this instance + * @param warnIfNothingChecked <code>true</code>: If this check is not evaluated for any elements an warning will be added to <tt>issues</tt> + */ + public void validate(ExecutionContext ctx, final Collection<?> colToCheck, final Issues issues, boolean warnIfNothingChecked) { + // get the type for which the check should be evaluated + final Type typeToCheck = ctx.getTypeForName(type.getValue()); + // The type is unknown => exit with exception + if (typeToCheck == null) + throw new EvaluationException("Type not found : " + type.getValue(), this, ctx); + + // will be set to true when check is evaluated for any object + boolean someObjectFound = false; + for (final Iterator<?> iter = colToCheck.iterator(); iter.hasNext();) { + final Object o = iter.next(); + // Object matches the type the check is declared for + if (typeToCheck.isInstance(o)) { + someObjectFound = true; + try { + // create a new execution context for evaluation + ctx = ctx.cloneWithVariable(new Variable(ExecutionContext.IMPLICIT_VARIABLE, o)); + // check the guard condition; do not evaluate if guard is evaluated to false + if (process(ctx)) { + final Object result = constraint.evaluate(ctx); + + // check result must be of Boolean type + if (result != null && !(result instanceof Boolean)) + throw new EvaluationException("Boolean expected! ( was " + result.getClass().getName()+")", this, ctx); + + // add issue if result of the check is false + final Boolean r = (Boolean) result; + if (Boolean.FALSE.equals(r)) { + // get the error message + final Object msgResult = msg.evaluate(ctx); + String stringResult = "Message evaluation returned null"; + if (msgResult != null) { + stringResult = msgResult.toString(); + } + if (errorSeverity) { + issues.addError(stringResult, o); + } else { + issues.addWarning(stringResult, o); + } + } + } + } catch (final NullPointerException npe) { + final Object msgResult = msg.evaluate(ctx); + String stringResult = "Message evaluation returned null"; + if (msgResult != null) { + stringResult = msgResult.toString(); + } + if (errorSeverity) { + issues.addError(stringResult + " (NPE in constraint evaluation)", o); + } else { + issues.addWarning(stringResult + " (NPE in constraint evaluation)", o); + } + } + } + } + if ( warnIfNothingChecked && (!someObjectFound) ) { + issues.addWarning( "The constraint did not match any model elements. Context: "+type.toString()+", message: "+msg ); + } + } + + private boolean process(final ExecutionContext ctx) { + if (guard != null) { + final Object result = guard.evaluate(ctx); + return result instanceof Boolean && ((Boolean) result).booleanValue(); + } + return true; + } + + @Override + public String toString() { + return type+" "+msg; + } + + public boolean isErrorCheck() { + return this.errorSeverity; + } + + public Expression getConstraint() { + return constraint; + } + + public Expression getGuard() { + return guard; + } + + public Expression getMsg() { + return msg; + } + + public Identifier getType() { + return type; + } + + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/CreateExtensionStatement.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/CreateExtensionStatement.java new file mode 100644 index 00000000..5e89b383 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/CreateExtensionStatement.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.internal.xtend.xtend.ast; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.internal.xtend.expression.ast.DeclaredParameter; +import org.eclipse.internal.xtend.expression.ast.Expression; +import org.eclipse.internal.xtend.expression.ast.Identifier; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.EvaluationException; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.Type; + +public class CreateExtensionStatement extends AbstractExtension { + + private Expression expression; + + private String returnVarName; + + public CreateExtensionStatement(final Identifier name, + final Identifier returnType, final Identifier rtName, final List<DeclaredParameter> params, final Expression expr, + final boolean isPrivate) { + super(name, returnType, params, true, isPrivate); + expression = expr; + returnVarName = rtName!=null ? rtName.getValue() : "this"; + } + + public Expression getExpression() { + return expression; + } + + @Override + protected Type internalGetReturnType(final Type[] parameters, final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + return ctx.getTypeForName(getReturnTypeIdentifier().getValue()); + } + + @Override + public void analyzeInternal(ExecutionContext ctx, final Set<AnalysationIssue> issues) { + final Type t = ctx.getTypeForName(returnType.getValue()); + if (t == null) { + issues.add(new AnalysationIssue(AnalysationIssue.TYPE_NOT_FOUND, "Couldn't resolve type " + returnType + + "!", returnType)); + return; + } + if (t.isAbstract()) + issues.add(new AnalysationIssue(AnalysationIssue.INCOMPATIBLE_TYPES, "Cannot create instance of " + returnType + + " because it is declared abstract!", returnType)); + ctx = ctx.cloneWithVariable(new Variable(returnVarName, t)); + expression.analyze(ctx, issues); + } + + private final Map<List<Object>, Object> cache = new HashMap<List<Object>, Object>(); + + @Override + public Object evaluate(final Object[] parameters, ExecutionContext ctx) { + final List<Object> l = Arrays.asList(parameters); + if (cache.containsKey(l)) + return cache.get(l); + ctx = ctx.cloneWithResource(getExtensionFile()); + final Type t = ctx.getTypeForName(returnType.getValue()); + if (t == null) + throw new EvaluationException("Couldn't resolve type " + returnType, returnType, ctx); + if (t.isAbstract()) + throw new EvaluationException("Cannot create instance of abstract class " + returnType, returnType, ctx); + final Object inst = t.newInstance(); + cache.put(l, inst); + ctx = ctx.cloneWithVariable(new Variable(returnVarName, inst)); + for (int i = 0; i < parameters.length; i++) { + final Object object = parameters[i]; + ctx = ctx.cloneWithVariable(new Variable(getParameterNames().get(i), object)); + } + expression.evaluate(ctx); + return inst; + } + + @Override + protected Object evaluateInternal(final Object[] parameters, final ExecutionContext ctx) { + throw new UnsupportedOperationException(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/ExpressionExtensionStatement.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/ExpressionExtensionStatement.java new file mode 100644 index 00000000..08e65a40 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/ExpressionExtensionStatement.java @@ -0,0 +1,115 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.xtend.ast; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.Stack; + +import org.eclipse.internal.xtend.expression.ast.DeclaredParameter; +import org.eclipse.internal.xtend.expression.ast.Expression; +import org.eclipse.internal.xtend.expression.ast.Identifier; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.Type; + +public class ExpressionExtensionStatement extends AbstractExtension { + + private Expression expression; + + public ExpressionExtensionStatement(final Identifier name, + final Identifier returnType, + final List<DeclaredParameter> formalParameters, + final Expression expression, final boolean cached, + final boolean isPrivate) { + super(name, returnType, formalParameters, cached, isPrivate); + this.expression = expression; + } + + public Expression getExpression() { + return expression; + } + + private final Stack<List<Type>> analyzations = new Stack<List<Type>>(); + + @Override + public Object evaluateInternal(final Object[] parameters, + final ExecutionContext ctx) { + return evaluateInternal2(parameters, ctx); + } + + protected Object evaluateInternal2(final Object[] parameters, + ExecutionContext ctx) { + ctx = ctx.cloneWithoutVariables(); + ctx = ctx.cloneWithResource(file); + final List<String> paramNames = getParameterNames(); + for (int i = 0, x = paramNames.size(); i < x; i++) { + final String name = paramNames.get(i); + ctx = ctx.cloneWithVariable(new Variable(name, parameters[i])); + } + return expression.evaluate(ctx); + } + + @Override + public void analyzeInternal(final ExecutionContext ctx, + final Set<AnalysationIssue> issues) { + if (expression != null) + expression.analyze(ctx, issues); + } + + @Override + protected Type internalGetReturnType(final Type[] parameters, + final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + if (getReturnTypeIdentifier() != null) + return ctx.getTypeForName(getReturnTypeIdentifier().getValue()); + if (parameters == null + || parameters.length != getParameterNames().size()) + return null; + final List<Type> params = Arrays.asList(parameters); + if (!analyzations.contains(params)) { + analyzations.push(params); + try { + return analyzeInternal(parameters, ctx, issues); + } finally { + analyzations.pop(); + } + } else { + if (returnType == null) { + issues + .add(new AnalysationIssue( + AnalysationIssue.INTERNAL_ERROR, + "Recursive extensions need to have a return type specified!", + this)); + return null; + } + return ctx.getTypeForName(returnType.getValue()); + } + } + + protected Type analyzeInternal(final Type[] parameters, + ExecutionContext ctx, final Set<AnalysationIssue> issues) { + ctx = ctx.cloneWithoutVariables(); + ctx = ctx.cloneWithResource(file); + final List<String> paramNames = getParameterNames(); + for (int i = 0, x = paramNames.size(); i < x; i++) { + final String name = paramNames.get(i); + final Type t = parameters[i]; + ctx = ctx.cloneWithVariable(new Variable(name, t)); + } + return expression.analyze(ctx, issues); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/Extension.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/Extension.java new file mode 100644 index 00000000..123583da --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/Extension.java @@ -0,0 +1,51 @@ +package org.eclipse.internal.xtend.xtend.ast; + +import java.util.List; +import java.util.Set; + +import org.eclipse.internal.xtend.expression.ast.DeclaredParameter; +import org.eclipse.internal.xtend.expression.ast.ISyntaxElement; +import org.eclipse.internal.xtend.expression.ast.Identifier; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.ParameterizedCallable; +import org.eclipse.xtend.typesystem.Type; + +public interface Extension extends ParameterizedCallable, ISyntaxElement { + + public List<DeclaredParameter> getFormalParameters(); + + public String getName(); + + public Type getReturnType(final Type[] parameters, ExecutionContext ctx, + final Set<AnalysationIssue> issues); + + public void analyze(ExecutionContext ctx, final Set<AnalysationIssue> issues); + + public Object evaluate(final Object[] parameters, ExecutionContext ctx); + + public ExtensionFile getExtensionFile(); + + public List<String> getParameterNames(); + + public void init(final ExecutionContext ctx); + + public Type getReturnType(); + + public List<Type> getParameterTypes(); + + public Identifier getReturnTypeIdentifier(); + + public String toString(); + + public String toOutlineString(); + + public boolean isPrivate(); + + public boolean isCached(); + + public void setExtensionFile(ExtensionFile file); + + public String getQualifiedName(); + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/ExtensionFile.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/ExtensionFile.java new file mode 100644 index 00000000..fe36bd4d --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/ExtensionFile.java @@ -0,0 +1,200 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.xtend.ast; + +import java.util.ArrayList; +import java.util.Arrays; +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.mwe.core.issues.Issues; +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; +import org.eclipse.internal.xtend.xtend.XtendFile; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.ResourceManager; + +public class ExtensionFile extends SyntaxElement implements XtendFile { + + private List<ImportStatement> nsImports; + + private List<ImportStatement> extImports; + + private List<Extension> extensions; + + private List<Around> arounds; + + private List<Check> checks; + + public List<Check> getChecks() { + return checks; + } + + public ExtensionFile(final List<ImportStatement> nsImports, final List<ImportStatement> extImports, + final List<Extension> extensions, final List<Around> arounds, final List<Check> checks) { + this.nsImports = nsImports; + this.extImports = extImports; + this.extensions = extensions; + this.arounds = arounds; + this.checks = checks; + for (Extension extension : extensions) { + extension.setExtensionFile(this); + } + for (Around around : arounds) { + around.setParent(this); + } + } + + public List<Around> getArounds() { + return arounds; + } + + public List<Extension> getExtensions() { + return extensions; + } + + public List<ImportStatement> getExtImports() { + return extImports; + } + + public List<ImportStatement> getNsImports() { + return nsImports; + } + + public String[] getImportedNamespaces() { + final List<String> namespaces = new ArrayList<String>(); + for (ImportStatement nsImport : nsImports) { + namespaces.add(nsImport.getImportedId().getValue()); + } + return namespaces.toArray(new String[namespaces.size()]); + } + + public List<String> getImportedNamespacesAsList() { + return Arrays.asList(getImportedNamespaces()); + } + + public void analyze(ExecutionContext ctx, final Set<AnalysationIssue> issues) { + ctx = ctx.cloneWithResource(this); + + // try to load all declared imported extensions. Add error issues if the resource cannot be located + // by the ResourceManager + for (ImportStatement imp : extImports) { + final XtendFile xf = (XtendFile) ctx.getResourceManager().loadResource(imp.getImportedId().getValue(), + XtendFile.FILE_EXTENSION); + if (xf == null) { + final String msg = "Error while importing extension: File " + imp.getImportedId().getValue() + " not found."; + issues.add(new AnalysationIssue(AnalysationIssue.RESOURCE_NOT_FOUND, msg, imp)); + return; + } + } + + for (Extension ext : extensions) { + try { + ext.analyze(ctx, issues); + } catch (RuntimeException ex) { + Map<String,Object> info = new HashMap<String,Object>(); + info.put("extension", ext); + ctx.handleRuntimeException(ex, this, info); + } + } + + for (Around around : arounds) { + try { + around.analyze(ctx, issues); + } catch (RuntimeException ex) { + Map<String,Object> info = new HashMap<String,Object>(); + info.put("around", around); + ctx.handleRuntimeException(ex, this, info); + } + } + + for (final Check check : checks) { + try { + check.analyze(ctx, issues); + } catch (RuntimeException ex) { + ctx.handleRuntimeException(ex, this, null); + } + } + } + + private String fullyQualifiedName; + + public void setFullyQualifiedName(final String fullyQualifiedName) { + this.fullyQualifiedName = fullyQualifiedName; + } + + public String getFullyQualifiedName() { + return fullyQualifiedName; + } + + public String[] getImportedExtensions() { + final List<String> namespaces = new ArrayList<String>(); + for (ImportStatement extImport : extImports) { + namespaces.add(extImport.getImportedId().getValue()); + } + return getImportedExtensionsAsList().toArray(new String[namespaces.size()]); + } + + public List<String> getImportedExtensionsAsList () { + final List<String> namespaces = new ArrayList<String>(); + for (ImportStatement extImport : extImports) { + namespaces.add(extImport.getImportedId().getValue()); + } + return namespaces; + } + + public List<Extension> getPublicExtensions(final ResourceManager rm, ExecutionContext ctx) { + return getPublicExtensions(rm, ctx, new HashSet<String>()); + } + + public List<Extension> getPublicExtensions(final ResourceManager rm, ExecutionContext ctx, Set<String> flowoverCache) { + if (flowoverCache.contains(getFullyQualifiedName())) + return new ArrayList<Extension>(); + flowoverCache.add (getFullyQualifiedName()); + + final List<Extension> result = new ArrayList<Extension>(); + + for (Extension ext : extensions) { + if (!ext.isPrivate()) { + result.add(ext); + } + } + for (ImportStatement imp : extImports) { + if (imp.isExported()) { + final XtendFile xf = (XtendFile) rm.loadResource(imp.getImportedId().getValue(), + XtendFile.FILE_EXTENSION); + ExecutionContext context = ctx.cloneWithResource(xf); + List<Extension> publicExtensions = xf.getPublicExtensions(rm, context, flowoverCache); + for (Extension extension : publicExtensions) { + extension.init(context); + if (!result.contains(extension)) + result.add(extension); + } + } + } + return result; + } + + public void check(ExecutionContext ctx, final Collection<?> objects, final Issues issues, boolean warnIfNothingChecked) { + ctx = ctx.cloneWithResource(this); + for (final Check check : checks) { + check.validate(ctx, objects, issues, warnIfNothingChecked); + } + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/ImportStatement.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/ImportStatement.java new file mode 100644 index 00000000..f5ffc4a7 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/ImportStatement.java @@ -0,0 +1,40 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.xtend.ast; + +import org.eclipse.internal.xtend.expression.ast.Identifier; +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; + +public class ImportStatement extends SyntaxElement { + + private Identifier importedId; + + private boolean exported; + + public ImportStatement(final Identifier importedID, + final boolean exported) { + importedId = importedID; + this.exported = exported; + } + + public Identifier getImportedId() { + return importedId; + } + + public boolean isExported() { + return exported; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/JavaExtensionStatement.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/JavaExtensionStatement.java new file mode 100644 index 00000000..077c4f68 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/JavaExtensionStatement.java @@ -0,0 +1,141 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.xtend.ast; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.mwe.core.resources.ResourceLoaderFactory; +import org.eclipse.internal.xtend.expression.ast.DeclaredParameter; +import org.eclipse.internal.xtend.expression.ast.Identifier; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.EvaluationException; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +public class JavaExtensionStatement extends AbstractExtension { + + protected Identifier javaType; + + protected Identifier javaMethod; + + protected List<Identifier> javaParamTypes; + + public JavaExtensionStatement(final Identifier name, + final List<DeclaredParameter> formalParameters, final Identifier returnType, final Identifier javaType, + final Identifier javaMethod, final List<Identifier> javaParamTypes, final boolean cached, final boolean isPrivate) { + super(name, returnType, formalParameters, cached, isPrivate); + this.javaType = javaType; + this.javaMethod = javaMethod; + this.javaParamTypes = javaParamTypes; + } + + public Identifier getJavaType() { + return javaType; + } + + public String getJavaMethodName () { + return javaMethod.getValue(); + } + + @Override + public Object evaluateInternal(final Object[] parameters, final ExecutionContext ctx) { + final HashSet<AnalysationIssue> issues = new HashSet<AnalysationIssue>(); + try { + final Method method = getJavaMethod(ctx, issues); + if (method == null) { + final StringBuffer b = new StringBuffer(); + for (final Iterator<AnalysationIssue> iter = issues.iterator(); iter.hasNext();) { + final AnalysationIssue element = iter.next(); + b.append(element.toString()).append("\n"); + } + throw new EvaluationException(javaMethodToString() + " not found, problems were: \n" + b, this, ctx); + } + return method.invoke(null, parameters); + } catch (final InvocationTargetException ite) { + throw new RuntimeException(ite.getCause()); + } catch (final Exception e) { + throw new EvaluationException(e, this, ctx); + } + } + + private String javaMethodToString() { + final StringBuffer buff = new StringBuffer(); + for (final Iterator<Identifier> iter = javaParamTypes.iterator(); iter.hasNext();) { + buff.append(iter.next()); + if (iter.hasNext()) { + buff.append(","); + } + } + + return javaType + "." + javaMethod + "(" + buff + ")"; + } + + public Method getJavaMethod(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + try { + Class clazz = null; + clazz = ResourceLoaderFactory.createResourceLoader().loadClass(javaType.getValue()); + if (clazz == null) { + issues.add(new AnalysationIssue(AnalysationIssue.TYPE_NOT_FOUND, "Couldn't find Java type "+javaType.getValue(), javaType)); + return null; + } + final Class[] paramTypes = new Class[javaParamTypes.size()]; + for (int i = 0, x = javaParamTypes.size(); i < x; i++) { + final Identifier javaParamType = javaParamTypes.get(i); + + paramTypes[i] = ResourceLoaderFactory.createResourceLoader().loadClass(javaParamType.getValue()); + if (paramTypes[i] == null) { + issues.add(new AnalysationIssue(AnalysationIssue.TYPE_NOT_FOUND, javaParamType.getValue(), javaParamType)); + return null; + } + } + final Method m = clazz.getMethod(javaMethod.getValue(), paramTypes); + if (!Modifier.isStatic(m.getModifiers())) { + issues.add(new AnalysationIssue(AnalysationIssue.FEATURE_NOT_FOUND, javaMethod.getValue() + " must be static!", javaMethod)); + } + + if (!Modifier.isPublic(m.getModifiers())) { + issues.add(new AnalysationIssue(AnalysationIssue.FEATURE_NOT_FOUND, javaMethod.getValue() + " must be public!", javaMethod)); + } + return m; + } catch (final NoSuchMethodException e) { + issues.add(new AnalysationIssue(AnalysationIssue.FEATURE_NOT_FOUND, javaMethod.getValue(), javaMethod)); + } + return null; + } + + @Override + public void analyzeInternal(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + if (returnType == null) { + issues.add(new AnalysationIssue(AnalysationIssue.SYNTAX_ERROR, "A return type must be specified for java extensions!", this)); + } + getJavaMethod(ctx, issues); + } + + @Override + protected Type internalGetReturnType(final Type[] parameters, final ExecutionContext ctx, final Set<AnalysationIssue> issues) { + if (returnType == null) { + issues.add(new AnalysationIssue(AnalysationIssue.SYNTAX_ERROR, "A return type must be specified for java extensions!", this)); + return null; + } else + return ctx.getTypeForName(returnType.getValue()); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/codeassist/FastAnalyzer.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/codeassist/FastAnalyzer.java new file mode 100644 index 00000000..04208196 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/codeassist/FastAnalyzer.java @@ -0,0 +1,272 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.xtend.codeassist; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.Stack; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.internal.xtend.expression.codeassist.LazyVar; +import org.eclipse.internal.xtend.xtend.XtendFile; +import org.eclipse.internal.xtend.xtend.ast.Around; +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.internal.xtend.xtend.types.AdviceContextType; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.ExpressionFacade; +import org.eclipse.xtend.expression.ResourceManager; +import org.eclipse.xtend.expression.Variable; +import org.eclipse.xtend.typesystem.ParameterizedType; +import org.eclipse.xtend.typesystem.Type; + +public class FastAnalyzer { + + private static final Pattern PARAM_PATTERN = Pattern + .compile("([\\[\\]:\\w]+)\\s+([\\w]+)"); + + private final static Pattern IMPORT_PATTERN = Pattern + .compile("import\\s+([\\w\\:]+)\\s*;"); + + private final static Pattern INCOMPLETE_IMPORT_PATTERN = Pattern + .compile("import\\s+[\\w\\:]*\\z"); + + private final static Pattern EXTENSION_PATTERN = Pattern + .compile("extension\\s+([\\w\\:]+)\\s*(reexport)?\\s*;"); + + private final static Pattern INCOMPLETE_EXTENSION_PATTERN = Pattern + .compile("extension\\s+[\\w\\:]*\\z"); + + private final static Pattern FUNCTION_PATTERN = Pattern + .compile("((\\w+)\\s+)?(create\\s+([\\w:]+)(\\s+(\\w+))?\\s+)?([\\w:]+)\\s*\\(\\s*([\\[\\]:\\w\\s\\,]+)?\\s*\\)\\s*:\\s*[^;]*\\z"); + + private final static Pattern AROUND_PATTERN = Pattern + .compile("around\\s+([\\w:*]+)\\s*\\(\\s*([\\[\\]:\\w\\s\\,]+)?[\\s,*]*\\)\\s*:\\s*[^;]*\\z"); + + private final static Pattern TYPEDECL_PATTERN = Pattern + .compile("(;|\\A)\\s*\\w+\\s*\\(([\\[\\]:\\w\\s,]*)\\z"); + + private final static Pattern TYPEDECL_PARAM_PATTERN = Pattern + .compile("(,|\\(|\\A)\\s*[\\[\\]:\\w]*\\z"); + + private FastAnalyzer() { + } + + public static boolean isInsideTypeDeclaration(final String s) { + final Matcher m = TYPEDECL_PATTERN.matcher(s); + if (m.find()) + return TYPEDECL_PARAM_PATTERN.matcher(m.group(2)).find(); + return false; + } + + public static boolean isInsideExtensionImport(final String s) { + final Matcher m = INCOMPLETE_EXTENSION_PATTERN.matcher(s); + return m.find(); + } + + public static boolean isInsideImport(final String s) { + final Matcher m = INCOMPLETE_IMPORT_PATTERN.matcher(s); + return m.find(); + } + + public static boolean isInsideExpression(final String s) { + final Matcher m1 = AROUND_PATTERN.matcher(s); + if (!m1.find()) { + final Matcher m = FUNCTION_PATTERN.matcher(s); + return m.find(); + } + return true; + } + + public final static List<String> findImports(final String template) { + final Matcher m = IMPORT_PATTERN.matcher(template); + final List<String> result = new ArrayList<String>(); + while (m.find()) { + result.add(m.group(1)); + } + return result; + } + + public final static List<String> findExtensions(final String template) { + final Matcher m = EXTENSION_PATTERN.matcher(template); + final List<String> result = new ArrayList<String>(); + while (m.find()) { + result.add(m.group(1)); + } + return result; + } + + public final static Stack<Set<LazyVar>> computeStack(String toAnalyze) { + Matcher m = AROUND_PATTERN.matcher(toAnalyze); + Pattern p = AROUND_PATTERN; + final Set<LazyVar> vars = new HashSet<LazyVar>(); + if (!m.find()) { + m = FUNCTION_PATTERN.matcher(toAnalyze); + p = FUNCTION_PATTERN; + if (m.find()) { + final int start = m.start(); + toAnalyze = toAnalyze.substring(start); + m = p.matcher(toAnalyze); + m.find(); + if (m.group(4) != null) { + final LazyVar v = new LazyVar(); + v.typeName = m.group(4); + v.name = m.group(6); + if (v.name == null) + v.name = "this"; + vars.add(v); + } + fillParams(vars, m.group(8)); + } + } else { + fillParams(vars, m.group(2)); + final LazyVar v = new LazyVar(); + v.typeName = AdviceContextType.TYPE_NAME; + v.name = Around.CONTEXT_PARAM_NAME; + vars.add(v); + } + final Stack<Set<LazyVar>> stack = new Stack<Set<LazyVar>>(); + stack.push(vars); + + return stack; + } + + private static void fillParams(final Set<LazyVar> vars, final String params) { + Matcher m; + if (params != null && !"".equals(params.trim())) { + final StringTokenizer st = new StringTokenizer(params, ","); + while (st.hasMoreTokens()) { + final String param = st.nextToken(); + m = PARAM_PATTERN.matcher(param); + if (m.find()) { + final LazyVar v = new LazyVar(); + v.typeName = m.group(1); + v.name = m.group(2); + vars.add(v); + } + } + } + } + + public final static Partition computePartition(final String str) { + if (isInsideImport(str)) + return Partition.NAMESPACE_IMPORT; + + if (isInsideExtensionImport(str)) + return Partition.EXTENSION_IMPORT; + + if (isInsideTypeDeclaration(str)) + return Partition.TYPE_DECLARATION; + + if (isInsideExpression(str)) + return Partition.EXPRESSION; + + return Partition.DEFAULT; + } + + public final static ExecutionContext computeExecutionContext( + final String str, ExecutionContext ctx, + final List<Extension> extensions) { + final Partition p = computePartition(str); + if (p == Partition.EXPRESSION || p == Partition.TYPE_DECLARATION) { + + final List<String> imports = findImports(str); + final List<String> extensionImports = findExtensions(str); + final XtendFile tpl = new XtendFile() { + + private String fqn; + + public String getFullyQualifiedName() { + return fqn; + } + + public void setFullyQualifiedName(String fqn) { + this.fqn = fqn; + } + + public String[] getImportedNamespaces() { + return imports.toArray(new String[imports.size()]); + } + + public String[] getImportedExtensions() { + return extensionImports.toArray(new String[extensionImports + .size()]); + } + + public List<Extension> getExtensions() { + return extensions; + } + + public void analyze(ExecutionContext ctx, + Set<AnalysationIssue> issues) { + // TODO Auto-generated method stub + + } + + public List<Extension> getPublicExtensions(ResourceManager rm, ExecutionContext ctx) { + return extensions; + } + + public List<Extension> getPublicExtensions( + ResourceManager resourceManager,ExecutionContext ctx, + Set<String> flowoverCache) { + return extensions; + } + + public List<Around> getArounds() { + return Collections.emptyList(); + } + + }; + + ctx = ctx.cloneWithResource(tpl); + final Stack<Set<LazyVar>> s = computeStack(str); + + for (final Iterator<Set<LazyVar>> iter = s.iterator(); iter + .hasNext();) { + final Set<LazyVar> vars = iter.next(); + for (final Iterator<LazyVar> iterator = vars.iterator(); iterator + .hasNext();) { + final LazyVar v = iterator.next(); + Type vType = null; + if (v.typeName != null) { + vType = ctx.getTypeForName(v.typeName); + } else { + vType = new ExpressionFacade(ctx).analyze(v.expression, + new HashSet<AnalysationIssue>()); + if (v.forEach) { + if (vType instanceof ParameterizedType) { + vType = ((ParameterizedType) vType) + .getInnerType(); + } else { + vType = null; + } + } + } + ctx = ctx.cloneWithVariable(new Variable(v.name, vType)); + } + } + } + return ctx; + + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/codeassist/Partition.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/codeassist/Partition.java new file mode 100644 index 00000000..feb5a8b5 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/codeassist/Partition.java @@ -0,0 +1,41 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.xtend.codeassist; + +public class Partition { + public final static Partition EXPRESSION = new Partition("Expression"); + + public final static Partition TYPE_DECLARATION = new Partition("Type Declaration"); + + public final static Partition NAMESPACE_IMPORT = new Partition("Namespace Import"); + + public final static Partition EXTENSION_IMPORT = new Partition("AbstractExtension Import"); + + public static final Partition DEFAULT = new Partition("Default"); + + public static final Partition COMMENT = new Partition("Comment"); + + private String name = null; + + protected Partition(final String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/ErrorHandler.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/ErrorHandler.java new file mode 100644 index 00000000..442c27e8 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/ErrorHandler.java @@ -0,0 +1,5 @@ +package org.eclipse.internal.xtend.xtend.parser; + +public interface ErrorHandler { + public void handleError(XtendError e); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/ExtensionFactory.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/ExtensionFactory.java new file mode 100644 index 00000000..1b1b1c3d --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/ExtensionFactory.java @@ -0,0 +1,80 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.internal.xtend.xtend.parser; + +import java.util.List; + +import org.eclipse.internal.xtend.expression.ast.DeclaredParameter; +import org.eclipse.internal.xtend.expression.ast.Expression; +import org.eclipse.internal.xtend.expression.ast.Identifier; +import org.eclipse.internal.xtend.expression.parser.ExpressionFactory; +import org.eclipse.internal.xtend.xtend.ast.Around; +import org.eclipse.internal.xtend.xtend.ast.Check; +import org.eclipse.internal.xtend.xtend.ast.CreateExtensionStatement; +import org.eclipse.internal.xtend.xtend.ast.ExpressionExtensionStatement; +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.internal.xtend.xtend.ast.ExtensionFile; +import org.eclipse.internal.xtend.xtend.ast.ImportStatement; +import org.eclipse.internal.xtend.xtend.ast.JavaExtensionStatement; + +public class ExtensionFactory extends ExpressionFactory { + + public ExtensionFactory() { + super("nofile"); + } + + public ExtensionFactory(final String string) { + super(string); + } + + public ExtensionFile createExtensionFile(final List<ImportStatement> nsimports, final List<ImportStatement> extimports, final List<Extension> extensions, final List<Around> arounds, List<Check> checks) { + return (ExtensionFile) handle(new ExtensionFile(nonNull(nsimports), nonNull(extimports), nonNull(extensions), nonNull(arounds),nonNull(checks))); + } + + public ImportStatement createNsImport(final Identifier t) { + return (ImportStatement) handle(new ImportStatement(t, false)); + } + + public ImportStatement createExtensionFileImport(final Identifier t, final Identifier exported) { + return (ImportStatement) handle(new ImportStatement( t, exported != null)); + } + + public JavaExtensionStatement createJavaExtension(final Identifier name, final Identifier type, + final List<DeclaredParameter> params, final Identifier typeName, final Identifier methodName, final List<Identifier> javaParamTypes, final Identifier cached, final Identifier priv) { + return (JavaExtensionStatement) handle(new JavaExtensionStatement(name, + nonNull(params), type, typeName, methodName, nonNull(javaParamTypes), cached != null, priv != null)); + } + + public ExpressionExtensionStatement createExpressionExtension(final Identifier name, + final Identifier returnType, final List<DeclaredParameter> params, final Expression expr, final Identifier cached, final Identifier priv) { + return (ExpressionExtensionStatement) handle(new ExpressionExtensionStatement( + name, returnType, nonNull(params), expr, cached != null, priv != null)); + } + + public Extension createCreateExtension(final Identifier create, final Identifier returnType, + final Identifier rtn, final Identifier name, final List<DeclaredParameter> params, final Expression expr, final Identifier priv) { + return (CreateExtensionStatement) handle(new CreateExtensionStatement( + name, returnType, rtn!=null ? rtn : null, nonNull(params), expr, priv != null)); + } + + public Around createAround( Identifier pointcut, List<DeclaredParameter> p, boolean wildparams, Expression expr) { + return (Around) handle(new Around(pointcut, nonNull(p),wildparams,expr)); + } + + public Check createCheck(Identifier t, Expression guard, boolean errorSev, Expression msg, Expression expr) { + return (Check) handle(new Check(t,guard,errorSev,msg,expr)); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/ParseException.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/ParseException.java new file mode 100644 index 00000000..f18103e7 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/ParseException.java @@ -0,0 +1,8 @@ +package org.eclipse.internal.xtend.xtend.parser; + +@SuppressWarnings("serial") +public class ParseException extends RuntimeException { + public ParseException(XtendError e) { + super(e.toString()); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/ParseFacade.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/ParseFacade.java new file mode 100644 index 00000000..2534c099 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/ParseFacade.java @@ -0,0 +1,110 @@ +package org.eclipse.internal.xtend.xtend.parser; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; + +import org.antlr.runtime.ANTLRReaderStream; +import org.antlr.runtime.CommonToken; +import org.antlr.runtime.CommonTokenStream; +import org.antlr.runtime.RecognitionException; +import org.eclipse.internal.xtend.expression.ast.Expression; +import org.eclipse.internal.xtend.xtend.ast.ExtensionFile; + +public final class ParseFacade { + private ParseFacade() { + } + + public static Expression expression(String r) { + return expression(new StringReader(r),null); + } + + public static Expression expression(Reader r, + ErrorHandler handler) { + ANTLRReaderStream readerStream; + try { + readerStream = new ANTLRReaderStream(r); + } catch (IOException e2) { + throw new RuntimeException(e2); + } + final ErrorHandler h = getErrorHandler(handler); + try { + return getParser(new ExtensionFactory("nofile"), readerStream, h).expression(); + } catch (final RecognitionException e) { + h.handleError(createError(e, "")); + } + return null; + } + + public static ExtensionFile file(Reader r, String fileName) { + return file(r,fileName,null); + } + + public static ExtensionFile file(Reader r, String fileName, + ErrorHandler handler) { + return file(r,fileName,handler,null); + } + + public static ExtensionFile file(Reader r, String fileName, + ErrorHandler handler, ExtensionFactory factory) { + if (factory == null) + factory = new ExtensionFactory(fileName); + ANTLRReaderStream readerStream; + try { + readerStream = new ANTLRReaderStream(r); + } catch (IOException e2) { + throw new RuntimeException(e2); + } + final ErrorHandler h = getErrorHandler(handler); + try { + return getParser(factory, readerStream, h).file(); + } catch (final RecognitionException e) { + h.handleError(createError(e, "")); + } + return null; + } + + private static XtendLocationAddingParser getParser(ExtensionFactory factory, ANTLRReaderStream readerStream, final ErrorHandler h) { + XtendLexer lex = new XtendLexer(readerStream) { + @Override + public void reportError(RecognitionException e) { + h.handleError(createError(e, this.getErrorMessage(e, this + .getTokenNames()))); + } + }; + + CommonTokenStream str = new CommonTokenStream(); + str.setTokenSource(lex); + XtendLocationAddingParser parser = new XtendLocationAddingParser(str, + factory) { + @Override + public void reportError(RecognitionException e) { + h.handleError(createError(e, this.getErrorMessage(e, this + .getTokenNames()))); + } + }; + return parser; + } + + private static ErrorHandler getErrorHandler(ErrorHandler handler) { + if (handler == null) + handler = new ErrorHandler() { + + public void handleError(XtendError e) { + throw new ParseException(e); + } + }; + final ErrorHandler h = handler; + return h; + } + + protected static XtendError createError(RecognitionException e, String string) { + if (e.token == null) { + return new SyntaxError(e.index, e.line, e.index + 1, string); + } else { + CommonToken t = (CommonToken) e.token; + return new SyntaxError(t.getStartIndex(), t.getStopIndex(), t + .getLine(), string); + } + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/SyntaxError.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/SyntaxError.java new file mode 100644 index 00000000..3c99ffd8 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/SyntaxError.java @@ -0,0 +1,33 @@ +package org.eclipse.internal.xtend.xtend.parser; + + +public class SyntaxError implements XtendError { + private int start,end, line; + private String message; + + + public SyntaxError(int start, int end, int line, String message) { + super(); + this.start = start; + this.end = end; + this.line = line; + this.message = message; + } + public int getEnd() { + return end; + } + public int getLine() { + return line; + } + public String getMessage() { + return message; + } + public int getStart() { + return start; + } + + @Override + public String toString() { + return getMessage()+" on line "+line; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/Xtend.g b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/Xtend.g new file mode 100644 index 00000000..dbb04d2d --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/Xtend.g @@ -0,0 +1,367 @@ +grammar Xtend; +@parser::members { + private ExtensionFactory factory; + public XtendParser(TokenStream stream, ExtensionFactory factory) { + this(stream); + this.factory = factory; + } + + protected Identifier id(Token t) { + if (t == null) + return null; + CommonToken ct = (CommonToken) t; + Identifier id = new Identifier(t.getText()); + id.setStart(ct.getStartIndex()); + id.setEnd(ct.getStopIndex()); + id.setLine(ct.getLine()); + return id; + } +} + +@parser::header { +package org.eclipse.internal.xtend.xtend.parser; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.internal.xtend.expression.ast.*; +import org.eclipse.internal.xtend.xtend.ast.*; +} + +@lexer::header { +package org.eclipse.internal.xtend.xtend.parser; + +import java.util.ArrayList; +import java.util.List; +import java.util.Collections; + +import org.eclipse.internal.xtend.expression.ast.*; +import org.eclipse.internal.xtend.xtend.ast.*; +} + + +file returns [ExtensionFile r] +@init {List nsimports = new ArrayList(), extimports = new ArrayList(), extensions = new ArrayList(), arounds = new ArrayList(), checks = new ArrayList();}: + (nsi=nsImport {nsimports.add(nsi);})* + (exti=extImport {extimports.add(exti);})* + (ext=extension {extensions.add(ext);} | a = around {arounds.add(a);} | c = check {checks.add(c);})* + EOF + { $r = factory.createExtensionFile(nsimports,extimports,extensions,arounds,checks);} +; + +nsImport returns [ImportStatement r]: + 'import' t=type {$r = factory.createNsImport(t);} ';' +; + +extImport returns [ImportStatement r]: + 'extension' t=type (exported='reexport')? ';' { $r = factory.createExtensionFileImport(t,id(exported));} +; + +check returns [Check ext]: + 'context' t=type ('if' guard=expression)? (sev1='ERROR'|'WARNING') msg=expression ':' + expr=expression ';' + {ext = factory.createCheck(t, guard, sev1!=null, msg, expr);} +; + +around returns [Around r] : + 'around' pc=pointcut '(' (p=declaredParameterList (','? wildparams='*')? | wildparams='*')? ')' ':' + expr=expression ';' + { $r = factory.createAround(pc,p,wildparams!=null,expr);} +; + +pointcut returns [Identifier r] : + ( a='*' {$r = id(a);} + |b=identifier{$r = b;}) + ( a1='*' {if ($r!=null)$r.append(id(a1));} + |b1=identifier {if ($r!=null)$r.append(b1);} + |c1='::' {if ($r!=null)$r.append(id(c1));})* +; + + + +extension returns [Extension r] @init {List<Identifier> javaParamTypes=new ArrayList<Identifier>();}: + (priv='private')? (cached='cached')? (rType=type)? name=identifier '(' (params=declaredParameterList)? ')' ':' + + ( 'JAVA' jt=javaType '.' m=identifier '('(pt=javaType {javaParamTypes.add(pt);}(',' pt=javaType {javaParamTypes.add(pt);})*)? ')' ';' + { $r = factory.createJavaExtension(name,rType,params,jt,m,javaParamTypes, id(cached),id(priv));} + | expr=expression ';' + { $r = factory.createExpressionExtension(name,rType,params,expr, id(cached),id(priv)); } + ) + +| (priv='private')? create='create' rType=type (rtn=identifier)? name=identifier '(' (params=declaredParameterList)? ')' ':' + expr=expression ';' + { $r = factory.createCreateExtension(id(create),rType,rtn,name,params,expr,id(priv)); } +; + + +javaType returns [Identifier r] : + i=identifier {$r = i;} + (d='.' {if ($r!=null)$r.append(id(d));}(i1=identifier {if ($r!=null)$r.append(i1);}|i2='Collection' {$r.append(id(i2));}| + i3='List' {if ($r!=null)$r.append(id(i3));}|i4='Set'{if ($r!=null)$r.append(id(i4));}))* +; + +// +// Expressions +// +expression returns [Expression e]: + x=letExpression {$e=x;} +; + +letExpression returns [Expression e] : + 'let' v=identifier '=' varExpr=castedExpression ':' target=expression + {$e=factory.createLetExpression(v,varExpr,target);} +| x=castedExpression {$e=x;} +; + +castedExpression returns [Expression e] : + ('(' type ')' castedExpression)=> + '(' t=type ')' x=chainExpression {$e = factory.createCast(t,x);} + | x=chainExpression {$e=x;} +; + + +chainExpression returns [Expression e] : + x=ifExpression {$e=x;} ( '->' right=ifExpression {$e=factory.createChainExpression($e,right);})* +; + +ifExpression returns [Expression e] : + x=switchExpression {$e=x;}('?' thenPart=switchExpression ':' elsePart=switchExpression {$e=factory.createIf($e,thenPart,elsePart);})? +| 'if' condition=switchExpression 'then' thenPart=switchExpression ('else' elsePart=expression)? {$e=factory.createIf(condition,thenPart,elsePart);} +; + + +switchExpression returns [Expression e=null] @init {List cases = new ArrayList();} : + 'switch' ('(' pred = orExpression ')')? + '{' + ( + 'case' c=orExpression ':' v=orExpression + {cases.add(factory.createCase(c, v));} + )* + 'default' ':' def = orExpression + '}' + {$e = factory.createSwitchExpression(pred,cases,def);} +| x=orExpression {$e=x;} +; + +orExpression returns [Expression e] : + x=andExpression {$e=x;} (name='||' r=andExpression {$e = factory.createBooleanOperation(id(name),$e,r);})* +; + +andExpression returns [Expression e] : + x=impliesExpression {$e=x;} (name='&&' r=impliesExpression {$e = factory.createBooleanOperation(id(name),$e,r);})* +; + +impliesExpression returns [Expression e] : + x=relationalExpression {$e=x;} (name='implies' r=relationalExpression {$e = factory.createBooleanOperation(id(name),$e,r);})* +; + + +relationalExpression returns [Expression e] : + x=additiveExpression {$e=x;} + (name=('==' | '!=' | '>=' | '<=' | '>' | '<') r=additiveExpression {$e = factory.createBinaryOperation(id(name),$e,r);})* +; + + +additiveExpression returns [Expression e] : + x=multiplicativeExpression {$e=x;} + (name=('+'| '-') r=multiplicativeExpression {$e = factory.createBinaryOperation(id(name),$e,r);})* +; + +multiplicativeExpression returns [Expression e]: + x=unaryExpression {$e=x;} + (name=('*' | '/') r=unaryExpression {$e = factory.createBinaryOperation(id(name),$e,r);})* +; + + +unaryExpression returns [Expression e] : + x=infixExpression {$e=x;} +| name='!' x=infixExpression {$e = factory.createOperationCall(id(name),x);} +| name='-' x=infixExpression {$e = factory.createOperationCall(id(name),x);} +; + +infixExpression returns [Expression e] : + x=primaryExpression {$e=x;} ( '.' op=featureCall { if (op!=null) { op.setTarget($e);$e=op;}} )* +; + +primaryExpression returns [Expression e] : + c=StringLiteral { $e = factory.createStringLiteral(id(c));} +| x=featureCall {$e=x;} +| x=booleanLiteral {$e=x;} +| x=numberLiteral {$e=x;} +| x=nullLiteral {$e=x;} +| x=listLiteral {$e=x;} +| x=constructorCall {$e=x;} +| x=globalVarExpression {$e=x;} +| x=paranthesizedExpression {$e=x;} +; + +paranthesizedExpression returns [Expression e] : + '(' x=expression ')' {$e=factory.createParanthesizedExpression(x);} +; + +globalVarExpression returns [GlobalVarExpression e] : + 'GLOBALVAR' name=identifier {$e = factory.createGlobalVarExpression(name);}; + +featureCall returns [FeatureCall e] : + id1=identifier '(' (l=parameterList)? ')' {$e = factory.createOperationCall(id1,l);} +| t=type {$e=factory.createFeatureCall(t,null);} +| x=collectionExpression {$e=x;} +; + +listLiteral returns [Expression e] : + '{' (l=parameterList)? '}' {$e=factory.createListLiteral(l);} +; + +constructorCall returns [Expression e] : + 'new' t=simpleType + {$e= factory.createConstructorCall(t);} +; + +booleanLiteral returns [Expression e=factory.createBooleanLiteral(id(input.LT(1)))] : + 'false'|'true' +; + +nullLiteral returns [Expression e=factory.createNullLiteral(id(input.LT(1)))] : + 'null' +; + +numberLiteral returns [Expression e] : + a=IntLiteral {$e=factory.createIntegerLiteral(id(a));} +| a=IntLiteral b='.' c=IntLiteral {$e=factory.createRealLiteral(id(a).append(id(b)).append(id(c)));} +; + +collectionExpression returns [FeatureCall e] : + name='typeSelect' + '(' t=type ')' { $e = factory.createTypeSelectExpression(id(name),t);} + + |name=('collect' + | 'select' + | 'selectFirst' + | 'reject' + | 'exists' + | 'notExists' + | 'sortBy' + | 'forAll') '(' (var=identifier '|')? x=expression ')' + { $e = factory.createCollectionExpression(id(name),var,x);} +; + +// helper + +declaredParameterList returns [List<DeclaredParameter> l = new ArrayList<DeclaredParameter>()] : + dp=declaredParameter {$l.add(dp);}(',' dp1=declaredParameter {$l.add(dp1);})* +; + +declaredParameter returns [DeclaredParameter dp] : + t=type name=identifier {$dp = factory.createDeclaredParameter(t,name);} +; + +parameterList returns [List<Expression> list = new ArrayList<Expression>()] : + a=expression {$list.add(a);} (',' b=expression {$list.add(b);})* +; + +// type + +type returns [Identifier id] : + a = collectionType {$id=a;}| + b = simpleType {$id=b;} +; + +collectionType returns [Identifier id ] : + cl=( 'Collection' | 'List' | 'Set' ) {$id = id(cl);} + (b='[' id1=simpleType c=']' { $id.append(id(b));$id.append(id1);$id.append(id(c));})? +; + +simpleType returns [Identifier id] : + x=identifier {$id=x;} + (d='::' end=identifier {$id.append(id(d)); $id.append(end);})* +; + +identifier returns [Identifier r] : + x=Identifier {$r=id(x);} + ; +// LEXER + +IntLiteral : ('0' | '1'..'9' '0'..'9'*) ; + +StringLiteral + : '"' ( EscapeSequence | ~('\\'|'"') )* '"' + | '\'' ( EscapeSequence | ~('\''|'\\') )* '\'' + ; + +fragment +EscapeSequence + : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') + | UnicodeEscape + | OctalEscape + ; + +fragment +OctalEscape + : '\\' ('0'..'3') ('0'..'7') ('0'..'7') + | '\\' ('0'..'7') ('0'..'7') + | '\\' ('0'..'7') + ; + +fragment +UnicodeEscape + : '\\' 'u' HexDigit HexDigit HexDigit HexDigit + ; +fragment +HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ; + +Identifier + : ('^')? Letter (Letter|JavaIDDigit)* + ; + +fragment +Letter + : '\u0024' | + '\u0041'..'\u005a' | + '\u005f' | + '\u0061'..'\u007a' | + '\u00c0'..'\u00d6' | + '\u00d8'..'\u00f6' | + '\u00f8'..'\u00ff' | + '\u0100'..'\u1fff' | + '\u3040'..'\u318f' | + '\u3300'..'\u337f' | + '\u3400'..'\u3d2d' | + '\u4e00'..'\u9fff' | + '\uf900'..'\ufaff' + ; + +fragment +JavaIDDigit + : '\u0030'..'\u0039' | + '\u0660'..'\u0669' | + '\u06f0'..'\u06f9' | + '\u0966'..'\u096f' | + '\u09e6'..'\u09ef' | + '\u0a66'..'\u0a6f' | + '\u0ae6'..'\u0aef' | + '\u0b66'..'\u0b6f' | + '\u0be7'..'\u0bef' | + '\u0c66'..'\u0c6f' | + '\u0ce6'..'\u0cef' | + '\u0d66'..'\u0d6f' | + '\u0e50'..'\u0e59' | + '\u0ed0'..'\u0ed9' | + '\u1040'..'\u1049' + ; + +WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;} + ; + +COMMENT + : '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;} + ; + +LINE_COMMENT + : '//' ~('\n'|'\r')* ('\r'? '\n'|EOF) {$channel=HIDDEN;} + ; + + +XPAND_TAG_OPEN + : '\u00AB'; +XPAND_TAG_CLOSE + : '\u00BB'; diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/Xtend.tokens b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/Xtend.tokens new file mode 100644 index 00000000..8e631107 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/Xtend.tokens @@ -0,0 +1,78 @@ +XPAND_TAG_OPEN=16 +JavaIDDigit=12 +Letter=11 +UnicodeEscape=8 +IntLiteral=5 +Identifier=6 +HexDigit=10 +EscapeSequence=7 +WS=13 +OctalEscape=9 +COMMENT=14 +StringLiteral=4 +LINE_COMMENT=15 +XPAND_TAG_CLOSE=17 +'<'=60 +'exists'=75 +'>'=59 +'context'=22 +'case'=49 +'let'=41 +'else'=46 +'selectFirst'=73 +'-'=62 +'reexport'=21 +'?'=44 +'!='=56 +'List'=39 +'>='=57 +'GLOBALVAR'=65 +'||'=52 +'<='=58 +'typeSelect'=70 +'='=42 +'JAVA'=35 +'forAll'=78 +'ERROR'=24 +'collect'=71 +'::'=32 +'around'=27 +'{'=48 +'then'=45 +':'=26 +'new'=66 +'.'=36 +'*'=30 +'sortBy'=77 +'Set'=40 +'notExists'=76 +'}'=51 +'->'=43 +'create'=37 +'extension'=20 +';'=19 +']'=81 +'true'=68 +'default'=50 +'false'=67 +','=29 +'&&'=53 +'['=80 +'/'=63 +'Collection'=38 +'implies'=54 +'reject'=74 +'private'=33 +'|'=79 +')'=31 +'=='=55 +'import'=18 +'if'=23 +'!'=64 +'('=28 +'switch'=47 +'select'=72 +'cached'=34 +'null'=69 +'+'=61 +'WARNING'=25 diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/XtendError.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/XtendError.java new file mode 100644 index 00000000..af663856 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/XtendError.java @@ -0,0 +1,8 @@ +package org.eclipse.internal.xtend.xtend.parser; + +public interface XtendError { + public int getStart(); + public int getEnd(); + public int getLine(); + public String getMessage(); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/XtendLexer.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/XtendLexer.java new file mode 100644 index 00000000..fcaa387d --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/XtendLexer.java @@ -0,0 +1,4061 @@ +// $ANTLR 3.0 ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g 2007-08-13 15:52:06 + +package org.eclipse.internal.xtend.xtend.parser; + +import org.antlr.runtime.CharStream; +import org.antlr.runtime.Lexer; +import org.antlr.runtime.MismatchedSetException; +import org.antlr.runtime.NoViableAltException; +import org.antlr.runtime.RecognitionException; + +public class XtendLexer extends Lexer { + public static final int T79=79; + public static final int IntLiteral=5; + public static final int T29=29; + public static final int HexDigit=10; + public static final int T36=36; + public static final int T58=58; + public static final int T70=70; + public static final int T74=74; + public static final int T35=35; + public static final int T61=61; + public static final int T45=45; + public static final int T20=20; + public static final int T34=34; + public static final int T64=64; + public static final int Letter=11; + public static final int T25=25; + public static final int T18=18; + public static final int T37=37; + public static final int EscapeSequence=7; + public static final int T26=26; + public static final int T32=32; + public static final int T81=81; + public static final int T51=51; + public static final int T46=46; + public static final int T77=77; + public static final int T38=38; + public static final int T41=41; + public static final int T24=24; + public static final int T19=19; + public static final int T69=69; + public static final int T39=39; + public static final int T21=21; + public static final int T62=62; + public static final int T44=44; + public static final int T55=55; + public static final int T73=73; + public static final int T68=68; + public static final int T33=33; + public static final int Identifier=6; + public static final int T22=22; + public static final int T50=50; + public static final int T78=78; + public static final int WS=13; + public static final int T43=43; + public static final int T23=23; + public static final int T28=28; + public static final int T42=42; + public static final int T66=66; + public static final int T40=40; + public static final int COMMENT=14; + public static final int T71=71; + public static final int StringLiteral=4; + public static final int T63=63; + public static final int T57=57; + public static final int LINE_COMMENT=15; + public static final int T72=72; + public static final int T65=65; + public static final int T56=56; + public static final int T76=76; + public static final int T80=80; + public static final int XPAND_TAG_OPEN=16; + public static final int JavaIDDigit=12; + public static final int UnicodeEscape=8; + public static final int T75=75; + public static final int T59=59; + public static final int T48=48; + public static final int T54=54; + public static final int EOF=-1; + public static final int T67=67; + public static final int T47=47; + public static final int Tokens=82; + public static final int T53=53; + public static final int T60=60; + public static final int T31=31; + public static final int OctalEscape=9; + public static final int T49=49; + public static final int T27=27; + public static final int T52=52; + public static final int XPAND_TAG_CLOSE=17; + public static final int T30=30; + public XtendLexer() {;} + public XtendLexer(CharStream input) { + super(input); + } + public String getGrammarFileName() { return "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g"; } + + // $ANTLR start T18 + public void mT18() throws RecognitionException { + try { + int _type = T18; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:13:7: ( 'import' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:13:7: 'import' + { + match("import"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T18 + + // $ANTLR start T19 + public void mT19() throws RecognitionException { + try { + int _type = T19; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:14:7: ( ';' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:14:7: ';' + { + match(';'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T19 + + // $ANTLR start T20 + public void mT20() throws RecognitionException { + try { + int _type = T20; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:15:7: ( 'extension' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:15:7: 'extension' + { + match("extension"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T20 + + // $ANTLR start T21 + public void mT21() throws RecognitionException { + try { + int _type = T21; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:16:7: ( 'reexport' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:16:7: 'reexport' + { + match("reexport"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T21 + + // $ANTLR start T22 + public void mT22() throws RecognitionException { + try { + int _type = T22; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:17:7: ( 'context' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:17:7: 'context' + { + match("context"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T22 + + // $ANTLR start T23 + public void mT23() throws RecognitionException { + try { + int _type = T23; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:18:7: ( 'if' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:18:7: 'if' + { + match("if"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T23 + + // $ANTLR start T24 + public void mT24() throws RecognitionException { + try { + int _type = T24; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:19:7: ( 'ERROR' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:19:7: 'ERROR' + { + match("ERROR"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T24 + + // $ANTLR start T25 + public void mT25() throws RecognitionException { + try { + int _type = T25; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:20:7: ( 'WARNING' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:20:7: 'WARNING' + { + match("WARNING"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T25 + + // $ANTLR start T26 + public void mT26() throws RecognitionException { + try { + int _type = T26; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:21:7: ( ':' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:21:7: ':' + { + match(':'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T26 + + // $ANTLR start T27 + public void mT27() throws RecognitionException { + try { + int _type = T27; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:22:7: ( 'around' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:22:7: 'around' + { + match("around"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T27 + + // $ANTLR start T28 + public void mT28() throws RecognitionException { + try { + int _type = T28; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:23:7: ( '(' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:23:7: '(' + { + match('('); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T28 + + // $ANTLR start T29 + public void mT29() throws RecognitionException { + try { + int _type = T29; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:24:7: ( ',' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:24:7: ',' + { + match(','); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T29 + + // $ANTLR start T30 + public void mT30() throws RecognitionException { + try { + int _type = T30; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:25:7: ( '*' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:25:7: '*' + { + match('*'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T30 + + // $ANTLR start T31 + public void mT31() throws RecognitionException { + try { + int _type = T31; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:26:7: ( ')' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:26:7: ')' + { + match(')'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T31 + + // $ANTLR start T32 + public void mT32() throws RecognitionException { + try { + int _type = T32; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:27:7: ( '::' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:27:7: '::' + { + match("::"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T32 + + // $ANTLR start T33 + public void mT33() throws RecognitionException { + try { + int _type = T33; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:28:7: ( 'private' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:28:7: 'private' + { + match("private"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T33 + + // $ANTLR start T34 + public void mT34() throws RecognitionException { + try { + int _type = T34; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:29:7: ( 'cached' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:29:7: 'cached' + { + match("cached"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T34 + + // $ANTLR start T35 + public void mT35() throws RecognitionException { + try { + int _type = T35; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:30:7: ( 'JAVA' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:30:7: 'JAVA' + { + match("JAVA"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T35 + + // $ANTLR start T36 + public void mT36() throws RecognitionException { + try { + int _type = T36; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:31:7: ( '.' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:31:7: '.' + { + match('.'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T36 + + // $ANTLR start T37 + public void mT37() throws RecognitionException { + try { + int _type = T37; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:32:7: ( 'create' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:32:7: 'create' + { + match("create"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T37 + + // $ANTLR start T38 + public void mT38() throws RecognitionException { + try { + int _type = T38; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:33:7: ( 'Collection' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:33:7: 'Collection' + { + match("Collection"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T38 + + // $ANTLR start T39 + public void mT39() throws RecognitionException { + try { + int _type = T39; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:34:7: ( 'List' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:34:7: 'List' + { + match("List"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T39 + + // $ANTLR start T40 + public void mT40() throws RecognitionException { + try { + int _type = T40; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:35:7: ( 'Set' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:35:7: 'Set' + { + match("Set"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T40 + + // $ANTLR start T41 + public void mT41() throws RecognitionException { + try { + int _type = T41; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:36:7: ( 'let' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:36:7: 'let' + { + match("let"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T41 + + // $ANTLR start T42 + public void mT42() throws RecognitionException { + try { + int _type = T42; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:37:7: ( '=' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:37:7: '=' + { + match('='); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T42 + + // $ANTLR start T43 + public void mT43() throws RecognitionException { + try { + int _type = T43; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:38:7: ( '->' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:38:7: '->' + { + match("->"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T43 + + // $ANTLR start T44 + public void mT44() throws RecognitionException { + try { + int _type = T44; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:39:7: ( '?' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:39:7: '?' + { + match('?'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T44 + + // $ANTLR start T45 + public void mT45() throws RecognitionException { + try { + int _type = T45; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:40:7: ( 'then' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:40:7: 'then' + { + match("then"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T45 + + // $ANTLR start T46 + public void mT46() throws RecognitionException { + try { + int _type = T46; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:41:7: ( 'else' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:41:7: 'else' + { + match("else"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T46 + + // $ANTLR start T47 + public void mT47() throws RecognitionException { + try { + int _type = T47; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:42:7: ( 'switch' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:42:7: 'switch' + { + match("switch"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T47 + + // $ANTLR start T48 + public void mT48() throws RecognitionException { + try { + int _type = T48; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:43:7: ( '{' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:43:7: '{' + { + match('{'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T48 + + // $ANTLR start T49 + public void mT49() throws RecognitionException { + try { + int _type = T49; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:44:7: ( 'case' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:44:7: 'case' + { + match("case"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T49 + + // $ANTLR start T50 + public void mT50() throws RecognitionException { + try { + int _type = T50; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:45:7: ( 'default' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:45:7: 'default' + { + match("default"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T50 + + // $ANTLR start T51 + public void mT51() throws RecognitionException { + try { + int _type = T51; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:46:7: ( '}' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:46:7: '}' + { + match('}'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T51 + + // $ANTLR start T52 + public void mT52() throws RecognitionException { + try { + int _type = T52; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:47:7: ( '||' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:47:7: '||' + { + match("||"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T52 + + // $ANTLR start T53 + public void mT53() throws RecognitionException { + try { + int _type = T53; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:48:7: ( '&&' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:48:7: '&&' + { + match("&&"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T53 + + // $ANTLR start T54 + public void mT54() throws RecognitionException { + try { + int _type = T54; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:49:7: ( 'implies' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:49:7: 'implies' + { + match("implies"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T54 + + // $ANTLR start T55 + public void mT55() throws RecognitionException { + try { + int _type = T55; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:50:7: ( '==' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:50:7: '==' + { + match("=="); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T55 + + // $ANTLR start T56 + public void mT56() throws RecognitionException { + try { + int _type = T56; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:51:7: ( '!=' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:51:7: '!=' + { + match("!="); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T56 + + // $ANTLR start T57 + public void mT57() throws RecognitionException { + try { + int _type = T57; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:52:7: ( '>=' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:52:7: '>=' + { + match(">="); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T57 + + // $ANTLR start T58 + public void mT58() throws RecognitionException { + try { + int _type = T58; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:53:7: ( '<=' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:53:7: '<=' + { + match("<="); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T58 + + // $ANTLR start T59 + public void mT59() throws RecognitionException { + try { + int _type = T59; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:54:7: ( '>' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:54:7: '>' + { + match('>'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T59 + + // $ANTLR start T60 + public void mT60() throws RecognitionException { + try { + int _type = T60; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:55:7: ( '<' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:55:7: '<' + { + match('<'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T60 + + // $ANTLR start T61 + public void mT61() throws RecognitionException { + try { + int _type = T61; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:56:7: ( '+' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:56:7: '+' + { + match('+'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T61 + + // $ANTLR start T62 + public void mT62() throws RecognitionException { + try { + int _type = T62; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:57:7: ( '-' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:57:7: '-' + { + match('-'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T62 + + // $ANTLR start T63 + public void mT63() throws RecognitionException { + try { + int _type = T63; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:58:7: ( '/' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:58:7: '/' + { + match('/'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T63 + + // $ANTLR start T64 + public void mT64() throws RecognitionException { + try { + int _type = T64; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:59:7: ( '!' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:59:7: '!' + { + match('!'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T64 + + // $ANTLR start T65 + public void mT65() throws RecognitionException { + try { + int _type = T65; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:60:7: ( 'GLOBALVAR' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:60:7: 'GLOBALVAR' + { + match("GLOBALVAR"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T65 + + // $ANTLR start T66 + public void mT66() throws RecognitionException { + try { + int _type = T66; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:61:7: ( 'new' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:61:7: 'new' + { + match("new"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T66 + + // $ANTLR start T67 + public void mT67() throws RecognitionException { + try { + int _type = T67; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:62:7: ( 'false' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:62:7: 'false' + { + match("false"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T67 + + // $ANTLR start T68 + public void mT68() throws RecognitionException { + try { + int _type = T68; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:63:7: ( 'true' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:63:7: 'true' + { + match("true"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T68 + + // $ANTLR start T69 + public void mT69() throws RecognitionException { + try { + int _type = T69; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:64:7: ( 'null' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:64:7: 'null' + { + match("null"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T69 + + // $ANTLR start T70 + public void mT70() throws RecognitionException { + try { + int _type = T70; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:65:7: ( 'typeSelect' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:65:7: 'typeSelect' + { + match("typeSelect"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T70 + + // $ANTLR start T71 + public void mT71() throws RecognitionException { + try { + int _type = T71; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:66:7: ( 'collect' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:66:7: 'collect' + { + match("collect"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T71 + + // $ANTLR start T72 + public void mT72() throws RecognitionException { + try { + int _type = T72; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:67:7: ( 'select' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:67:7: 'select' + { + match("select"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T72 + + // $ANTLR start T73 + public void mT73() throws RecognitionException { + try { + int _type = T73; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:68:7: ( 'selectFirst' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:68:7: 'selectFirst' + { + match("selectFirst"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T73 + + // $ANTLR start T74 + public void mT74() throws RecognitionException { + try { + int _type = T74; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:69:7: ( 'reject' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:69:7: 'reject' + { + match("reject"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T74 + + // $ANTLR start T75 + public void mT75() throws RecognitionException { + try { + int _type = T75; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:70:7: ( 'exists' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:70:7: 'exists' + { + match("exists"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T75 + + // $ANTLR start T76 + public void mT76() throws RecognitionException { + try { + int _type = T76; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:71:7: ( 'notExists' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:71:7: 'notExists' + { + match("notExists"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T76 + + // $ANTLR start T77 + public void mT77() throws RecognitionException { + try { + int _type = T77; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:72:7: ( 'sortBy' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:72:7: 'sortBy' + { + match("sortBy"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T77 + + // $ANTLR start T78 + public void mT78() throws RecognitionException { + try { + int _type = T78; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:73:7: ( 'forAll' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:73:7: 'forAll' + { + match("forAll"); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T78 + + // $ANTLR start T79 + public void mT79() throws RecognitionException { + try { + int _type = T79; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:74:7: ( '|' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:74:7: '|' + { + match('|'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T79 + + // $ANTLR start T80 + public void mT80() throws RecognitionException { + try { + int _type = T80; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:75:7: ( '[' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:75:7: '[' + { + match('['); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T80 + + // $ANTLR start T81 + public void mT81() throws RecognitionException { + try { + int _type = T81; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:76:7: ( ']' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:76:7: ']' + { + match(']'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end T81 + + // $ANTLR start IntLiteral + public void mIntLiteral() throws RecognitionException { + try { + int _type = IntLiteral; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:284:14: ( ( '0' | '1' .. '9' ( '0' .. '9' )* ) ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:284:14: ( '0' | '1' .. '9' ( '0' .. '9' )* ) + { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:284:14: ( '0' | '1' .. '9' ( '0' .. '9' )* ) + int alt2=2; + int LA2_0 = input.LA(1); + + if ( (LA2_0=='0') ) { + alt2=1; + } + else if ( ((LA2_0>='1' && LA2_0<='9')) ) { + alt2=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("284:14: ( '0' | '1' .. '9' ( '0' .. '9' )* )", 2, 0, input); + + throw nvae; + } + switch (alt2) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:284:15: '0' + { + match('0'); + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:284:21: '1' .. '9' ( '0' .. '9' )* + { + matchRange('1','9'); + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:284:30: ( '0' .. '9' )* + loop1: + do { + int alt1=2; + int LA1_0 = input.LA(1); + + if ( ((LA1_0>='0' && LA1_0<='9')) ) { + alt1=1; + } + + + switch (alt1) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:284:30: '0' .. '9' + { + matchRange('0','9'); + + } + break; + + default : + break loop1; + } + } while (true); + + + } + break; + + } + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end IntLiteral + + // $ANTLR start StringLiteral + public void mStringLiteral() throws RecognitionException { + try { + int _type = StringLiteral; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:287:8: ( '\"' ( EscapeSequence | ~ ( '\\\\' | '\"' ) )* '\"' | '\\'' ( EscapeSequence | ~ ( '\\'' | '\\\\' ) )* '\\'' ) + int alt5=2; + int LA5_0 = input.LA(1); + + if ( (LA5_0=='\"') ) { + alt5=1; + } + else if ( (LA5_0=='\'') ) { + alt5=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("286:1: StringLiteral : ( '\"' ( EscapeSequence | ~ ( '\\\\' | '\"' ) )* '\"' | '\\'' ( EscapeSequence | ~ ( '\\'' | '\\\\' ) )* '\\'' );", 5, 0, input); + + throw nvae; + } + switch (alt5) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:287:8: '\"' ( EscapeSequence | ~ ( '\\\\' | '\"' ) )* '\"' + { + match('\"'); + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:287:12: ( EscapeSequence | ~ ( '\\\\' | '\"' ) )* + loop3: + do { + int alt3=3; + int LA3_0 = input.LA(1); + + if ( (LA3_0=='\\') ) { + alt3=1; + } + else if ( ((LA3_0>='\u0000' && LA3_0<='!')||(LA3_0>='#' && LA3_0<='[')||(LA3_0>=']' && LA3_0<='\uFFFE')) ) { + alt3=2; + } + + + switch (alt3) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:287:14: EscapeSequence + { + mEscapeSequence(); + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:287:31: ~ ( '\\\\' | '\"' ) + { + if ( (input.LA(1)>='\u0000' && input.LA(1)<='!')||(input.LA(1)>='#' && input.LA(1)<='[')||(input.LA(1)>=']' && input.LA(1)<='\uFFFE') ) { + input.consume(); + + } + else { + MismatchedSetException mse = + new MismatchedSetException(null,input); + recover(mse); throw mse; + } + + + } + break; + + default : + break loop3; + } + } while (true); + + match('\"'); + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:288:8: '\\'' ( EscapeSequence | ~ ( '\\'' | '\\\\' ) )* '\\'' + { + match('\''); + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:288:13: ( EscapeSequence | ~ ( '\\'' | '\\\\' ) )* + loop4: + do { + int alt4=3; + int LA4_0 = input.LA(1); + + if ( (LA4_0=='\\') ) { + alt4=1; + } + else if ( ((LA4_0>='\u0000' && LA4_0<='&')||(LA4_0>='(' && LA4_0<='[')||(LA4_0>=']' && LA4_0<='\uFFFE')) ) { + alt4=2; + } + + + switch (alt4) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:288:15: EscapeSequence + { + mEscapeSequence(); + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:288:32: ~ ( '\\'' | '\\\\' ) + { + if ( (input.LA(1)>='\u0000' && input.LA(1)<='&')||(input.LA(1)>='(' && input.LA(1)<='[')||(input.LA(1)>=']' && input.LA(1)<='\uFFFE') ) { + input.consume(); + + } + else { + MismatchedSetException mse = + new MismatchedSetException(null,input); + recover(mse); throw mse; + } + + + } + break; + + default : + break loop4; + } + } while (true); + + match('\''); + + } + break; + + } + this.type = _type; + } + finally { + } + } + // $ANTLR end StringLiteral + + // $ANTLR start EscapeSequence + public void mEscapeSequence() throws RecognitionException { + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:293:9: ( '\\\\' ( 'b' | 't' | 'n' | 'f' | 'r' | '\\\"' | '\\'' | '\\\\' ) | UnicodeEscape | OctalEscape ) + int alt6=3; + int LA6_0 = input.LA(1); + + if ( (LA6_0=='\\') ) { + switch ( input.LA(2) ) { + case '\"': + case '\'': + case '\\': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + { + alt6=1; + } + break; + case 'u': + { + alt6=2; + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + alt6=3; + } + break; + default: + NoViableAltException nvae = + new NoViableAltException("291:1: fragment EscapeSequence : ( '\\\\' ( 'b' | 't' | 'n' | 'f' | 'r' | '\\\"' | '\\'' | '\\\\' ) | UnicodeEscape | OctalEscape );", 6, 1, input); + + throw nvae; + } + + } + else { + NoViableAltException nvae = + new NoViableAltException("291:1: fragment EscapeSequence : ( '\\\\' ( 'b' | 't' | 'n' | 'f' | 'r' | '\\\"' | '\\'' | '\\\\' ) | UnicodeEscape | OctalEscape );", 6, 0, input); + + throw nvae; + } + switch (alt6) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:293:9: '\\\\' ( 'b' | 't' | 'n' | 'f' | 'r' | '\\\"' | '\\'' | '\\\\' ) + { + match('\\'); + if ( input.LA(1)=='\"'||input.LA(1)=='\''||input.LA(1)=='\\'||input.LA(1)=='b'||input.LA(1)=='f'||input.LA(1)=='n'||input.LA(1)=='r'||input.LA(1)=='t' ) { + input.consume(); + + } + else { + MismatchedSetException mse = + new MismatchedSetException(null,input); + recover(mse); throw mse; + } + + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:294:9: UnicodeEscape + { + mUnicodeEscape(); + + } + break; + case 3 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:295:9: OctalEscape + { + mOctalEscape(); + + } + break; + + } + } + finally { + } + } + // $ANTLR end EscapeSequence + + // $ANTLR start OctalEscape + public void mOctalEscape() throws RecognitionException { + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:300:9: ( '\\\\' ( '0' .. '3' ) ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) ) + int alt7=3; + int LA7_0 = input.LA(1); + + if ( (LA7_0=='\\') ) { + int LA7_1 = input.LA(2); + + if ( ((LA7_1>='0' && LA7_1<='3')) ) { + int LA7_2 = input.LA(3); + + if ( ((LA7_2>='0' && LA7_2<='7')) ) { + int LA7_5 = input.LA(4); + + if ( ((LA7_5>='0' && LA7_5<='7')) ) { + alt7=1; + } + else { + alt7=2;} + } + else { + alt7=3;} + } + else if ( ((LA7_1>='4' && LA7_1<='7')) ) { + int LA7_3 = input.LA(3); + + if ( ((LA7_3>='0' && LA7_3<='7')) ) { + alt7=2; + } + else { + alt7=3;} + } + else { + NoViableAltException nvae = + new NoViableAltException("298:1: fragment OctalEscape : ( '\\\\' ( '0' .. '3' ) ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) );", 7, 1, input); + + throw nvae; + } + } + else { + NoViableAltException nvae = + new NoViableAltException("298:1: fragment OctalEscape : ( '\\\\' ( '0' .. '3' ) ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) );", 7, 0, input); + + throw nvae; + } + switch (alt7) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:300:9: '\\\\' ( '0' .. '3' ) ( '0' .. '7' ) ( '0' .. '7' ) + { + match('\\'); + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:300:14: ( '0' .. '3' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:300:15: '0' .. '3' + { + matchRange('0','3'); + + } + + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:300:25: ( '0' .. '7' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:300:26: '0' .. '7' + { + matchRange('0','7'); + + } + + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:300:36: ( '0' .. '7' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:300:37: '0' .. '7' + { + matchRange('0','7'); + + } + + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:301:9: '\\\\' ( '0' .. '7' ) ( '0' .. '7' ) + { + match('\\'); + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:301:14: ( '0' .. '7' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:301:15: '0' .. '7' + { + matchRange('0','7'); + + } + + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:301:25: ( '0' .. '7' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:301:26: '0' .. '7' + { + matchRange('0','7'); + + } + + + } + break; + case 3 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:302:9: '\\\\' ( '0' .. '7' ) + { + match('\\'); + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:302:14: ( '0' .. '7' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:302:15: '0' .. '7' + { + matchRange('0','7'); + + } + + + } + break; + + } + } + finally { + } + } + // $ANTLR end OctalEscape + + // $ANTLR start UnicodeEscape + public void mUnicodeEscape() throws RecognitionException { + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:307:9: ( '\\\\' 'u' HexDigit HexDigit HexDigit HexDigit ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:307:9: '\\\\' 'u' HexDigit HexDigit HexDigit HexDigit + { + match('\\'); + match('u'); + mHexDigit(); + mHexDigit(); + mHexDigit(); + mHexDigit(); + + } + + } + finally { + } + } + // $ANTLR end UnicodeEscape + + // $ANTLR start HexDigit + public void mHexDigit() throws RecognitionException { + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:310:12: ( ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' ) ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:310:12: ( '0' .. '9' | '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(); + + } + else { + MismatchedSetException mse = + new MismatchedSetException(null,input); + recover(mse); throw mse; + } + + + } + + } + finally { + } + } + // $ANTLR end HexDigit + + // $ANTLR start Identifier + public void mIdentifier() throws RecognitionException { + try { + int _type = Identifier; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:313:9: ( ( '^' )? Letter ( Letter | JavaIDDigit )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:313:9: ( '^' )? Letter ( Letter | JavaIDDigit )* + { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:313:9: ( '^' )? + int alt8=2; + int LA8_0 = input.LA(1); + + if ( (LA8_0=='^') ) { + alt8=1; + } + switch (alt8) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:313:10: '^' + { + match('^'); + + } + break; + + } + + mLetter(); + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:313:23: ( Letter | JavaIDDigit )* + loop9: + do { + int alt9=2; + int LA9_0 = input.LA(1); + + if ( (LA9_0=='$'||(LA9_0>='0' && LA9_0<='9')||(LA9_0>='A' && LA9_0<='Z')||LA9_0=='_'||(LA9_0>='a' && LA9_0<='z')||(LA9_0>='\u00C0' && LA9_0<='\u00D6')||(LA9_0>='\u00D8' && LA9_0<='\u00F6')||(LA9_0>='\u00F8' && LA9_0<='\u1FFF')||(LA9_0>='\u3040' && LA9_0<='\u318F')||(LA9_0>='\u3300' && LA9_0<='\u337F')||(LA9_0>='\u3400' && LA9_0<='\u3D2D')||(LA9_0>='\u4E00' && LA9_0<='\u9FFF')||(LA9_0>='\uF900' && LA9_0<='\uFAFF')) ) { + alt9=1; + } + + + switch (alt9) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g: + { + if ( input.LA(1)=='$'||(input.LA(1)>='0' && input.LA(1)<='9')||(input.LA(1)>='A' && input.LA(1)<='Z')||input.LA(1)=='_'||(input.LA(1)>='a' && input.LA(1)<='z')||(input.LA(1)>='\u00C0' && input.LA(1)<='\u00D6')||(input.LA(1)>='\u00D8' && input.LA(1)<='\u00F6')||(input.LA(1)>='\u00F8' && input.LA(1)<='\u1FFF')||(input.LA(1)>='\u3040' && input.LA(1)<='\u318F')||(input.LA(1)>='\u3300' && input.LA(1)<='\u337F')||(input.LA(1)>='\u3400' && input.LA(1)<='\u3D2D')||(input.LA(1)>='\u4E00' && input.LA(1)<='\u9FFF')||(input.LA(1)>='\uF900' && input.LA(1)<='\uFAFF') ) { + input.consume(); + + } + else { + MismatchedSetException mse = + new MismatchedSetException(null,input); + recover(mse); throw mse; + } + + + } + break; + + default : + break loop9; + } + } while (true); + + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end Identifier + + // $ANTLR start Letter + public void mLetter() throws RecognitionException { + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:318:8: ( '\\u0024' | '\\u0041' .. '\\u005a' | '\\u005f' | '\\u0061' .. '\\u007a' | '\\u00c0' .. '\\u00d6' | '\\u00d8' .. '\\u00f6' | '\\u00f8' .. '\\u00ff' | '\\u0100' .. '\\u1fff' | '\\u3040' .. '\\u318f' | '\\u3300' .. '\\u337f' | '\\u3400' .. '\\u3d2d' | '\\u4e00' .. '\\u9fff' | '\\uf900' .. '\\ufaff' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g: + { + if ( input.LA(1)=='$'||(input.LA(1)>='A' && input.LA(1)<='Z')||input.LA(1)=='_'||(input.LA(1)>='a' && input.LA(1)<='z')||(input.LA(1)>='\u00C0' && input.LA(1)<='\u00D6')||(input.LA(1)>='\u00D8' && input.LA(1)<='\u00F6')||(input.LA(1)>='\u00F8' && input.LA(1)<='\u1FFF')||(input.LA(1)>='\u3040' && input.LA(1)<='\u318F')||(input.LA(1)>='\u3300' && input.LA(1)<='\u337F')||(input.LA(1)>='\u3400' && input.LA(1)<='\u3D2D')||(input.LA(1)>='\u4E00' && input.LA(1)<='\u9FFF')||(input.LA(1)>='\uF900' && input.LA(1)<='\uFAFF') ) { + input.consume(); + + } + else { + MismatchedSetException mse = + new MismatchedSetException(null,input); + recover(mse); throw mse; + } + + + } + + } + finally { + } + } + // $ANTLR end Letter + + // $ANTLR start JavaIDDigit + public void mJavaIDDigit() throws RecognitionException { + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:335:8: ( '\\u0030' .. '\\u0039' | '\\u0660' .. '\\u0669' | '\\u06f0' .. '\\u06f9' | '\\u0966' .. '\\u096f' | '\\u09e6' .. '\\u09ef' | '\\u0a66' .. '\\u0a6f' | '\\u0ae6' .. '\\u0aef' | '\\u0b66' .. '\\u0b6f' | '\\u0be7' .. '\\u0bef' | '\\u0c66' .. '\\u0c6f' | '\\u0ce6' .. '\\u0cef' | '\\u0d66' .. '\\u0d6f' | '\\u0e50' .. '\\u0e59' | '\\u0ed0' .. '\\u0ed9' | '\\u1040' .. '\\u1049' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g: + { + 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)>='\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)>='\u0BE7' && 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)>='\u0E50' && input.LA(1)<='\u0E59')||(input.LA(1)>='\u0ED0' && input.LA(1)<='\u0ED9')||(input.LA(1)>='\u1040' && input.LA(1)<='\u1049') ) { + input.consume(); + + } + else { + MismatchedSetException mse = + new MismatchedSetException(null,input); + recover(mse); throw mse; + } + + + } + + } + finally { + } + } + // $ANTLR end JavaIDDigit + + // $ANTLR start WS + public void mWS() throws RecognitionException { + try { + int _type = WS; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:352:8: ( ( ' ' | '\\r' | '\\t' | '\\u000C' | '\\n' ) ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:352:8: ( ' ' | '\\r' | '\\t' | '\\u000C' | '\\n' ) + { + if ( (input.LA(1)>='\t' && input.LA(1)<='\n')||(input.LA(1)>='\f' && input.LA(1)<='\r')||input.LA(1)==' ' ) { + input.consume(); + + } + else { + MismatchedSetException mse = + new MismatchedSetException(null,input); + recover(mse); throw mse; + } + + channel=HIDDEN; + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end WS + + // $ANTLR start COMMENT + public void mCOMMENT() throws RecognitionException { + try { + int _type = COMMENT; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:356:9: ( '/*' ( options {greedy=false; } : . )* '*/' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:356:9: '/*' ( options {greedy=false; } : . )* '*/' + { + match("/*"); + + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:356:14: ( options {greedy=false; } : . )* + loop10: + do { + int alt10=2; + int LA10_0 = input.LA(1); + + if ( (LA10_0=='*') ) { + int LA10_1 = input.LA(2); + + if ( (LA10_1=='/') ) { + alt10=2; + } + else if ( ((LA10_1>='\u0000' && LA10_1<='.')||(LA10_1>='0' && LA10_1<='\uFFFE')) ) { + alt10=1; + } + + + } + else if ( ((LA10_0>='\u0000' && LA10_0<=')')||(LA10_0>='+' && LA10_0<='\uFFFE')) ) { + alt10=1; + } + + + switch (alt10) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:356:42: . + { + matchAny(); + + } + break; + + default : + break loop10; + } + } while (true); + + match("*/"); + + channel=HIDDEN; + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end COMMENT + + // $ANTLR start LINE_COMMENT + public void mLINE_COMMENT() throws RecognitionException { + try { + int _type = LINE_COMMENT; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:360:7: ( '//' (~ ( '\\n' | '\\r' ) )* ( ( '\\r' )? '\\n' | EOF ) ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:360:7: '//' (~ ( '\\n' | '\\r' ) )* ( ( '\\r' )? '\\n' | EOF ) + { + match("//"); + + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:360:12: (~ ( '\\n' | '\\r' ) )* + loop11: + do { + int alt11=2; + int LA11_0 = input.LA(1); + + if ( ((LA11_0>='\u0000' && LA11_0<='\t')||(LA11_0>='\u000B' && LA11_0<='\f')||(LA11_0>='\u000E' && LA11_0<='\uFFFE')) ) { + alt11=1; + } + + + switch (alt11) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:360:12: ~ ( '\\n' | '\\r' ) + { + if ( (input.LA(1)>='\u0000' && input.LA(1)<='\t')||(input.LA(1)>='\u000B' && input.LA(1)<='\f')||(input.LA(1)>='\u000E' && input.LA(1)<='\uFFFE') ) { + input.consume(); + + } + else { + MismatchedSetException mse = + new MismatchedSetException(null,input); + recover(mse); throw mse; + } + + + } + break; + + default : + break loop11; + } + } while (true); + + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:360:26: ( ( '\\r' )? '\\n' | EOF ) + int alt13=2; + int LA13_0 = input.LA(1); + + if ( (LA13_0=='\n'||LA13_0=='\r') ) { + alt13=1; + } + else { + alt13=2;} + switch (alt13) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:360:27: ( '\\r' )? '\\n' + { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:360:27: ( '\\r' )? + int alt12=2; + int LA12_0 = input.LA(1); + + if ( (LA12_0=='\r') ) { + alt12=1; + } + switch (alt12) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:360:27: '\\r' + { + match('\r'); + + } + break; + + } + + match('\n'); + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:360:38: EOF + { + match(EOF); + + } + break; + + } + + channel=HIDDEN; + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end LINE_COMMENT + + // $ANTLR start XPAND_TAG_OPEN + public void mXPAND_TAG_OPEN() throws RecognitionException { + try { + int _type = XPAND_TAG_OPEN; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:365:4: ( '\\u00AB' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:365:4: '\\u00AB' + { + match('\u00AB'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end XPAND_TAG_OPEN + + // $ANTLR start XPAND_TAG_CLOSE + public void mXPAND_TAG_CLOSE() throws RecognitionException { + try { + int _type = XPAND_TAG_CLOSE; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:367:4: ( '\\u00BB' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:367:4: '\\u00BB' + { + match('\u00BB'); + + } + + this.type = _type; + } + finally { + } + } + // $ANTLR end XPAND_TAG_CLOSE + + public void mTokens() throws RecognitionException { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:10: ( T18 | T19 | T20 | T21 | T22 | T23 | T24 | T25 | T26 | T27 | T28 | T29 | T30 | T31 | T32 | T33 | T34 | T35 | T36 | T37 | T38 | T39 | T40 | T41 | T42 | T43 | T44 | T45 | T46 | T47 | T48 | T49 | T50 | T51 | T52 | T53 | T54 | T55 | T56 | T57 | T58 | T59 | T60 | T61 | T62 | T63 | T64 | T65 | T66 | T67 | T68 | T69 | T70 | T71 | T72 | T73 | T74 | T75 | T76 | T77 | T78 | T79 | T80 | T81 | IntLiteral | StringLiteral | Identifier | WS | COMMENT | LINE_COMMENT | XPAND_TAG_OPEN | XPAND_TAG_CLOSE ) + int alt14=72; + int LA14_0 = input.LA(1); + + if ( (LA14_0=='i') ) { + switch ( input.LA(2) ) { + case 'f': + { + int LA14_47 = input.LA(3); + + if ( (LA14_47=='$'||(LA14_47>='0' && LA14_47<='9')||(LA14_47>='A' && LA14_47<='Z')||LA14_47=='_'||(LA14_47>='a' && LA14_47<='z')||(LA14_47>='\u00C0' && LA14_47<='\u00D6')||(LA14_47>='\u00D8' && LA14_47<='\u00F6')||(LA14_47>='\u00F8' && LA14_47<='\u1FFF')||(LA14_47>='\u3040' && LA14_47<='\u318F')||(LA14_47>='\u3300' && LA14_47<='\u337F')||(LA14_47>='\u3400' && LA14_47<='\u3D2D')||(LA14_47>='\u4E00' && LA14_47<='\u9FFF')||(LA14_47>='\uF900' && LA14_47<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=6;} + } + break; + case 'm': + { + int LA14_48 = input.LA(3); + + if ( (LA14_48=='p') ) { + switch ( input.LA(4) ) { + case 'o': + { + int LA14_128 = input.LA(5); + + if ( (LA14_128=='r') ) { + int LA14_162 = input.LA(6); + + if ( (LA14_162=='t') ) { + int LA14_193 = input.LA(7); + + if ( (LA14_193=='$'||(LA14_193>='0' && LA14_193<='9')||(LA14_193>='A' && LA14_193<='Z')||LA14_193=='_'||(LA14_193>='a' && LA14_193<='z')||(LA14_193>='\u00C0' && LA14_193<='\u00D6')||(LA14_193>='\u00D8' && LA14_193<='\u00F6')||(LA14_193>='\u00F8' && LA14_193<='\u1FFF')||(LA14_193>='\u3040' && LA14_193<='\u318F')||(LA14_193>='\u3300' && LA14_193<='\u337F')||(LA14_193>='\u3400' && LA14_193<='\u3D2D')||(LA14_193>='\u4E00' && LA14_193<='\u9FFF')||(LA14_193>='\uF900' && LA14_193<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=1;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + case 'l': + { + int LA14_129 = input.LA(5); + + if ( (LA14_129=='i') ) { + int LA14_163 = input.LA(6); + + if ( (LA14_163=='e') ) { + int LA14_194 = input.LA(7); + + if ( (LA14_194=='s') ) { + int LA14_218 = input.LA(8); + + if ( (LA14_218=='$'||(LA14_218>='0' && LA14_218<='9')||(LA14_218>='A' && LA14_218<='Z')||LA14_218=='_'||(LA14_218>='a' && LA14_218<='z')||(LA14_218>='\u00C0' && LA14_218<='\u00D6')||(LA14_218>='\u00D8' && LA14_218<='\u00F6')||(LA14_218>='\u00F8' && LA14_218<='\u1FFF')||(LA14_218>='\u3040' && LA14_218<='\u318F')||(LA14_218>='\u3300' && LA14_218<='\u337F')||(LA14_218>='\u3400' && LA14_218<='\u3D2D')||(LA14_218>='\u4E00' && LA14_218<='\u9FFF')||(LA14_218>='\uF900' && LA14_218<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=37;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + default: + alt14=67;} + + } + else { + alt14=67;} + } + break; + default: + alt14=67;} + + } + else if ( (LA14_0==';') ) { + alt14=2; + } + else if ( (LA14_0=='e') ) { + switch ( input.LA(2) ) { + case 'x': + { + switch ( input.LA(3) ) { + case 'i': + { + int LA14_96 = input.LA(4); + + if ( (LA14_96=='s') ) { + int LA14_130 = input.LA(5); + + if ( (LA14_130=='t') ) { + int LA14_164 = input.LA(6); + + if ( (LA14_164=='s') ) { + int LA14_195 = input.LA(7); + + if ( (LA14_195=='$'||(LA14_195>='0' && LA14_195<='9')||(LA14_195>='A' && LA14_195<='Z')||LA14_195=='_'||(LA14_195>='a' && LA14_195<='z')||(LA14_195>='\u00C0' && LA14_195<='\u00D6')||(LA14_195>='\u00D8' && LA14_195<='\u00F6')||(LA14_195>='\u00F8' && LA14_195<='\u1FFF')||(LA14_195>='\u3040' && LA14_195<='\u318F')||(LA14_195>='\u3300' && LA14_195<='\u337F')||(LA14_195>='\u3400' && LA14_195<='\u3D2D')||(LA14_195>='\u4E00' && LA14_195<='\u9FFF')||(LA14_195>='\uF900' && LA14_195<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=58;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + case 't': + { + int LA14_97 = input.LA(4); + + if ( (LA14_97=='e') ) { + int LA14_131 = input.LA(5); + + if ( (LA14_131=='n') ) { + int LA14_165 = input.LA(6); + + if ( (LA14_165=='s') ) { + int LA14_196 = input.LA(7); + + if ( (LA14_196=='i') ) { + int LA14_220 = input.LA(8); + + if ( (LA14_220=='o') ) { + int LA14_241 = input.LA(9); + + if ( (LA14_241=='n') ) { + int LA14_253 = input.LA(10); + + if ( (LA14_253=='$'||(LA14_253>='0' && LA14_253<='9')||(LA14_253>='A' && LA14_253<='Z')||LA14_253=='_'||(LA14_253>='a' && LA14_253<='z')||(LA14_253>='\u00C0' && LA14_253<='\u00D6')||(LA14_253>='\u00D8' && LA14_253<='\u00F6')||(LA14_253>='\u00F8' && LA14_253<='\u1FFF')||(LA14_253>='\u3040' && LA14_253<='\u318F')||(LA14_253>='\u3300' && LA14_253<='\u337F')||(LA14_253>='\u3400' && LA14_253<='\u3D2D')||(LA14_253>='\u4E00' && LA14_253<='\u9FFF')||(LA14_253>='\uF900' && LA14_253<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=3;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + default: + alt14=67;} + + } + break; + case 'l': + { + int LA14_50 = input.LA(3); + + if ( (LA14_50=='s') ) { + int LA14_98 = input.LA(4); + + if ( (LA14_98=='e') ) { + int LA14_132 = input.LA(5); + + if ( (LA14_132=='$'||(LA14_132>='0' && LA14_132<='9')||(LA14_132>='A' && LA14_132<='Z')||LA14_132=='_'||(LA14_132>='a' && LA14_132<='z')||(LA14_132>='\u00C0' && LA14_132<='\u00D6')||(LA14_132>='\u00D8' && LA14_132<='\u00F6')||(LA14_132>='\u00F8' && LA14_132<='\u1FFF')||(LA14_132>='\u3040' && LA14_132<='\u318F')||(LA14_132>='\u3300' && LA14_132<='\u337F')||(LA14_132>='\u3400' && LA14_132<='\u3D2D')||(LA14_132>='\u4E00' && LA14_132<='\u9FFF')||(LA14_132>='\uF900' && LA14_132<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=29;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + default: + alt14=67;} + + } + else if ( (LA14_0=='r') ) { + int LA14_4 = input.LA(2); + + if ( (LA14_4=='e') ) { + switch ( input.LA(3) ) { + case 'j': + { + int LA14_99 = input.LA(4); + + if ( (LA14_99=='e') ) { + int LA14_133 = input.LA(5); + + if ( (LA14_133=='c') ) { + int LA14_167 = input.LA(6); + + if ( (LA14_167=='t') ) { + int LA14_197 = input.LA(7); + + if ( (LA14_197=='$'||(LA14_197>='0' && LA14_197<='9')||(LA14_197>='A' && LA14_197<='Z')||LA14_197=='_'||(LA14_197>='a' && LA14_197<='z')||(LA14_197>='\u00C0' && LA14_197<='\u00D6')||(LA14_197>='\u00D8' && LA14_197<='\u00F6')||(LA14_197>='\u00F8' && LA14_197<='\u1FFF')||(LA14_197>='\u3040' && LA14_197<='\u318F')||(LA14_197>='\u3300' && LA14_197<='\u337F')||(LA14_197>='\u3400' && LA14_197<='\u3D2D')||(LA14_197>='\u4E00' && LA14_197<='\u9FFF')||(LA14_197>='\uF900' && LA14_197<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=57;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + case 'e': + { + int LA14_100 = input.LA(4); + + if ( (LA14_100=='x') ) { + int LA14_134 = input.LA(5); + + if ( (LA14_134=='p') ) { + int LA14_168 = input.LA(6); + + if ( (LA14_168=='o') ) { + int LA14_198 = input.LA(7); + + if ( (LA14_198=='r') ) { + int LA14_222 = input.LA(8); + + if ( (LA14_222=='t') ) { + int LA14_242 = input.LA(9); + + if ( (LA14_242=='$'||(LA14_242>='0' && LA14_242<='9')||(LA14_242>='A' && LA14_242<='Z')||LA14_242=='_'||(LA14_242>='a' && LA14_242<='z')||(LA14_242>='\u00C0' && LA14_242<='\u00D6')||(LA14_242>='\u00D8' && LA14_242<='\u00F6')||(LA14_242>='\u00F8' && LA14_242<='\u1FFF')||(LA14_242>='\u3040' && LA14_242<='\u318F')||(LA14_242>='\u3300' && LA14_242<='\u337F')||(LA14_242>='\u3400' && LA14_242<='\u3D2D')||(LA14_242>='\u4E00' && LA14_242<='\u9FFF')||(LA14_242>='\uF900' && LA14_242<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=4;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + default: + alt14=67;} + + } + else { + alt14=67;} + } + else if ( (LA14_0=='c') ) { + switch ( input.LA(2) ) { + case 'a': + { + switch ( input.LA(3) ) { + case 'c': + { + int LA14_101 = input.LA(4); + + if ( (LA14_101=='h') ) { + int LA14_135 = input.LA(5); + + if ( (LA14_135=='e') ) { + int LA14_169 = input.LA(6); + + if ( (LA14_169=='d') ) { + int LA14_199 = input.LA(7); + + if ( (LA14_199=='$'||(LA14_199>='0' && LA14_199<='9')||(LA14_199>='A' && LA14_199<='Z')||LA14_199=='_'||(LA14_199>='a' && LA14_199<='z')||(LA14_199>='\u00C0' && LA14_199<='\u00D6')||(LA14_199>='\u00D8' && LA14_199<='\u00F6')||(LA14_199>='\u00F8' && LA14_199<='\u1FFF')||(LA14_199>='\u3040' && LA14_199<='\u318F')||(LA14_199>='\u3300' && LA14_199<='\u337F')||(LA14_199>='\u3400' && LA14_199<='\u3D2D')||(LA14_199>='\u4E00' && LA14_199<='\u9FFF')||(LA14_199>='\uF900' && LA14_199<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=17;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + case 's': + { + int LA14_102 = input.LA(4); + + if ( (LA14_102=='e') ) { + int LA14_136 = input.LA(5); + + if ( (LA14_136=='$'||(LA14_136>='0' && LA14_136<='9')||(LA14_136>='A' && LA14_136<='Z')||LA14_136=='_'||(LA14_136>='a' && LA14_136<='z')||(LA14_136>='\u00C0' && LA14_136<='\u00D6')||(LA14_136>='\u00D8' && LA14_136<='\u00F6')||(LA14_136>='\u00F8' && LA14_136<='\u1FFF')||(LA14_136>='\u3040' && LA14_136<='\u318F')||(LA14_136>='\u3300' && LA14_136<='\u337F')||(LA14_136>='\u3400' && LA14_136<='\u3D2D')||(LA14_136>='\u4E00' && LA14_136<='\u9FFF')||(LA14_136>='\uF900' && LA14_136<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=32;} + } + else { + alt14=67;} + } + break; + default: + alt14=67;} + + } + break; + case 'r': + { + int LA14_53 = input.LA(3); + + if ( (LA14_53=='e') ) { + int LA14_103 = input.LA(4); + + if ( (LA14_103=='a') ) { + int LA14_137 = input.LA(5); + + if ( (LA14_137=='t') ) { + int LA14_171 = input.LA(6); + + if ( (LA14_171=='e') ) { + int LA14_200 = input.LA(7); + + if ( (LA14_200=='$'||(LA14_200>='0' && LA14_200<='9')||(LA14_200>='A' && LA14_200<='Z')||LA14_200=='_'||(LA14_200>='a' && LA14_200<='z')||(LA14_200>='\u00C0' && LA14_200<='\u00D6')||(LA14_200>='\u00D8' && LA14_200<='\u00F6')||(LA14_200>='\u00F8' && LA14_200<='\u1FFF')||(LA14_200>='\u3040' && LA14_200<='\u318F')||(LA14_200>='\u3300' && LA14_200<='\u337F')||(LA14_200>='\u3400' && LA14_200<='\u3D2D')||(LA14_200>='\u4E00' && LA14_200<='\u9FFF')||(LA14_200>='\uF900' && LA14_200<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=20;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + case 'o': + { + switch ( input.LA(3) ) { + case 'n': + { + int LA14_104 = input.LA(4); + + if ( (LA14_104=='t') ) { + int LA14_138 = input.LA(5); + + if ( (LA14_138=='e') ) { + int LA14_172 = input.LA(6); + + if ( (LA14_172=='x') ) { + int LA14_201 = input.LA(7); + + if ( (LA14_201=='t') ) { + int LA14_225 = input.LA(8); + + if ( (LA14_225=='$'||(LA14_225>='0' && LA14_225<='9')||(LA14_225>='A' && LA14_225<='Z')||LA14_225=='_'||(LA14_225>='a' && LA14_225<='z')||(LA14_225>='\u00C0' && LA14_225<='\u00D6')||(LA14_225>='\u00D8' && LA14_225<='\u00F6')||(LA14_225>='\u00F8' && LA14_225<='\u1FFF')||(LA14_225>='\u3040' && LA14_225<='\u318F')||(LA14_225>='\u3300' && LA14_225<='\u337F')||(LA14_225>='\u3400' && LA14_225<='\u3D2D')||(LA14_225>='\u4E00' && LA14_225<='\u9FFF')||(LA14_225>='\uF900' && LA14_225<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=5;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + case 'l': + { + int LA14_105 = input.LA(4); + + if ( (LA14_105=='l') ) { + int LA14_139 = input.LA(5); + + if ( (LA14_139=='e') ) { + int LA14_173 = input.LA(6); + + if ( (LA14_173=='c') ) { + int LA14_202 = input.LA(7); + + if ( (LA14_202=='t') ) { + int LA14_226 = input.LA(8); + + if ( (LA14_226=='$'||(LA14_226>='0' && LA14_226<='9')||(LA14_226>='A' && LA14_226<='Z')||LA14_226=='_'||(LA14_226>='a' && LA14_226<='z')||(LA14_226>='\u00C0' && LA14_226<='\u00D6')||(LA14_226>='\u00D8' && LA14_226<='\u00F6')||(LA14_226>='\u00F8' && LA14_226<='\u1FFF')||(LA14_226>='\u3040' && LA14_226<='\u318F')||(LA14_226>='\u3300' && LA14_226<='\u337F')||(LA14_226>='\u3400' && LA14_226<='\u3D2D')||(LA14_226>='\u4E00' && LA14_226<='\u9FFF')||(LA14_226>='\uF900' && LA14_226<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=54;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + default: + alt14=67;} + + } + break; + default: + alt14=67;} + + } + else if ( (LA14_0=='E') ) { + int LA14_6 = input.LA(2); + + if ( (LA14_6=='R') ) { + int LA14_55 = input.LA(3); + + if ( (LA14_55=='R') ) { + int LA14_106 = input.LA(4); + + if ( (LA14_106=='O') ) { + int LA14_140 = input.LA(5); + + if ( (LA14_140=='R') ) { + int LA14_174 = input.LA(6); + + if ( (LA14_174=='$'||(LA14_174>='0' && LA14_174<='9')||(LA14_174>='A' && LA14_174<='Z')||LA14_174=='_'||(LA14_174>='a' && LA14_174<='z')||(LA14_174>='\u00C0' && LA14_174<='\u00D6')||(LA14_174>='\u00D8' && LA14_174<='\u00F6')||(LA14_174>='\u00F8' && LA14_174<='\u1FFF')||(LA14_174>='\u3040' && LA14_174<='\u318F')||(LA14_174>='\u3300' && LA14_174<='\u337F')||(LA14_174>='\u3400' && LA14_174<='\u3D2D')||(LA14_174>='\u4E00' && LA14_174<='\u9FFF')||(LA14_174>='\uF900' && LA14_174<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=7;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else if ( (LA14_0=='W') ) { + int LA14_7 = input.LA(2); + + if ( (LA14_7=='A') ) { + int LA14_56 = input.LA(3); + + if ( (LA14_56=='R') ) { + int LA14_107 = input.LA(4); + + if ( (LA14_107=='N') ) { + int LA14_141 = input.LA(5); + + if ( (LA14_141=='I') ) { + int LA14_175 = input.LA(6); + + if ( (LA14_175=='N') ) { + int LA14_204 = input.LA(7); + + if ( (LA14_204=='G') ) { + int LA14_227 = input.LA(8); + + if ( (LA14_227=='$'||(LA14_227>='0' && LA14_227<='9')||(LA14_227>='A' && LA14_227<='Z')||LA14_227=='_'||(LA14_227>='a' && LA14_227<='z')||(LA14_227>='\u00C0' && LA14_227<='\u00D6')||(LA14_227>='\u00D8' && LA14_227<='\u00F6')||(LA14_227>='\u00F8' && LA14_227<='\u1FFF')||(LA14_227>='\u3040' && LA14_227<='\u318F')||(LA14_227>='\u3300' && LA14_227<='\u337F')||(LA14_227>='\u3400' && LA14_227<='\u3D2D')||(LA14_227>='\u4E00' && LA14_227<='\u9FFF')||(LA14_227>='\uF900' && LA14_227<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=8;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else if ( (LA14_0==':') ) { + int LA14_8 = input.LA(2); + + if ( (LA14_8==':') ) { + alt14=15; + } + else { + alt14=9;} + } + else if ( (LA14_0=='a') ) { + int LA14_9 = input.LA(2); + + if ( (LA14_9=='r') ) { + int LA14_59 = input.LA(3); + + if ( (LA14_59=='o') ) { + int LA14_108 = input.LA(4); + + if ( (LA14_108=='u') ) { + int LA14_142 = input.LA(5); + + if ( (LA14_142=='n') ) { + int LA14_176 = input.LA(6); + + if ( (LA14_176=='d') ) { + int LA14_205 = input.LA(7); + + if ( (LA14_205=='$'||(LA14_205>='0' && LA14_205<='9')||(LA14_205>='A' && LA14_205<='Z')||LA14_205=='_'||(LA14_205>='a' && LA14_205<='z')||(LA14_205>='\u00C0' && LA14_205<='\u00D6')||(LA14_205>='\u00D8' && LA14_205<='\u00F6')||(LA14_205>='\u00F8' && LA14_205<='\u1FFF')||(LA14_205>='\u3040' && LA14_205<='\u318F')||(LA14_205>='\u3300' && LA14_205<='\u337F')||(LA14_205>='\u3400' && LA14_205<='\u3D2D')||(LA14_205>='\u4E00' && LA14_205<='\u9FFF')||(LA14_205>='\uF900' && LA14_205<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=10;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else if ( (LA14_0=='(') ) { + alt14=11; + } + else if ( (LA14_0==',') ) { + alt14=12; + } + else if ( (LA14_0=='*') ) { + alt14=13; + } + else if ( (LA14_0==')') ) { + alt14=14; + } + else if ( (LA14_0=='p') ) { + int LA14_14 = input.LA(2); + + if ( (LA14_14=='r') ) { + int LA14_60 = input.LA(3); + + if ( (LA14_60=='i') ) { + int LA14_109 = input.LA(4); + + if ( (LA14_109=='v') ) { + int LA14_143 = input.LA(5); + + if ( (LA14_143=='a') ) { + int LA14_177 = input.LA(6); + + if ( (LA14_177=='t') ) { + int LA14_206 = input.LA(7); + + if ( (LA14_206=='e') ) { + int LA14_229 = input.LA(8); + + if ( (LA14_229=='$'||(LA14_229>='0' && LA14_229<='9')||(LA14_229>='A' && LA14_229<='Z')||LA14_229=='_'||(LA14_229>='a' && LA14_229<='z')||(LA14_229>='\u00C0' && LA14_229<='\u00D6')||(LA14_229>='\u00D8' && LA14_229<='\u00F6')||(LA14_229>='\u00F8' && LA14_229<='\u1FFF')||(LA14_229>='\u3040' && LA14_229<='\u318F')||(LA14_229>='\u3300' && LA14_229<='\u337F')||(LA14_229>='\u3400' && LA14_229<='\u3D2D')||(LA14_229>='\u4E00' && LA14_229<='\u9FFF')||(LA14_229>='\uF900' && LA14_229<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=16;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else if ( (LA14_0=='J') ) { + int LA14_15 = input.LA(2); + + if ( (LA14_15=='A') ) { + int LA14_61 = input.LA(3); + + if ( (LA14_61=='V') ) { + int LA14_110 = input.LA(4); + + if ( (LA14_110=='A') ) { + int LA14_144 = input.LA(5); + + if ( (LA14_144=='$'||(LA14_144>='0' && LA14_144<='9')||(LA14_144>='A' && LA14_144<='Z')||LA14_144=='_'||(LA14_144>='a' && LA14_144<='z')||(LA14_144>='\u00C0' && LA14_144<='\u00D6')||(LA14_144>='\u00D8' && LA14_144<='\u00F6')||(LA14_144>='\u00F8' && LA14_144<='\u1FFF')||(LA14_144>='\u3040' && LA14_144<='\u318F')||(LA14_144>='\u3300' && LA14_144<='\u337F')||(LA14_144>='\u3400' && LA14_144<='\u3D2D')||(LA14_144>='\u4E00' && LA14_144<='\u9FFF')||(LA14_144>='\uF900' && LA14_144<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=18;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else if ( (LA14_0=='.') ) { + alt14=19; + } + else if ( (LA14_0=='C') ) { + int LA14_17 = input.LA(2); + + if ( (LA14_17=='o') ) { + int LA14_62 = input.LA(3); + + if ( (LA14_62=='l') ) { + int LA14_111 = input.LA(4); + + if ( (LA14_111=='l') ) { + int LA14_145 = input.LA(5); + + if ( (LA14_145=='e') ) { + int LA14_179 = input.LA(6); + + if ( (LA14_179=='c') ) { + int LA14_207 = input.LA(7); + + if ( (LA14_207=='t') ) { + int LA14_230 = input.LA(8); + + if ( (LA14_230=='i') ) { + int LA14_247 = input.LA(9); + + if ( (LA14_247=='o') ) { + int LA14_255 = input.LA(10); + + if ( (LA14_255=='n') ) { + int LA14_261 = input.LA(11); + + if ( (LA14_261=='$'||(LA14_261>='0' && LA14_261<='9')||(LA14_261>='A' && LA14_261<='Z')||LA14_261=='_'||(LA14_261>='a' && LA14_261<='z')||(LA14_261>='\u00C0' && LA14_261<='\u00D6')||(LA14_261>='\u00D8' && LA14_261<='\u00F6')||(LA14_261>='\u00F8' && LA14_261<='\u1FFF')||(LA14_261>='\u3040' && LA14_261<='\u318F')||(LA14_261>='\u3300' && LA14_261<='\u337F')||(LA14_261>='\u3400' && LA14_261<='\u3D2D')||(LA14_261>='\u4E00' && LA14_261<='\u9FFF')||(LA14_261>='\uF900' && LA14_261<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=21;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else if ( (LA14_0=='L') ) { + int LA14_18 = input.LA(2); + + if ( (LA14_18=='i') ) { + int LA14_63 = input.LA(3); + + if ( (LA14_63=='s') ) { + int LA14_112 = input.LA(4); + + if ( (LA14_112=='t') ) { + int LA14_146 = input.LA(5); + + if ( (LA14_146=='$'||(LA14_146>='0' && LA14_146<='9')||(LA14_146>='A' && LA14_146<='Z')||LA14_146=='_'||(LA14_146>='a' && LA14_146<='z')||(LA14_146>='\u00C0' && LA14_146<='\u00D6')||(LA14_146>='\u00D8' && LA14_146<='\u00F6')||(LA14_146>='\u00F8' && LA14_146<='\u1FFF')||(LA14_146>='\u3040' && LA14_146<='\u318F')||(LA14_146>='\u3300' && LA14_146<='\u337F')||(LA14_146>='\u3400' && LA14_146<='\u3D2D')||(LA14_146>='\u4E00' && LA14_146<='\u9FFF')||(LA14_146>='\uF900' && LA14_146<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=22;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else if ( (LA14_0=='S') ) { + int LA14_19 = input.LA(2); + + if ( (LA14_19=='e') ) { + int LA14_64 = input.LA(3); + + if ( (LA14_64=='t') ) { + int LA14_113 = input.LA(4); + + if ( (LA14_113=='$'||(LA14_113>='0' && LA14_113<='9')||(LA14_113>='A' && LA14_113<='Z')||LA14_113=='_'||(LA14_113>='a' && LA14_113<='z')||(LA14_113>='\u00C0' && LA14_113<='\u00D6')||(LA14_113>='\u00D8' && LA14_113<='\u00F6')||(LA14_113>='\u00F8' && LA14_113<='\u1FFF')||(LA14_113>='\u3040' && LA14_113<='\u318F')||(LA14_113>='\u3300' && LA14_113<='\u337F')||(LA14_113>='\u3400' && LA14_113<='\u3D2D')||(LA14_113>='\u4E00' && LA14_113<='\u9FFF')||(LA14_113>='\uF900' && LA14_113<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=23;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else if ( (LA14_0=='l') ) { + int LA14_20 = input.LA(2); + + if ( (LA14_20=='e') ) { + int LA14_65 = input.LA(3); + + if ( (LA14_65=='t') ) { + int LA14_114 = input.LA(4); + + if ( (LA14_114=='$'||(LA14_114>='0' && LA14_114<='9')||(LA14_114>='A' && LA14_114<='Z')||LA14_114=='_'||(LA14_114>='a' && LA14_114<='z')||(LA14_114>='\u00C0' && LA14_114<='\u00D6')||(LA14_114>='\u00D8' && LA14_114<='\u00F6')||(LA14_114>='\u00F8' && LA14_114<='\u1FFF')||(LA14_114>='\u3040' && LA14_114<='\u318F')||(LA14_114>='\u3300' && LA14_114<='\u337F')||(LA14_114>='\u3400' && LA14_114<='\u3D2D')||(LA14_114>='\u4E00' && LA14_114<='\u9FFF')||(LA14_114>='\uF900' && LA14_114<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=24;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else if ( (LA14_0=='=') ) { + int LA14_21 = input.LA(2); + + if ( (LA14_21=='=') ) { + alt14=38; + } + else { + alt14=25;} + } + else if ( (LA14_0=='-') ) { + int LA14_22 = input.LA(2); + + if ( (LA14_22=='>') ) { + alt14=26; + } + else { + alt14=45;} + } + else if ( (LA14_0=='?') ) { + alt14=27; + } + else if ( (LA14_0=='t') ) { + switch ( input.LA(2) ) { + case 'h': + { + int LA14_70 = input.LA(3); + + if ( (LA14_70=='e') ) { + int LA14_115 = input.LA(4); + + if ( (LA14_115=='n') ) { + int LA14_149 = input.LA(5); + + if ( (LA14_149=='$'||(LA14_149>='0' && LA14_149<='9')||(LA14_149>='A' && LA14_149<='Z')||LA14_149=='_'||(LA14_149>='a' && LA14_149<='z')||(LA14_149>='\u00C0' && LA14_149<='\u00D6')||(LA14_149>='\u00D8' && LA14_149<='\u00F6')||(LA14_149>='\u00F8' && LA14_149<='\u1FFF')||(LA14_149>='\u3040' && LA14_149<='\u318F')||(LA14_149>='\u3300' && LA14_149<='\u337F')||(LA14_149>='\u3400' && LA14_149<='\u3D2D')||(LA14_149>='\u4E00' && LA14_149<='\u9FFF')||(LA14_149>='\uF900' && LA14_149<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=28;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + case 'r': + { + int LA14_71 = input.LA(3); + + if ( (LA14_71=='u') ) { + int LA14_116 = input.LA(4); + + if ( (LA14_116=='e') ) { + int LA14_150 = input.LA(5); + + if ( (LA14_150=='$'||(LA14_150>='0' && LA14_150<='9')||(LA14_150>='A' && LA14_150<='Z')||LA14_150=='_'||(LA14_150>='a' && LA14_150<='z')||(LA14_150>='\u00C0' && LA14_150<='\u00D6')||(LA14_150>='\u00D8' && LA14_150<='\u00F6')||(LA14_150>='\u00F8' && LA14_150<='\u1FFF')||(LA14_150>='\u3040' && LA14_150<='\u318F')||(LA14_150>='\u3300' && LA14_150<='\u337F')||(LA14_150>='\u3400' && LA14_150<='\u3D2D')||(LA14_150>='\u4E00' && LA14_150<='\u9FFF')||(LA14_150>='\uF900' && LA14_150<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=51;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + case 'y': + { + int LA14_72 = input.LA(3); + + if ( (LA14_72=='p') ) { + int LA14_117 = input.LA(4); + + if ( (LA14_117=='e') ) { + int LA14_151 = input.LA(5); + + if ( (LA14_151=='S') ) { + int LA14_183 = input.LA(6); + + if ( (LA14_183=='e') ) { + int LA14_208 = input.LA(7); + + if ( (LA14_208=='l') ) { + int LA14_231 = input.LA(8); + + if ( (LA14_231=='e') ) { + int LA14_248 = input.LA(9); + + if ( (LA14_248=='c') ) { + int LA14_256 = input.LA(10); + + if ( (LA14_256=='t') ) { + int LA14_262 = input.LA(11); + + if ( (LA14_262=='$'||(LA14_262>='0' && LA14_262<='9')||(LA14_262>='A' && LA14_262<='Z')||LA14_262=='_'||(LA14_262>='a' && LA14_262<='z')||(LA14_262>='\u00C0' && LA14_262<='\u00D6')||(LA14_262>='\u00D8' && LA14_262<='\u00F6')||(LA14_262>='\u00F8' && LA14_262<='\u1FFF')||(LA14_262>='\u3040' && LA14_262<='\u318F')||(LA14_262>='\u3300' && LA14_262<='\u337F')||(LA14_262>='\u3400' && LA14_262<='\u3D2D')||(LA14_262>='\u4E00' && LA14_262<='\u9FFF')||(LA14_262>='\uF900' && LA14_262<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=53;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + default: + alt14=67;} + + } + else if ( (LA14_0=='s') ) { + switch ( input.LA(2) ) { + case 'w': + { + int LA14_73 = input.LA(3); + + if ( (LA14_73=='i') ) { + int LA14_118 = input.LA(4); + + if ( (LA14_118=='t') ) { + int LA14_152 = input.LA(5); + + if ( (LA14_152=='c') ) { + int LA14_184 = input.LA(6); + + if ( (LA14_184=='h') ) { + int LA14_209 = input.LA(7); + + if ( (LA14_209=='$'||(LA14_209>='0' && LA14_209<='9')||(LA14_209>='A' && LA14_209<='Z')||LA14_209=='_'||(LA14_209>='a' && LA14_209<='z')||(LA14_209>='\u00C0' && LA14_209<='\u00D6')||(LA14_209>='\u00D8' && LA14_209<='\u00F6')||(LA14_209>='\u00F8' && LA14_209<='\u1FFF')||(LA14_209>='\u3040' && LA14_209<='\u318F')||(LA14_209>='\u3300' && LA14_209<='\u337F')||(LA14_209>='\u3400' && LA14_209<='\u3D2D')||(LA14_209>='\u4E00' && LA14_209<='\u9FFF')||(LA14_209>='\uF900' && LA14_209<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=30;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + case 'e': + { + int LA14_74 = input.LA(3); + + if ( (LA14_74=='l') ) { + int LA14_119 = input.LA(4); + + if ( (LA14_119=='e') ) { + int LA14_153 = input.LA(5); + + if ( (LA14_153=='c') ) { + int LA14_185 = input.LA(6); + + if ( (LA14_185=='t') ) { + int LA14_210 = input.LA(7); + + if ( (LA14_210=='F') ) { + int LA14_233 = input.LA(8); + + if ( (LA14_233=='i') ) { + int LA14_249 = input.LA(9); + + if ( (LA14_249=='r') ) { + int LA14_257 = input.LA(10); + + if ( (LA14_257=='s') ) { + int LA14_263 = input.LA(11); + + if ( (LA14_263=='t') ) { + int LA14_268 = input.LA(12); + + if ( (LA14_268=='$'||(LA14_268>='0' && LA14_268<='9')||(LA14_268>='A' && LA14_268<='Z')||LA14_268=='_'||(LA14_268>='a' && LA14_268<='z')||(LA14_268>='\u00C0' && LA14_268<='\u00D6')||(LA14_268>='\u00D8' && LA14_268<='\u00F6')||(LA14_268>='\u00F8' && LA14_268<='\u1FFF')||(LA14_268>='\u3040' && LA14_268<='\u318F')||(LA14_268>='\u3300' && LA14_268<='\u337F')||(LA14_268>='\u3400' && LA14_268<='\u3D2D')||(LA14_268>='\u4E00' && LA14_268<='\u9FFF')||(LA14_268>='\uF900' && LA14_268<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=56;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else if ( (LA14_210=='$'||(LA14_210>='0' && LA14_210<='9')||(LA14_210>='A' && LA14_210<='E')||(LA14_210>='G' && LA14_210<='Z')||LA14_210=='_'||(LA14_210>='a' && LA14_210<='z')||(LA14_210>='\u00C0' && LA14_210<='\u00D6')||(LA14_210>='\u00D8' && LA14_210<='\u00F6')||(LA14_210>='\u00F8' && LA14_210<='\u1FFF')||(LA14_210>='\u3040' && LA14_210<='\u318F')||(LA14_210>='\u3300' && LA14_210<='\u337F')||(LA14_210>='\u3400' && LA14_210<='\u3D2D')||(LA14_210>='\u4E00' && LA14_210<='\u9FFF')||(LA14_210>='\uF900' && LA14_210<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=55;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + case 'o': + { + int LA14_75 = input.LA(3); + + if ( (LA14_75=='r') ) { + int LA14_120 = input.LA(4); + + if ( (LA14_120=='t') ) { + int LA14_154 = input.LA(5); + + if ( (LA14_154=='B') ) { + int LA14_186 = input.LA(6); + + if ( (LA14_186=='y') ) { + int LA14_211 = input.LA(7); + + if ( (LA14_211=='$'||(LA14_211>='0' && LA14_211<='9')||(LA14_211>='A' && LA14_211<='Z')||LA14_211=='_'||(LA14_211>='a' && LA14_211<='z')||(LA14_211>='\u00C0' && LA14_211<='\u00D6')||(LA14_211>='\u00D8' && LA14_211<='\u00F6')||(LA14_211>='\u00F8' && LA14_211<='\u1FFF')||(LA14_211>='\u3040' && LA14_211<='\u318F')||(LA14_211>='\u3300' && LA14_211<='\u337F')||(LA14_211>='\u3400' && LA14_211<='\u3D2D')||(LA14_211>='\u4E00' && LA14_211<='\u9FFF')||(LA14_211>='\uF900' && LA14_211<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=60;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + default: + alt14=67;} + + } + else if ( (LA14_0=='{') ) { + alt14=31; + } + else if ( (LA14_0=='d') ) { + int LA14_27 = input.LA(2); + + if ( (LA14_27=='e') ) { + int LA14_76 = input.LA(3); + + if ( (LA14_76=='f') ) { + int LA14_121 = input.LA(4); + + if ( (LA14_121=='a') ) { + int LA14_155 = input.LA(5); + + if ( (LA14_155=='u') ) { + int LA14_187 = input.LA(6); + + if ( (LA14_187=='l') ) { + int LA14_212 = input.LA(7); + + if ( (LA14_212=='t') ) { + int LA14_236 = input.LA(8); + + if ( (LA14_236=='$'||(LA14_236>='0' && LA14_236<='9')||(LA14_236>='A' && LA14_236<='Z')||LA14_236=='_'||(LA14_236>='a' && LA14_236<='z')||(LA14_236>='\u00C0' && LA14_236<='\u00D6')||(LA14_236>='\u00D8' && LA14_236<='\u00F6')||(LA14_236>='\u00F8' && LA14_236<='\u1FFF')||(LA14_236>='\u3040' && LA14_236<='\u318F')||(LA14_236>='\u3300' && LA14_236<='\u337F')||(LA14_236>='\u3400' && LA14_236<='\u3D2D')||(LA14_236>='\u4E00' && LA14_236<='\u9FFF')||(LA14_236>='\uF900' && LA14_236<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=33;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else if ( (LA14_0=='}') ) { + alt14=34; + } + else if ( (LA14_0=='|') ) { + int LA14_29 = input.LA(2); + + if ( (LA14_29=='|') ) { + alt14=35; + } + else { + alt14=62;} + } + else if ( (LA14_0=='&') ) { + alt14=36; + } + else if ( (LA14_0=='!') ) { + int LA14_31 = input.LA(2); + + if ( (LA14_31=='=') ) { + alt14=39; + } + else { + alt14=47;} + } + else if ( (LA14_0=='>') ) { + int LA14_32 = input.LA(2); + + if ( (LA14_32=='=') ) { + alt14=40; + } + else { + alt14=42;} + } + else if ( (LA14_0=='<') ) { + int LA14_33 = input.LA(2); + + if ( (LA14_33=='=') ) { + alt14=41; + } + else { + alt14=43;} + } + else if ( (LA14_0=='+') ) { + alt14=44; + } + else if ( (LA14_0=='/') ) { + switch ( input.LA(2) ) { + case '*': + { + alt14=69; + } + break; + case '/': + { + alt14=70; + } + break; + default: + alt14=46;} + + } + else if ( (LA14_0=='G') ) { + int LA14_36 = input.LA(2); + + if ( (LA14_36=='L') ) { + int LA14_88 = input.LA(3); + + if ( (LA14_88=='O') ) { + int LA14_122 = input.LA(4); + + if ( (LA14_122=='B') ) { + int LA14_156 = input.LA(5); + + if ( (LA14_156=='A') ) { + int LA14_188 = input.LA(6); + + if ( (LA14_188=='L') ) { + int LA14_213 = input.LA(7); + + if ( (LA14_213=='V') ) { + int LA14_237 = input.LA(8); + + if ( (LA14_237=='A') ) { + int LA14_251 = input.LA(9); + + if ( (LA14_251=='R') ) { + int LA14_258 = input.LA(10); + + if ( (LA14_258=='$'||(LA14_258>='0' && LA14_258<='9')||(LA14_258>='A' && LA14_258<='Z')||LA14_258=='_'||(LA14_258>='a' && LA14_258<='z')||(LA14_258>='\u00C0' && LA14_258<='\u00D6')||(LA14_258>='\u00D8' && LA14_258<='\u00F6')||(LA14_258>='\u00F8' && LA14_258<='\u1FFF')||(LA14_258>='\u3040' && LA14_258<='\u318F')||(LA14_258>='\u3300' && LA14_258<='\u337F')||(LA14_258>='\u3400' && LA14_258<='\u3D2D')||(LA14_258>='\u4E00' && LA14_258<='\u9FFF')||(LA14_258>='\uF900' && LA14_258<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=48;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else if ( (LA14_0=='n') ) { + switch ( input.LA(2) ) { + case 'u': + { + int LA14_89 = input.LA(3); + + if ( (LA14_89=='l') ) { + int LA14_123 = input.LA(4); + + if ( (LA14_123=='l') ) { + int LA14_157 = input.LA(5); + + if ( (LA14_157=='$'||(LA14_157>='0' && LA14_157<='9')||(LA14_157>='A' && LA14_157<='Z')||LA14_157=='_'||(LA14_157>='a' && LA14_157<='z')||(LA14_157>='\u00C0' && LA14_157<='\u00D6')||(LA14_157>='\u00D8' && LA14_157<='\u00F6')||(LA14_157>='\u00F8' && LA14_157<='\u1FFF')||(LA14_157>='\u3040' && LA14_157<='\u318F')||(LA14_157>='\u3300' && LA14_157<='\u337F')||(LA14_157>='\u3400' && LA14_157<='\u3D2D')||(LA14_157>='\u4E00' && LA14_157<='\u9FFF')||(LA14_157>='\uF900' && LA14_157<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=52;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + case 'o': + { + int LA14_90 = input.LA(3); + + if ( (LA14_90=='t') ) { + int LA14_124 = input.LA(4); + + if ( (LA14_124=='E') ) { + int LA14_158 = input.LA(5); + + if ( (LA14_158=='x') ) { + int LA14_190 = input.LA(6); + + if ( (LA14_190=='i') ) { + int LA14_214 = input.LA(7); + + if ( (LA14_214=='s') ) { + int LA14_238 = input.LA(8); + + if ( (LA14_238=='t') ) { + int LA14_252 = input.LA(9); + + if ( (LA14_252=='s') ) { + int LA14_259 = input.LA(10); + + if ( (LA14_259=='$'||(LA14_259>='0' && LA14_259<='9')||(LA14_259>='A' && LA14_259<='Z')||LA14_259=='_'||(LA14_259>='a' && LA14_259<='z')||(LA14_259>='\u00C0' && LA14_259<='\u00D6')||(LA14_259>='\u00D8' && LA14_259<='\u00F6')||(LA14_259>='\u00F8' && LA14_259<='\u1FFF')||(LA14_259>='\u3040' && LA14_259<='\u318F')||(LA14_259>='\u3300' && LA14_259<='\u337F')||(LA14_259>='\u3400' && LA14_259<='\u3D2D')||(LA14_259>='\u4E00' && LA14_259<='\u9FFF')||(LA14_259>='\uF900' && LA14_259<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=59;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + case 'e': + { + int LA14_91 = input.LA(3); + + if ( (LA14_91=='w') ) { + int LA14_125 = input.LA(4); + + if ( (LA14_125=='$'||(LA14_125>='0' && LA14_125<='9')||(LA14_125>='A' && LA14_125<='Z')||LA14_125=='_'||(LA14_125>='a' && LA14_125<='z')||(LA14_125>='\u00C0' && LA14_125<='\u00D6')||(LA14_125>='\u00D8' && LA14_125<='\u00F6')||(LA14_125>='\u00F8' && LA14_125<='\u1FFF')||(LA14_125>='\u3040' && LA14_125<='\u318F')||(LA14_125>='\u3300' && LA14_125<='\u337F')||(LA14_125>='\u3400' && LA14_125<='\u3D2D')||(LA14_125>='\u4E00' && LA14_125<='\u9FFF')||(LA14_125>='\uF900' && LA14_125<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=49;} + } + else { + alt14=67;} + } + break; + default: + alt14=67;} + + } + else if ( (LA14_0=='f') ) { + switch ( input.LA(2) ) { + case 'a': + { + int LA14_92 = input.LA(3); + + if ( (LA14_92=='l') ) { + int LA14_126 = input.LA(4); + + if ( (LA14_126=='s') ) { + int LA14_160 = input.LA(5); + + if ( (LA14_160=='e') ) { + int LA14_191 = input.LA(6); + + if ( (LA14_191=='$'||(LA14_191>='0' && LA14_191<='9')||(LA14_191>='A' && LA14_191<='Z')||LA14_191=='_'||(LA14_191>='a' && LA14_191<='z')||(LA14_191>='\u00C0' && LA14_191<='\u00D6')||(LA14_191>='\u00D8' && LA14_191<='\u00F6')||(LA14_191>='\u00F8' && LA14_191<='\u1FFF')||(LA14_191>='\u3040' && LA14_191<='\u318F')||(LA14_191>='\u3300' && LA14_191<='\u337F')||(LA14_191>='\u3400' && LA14_191<='\u3D2D')||(LA14_191>='\u4E00' && LA14_191<='\u9FFF')||(LA14_191>='\uF900' && LA14_191<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=50;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + case 'o': + { + int LA14_93 = input.LA(3); + + if ( (LA14_93=='r') ) { + int LA14_127 = input.LA(4); + + if ( (LA14_127=='A') ) { + int LA14_161 = input.LA(5); + + if ( (LA14_161=='l') ) { + int LA14_192 = input.LA(6); + + if ( (LA14_192=='l') ) { + int LA14_216 = input.LA(7); + + if ( (LA14_216=='$'||(LA14_216>='0' && LA14_216<='9')||(LA14_216>='A' && LA14_216<='Z')||LA14_216=='_'||(LA14_216>='a' && LA14_216<='z')||(LA14_216>='\u00C0' && LA14_216<='\u00D6')||(LA14_216>='\u00D8' && LA14_216<='\u00F6')||(LA14_216>='\u00F8' && LA14_216<='\u1FFF')||(LA14_216>='\u3040' && LA14_216<='\u318F')||(LA14_216>='\u3300' && LA14_216<='\u337F')||(LA14_216>='\u3400' && LA14_216<='\u3D2D')||(LA14_216>='\u4E00' && LA14_216<='\u9FFF')||(LA14_216>='\uF900' && LA14_216<='\uFAFF')) ) { + alt14=67; + } + else { + alt14=61;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + else { + alt14=67;} + } + break; + default: + alt14=67;} + + } + else if ( (LA14_0=='[') ) { + alt14=63; + } + else if ( (LA14_0==']') ) { + alt14=64; + } + else if ( ((LA14_0>='0' && LA14_0<='9')) ) { + alt14=65; + } + else if ( (LA14_0=='\"'||LA14_0=='\'') ) { + alt14=66; + } + else if ( (LA14_0=='$'||(LA14_0>='A' && LA14_0<='B')||LA14_0=='D'||LA14_0=='F'||(LA14_0>='H' && LA14_0<='I')||LA14_0=='K'||(LA14_0>='M' && LA14_0<='R')||(LA14_0>='T' && LA14_0<='V')||(LA14_0>='X' && LA14_0<='Z')||(LA14_0>='^' && LA14_0<='_')||LA14_0=='b'||(LA14_0>='g' && LA14_0<='h')||(LA14_0>='j' && LA14_0<='k')||LA14_0=='m'||LA14_0=='o'||LA14_0=='q'||(LA14_0>='u' && LA14_0<='z')||(LA14_0>='\u00C0' && LA14_0<='\u00D6')||(LA14_0>='\u00D8' && LA14_0<='\u00F6')||(LA14_0>='\u00F8' && LA14_0<='\u1FFF')||(LA14_0>='\u3040' && LA14_0<='\u318F')||(LA14_0>='\u3300' && LA14_0<='\u337F')||(LA14_0>='\u3400' && LA14_0<='\u3D2D')||(LA14_0>='\u4E00' && LA14_0<='\u9FFF')||(LA14_0>='\uF900' && LA14_0<='\uFAFF')) ) { + alt14=67; + } + else if ( ((LA14_0>='\t' && LA14_0<='\n')||(LA14_0>='\f' && LA14_0<='\r')||LA14_0==' ') ) { + alt14=68; + } + else if ( (LA14_0=='\u00AB') ) { + alt14=71; + } + else if ( (LA14_0=='\u00BB') ) { + alt14=72; + } + else { + NoViableAltException nvae = + new NoViableAltException("1:1: Tokens : ( T18 | T19 | T20 | T21 | T22 | T23 | T24 | T25 | T26 | T27 | T28 | T29 | T30 | T31 | T32 | T33 | T34 | T35 | T36 | T37 | T38 | T39 | T40 | T41 | T42 | T43 | T44 | T45 | T46 | T47 | T48 | T49 | T50 | T51 | T52 | T53 | T54 | T55 | T56 | T57 | T58 | T59 | T60 | T61 | T62 | T63 | T64 | T65 | T66 | T67 | T68 | T69 | T70 | T71 | T72 | T73 | T74 | T75 | T76 | T77 | T78 | T79 | T80 | T81 | IntLiteral | StringLiteral | Identifier | WS | COMMENT | LINE_COMMENT | XPAND_TAG_OPEN | XPAND_TAG_CLOSE );", 14, 0, input); + + throw nvae; + } + switch (alt14) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:10: T18 + { + mT18(); + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:14: T19 + { + mT19(); + + } + break; + case 3 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:18: T20 + { + mT20(); + + } + break; + case 4 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:22: T21 + { + mT21(); + + } + break; + case 5 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:26: T22 + { + mT22(); + + } + break; + case 6 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:30: T23 + { + mT23(); + + } + break; + case 7 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:34: T24 + { + mT24(); + + } + break; + case 8 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:38: T25 + { + mT25(); + + } + break; + case 9 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:42: T26 + { + mT26(); + + } + break; + case 10 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:46: T27 + { + mT27(); + + } + break; + case 11 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:50: T28 + { + mT28(); + + } + break; + case 12 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:54: T29 + { + mT29(); + + } + break; + case 13 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:58: T30 + { + mT30(); + + } + break; + case 14 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:62: T31 + { + mT31(); + + } + break; + case 15 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:66: T32 + { + mT32(); + + } + break; + case 16 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:70: T33 + { + mT33(); + + } + break; + case 17 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:74: T34 + { + mT34(); + + } + break; + case 18 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:78: T35 + { + mT35(); + + } + break; + case 19 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:82: T36 + { + mT36(); + + } + break; + case 20 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:86: T37 + { + mT37(); + + } + break; + case 21 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:90: T38 + { + mT38(); + + } + break; + case 22 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:94: T39 + { + mT39(); + + } + break; + case 23 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:98: T40 + { + mT40(); + + } + break; + case 24 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:102: T41 + { + mT41(); + + } + break; + case 25 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:106: T42 + { + mT42(); + + } + break; + case 26 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:110: T43 + { + mT43(); + + } + break; + case 27 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:114: T44 + { + mT44(); + + } + break; + case 28 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:118: T45 + { + mT45(); + + } + break; + case 29 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:122: T46 + { + mT46(); + + } + break; + case 30 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:126: T47 + { + mT47(); + + } + break; + case 31 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:130: T48 + { + mT48(); + + } + break; + case 32 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:134: T49 + { + mT49(); + + } + break; + case 33 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:138: T50 + { + mT50(); + + } + break; + case 34 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:142: T51 + { + mT51(); + + } + break; + case 35 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:146: T52 + { + mT52(); + + } + break; + case 36 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:150: T53 + { + mT53(); + + } + break; + case 37 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:154: T54 + { + mT54(); + + } + break; + case 38 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:158: T55 + { + mT55(); + + } + break; + case 39 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:162: T56 + { + mT56(); + + } + break; + case 40 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:166: T57 + { + mT57(); + + } + break; + case 41 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:170: T58 + { + mT58(); + + } + break; + case 42 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:174: T59 + { + mT59(); + + } + break; + case 43 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:178: T60 + { + mT60(); + + } + break; + case 44 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:182: T61 + { + mT61(); + + } + break; + case 45 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:186: T62 + { + mT62(); + + } + break; + case 46 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:190: T63 + { + mT63(); + + } + break; + case 47 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:194: T64 + { + mT64(); + + } + break; + case 48 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:198: T65 + { + mT65(); + + } + break; + case 49 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:202: T66 + { + mT66(); + + } + break; + case 50 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:206: T67 + { + mT67(); + + } + break; + case 51 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:210: T68 + { + mT68(); + + } + break; + case 52 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:214: T69 + { + mT69(); + + } + break; + case 53 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:218: T70 + { + mT70(); + + } + break; + case 54 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:222: T71 + { + mT71(); + + } + break; + case 55 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:226: T72 + { + mT72(); + + } + break; + case 56 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:230: T73 + { + mT73(); + + } + break; + case 57 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:234: T74 + { + mT74(); + + } + break; + case 58 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:238: T75 + { + mT75(); + + } + break; + case 59 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:242: T76 + { + mT76(); + + } + break; + case 60 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:246: T77 + { + mT77(); + + } + break; + case 61 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:250: T78 + { + mT78(); + + } + break; + case 62 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:254: T79 + { + mT79(); + + } + break; + case 63 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:258: T80 + { + mT80(); + + } + break; + case 64 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:262: T81 + { + mT81(); + + } + break; + case 65 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:266: IntLiteral + { + mIntLiteral(); + + } + break; + case 66 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:277: StringLiteral + { + mStringLiteral(); + + } + break; + case 67 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:291: Identifier + { + mIdentifier(); + + } + break; + case 68 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:302: WS + { + mWS(); + + } + break; + case 69 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:305: COMMENT + { + mCOMMENT(); + + } + break; + case 70 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:313: LINE_COMMENT + { + mLINE_COMMENT(); + + } + break; + case 71 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:326: XPAND_TAG_OPEN + { + mXPAND_TAG_OPEN(); + + } + break; + case 72 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:1:341: XPAND_TAG_CLOSE + { + mXPAND_TAG_CLOSE(); + + } + break; + + } + + } + + + + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/XtendLocationAddingParser.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/XtendLocationAddingParser.java new file mode 100644 index 00000000..70565d81 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/XtendLocationAddingParser.java @@ -0,0 +1,251 @@ +package org.eclipse.internal.xtend.xtend.parser; + +import org.antlr.runtime.CommonToken; +import org.antlr.runtime.RecognitionException; +import org.antlr.runtime.TokenStream; +import org.eclipse.internal.xtend.expression.ast.DeclaredParameter; +import org.eclipse.internal.xtend.expression.ast.Expression; +import org.eclipse.internal.xtend.expression.ast.FeatureCall; +import org.eclipse.internal.xtend.expression.ast.GlobalVarExpression; +import org.eclipse.internal.xtend.expression.ast.Identifier; +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; +import org.eclipse.internal.xtend.xtend.ast.AbstractExtension; +import org.eclipse.internal.xtend.xtend.ast.Around; +import org.eclipse.internal.xtend.xtend.ast.Check; +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.internal.xtend.xtend.ast.ExtensionFile; +import org.eclipse.internal.xtend.xtend.ast.ImportStatement; + +public class XtendLocationAddingParser extends XtendParser { + + public XtendLocationAddingParser(TokenStream stream) { + this(stream, new ExtensionFactory()); + } + + public XtendLocationAddingParser(TokenStream stream, String fileName) { + this(stream, new ExtensionFactory(fileName)); + } + + public XtendLocationAddingParser(TokenStream stream, ExtensionFactory factory) { + super(stream, factory); + } + + @Override + public Extension extension() throws RecognitionException { + return addLocation(start(), (AbstractExtension) super.extension(), end()); + } + + @Override + public Identifier javaType() throws RecognitionException { + return addLocation(start(), super.javaType(), end()); + } + + + @Override + public Expression additiveExpression() throws RecognitionException { + return addLocation(start(), super.additiveExpression(), end()); + } + + @Override + public Check check() throws RecognitionException { + return addLocation(start(), super.check(), end()); + } + + @Override + public Expression andExpression() throws RecognitionException { + return addLocation(start(), super.andExpression(), end()); + } + + @Override + public Around around() throws RecognitionException { + return addLocation(start(), super.around(), end()); + } + + @Override + public Expression booleanLiteral() throws RecognitionException { + return addLocation(start(), super.booleanLiteral(), end()); + } + + @Override + public Expression castedExpression() throws RecognitionException { + return addLocation(start(), super.castedExpression(), end()); + } + + @Override + public Expression chainExpression() throws RecognitionException { + return addLocation(start(), super.chainExpression(), end()); + } + + @Override + public FeatureCall collectionExpression() throws RecognitionException { + return addLocation(start(), super.collectionExpression(), end()); + } + + @Override + public org.eclipse.internal.xtend.expression.ast.Identifier collectionType() + throws RecognitionException { + return addLocation(start(), super.collectionType(), end()); + } + + @Override + public Expression constructorCall() throws RecognitionException { + return addLocation(start(), super.constructorCall(), end()); + } + + @Override + public DeclaredParameter declaredParameter() throws RecognitionException { + return addLocation(start(), super.declaredParameter(), end()); + } + + @Override + public Expression expression() throws RecognitionException { + return addLocation(start(), super.expression(), end()); + } + + @Override + public ImportStatement extImport() throws RecognitionException { + return addLocation(start(), super.extImport(), end()); + } + + @Override + public FeatureCall featureCall() throws RecognitionException { + return addLocation(start(), super.featureCall(), end()); + } + + @Override + public GlobalVarExpression globalVarExpression() + throws RecognitionException { + return addLocation(start(), super.globalVarExpression(), end()); + } + + @Override + public Expression ifExpression() throws RecognitionException { + return addLocation(start(), super.ifExpression(), end()); + } + + @Override + public Expression impliesExpression() throws RecognitionException { + return addLocation(start(), super.impliesExpression(), end()); + } + + @Override + public Expression infixExpression() throws RecognitionException { + return addLocation(start(), super.infixExpression(), end()); + } + + @Override + public Expression numberLiteral() throws RecognitionException { + return addLocation(start(), super.numberLiteral(), end()); + } + + @Override + public Expression letExpression() throws RecognitionException { + return addLocation(start(), super.letExpression(), end()); + } + + @Override + public Expression listLiteral() throws RecognitionException { + return addLocation(start(), super.listLiteral(), end()); + } + + @Override + public Expression multiplicativeExpression() throws RecognitionException { + return addLocation(start(), super.multiplicativeExpression(), end()); + } + + @Override + public ImportStatement nsImport() throws RecognitionException { + return addLocation(start(), super.nsImport(), end()); + } + + @Override + public Expression nullLiteral() throws RecognitionException { + return addLocation(start(), super.nullLiteral(), end()); + } + + @Override + public Expression orExpression() throws RecognitionException { + return addLocation(start(), super.orExpression(), end()); + } + + @Override + public Expression paranthesizedExpression() throws RecognitionException { + return addLocation(start(), super.paranthesizedExpression(), end()); + } + + @Override + public org.eclipse.internal.xtend.expression.ast.Identifier pointcut() + throws RecognitionException { + return addLocation(start(), super.pointcut(), end()); + } + + @Override + public Expression primaryExpression() throws RecognitionException { + return addLocation(start(), super.primaryExpression(), end()); + } + + @Override + public Expression relationalExpression() throws RecognitionException { + return addLocation(start(), super.relationalExpression(), end()); + } + + @Override + public org.eclipse.internal.xtend.expression.ast.Identifier simpleType() + throws RecognitionException { + return addLocation(start(), super.simpleType(), end()); + } + + @Override + public ExtensionFile file() throws RecognitionException { + return addLocation(start(), super.file(), end()); + } + + @Override + public Expression switchExpression() throws RecognitionException { + return addLocation(start(), super.switchExpression(), end()); + } + + @Override + public org.eclipse.internal.xtend.expression.ast.Identifier type() + throws RecognitionException { + return addLocation(start(), super.type(), end()); + } + + @Override + public Expression unaryExpression() throws RecognitionException { + return addLocation(start(), super.unaryExpression(), end()); + } + + private static <T extends SyntaxElement> T addLocation(int[] startAndLine, + T ele, int end) { + if (ele != null) { + ele.setStart(startAndLine[0]); + ele.setLine(startAndLine[1]); + ele.setEnd(end); + } + return ele; + } + + private int[] start() { + CommonToken t = (CommonToken) input.LT(1); + if (t == null) { + return new int[] { 0, 0 }; + } + return new int[] { t.getStartIndex(), t.getLine() }; + } + + private int end() { + CommonToken t = (CommonToken) input.LT(-1); + if (t == null) { + return -1; + } + return t.getStopIndex() + 1; + } + + @Override + public void reportError(RecognitionException e) { + System.out.println(super.getErrorMessage(e, tokenNames)); + throw new RuntimeException(e); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/XtendParser.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/XtendParser.java new file mode 100644 index 00000000..fab7d5af --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/XtendParser.java @@ -0,0 +1,4224 @@ +// $ANTLR 3.0 ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g 2007-08-13 15:52:05 + +package org.eclipse.internal.xtend.xtend.parser; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.antlr.runtime.BaseRecognizer; +import org.antlr.runtime.BitSet; +import org.antlr.runtime.CommonToken; +import org.antlr.runtime.DFA; +import org.antlr.runtime.IntStream; +import org.antlr.runtime.MismatchedSetException; +import org.antlr.runtime.NoViableAltException; +import org.antlr.runtime.Parser; +import org.antlr.runtime.RecognitionException; +import org.antlr.runtime.Token; +import org.antlr.runtime.TokenStream; +import org.eclipse.internal.xtend.expression.ast.DeclaredParameter; +import org.eclipse.internal.xtend.expression.ast.Expression; +import org.eclipse.internal.xtend.expression.ast.FeatureCall; +import org.eclipse.internal.xtend.expression.ast.GlobalVarExpression; +import org.eclipse.internal.xtend.expression.ast.Identifier; +import org.eclipse.internal.xtend.xtend.ast.Around; +import org.eclipse.internal.xtend.xtend.ast.Check; +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.internal.xtend.xtend.ast.ExtensionFile; +import org.eclipse.internal.xtend.xtend.ast.ImportStatement; +@SuppressWarnings("unused") +public class XtendParser extends Parser { + public static final String[] tokenNames = new String[] { + "<invalid>", "<EOR>", "<DOWN>", "<UP>", "StringLiteral", "IntLiteral", "Identifier", "EscapeSequence", "UnicodeEscape", "OctalEscape", "HexDigit", "Letter", "JavaIDDigit", "WS", "COMMENT", "LINE_COMMENT", "XPAND_TAG_OPEN", "XPAND_TAG_CLOSE", "'import'", "';'", "'extension'", "'reexport'", "'context'", "'if'", "'ERROR'", "'WARNING'", "':'", "'around'", "'('", "','", "'*'", "')'", "'::'", "'private'", "'cached'", "'JAVA'", "'.'", "'create'", "'Collection'", "'List'", "'Set'", "'let'", "'='", "'->'", "'?'", "'then'", "'else'", "'switch'", "'{'", "'case'", "'default'", "'}'", "'||'", "'&&'", "'implies'", "'=='", "'!='", "'>='", "'<='", "'>'", "'<'", "'+'", "'-'", "'/'", "'!'", "'GLOBALVAR'", "'new'", "'false'", "'true'", "'null'", "'typeSelect'", "'collect'", "'select'", "'selectFirst'", "'reject'", "'exists'", "'notExists'", "'sortBy'", "'forAll'", "'|'", "'['", "']'" + }; + public static final int XPAND_TAG_OPEN=16; + public static final int JavaIDDigit=12; + public static final int Letter=11; + public static final int UnicodeEscape=8; + public static final int IntLiteral=5; + public static final int Identifier=6; + public static final int HexDigit=10; + public static final int EscapeSequence=7; + public static final int WS=13; + public static final int EOF=-1; + public static final int OctalEscape=9; + public static final int COMMENT=14; + public static final int StringLiteral=4; + public static final int LINE_COMMENT=15; + public static final int XPAND_TAG_CLOSE=17; + + public XtendParser(TokenStream input) { + super(input); + ruleMemo = new HashMap[40+1]; + } + + + public String[] getTokenNames() { return tokenNames; } + public String getGrammarFileName() { return "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g"; } + + + private ExtensionFactory factory; + public XtendParser(TokenStream stream, ExtensionFactory factory) { + this(stream); + this.factory = factory; + } + + protected Identifier id(Token t) { + if (t == null) + return null; + CommonToken ct = (CommonToken) t; + Identifier id = new Identifier(t.getText()); + id.setStart(ct.getStartIndex()); + id.setEnd(ct.getStopIndex()); + id.setLine(ct.getLine()); + return id; + } + + + + // $ANTLR start file + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:43:1: file returns [ExtensionFile r] : (nsi= nsImport )* (exti= extImport )* (ext= extension | a= around | c= check )* EOF ; + public ExtensionFile file() throws RecognitionException { + ExtensionFile r = null; + + ImportStatement nsi = null; + + ImportStatement exti = null; + + Extension ext = null; + + Around a = null; + + Check c = null; + + + List nsimports = new ArrayList(), extimports = new ArrayList(), extensions = new ArrayList(), arounds = new ArrayList(), checks = new ArrayList(); + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:45:2: ( (nsi= nsImport )* (exti= extImport )* (ext= extension | a= around | c= check )* EOF ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:45:2: (nsi= nsImport )* (exti= extImport )* (ext= extension | a= around | c= check )* EOF + { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:45:2: (nsi= nsImport )* + loop1: + do { + int alt1=2; + int LA1_0 = input.LA(1); + + if ( (LA1_0==18) ) { + alt1=1; + } + + + switch (alt1) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:45:3: nsi= nsImport + { + pushFollow(FOLLOW_nsImport_in_file51); + nsi=nsImport(); + _fsp--; + if (failed) return r; + if ( backtracking==0 ) { + nsimports.add(nsi); + } + + } + break; + + default : + break loop1; + } + } while (true); + + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:46:2: (exti= extImport )* + loop2: + do { + int alt2=2; + int LA2_0 = input.LA(1); + + if ( (LA2_0==20) ) { + alt2=1; + } + + + switch (alt2) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:46:3: exti= extImport + { + pushFollow(FOLLOW_extImport_in_file61); + exti=extImport(); + _fsp--; + if (failed) return r; + if ( backtracking==0 ) { + extimports.add(exti); + } + + } + break; + + default : + break loop2; + } + } while (true); + + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:47:2: (ext= extension | a= around | c= check )* + loop3: + do { + int alt3=4; + switch ( input.LA(1) ) { + case Identifier: + case 33: + case 34: + case 37: + case 38: + case 39: + case 40: + { + alt3=1; + } + break; + case 27: + { + alt3=2; + } + break; + case 22: + { + alt3=3; + } + break; + + } + + switch (alt3) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:47:3: ext= extension + { + pushFollow(FOLLOW_extension_in_file71); + ext=extension(); + _fsp--; + if (failed) return r; + if ( backtracking==0 ) { + extensions.add(ext); + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:47:42: a= around + { + pushFollow(FOLLOW_around_in_file81); + a=around(); + _fsp--; + if (failed) return r; + if ( backtracking==0 ) { + arounds.add(a); + } + + } + break; + case 3 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:47:73: c= check + { + pushFollow(FOLLOW_check_in_file91); + c=check(); + _fsp--; + if (failed) return r; + if ( backtracking==0 ) { + checks.add(c); + } + + } + break; + + default : + break loop3; + } + } while (true); + + match(input,EOF,FOLLOW_EOF_in_file99); if (failed) return r; + if ( backtracking==0 ) { + r = factory.createExtensionFile(nsimports,extimports,extensions,arounds,checks); + } + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return r; + } + // $ANTLR end file + + + // $ANTLR start nsImport + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:52:1: nsImport returns [ImportStatement r] : 'import' t= type ';' ; + public ImportStatement nsImport() throws RecognitionException { + ImportStatement r = null; + + Identifier t = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:53:2: ( 'import' t= type ';' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:53:2: 'import' t= type ';' + { + match(input,18,FOLLOW_18_in_nsImport117); if (failed) return r; + pushFollow(FOLLOW_type_in_nsImport121); + t=type(); + _fsp--; + if (failed) return r; + if ( backtracking==0 ) { + r = factory.createNsImport(t); + } + match(input,19,FOLLOW_19_in_nsImport125); if (failed) return r; + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return r; + } + // $ANTLR end nsImport + + + // $ANTLR start extImport + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:56:1: extImport returns [ImportStatement r] : 'extension' t= type (exported= 'reexport' )? ';' ; + public ImportStatement extImport() throws RecognitionException { + ImportStatement r = null; + + Token exported=null; + Identifier t = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:57:2: ( 'extension' t= type (exported= 'reexport' )? ';' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:57:2: 'extension' t= type (exported= 'reexport' )? ';' + { + match(input,20,FOLLOW_20_in_extImport140); if (failed) return r; + pushFollow(FOLLOW_type_in_extImport144); + t=type(); + _fsp--; + if (failed) return r; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:57:21: (exported= 'reexport' )? + int alt4=2; + int LA4_0 = input.LA(1); + + if ( (LA4_0==21) ) { + alt4=1; + } + switch (alt4) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:57:22: exported= 'reexport' + { + exported=(Token)input.LT(1); + match(input,21,FOLLOW_21_in_extImport149); if (failed) return r; + + } + break; + + } + + match(input,19,FOLLOW_19_in_extImport153); if (failed) return r; + if ( backtracking==0 ) { + r = factory.createExtensionFileImport(t,id(exported)); + } + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return r; + } + // $ANTLR end extImport + + + // $ANTLR start check + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:60:1: check returns [Check ext] : 'context' t= type ( 'if' guard= expression )? (sev1= 'ERROR' | 'WARNING' ) msg= expression ':' expr= expression ';' ; + public Check check() throws RecognitionException { + Check ext = null; + + Token sev1=null; + Identifier t = null; + + Expression guard = null; + + Expression msg = null; + + Expression expr = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:61:2: ( 'context' t= type ( 'if' guard= expression )? (sev1= 'ERROR' | 'WARNING' ) msg= expression ':' expr= expression ';' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:61:2: 'context' t= type ( 'if' guard= expression )? (sev1= 'ERROR' | 'WARNING' ) msg= expression ':' expr= expression ';' + { + match(input,22,FOLLOW_22_in_check168); if (failed) return ext; + pushFollow(FOLLOW_type_in_check172); + t=type(); + _fsp--; + if (failed) return ext; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:61:19: ( 'if' guard= expression )? + int alt5=2; + int LA5_0 = input.LA(1); + + if ( (LA5_0==23) ) { + alt5=1; + } + switch (alt5) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:61:20: 'if' guard= expression + { + match(input,23,FOLLOW_23_in_check175); if (failed) return ext; + pushFollow(FOLLOW_expression_in_check179); + guard=expression(); + _fsp--; + if (failed) return ext; + + } + break; + + } + + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:61:44: (sev1= 'ERROR' | 'WARNING' ) + int alt6=2; + int LA6_0 = input.LA(1); + + if ( (LA6_0==24) ) { + alt6=1; + } + else if ( (LA6_0==25) ) { + alt6=2; + } + else { + if (backtracking>0) {failed=true; return ext;} + NoViableAltException nvae = + new NoViableAltException("61:44: (sev1= 'ERROR' | 'WARNING' )", 6, 0, input); + + throw nvae; + } + switch (alt6) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:61:45: sev1= 'ERROR' + { + sev1=(Token)input.LT(1); + match(input,24,FOLLOW_24_in_check186); if (failed) return ext; + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:61:58: 'WARNING' + { + match(input,25,FOLLOW_25_in_check188); if (failed) return ext; + + } + break; + + } + + pushFollow(FOLLOW_expression_in_check193); + msg=expression(); + _fsp--; + if (failed) return ext; + match(input,26,FOLLOW_26_in_check195); if (failed) return ext; + pushFollow(FOLLOW_expression_in_check200); + expr=expression(); + _fsp--; + if (failed) return ext; + match(input,19,FOLLOW_19_in_check202); if (failed) return ext; + if ( backtracking==0 ) { + ext = factory.createCheck(t, guard, sev1!=null, msg, expr); + } + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return ext; + } + // $ANTLR end check + + + // $ANTLR start around + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:66:1: around returns [Around r] : 'around' pc= pointcut '(' (p= declaredParameterList ( ( ',' )? wildparams= '*' )? | wildparams= '*' )? ')' ':' expr= expression ';' ; + public Around around() throws RecognitionException { + Around r = null; + + Token wildparams=null; + Identifier pc = null; + + List<DeclaredParameter> p = null; + + Expression expr = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:67:5: ( 'around' pc= pointcut '(' (p= declaredParameterList ( ( ',' )? wildparams= '*' )? | wildparams= '*' )? ')' ':' expr= expression ';' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:67:5: 'around' pc= pointcut '(' (p= declaredParameterList ( ( ',' )? wildparams= '*' )? | wildparams= '*' )? ')' ':' expr= expression ';' + { + match(input,27,FOLLOW_27_in_around223); if (failed) return r; + pushFollow(FOLLOW_pointcut_in_around227); + pc=pointcut(); + _fsp--; + if (failed) return r; + match(input,28,FOLLOW_28_in_around229); if (failed) return r; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:67:30: (p= declaredParameterList ( ( ',' )? wildparams= '*' )? | wildparams= '*' )? + int alt9=3; + int LA9_0 = input.LA(1); + + if ( (LA9_0==Identifier||(LA9_0>=38 && LA9_0<=40)) ) { + alt9=1; + } + else if ( (LA9_0==30) ) { + alt9=2; + } + switch (alt9) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:67:31: p= declaredParameterList ( ( ',' )? wildparams= '*' )? + { + pushFollow(FOLLOW_declaredParameterList_in_around234); + p=declaredParameterList(); + _fsp--; + if (failed) return r; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:67:55: ( ( ',' )? wildparams= '*' )? + int alt8=2; + int LA8_0 = input.LA(1); + + if ( ((LA8_0>=29 && LA8_0<=30)) ) { + alt8=1; + } + switch (alt8) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:67:56: ( ',' )? wildparams= '*' + { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:67:56: ( ',' )? + int alt7=2; + int LA7_0 = input.LA(1); + + if ( (LA7_0==29) ) { + alt7=1; + } + switch (alt7) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:67:56: ',' + { + match(input,29,FOLLOW_29_in_around237); if (failed) return r; + + } + break; + + } + + wildparams=(Token)input.LT(1); + match(input,30,FOLLOW_30_in_around242); if (failed) return r; + + } + break; + + } + + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:67:80: wildparams= '*' + { + wildparams=(Token)input.LT(1); + match(input,30,FOLLOW_30_in_around250); if (failed) return r; + + } + break; + + } + + match(input,31,FOLLOW_31_in_around254); if (failed) return r; + match(input,26,FOLLOW_26_in_around256); if (failed) return r; + pushFollow(FOLLOW_expression_in_around265); + expr=expression(); + _fsp--; + if (failed) return r; + match(input,19,FOLLOW_19_in_around267); if (failed) return r; + if ( backtracking==0 ) { + r = factory.createAround(pc,p,wildparams!=null,expr); + } + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return r; + } + // $ANTLR end around + + + // $ANTLR start pointcut + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:72:1: pointcut returns [Identifier r] : (a= '*' | b= identifier ) (a1= '*' | b1= identifier | c1= '::' )* ; + public Identifier pointcut() throws RecognitionException { + Identifier r = null; + + Token a=null; + Token a1=null; + Token c1=null; + Identifier b = null; + + Identifier b1 = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:73:2: ( (a= '*' | b= identifier ) (a1= '*' | b1= identifier | c1= '::' )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:73:2: (a= '*' | b= identifier ) (a1= '*' | b1= identifier | c1= '::' )* + { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:73:2: (a= '*' | b= identifier ) + int alt10=2; + int LA10_0 = input.LA(1); + + if ( (LA10_0==30) ) { + alt10=1; + } + else if ( (LA10_0==Identifier) ) { + alt10=2; + } + else { + if (backtracking>0) {failed=true; return r;} + NoViableAltException nvae = + new NoViableAltException("73:2: (a= '*' | b= identifier )", 10, 0, input); + + throw nvae; + } + switch (alt10) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:73:4: a= '*' + { + a=(Token)input.LT(1); + match(input,30,FOLLOW_30_in_pointcut295); if (failed) return r; + if ( backtracking==0 ) { + r = id(a); + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:74:4: b= identifier + { + pushFollow(FOLLOW_identifier_in_pointcut304); + b=identifier(); + _fsp--; + if (failed) return r; + if ( backtracking==0 ) { + r = b; + } + + } + break; + + } + + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:75:4: (a1= '*' | b1= identifier | c1= '::' )* + loop11: + do { + int alt11=4; + switch ( input.LA(1) ) { + case 30: + { + alt11=1; + } + break; + case Identifier: + { + alt11=2; + } + break; + case 32: + { + alt11=3; + } + break; + + } + + switch (alt11) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:75:6: a1= '*' + { + a1=(Token)input.LT(1); + match(input,30,FOLLOW_30_in_pointcut315); if (failed) return r; + if ( backtracking==0 ) { + if (r!=null)r.append(id(a1)); + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:76:6: b1= identifier + { + pushFollow(FOLLOW_identifier_in_pointcut326); + b1=identifier(); + _fsp--; + if (failed) return r; + if ( backtracking==0 ) { + if (r!=null)r.append(b1); + } + + } + break; + case 3 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:77:6: c1= '::' + { + c1=(Token)input.LT(1); + match(input,32,FOLLOW_32_in_pointcut337); if (failed) return r; + if ( backtracking==0 ) { + if (r!=null)r.append(id(c1)); + } + + } + break; + + default : + break loop11; + } + } while (true); + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return r; + } + // $ANTLR end pointcut + + + // $ANTLR start extension + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:82:1: extension returns [Extension r] : ( (priv= 'private' )? (cached= 'cached' )? (rType= type )? name= identifier '(' (params= declaredParameterList )? ')' ':' ( 'JAVA' jt= javaType '.' m= identifier '(' (pt= javaType ( ',' pt= javaType )* )? ')' ';' | expr= expression ';' ) | (priv= 'private' )? create= 'create' rType= type (rtn= identifier )? name= identifier '(' (params= declaredParameterList )? ')' ':' expr= expression ';' ); + public Extension extension() throws RecognitionException { + Extension r = null; + + Token priv=null; + Token cached=null; + Token create=null; + Identifier rType = null; + + Identifier name = null; + + List<DeclaredParameter> params = null; + + Identifier jt = null; + + Identifier m = null; + + Identifier pt = null; + + Expression expr = null; + + Identifier rtn = null; + + + List<Identifier> javaParamTypes=new ArrayList<Identifier>(); + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:83:2: ( (priv= 'private' )? (cached= 'cached' )? (rType= type )? name= identifier '(' (params= declaredParameterList )? ')' ':' ( 'JAVA' jt= javaType '.' m= identifier '(' (pt= javaType ( ',' pt= javaType )* )? ')' ';' | expr= expression ';' ) | (priv= 'private' )? create= 'create' rType= type (rtn= identifier )? name= identifier '(' (params= declaredParameterList )? ')' ':' expr= expression ';' ) + int alt22=2; + switch ( input.LA(1) ) { + case 33: + { + int LA22_1 = input.LA(2); + + if ( (LA22_1==Identifier||LA22_1==34||(LA22_1>=38 && LA22_1<=40)) ) { + alt22=1; + } + else if ( (LA22_1==37) ) { + alt22=2; + } + else { + if (backtracking>0) {failed=true; return r;} + NoViableAltException nvae = + new NoViableAltException("82:1: extension returns [Extension r] : ( (priv= 'private' )? (cached= 'cached' )? (rType= type )? name= identifier '(' (params= declaredParameterList )? ')' ':' ( 'JAVA' jt= javaType '.' m= identifier '(' (pt= javaType ( ',' pt= javaType )* )? ')' ';' | expr= expression ';' ) | (priv= 'private' )? create= 'create' rType= type (rtn= identifier )? name= identifier '(' (params= declaredParameterList )? ')' ':' expr= expression ';' );", 22, 1, input); + + throw nvae; + } + } + break; + case Identifier: + case 34: + case 38: + case 39: + case 40: + { + alt22=1; + } + break; + case 37: + { + alt22=2; + } + break; + default: + if (backtracking>0) {failed=true; return r;} + NoViableAltException nvae = + new NoViableAltException("82:1: extension returns [Extension r] : ( (priv= 'private' )? (cached= 'cached' )? (rType= type )? name= identifier '(' (params= declaredParameterList )? ')' ':' ( 'JAVA' jt= javaType '.' m= identifier '(' (pt= javaType ( ',' pt= javaType )* )? ')' ';' | expr= expression ';' ) | (priv= 'private' )? create= 'create' rType= type (rtn= identifier )? name= identifier '(' (params= declaredParameterList )? ')' ':' expr= expression ';' );", 22, 0, input); + + throw nvae; + } + + switch (alt22) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:83:2: (priv= 'private' )? (cached= 'cached' )? (rType= type )? name= identifier '(' (params= declaredParameterList )? ')' ':' ( 'JAVA' jt= javaType '.' m= identifier '(' (pt= javaType ( ',' pt= javaType )* )? ')' ';' | expr= expression ';' ) + { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:83:2: (priv= 'private' )? + int alt12=2; + int LA12_0 = input.LA(1); + + if ( (LA12_0==33) ) { + alt12=1; + } + switch (alt12) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:83:3: priv= 'private' + { + priv=(Token)input.LT(1); + match(input,33,FOLLOW_33_in_extension365); if (failed) return r; + + } + break; + + } + + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:83:20: (cached= 'cached' )? + int alt13=2; + int LA13_0 = input.LA(1); + + if ( (LA13_0==34) ) { + alt13=1; + } + switch (alt13) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:83:21: cached= 'cached' + { + cached=(Token)input.LT(1); + match(input,34,FOLLOW_34_in_extension372); if (failed) return r; + + } + break; + + } + + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:83:39: (rType= type )? + int alt14=2; + int LA14_0 = input.LA(1); + + if ( ((LA14_0>=38 && LA14_0<=40)) ) { + alt14=1; + } + else if ( (LA14_0==Identifier) ) { + int LA14_2 = input.LA(2); + + if ( (LA14_2==Identifier||LA14_2==32) ) { + alt14=1; + } + } + switch (alt14) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:83:40: rType= type + { + pushFollow(FOLLOW_type_in_extension379); + rType=type(); + _fsp--; + if (failed) return r; + + } + break; + + } + + pushFollow(FOLLOW_identifier_in_extension385); + name=identifier(); + _fsp--; + if (failed) return r; + match(input,28,FOLLOW_28_in_extension387); if (failed) return r; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:83:73: (params= declaredParameterList )? + int alt15=2; + int LA15_0 = input.LA(1); + + if ( (LA15_0==Identifier||(LA15_0>=38 && LA15_0<=40)) ) { + alt15=1; + } + switch (alt15) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:83:74: params= declaredParameterList + { + pushFollow(FOLLOW_declaredParameterList_in_extension392); + params=declaredParameterList(); + _fsp--; + if (failed) return r; + + } + break; + + } + + match(input,31,FOLLOW_31_in_extension396); if (failed) return r; + match(input,26,FOLLOW_26_in_extension398); if (failed) return r; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:85:2: ( 'JAVA' jt= javaType '.' m= identifier '(' (pt= javaType ( ',' pt= javaType )* )? ')' ';' | expr= expression ';' ) + int alt18=2; + int LA18_0 = input.LA(1); + + if ( (LA18_0==35) ) { + alt18=1; + } + else if ( ((LA18_0>=StringLiteral && LA18_0<=Identifier)||LA18_0==23||LA18_0==28||(LA18_0>=38 && LA18_0<=41)||(LA18_0>=47 && LA18_0<=48)||LA18_0==62||(LA18_0>=64 && LA18_0<=78)) ) { + alt18=2; + } + else { + if (backtracking>0) {failed=true; return r;} + NoViableAltException nvae = + new NoViableAltException("85:2: ( 'JAVA' jt= javaType '.' m= identifier '(' (pt= javaType ( ',' pt= javaType )* )? ')' ';' | expr= expression ';' )", 18, 0, input); + + throw nvae; + } + switch (alt18) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:85:4: 'JAVA' jt= javaType '.' m= identifier '(' (pt= javaType ( ',' pt= javaType )* )? ')' ';' + { + match(input,35,FOLLOW_35_in_extension405); if (failed) return r; + pushFollow(FOLLOW_javaType_in_extension409); + jt=javaType(); + _fsp--; + if (failed) return r; + match(input,36,FOLLOW_36_in_extension411); if (failed) return r; + pushFollow(FOLLOW_identifier_in_extension415); + m=identifier(); + _fsp--; + if (failed) return r; + match(input,28,FOLLOW_28_in_extension417); if (failed) return r; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:85:43: (pt= javaType ( ',' pt= javaType )* )? + int alt17=2; + int LA17_0 = input.LA(1); + + if ( (LA17_0==Identifier) ) { + alt17=1; + } + switch (alt17) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:85:44: pt= javaType ( ',' pt= javaType )* + { + pushFollow(FOLLOW_javaType_in_extension421); + pt=javaType(); + _fsp--; + if (failed) return r; + if ( backtracking==0 ) { + javaParamTypes.add(pt); + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:85:81: ( ',' pt= javaType )* + loop16: + do { + int alt16=2; + int LA16_0 = input.LA(1); + + if ( (LA16_0==29) ) { + alt16=1; + } + + + switch (alt16) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:85:82: ',' pt= javaType + { + match(input,29,FOLLOW_29_in_extension425); if (failed) return r; + pushFollow(FOLLOW_javaType_in_extension429); + pt=javaType(); + _fsp--; + if (failed) return r; + if ( backtracking==0 ) { + javaParamTypes.add(pt); + } + + } + break; + + default : + break loop16; + } + } while (true); + + + } + break; + + } + + match(input,31,FOLLOW_31_in_extension437); if (failed) return r; + match(input,19,FOLLOW_19_in_extension439); if (failed) return r; + if ( backtracking==0 ) { + r = factory.createJavaExtension(name,rType,params,jt,m,javaParamTypes, id(cached),id(priv)); + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:87:4: expr= expression ';' + { + pushFollow(FOLLOW_expression_in_extension449); + expr=expression(); + _fsp--; + if (failed) return r; + match(input,19,FOLLOW_19_in_extension451); if (failed) return r; + if ( backtracking==0 ) { + r = factory.createExpressionExtension(name,rType,params,expr, id(cached),id(priv)); + } + + } + break; + + } + + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:91:3: (priv= 'private' )? create= 'create' rType= type (rtn= identifier )? name= identifier '(' (params= declaredParameterList )? ')' ':' expr= expression ';' + { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:91:3: (priv= 'private' )? + int alt19=2; + int LA19_0 = input.LA(1); + + if ( (LA19_0==33) ) { + alt19=1; + } + switch (alt19) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:91:4: priv= 'private' + { + priv=(Token)input.LT(1); + match(input,33,FOLLOW_33_in_extension465); if (failed) return r; + + } + break; + + } + + create=(Token)input.LT(1); + match(input,37,FOLLOW_37_in_extension471); if (failed) return r; + pushFollow(FOLLOW_type_in_extension475); + rType=type(); + _fsp--; + if (failed) return r; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:91:48: (rtn= identifier )? + int alt20=2; + int LA20_0 = input.LA(1); + + if ( (LA20_0==Identifier) ) { + int LA20_1 = input.LA(2); + + if ( (LA20_1==Identifier) ) { + alt20=1; + } + } + switch (alt20) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:91:49: rtn= identifier + { + pushFollow(FOLLOW_identifier_in_extension480); + rtn=identifier(); + _fsp--; + if (failed) return r; + + } + break; + + } + + pushFollow(FOLLOW_identifier_in_extension486); + name=identifier(); + _fsp--; + if (failed) return r; + match(input,28,FOLLOW_28_in_extension488); if (failed) return r; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:91:86: (params= declaredParameterList )? + int alt21=2; + int LA21_0 = input.LA(1); + + if ( (LA21_0==Identifier||(LA21_0>=38 && LA21_0<=40)) ) { + alt21=1; + } + switch (alt21) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:91:87: params= declaredParameterList + { + pushFollow(FOLLOW_declaredParameterList_in_extension493); + params=declaredParameterList(); + _fsp--; + if (failed) return r; + + } + break; + + } + + match(input,31,FOLLOW_31_in_extension497); if (failed) return r; + match(input,26,FOLLOW_26_in_extension499); if (failed) return r; + pushFollow(FOLLOW_expression_in_extension505); + expr=expression(); + _fsp--; + if (failed) return r; + match(input,19,FOLLOW_19_in_extension507); if (failed) return r; + if ( backtracking==0 ) { + r = factory.createCreateExtension(id(create),rType,rtn,name,params,expr,id(priv)); + } + + } + break; + + } + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return r; + } + // $ANTLR end extension + + + // $ANTLR start javaType + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:97:1: javaType returns [Identifier r] : i= identifier (d= '.' (i1= identifier | i2= 'Collection' | i3= 'List' | i4= 'Set' ) )* ; + public Identifier javaType() throws RecognitionException { + Identifier r = null; + + Token d=null; + Token i2=null; + Token i3=null; + Token i4=null; + Identifier i = null; + + Identifier i1 = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:98:2: (i= identifier (d= '.' (i1= identifier | i2= 'Collection' | i3= 'List' | i4= 'Set' ) )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:98:2: i= identifier (d= '.' (i1= identifier | i2= 'Collection' | i3= 'List' | i4= 'Set' ) )* + { + pushFollow(FOLLOW_identifier_in_javaType529); + i=identifier(); + _fsp--; + if (failed) return r; + if ( backtracking==0 ) { + r = i; + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:99:2: (d= '.' (i1= identifier | i2= 'Collection' | i3= 'List' | i4= 'Set' ) )* + loop24: + do { + int alt24=2; + int LA24_0 = input.LA(1); + + if ( (LA24_0==36) ) { + int LA24_1 = input.LA(2); + + if ( (LA24_1==Identifier) ) { + int LA24_3 = input.LA(3); + + if ( (LA24_3==29||LA24_3==31||LA24_3==36) ) { + alt24=1; + } + + + } + else if ( ((LA24_1>=38 && LA24_1<=40)) ) { + alt24=1; + } + + + } + + + switch (alt24) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:99:3: d= '.' (i1= identifier | i2= 'Collection' | i3= 'List' | i4= 'Set' ) + { + d=(Token)input.LT(1); + match(input,36,FOLLOW_36_in_javaType538); if (failed) return r; + if ( backtracking==0 ) { + if (r!=null)r.append(id(d)); + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:99:41: (i1= identifier | i2= 'Collection' | i3= 'List' | i4= 'Set' ) + int alt23=4; + switch ( input.LA(1) ) { + case Identifier: + { + alt23=1; + } + break; + case 38: + { + alt23=2; + } + break; + case 39: + { + alt23=3; + } + break; + case 40: + { + alt23=4; + } + break; + default: + if (backtracking>0) {failed=true; return r;} + NoViableAltException nvae = + new NoViableAltException("99:41: (i1= identifier | i2= 'Collection' | i3= 'List' | i4= 'Set' )", 23, 0, input); + + throw nvae; + } + + switch (alt23) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:99:42: i1= identifier + { + pushFollow(FOLLOW_identifier_in_javaType544); + i1=identifier(); + _fsp--; + if (failed) return r; + if ( backtracking==0 ) { + if (r!=null)r.append(i1); + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:99:86: i2= 'Collection' + { + i2=(Token)input.LT(1); + match(input,38,FOLLOW_38_in_javaType550); if (failed) return r; + if ( backtracking==0 ) { + r.append(id(i2)); + } + + } + break; + case 3 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:100:2: i3= 'List' + { + i3=(Token)input.LT(1); + match(input,39,FOLLOW_39_in_javaType559); if (failed) return r; + if ( backtracking==0 ) { + if (r!=null)r.append(id(i3)); + } + + } + break; + case 4 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:100:46: i4= 'Set' + { + i4=(Token)input.LT(1); + match(input,40,FOLLOW_40_in_javaType565); if (failed) return r; + if ( backtracking==0 ) { + if (r!=null)r.append(id(i4)); + } + + } + break; + + } + + + } + break; + + default : + break loop24; + } + } while (true); + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return r; + } + // $ANTLR end javaType + + + // $ANTLR start expression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:106:1: expression returns [Expression e] : x= letExpression ; + public Expression expression() throws RecognitionException { + Expression e = null; + + Expression x = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:107:2: (x= letExpression ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:107:2: x= letExpression + { + pushFollow(FOLLOW_letExpression_in_expression587); + x=letExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end expression + + + // $ANTLR start letExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:110:1: letExpression returns [Expression e] : ( 'let' v= identifier '=' varExpr= castedExpression ':' target= expression | x= castedExpression ); + public Expression letExpression() throws RecognitionException { + Expression e = null; + + Identifier v = null; + + Expression varExpr = null; + + Expression target = null; + + Expression x = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:111:4: ( 'let' v= identifier '=' varExpr= castedExpression ':' target= expression | x= castedExpression ) + int alt25=2; + int LA25_0 = input.LA(1); + + if ( (LA25_0==41) ) { + alt25=1; + } + else if ( ((LA25_0>=StringLiteral && LA25_0<=Identifier)||LA25_0==23||LA25_0==28||(LA25_0>=38 && LA25_0<=40)||(LA25_0>=47 && LA25_0<=48)||LA25_0==62||(LA25_0>=64 && LA25_0<=78)) ) { + alt25=2; + } + else { + if (backtracking>0) {failed=true; return e;} + NoViableAltException nvae = + new NoViableAltException("110:1: letExpression returns [Expression e] : ( 'let' v= identifier '=' varExpr= castedExpression ':' target= expression | x= castedExpression );", 25, 0, input); + + throw nvae; + } + switch (alt25) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:111:4: 'let' v= identifier '=' varExpr= castedExpression ':' target= expression + { + match(input,41,FOLLOW_41_in_letExpression606); if (failed) return e; + pushFollow(FOLLOW_identifier_in_letExpression610); + v=identifier(); + _fsp--; + if (failed) return e; + match(input,42,FOLLOW_42_in_letExpression612); if (failed) return e; + pushFollow(FOLLOW_castedExpression_in_letExpression616); + varExpr=castedExpression(); + _fsp--; + if (failed) return e; + match(input,26,FOLLOW_26_in_letExpression618); if (failed) return e; + pushFollow(FOLLOW_expression_in_letExpression622); + target=expression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =factory.createLetExpression(v,varExpr,target); + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:113:4: x= castedExpression + { + pushFollow(FOLLOW_castedExpression_in_letExpression635); + x=castedExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + break; + + } + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end letExpression + + + // $ANTLR start castedExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:116:1: castedExpression returns [Expression e] : ( ( '(' type ')' castedExpression )=> '(' t= type ')' x= chainExpression | x= chainExpression ); + public Expression castedExpression() throws RecognitionException { + Expression e = null; + + Identifier t = null; + + Expression x = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:117:5: ( ( '(' type ')' castedExpression )=> '(' t= type ')' x= chainExpression | x= chainExpression ) + int alt26=2; + alt26 = dfa26.predict(input); + switch (alt26) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:117:5: ( '(' type ')' castedExpression )=> '(' t= type ')' x= chainExpression + { + match(input,28,FOLLOW_28_in_castedExpression666); if (failed) return e; + pushFollow(FOLLOW_type_in_castedExpression670); + t=type(); + _fsp--; + if (failed) return e; + match(input,31,FOLLOW_31_in_castedExpression672); if (failed) return e; + pushFollow(FOLLOW_chainExpression_in_castedExpression676); + x=chainExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e = factory.createCast(t,x); + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:119:4: x= chainExpression + { + pushFollow(FOLLOW_chainExpression_in_castedExpression685); + x=chainExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + break; + + } + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end castedExpression + + + // $ANTLR start chainExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:123:1: chainExpression returns [Expression e] : x= ifExpression ( '->' right= ifExpression )* ; + public Expression chainExpression() throws RecognitionException { + Expression e = null; + + Expression x = null; + + Expression right = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:124:2: (x= ifExpression ( '->' right= ifExpression )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:124:2: x= ifExpression ( '->' right= ifExpression )* + { + pushFollow(FOLLOW_ifExpression_in_chainExpression705); + x=ifExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:124:25: ( '->' right= ifExpression )* + loop27: + do { + int alt27=2; + int LA27_0 = input.LA(1); + + if ( (LA27_0==43) ) { + alt27=1; + } + + + switch (alt27) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:124:27: '->' right= ifExpression + { + match(input,43,FOLLOW_43_in_chainExpression711); if (failed) return e; + pushFollow(FOLLOW_ifExpression_in_chainExpression715); + right=ifExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =factory.createChainExpression(e,right); + } + + } + break; + + default : + break loop27; + } + } while (true); + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end chainExpression + + + // $ANTLR start ifExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:127:1: ifExpression returns [Expression e] : (x= switchExpression ( '?' thenPart= switchExpression ':' elsePart= switchExpression )? | 'if' condition= switchExpression 'then' thenPart= switchExpression ( 'else' elsePart= expression )? ); + public Expression ifExpression() throws RecognitionException { + Expression e = null; + + Expression x = null; + + Expression thenPart = null; + + Expression elsePart = null; + + Expression condition = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:128:2: (x= switchExpression ( '?' thenPart= switchExpression ':' elsePart= switchExpression )? | 'if' condition= switchExpression 'then' thenPart= switchExpression ( 'else' elsePart= expression )? ) + int alt30=2; + int LA30_0 = input.LA(1); + + if ( ((LA30_0>=StringLiteral && LA30_0<=Identifier)||LA30_0==28||(LA30_0>=38 && LA30_0<=40)||(LA30_0>=47 && LA30_0<=48)||LA30_0==62||(LA30_0>=64 && LA30_0<=78)) ) { + alt30=1; + } + else if ( (LA30_0==23) ) { + alt30=2; + } + else { + if (backtracking>0) {failed=true; return e;} + NoViableAltException nvae = + new NoViableAltException("127:1: ifExpression returns [Expression e] : (x= switchExpression ( '?' thenPart= switchExpression ':' elsePart= switchExpression )? | 'if' condition= switchExpression 'then' thenPart= switchExpression ( 'else' elsePart= expression )? );", 30, 0, input); + + throw nvae; + } + switch (alt30) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:128:2: x= switchExpression ( '?' thenPart= switchExpression ':' elsePart= switchExpression )? + { + pushFollow(FOLLOW_switchExpression_in_ifExpression736); + x=switchExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:128:28: ( '?' thenPart= switchExpression ':' elsePart= switchExpression )? + int alt28=2; + int LA28_0 = input.LA(1); + + if ( (LA28_0==44) ) { + alt28=1; + } + switch (alt28) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:128:29: '?' thenPart= switchExpression ':' elsePart= switchExpression + { + match(input,44,FOLLOW_44_in_ifExpression740); if (failed) return e; + pushFollow(FOLLOW_switchExpression_in_ifExpression744); + thenPart=switchExpression(); + _fsp--; + if (failed) return e; + match(input,26,FOLLOW_26_in_ifExpression746); if (failed) return e; + pushFollow(FOLLOW_switchExpression_in_ifExpression750); + elsePart=switchExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =factory.createIf(e,thenPart,elsePart); + } + + } + break; + + } + + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:129:3: 'if' condition= switchExpression 'then' thenPart= switchExpression ( 'else' elsePart= expression )? + { + match(input,23,FOLLOW_23_in_ifExpression758); if (failed) return e; + pushFollow(FOLLOW_switchExpression_in_ifExpression762); + condition=switchExpression(); + _fsp--; + if (failed) return e; + match(input,45,FOLLOW_45_in_ifExpression764); if (failed) return e; + pushFollow(FOLLOW_switchExpression_in_ifExpression768); + thenPart=switchExpression(); + _fsp--; + if (failed) return e; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:129:68: ( 'else' elsePart= expression )? + int alt29=2; + int LA29_0 = input.LA(1); + + if ( (LA29_0==46) ) { + alt29=1; + } + switch (alt29) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:129:69: 'else' elsePart= expression + { + match(input,46,FOLLOW_46_in_ifExpression771); if (failed) return e; + pushFollow(FOLLOW_expression_in_ifExpression775); + elsePart=expression(); + _fsp--; + if (failed) return e; + + } + break; + + } + + if ( backtracking==0 ) { + e =factory.createIf(condition,thenPart,elsePart); + } + + } + break; + + } + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end ifExpression + + + // $ANTLR start switchExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:133:1: switchExpression returns [Expression e=null] : ( 'switch' ( '(' pred= orExpression ')' )? '{' ( 'case' c= orExpression ':' v= orExpression )* 'default' ':' def= orExpression '}' | x= orExpression ); + public Expression switchExpression() throws RecognitionException { + Expression e = null; + + Expression pred = null; + + Expression c = null; + + Expression v = null; + + Expression def = null; + + Expression x = null; + + + List cases = new ArrayList(); + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:134:4: ( 'switch' ( '(' pred= orExpression ')' )? '{' ( 'case' c= orExpression ':' v= orExpression )* 'default' ':' def= orExpression '}' | x= orExpression ) + int alt33=2; + int LA33_0 = input.LA(1); + + if ( (LA33_0==47) ) { + alt33=1; + } + else if ( ((LA33_0>=StringLiteral && LA33_0<=Identifier)||LA33_0==28||(LA33_0>=38 && LA33_0<=40)||LA33_0==48||LA33_0==62||(LA33_0>=64 && LA33_0<=78)) ) { + alt33=2; + } + else { + if (backtracking>0) {failed=true; return e;} + NoViableAltException nvae = + new NoViableAltException("133:1: switchExpression returns [Expression e=null] : ( 'switch' ( '(' pred= orExpression ')' )? '{' ( 'case' c= orExpression ':' v= orExpression )* 'default' ':' def= orExpression '}' | x= orExpression );", 33, 0, input); + + throw nvae; + } + switch (alt33) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:134:4: 'switch' ( '(' pred= orExpression ')' )? '{' ( 'case' c= orExpression ':' v= orExpression )* 'default' ':' def= orExpression '}' + { + match(input,47,FOLLOW_47_in_switchExpression802); if (failed) return e; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:134:13: ( '(' pred= orExpression ')' )? + int alt31=2; + int LA31_0 = input.LA(1); + + if ( (LA31_0==28) ) { + alt31=1; + } + switch (alt31) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:134:14: '(' pred= orExpression ')' + { + match(input,28,FOLLOW_28_in_switchExpression805); if (failed) return e; + pushFollow(FOLLOW_orExpression_in_switchExpression811); + pred=orExpression(); + _fsp--; + if (failed) return e; + match(input,31,FOLLOW_31_in_switchExpression813); if (failed) return e; + + } + break; + + } + + match(input,48,FOLLOW_48_in_switchExpression820); if (failed) return e; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:136:4: ( 'case' c= orExpression ':' v= orExpression )* + loop32: + do { + int alt32=2; + int LA32_0 = input.LA(1); + + if ( (LA32_0==49) ) { + alt32=1; + } + + + switch (alt32) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:137:6: 'case' c= orExpression ':' v= orExpression + { + match(input,49,FOLLOW_49_in_switchExpression833); if (failed) return e; + pushFollow(FOLLOW_orExpression_in_switchExpression837); + c=orExpression(); + _fsp--; + if (failed) return e; + match(input,26,FOLLOW_26_in_switchExpression840); if (failed) return e; + pushFollow(FOLLOW_orExpression_in_switchExpression845); + v=orExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + cases.add(factory.createCase(c, v)); + } + + } + break; + + default : + break loop32; + } + } while (true); + + match(input,50,FOLLOW_50_in_switchExpression863); if (failed) return e; + match(input,26,FOLLOW_26_in_switchExpression865); if (failed) return e; + pushFollow(FOLLOW_orExpression_in_switchExpression871); + def=orExpression(); + _fsp--; + if (failed) return e; + match(input,51,FOLLOW_51_in_switchExpression876); if (failed) return e; + if ( backtracking==0 ) { + e = factory.createSwitchExpression(pred,cases,def); + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:143:4: x= orExpression + { + pushFollow(FOLLOW_orExpression_in_switchExpression888); + x=orExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + break; + + } + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end switchExpression + + + // $ANTLR start orExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:146:1: orExpression returns [Expression e] : x= andExpression (name= '||' r= andExpression )* ; + public Expression orExpression() throws RecognitionException { + Expression e = null; + + Token name=null; + Expression x = null; + + Expression r = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:147:4: (x= andExpression (name= '||' r= andExpression )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:147:4: x= andExpression (name= '||' r= andExpression )* + { + pushFollow(FOLLOW_andExpression_in_orExpression908); + x=andExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:147:28: (name= '||' r= andExpression )* + loop34: + do { + int alt34=2; + int LA34_0 = input.LA(1); + + if ( (LA34_0==52) ) { + alt34=1; + } + + + switch (alt34) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:147:29: name= '||' r= andExpression + { + name=(Token)input.LT(1); + match(input,52,FOLLOW_52_in_orExpression915); if (failed) return e; + pushFollow(FOLLOW_andExpression_in_orExpression919); + r=andExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e = factory.createBooleanOperation(id(name),e,r); + } + + } + break; + + default : + break loop34; + } + } while (true); + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end orExpression + + + // $ANTLR start andExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:150:1: andExpression returns [Expression e] : x= impliesExpression (name= '&&' r= impliesExpression )* ; + public Expression andExpression() throws RecognitionException { + Expression e = null; + + Token name=null; + Expression x = null; + + Expression r = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:151:2: (x= impliesExpression (name= '&&' r= impliesExpression )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:151:2: x= impliesExpression (name= '&&' r= impliesExpression )* + { + pushFollow(FOLLOW_impliesExpression_in_andExpression942); + x=impliesExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:151:30: (name= '&&' r= impliesExpression )* + loop35: + do { + int alt35=2; + int LA35_0 = input.LA(1); + + if ( (LA35_0==53) ) { + alt35=1; + } + + + switch (alt35) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:151:31: name= '&&' r= impliesExpression + { + name=(Token)input.LT(1); + match(input,53,FOLLOW_53_in_andExpression949); if (failed) return e; + pushFollow(FOLLOW_impliesExpression_in_andExpression953); + r=impliesExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e = factory.createBooleanOperation(id(name),e,r); + } + + } + break; + + default : + break loop35; + } + } while (true); + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end andExpression + + + // $ANTLR start impliesExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:154:1: impliesExpression returns [Expression e] : x= relationalExpression (name= 'implies' r= relationalExpression )* ; + public Expression impliesExpression() throws RecognitionException { + Expression e = null; + + Token name=null; + Expression x = null; + + Expression r = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:155:2: (x= relationalExpression (name= 'implies' r= relationalExpression )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:155:2: x= relationalExpression (name= 'implies' r= relationalExpression )* + { + pushFollow(FOLLOW_relationalExpression_in_impliesExpression975); + x=relationalExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:155:33: (name= 'implies' r= relationalExpression )* + loop36: + do { + int alt36=2; + int LA36_0 = input.LA(1); + + if ( (LA36_0==54) ) { + alt36=1; + } + + + switch (alt36) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:155:34: name= 'implies' r= relationalExpression + { + name=(Token)input.LT(1); + match(input,54,FOLLOW_54_in_impliesExpression982); if (failed) return e; + pushFollow(FOLLOW_relationalExpression_in_impliesExpression986); + r=relationalExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e = factory.createBooleanOperation(id(name),e,r); + } + + } + break; + + default : + break loop36; + } + } while (true); + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end impliesExpression + + + // $ANTLR start relationalExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:159:1: relationalExpression returns [Expression e] : x= additiveExpression (name= ( '==' | '!=' | '>=' | '<=' | '>' | '<' ) r= additiveExpression )* ; + public Expression relationalExpression() throws RecognitionException { + Expression e = null; + + Token name=null; + Expression x = null; + + Expression r = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:160:2: (x= additiveExpression (name= ( '==' | '!=' | '>=' | '<=' | '>' | '<' ) r= additiveExpression )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:160:2: x= additiveExpression (name= ( '==' | '!=' | '>=' | '<=' | '>' | '<' ) r= additiveExpression )* + { + pushFollow(FOLLOW_additiveExpression_in_relationalExpression1010); + x=additiveExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:161:2: (name= ( '==' | '!=' | '>=' | '<=' | '>' | '<' ) r= additiveExpression )* + loop37: + do { + int alt37=2; + int LA37_0 = input.LA(1); + + if ( ((LA37_0>=55 && LA37_0<=60)) ) { + alt37=1; + } + + + switch (alt37) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:161:3: name= ( '==' | '!=' | '>=' | '<=' | '>' | '<' ) r= additiveExpression + { + name=(Token)input.LT(1); + if ( (input.LA(1)>=55 && input.LA(1)<=60) ) { + input.consume(); + errorRecovery=false;failed=false; + } + else { + if (backtracking>0) {failed=true; return e;} + MismatchedSetException mse = + new MismatchedSetException(null,input); + recoverFromMismatchedSet(input,mse,FOLLOW_set_in_relationalExpression1018); throw mse; + } + + pushFollow(FOLLOW_additiveExpression_in_relationalExpression1044); + r=additiveExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e = factory.createBinaryOperation(id(name),e,r); + } + + } + break; + + default : + break loop37; + } + } while (true); + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end relationalExpression + + + // $ANTLR start additiveExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:165:1: additiveExpression returns [Expression e] : x= multiplicativeExpression (name= ( '+' | '-' ) r= multiplicativeExpression )* ; + public Expression additiveExpression() throws RecognitionException { + Expression e = null; + + Token name=null; + Expression x = null; + + Expression r = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:166:2: (x= multiplicativeExpression (name= ( '+' | '-' ) r= multiplicativeExpression )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:166:2: x= multiplicativeExpression (name= ( '+' | '-' ) r= multiplicativeExpression )* + { + pushFollow(FOLLOW_multiplicativeExpression_in_additiveExpression1065); + x=multiplicativeExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:167:4: (name= ( '+' | '-' ) r= multiplicativeExpression )* + loop38: + do { + int alt38=2; + int LA38_0 = input.LA(1); + + if ( ((LA38_0>=61 && LA38_0<=62)) ) { + alt38=1; + } + + + switch (alt38) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:167:5: name= ( '+' | '-' ) r= multiplicativeExpression + { + name=(Token)input.LT(1); + if ( (input.LA(1)>=61 && input.LA(1)<=62) ) { + input.consume(); + errorRecovery=false;failed=false; + } + else { + if (backtracking>0) {failed=true; return e;} + MismatchedSetException mse = + new MismatchedSetException(null,input); + recoverFromMismatchedSet(input,mse,FOLLOW_set_in_additiveExpression1075); throw mse; + } + + pushFollow(FOLLOW_multiplicativeExpression_in_additiveExpression1084); + r=multiplicativeExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e = factory.createBinaryOperation(id(name),e,r); + } + + } + break; + + default : + break loop38; + } + } while (true); + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end additiveExpression + + + // $ANTLR start multiplicativeExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:170:1: multiplicativeExpression returns [Expression e] : x= unaryExpression (name= ( '*' | '/' ) r= unaryExpression )* ; + public Expression multiplicativeExpression() throws RecognitionException { + Expression e = null; + + Token name=null; + Expression x = null; + + Expression r = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:171:2: (x= unaryExpression (name= ( '*' | '/' ) r= unaryExpression )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:171:2: x= unaryExpression (name= ( '*' | '/' ) r= unaryExpression )* + { + pushFollow(FOLLOW_unaryExpression_in_multiplicativeExpression1103); + x=unaryExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:172:2: (name= ( '*' | '/' ) r= unaryExpression )* + loop39: + do { + int alt39=2; + int LA39_0 = input.LA(1); + + if ( (LA39_0==30||LA39_0==63) ) { + alt39=1; + } + + + switch (alt39) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:172:3: name= ( '*' | '/' ) r= unaryExpression + { + name=(Token)input.LT(1); + if ( input.LA(1)==30||input.LA(1)==63 ) { + input.consume(); + errorRecovery=false;failed=false; + } + else { + if (backtracking>0) {failed=true; return e;} + MismatchedSetException mse = + new MismatchedSetException(null,input); + recoverFromMismatchedSet(input,mse,FOLLOW_set_in_multiplicativeExpression1111); throw mse; + } + + pushFollow(FOLLOW_unaryExpression_in_multiplicativeExpression1121); + r=unaryExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e = factory.createBinaryOperation(id(name),e,r); + } + + } + break; + + default : + break loop39; + } + } while (true); + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end multiplicativeExpression + + + // $ANTLR start unaryExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:176:1: unaryExpression returns [Expression e] : (x= infixExpression | name= '!' x= infixExpression | name= '-' x= infixExpression ); + public Expression unaryExpression() throws RecognitionException { + Expression e = null; + + Token name=null; + Expression x = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:177:2: (x= infixExpression | name= '!' x= infixExpression | name= '-' x= infixExpression ) + int alt40=3; + switch ( input.LA(1) ) { + case StringLiteral: + case IntLiteral: + case Identifier: + case 28: + case 38: + case 39: + case 40: + case 48: + case 65: + case 66: + case 67: + case 68: + case 69: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + { + alt40=1; + } + break; + case 64: + { + alt40=2; + } + break; + case 62: + { + alt40=3; + } + break; + default: + if (backtracking>0) {failed=true; return e;} + NoViableAltException nvae = + new NoViableAltException("176:1: unaryExpression returns [Expression e] : (x= infixExpression | name= '!' x= infixExpression | name= '-' x= infixExpression );", 40, 0, input); + + throw nvae; + } + + switch (alt40) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:177:2: x= infixExpression + { + pushFollow(FOLLOW_infixExpression_in_unaryExpression1142); + x=infixExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:178:3: name= '!' x= infixExpression + { + name=(Token)input.LT(1); + match(input,64,FOLLOW_64_in_unaryExpression1150); if (failed) return e; + pushFollow(FOLLOW_infixExpression_in_unaryExpression1154); + x=infixExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e = factory.createOperationCall(id(name),x); + } + + } + break; + case 3 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:179:3: name= '-' x= infixExpression + { + name=(Token)input.LT(1); + match(input,62,FOLLOW_62_in_unaryExpression1162); if (failed) return e; + pushFollow(FOLLOW_infixExpression_in_unaryExpression1166); + x=infixExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e = factory.createOperationCall(id(name),x); + } + + } + break; + + } + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end unaryExpression + + + // $ANTLR start infixExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:182:1: infixExpression returns [Expression e] : x= primaryExpression ( '.' op= featureCall )* ; + public Expression infixExpression() throws RecognitionException { + Expression e = null; + + Expression x = null; + + FeatureCall op = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:183:2: (x= primaryExpression ( '.' op= featureCall )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:183:2: x= primaryExpression ( '.' op= featureCall )* + { + pushFollow(FOLLOW_primaryExpression_in_infixExpression1184); + x=primaryExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:183:30: ( '.' op= featureCall )* + loop41: + do { + int alt41=2; + int LA41_0 = input.LA(1); + + if ( (LA41_0==36) ) { + alt41=1; + } + + + switch (alt41) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:183:32: '.' op= featureCall + { + match(input,36,FOLLOW_36_in_infixExpression1190); if (failed) return e; + pushFollow(FOLLOW_featureCall_in_infixExpression1194); + op=featureCall(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + if (op!=null) { op.setTarget(e);e =op;} + } + + } + break; + + default : + break loop41; + } + } while (true); + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end infixExpression + + + // $ANTLR start primaryExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:186:1: primaryExpression returns [Expression e] : (c= StringLiteral | x= featureCall | x= booleanLiteral | x= numberLiteral | x= nullLiteral | x= listLiteral | x= constructorCall | x= globalVarExpression | x= paranthesizedExpression ); + public Expression primaryExpression() throws RecognitionException { + Expression e = null; + + Token c=null; + Expression x = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:187:4: (c= StringLiteral | x= featureCall | x= booleanLiteral | x= numberLiteral | x= nullLiteral | x= listLiteral | x= constructorCall | x= globalVarExpression | x= paranthesizedExpression ) + int alt42=9; + switch ( input.LA(1) ) { + case StringLiteral: + { + alt42=1; + } + break; + case Identifier: + case 38: + case 39: + case 40: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + { + alt42=2; + } + break; + case 67: + case 68: + { + alt42=3; + } + break; + case IntLiteral: + { + alt42=4; + } + break; + case 69: + { + alt42=5; + } + break; + case 48: + { + alt42=6; + } + break; + case 66: + { + alt42=7; + } + break; + case 65: + { + alt42=8; + } + break; + case 28: + { + alt42=9; + } + break; + default: + if (backtracking>0) {failed=true; return e;} + NoViableAltException nvae = + new NoViableAltException("186:1: primaryExpression returns [Expression e] : (c= StringLiteral | x= featureCall | x= booleanLiteral | x= numberLiteral | x= nullLiteral | x= listLiteral | x= constructorCall | x= globalVarExpression | x= paranthesizedExpression );", 42, 0, input); + + throw nvae; + } + + switch (alt42) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:187:4: c= StringLiteral + { + c=(Token)input.LT(1); + match(input,StringLiteral,FOLLOW_StringLiteral_in_primaryExpression1220); if (failed) return e; + if ( backtracking==0 ) { + e = factory.createStringLiteral(id(c)); + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:188:5: x= featureCall + { + pushFollow(FOLLOW_featureCall_in_primaryExpression1231); + x=featureCall(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + break; + case 3 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:189:5: x= booleanLiteral + { + pushFollow(FOLLOW_booleanLiteral_in_primaryExpression1241); + x=booleanLiteral(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + break; + case 4 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:190:5: x= numberLiteral + { + pushFollow(FOLLOW_numberLiteral_in_primaryExpression1251); + x=numberLiteral(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + break; + case 5 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:191:5: x= nullLiteral + { + pushFollow(FOLLOW_nullLiteral_in_primaryExpression1261); + x=nullLiteral(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + break; + case 6 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:192:5: x= listLiteral + { + pushFollow(FOLLOW_listLiteral_in_primaryExpression1271); + x=listLiteral(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + break; + case 7 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:193:5: x= constructorCall + { + pushFollow(FOLLOW_constructorCall_in_primaryExpression1281); + x=constructorCall(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + break; + case 8 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:194:5: x= globalVarExpression + { + pushFollow(FOLLOW_globalVarExpression_in_primaryExpression1291); + x=globalVarExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + break; + case 9 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:195:5: x= paranthesizedExpression + { + pushFollow(FOLLOW_paranthesizedExpression_in_primaryExpression1301); + x=paranthesizedExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + break; + + } + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end primaryExpression + + + // $ANTLR start paranthesizedExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:198:1: paranthesizedExpression returns [Expression e] : '(' x= expression ')' ; + public Expression paranthesizedExpression() throws RecognitionException { + Expression e = null; + + Expression x = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:199:5: ( '(' x= expression ')' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:199:5: '(' x= expression ')' + { + match(input,28,FOLLOW_28_in_paranthesizedExpression1320); if (failed) return e; + pushFollow(FOLLOW_expression_in_paranthesizedExpression1324); + x=expression(); + _fsp--; + if (failed) return e; + match(input,31,FOLLOW_31_in_paranthesizedExpression1326); if (failed) return e; + if ( backtracking==0 ) { + e =factory.createParanthesizedExpression(x); + } + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end paranthesizedExpression + + + // $ANTLR start globalVarExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:202:1: globalVarExpression returns [GlobalVarExpression e] : 'GLOBALVAR' name= identifier ; + public GlobalVarExpression globalVarExpression() throws RecognitionException { + GlobalVarExpression e = null; + + Identifier name = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:203:5: ( 'GLOBALVAR' name= identifier ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:203:5: 'GLOBALVAR' name= identifier + { + match(input,65,FOLLOW_65_in_globalVarExpression1346); if (failed) return e; + pushFollow(FOLLOW_identifier_in_globalVarExpression1350); + name=identifier(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e = factory.createGlobalVarExpression(name); + } + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end globalVarExpression + + + // $ANTLR start featureCall + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:205:1: featureCall returns [FeatureCall e] : (id1= identifier '(' (l= parameterList )? ')' | t= type | x= collectionExpression ); + public FeatureCall featureCall() throws RecognitionException { + FeatureCall e = null; + + Identifier id1 = null; + + List<Expression> l = null; + + Identifier t = null; + + FeatureCall x = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:206:2: (id1= identifier '(' (l= parameterList )? ')' | t= type | x= collectionExpression ) + int alt44=3; + switch ( input.LA(1) ) { + case Identifier: + { + int LA44_1 = input.LA(2); + + if ( (LA44_1==28) ) { + alt44=1; + } + else if ( (LA44_1==EOF||LA44_1==19||(LA44_1>=24 && LA44_1<=26)||(LA44_1>=29 && LA44_1<=32)||LA44_1==36||(LA44_1>=43 && LA44_1<=46)||(LA44_1>=49 && LA44_1<=63)) ) { + alt44=2; + } + else { + if (backtracking>0) {failed=true; return e;} + NoViableAltException nvae = + new NoViableAltException("205:1: featureCall returns [FeatureCall e] : (id1= identifier '(' (l= parameterList )? ')' | t= type | x= collectionExpression );", 44, 1, input); + + throw nvae; + } + } + break; + case 38: + case 39: + case 40: + { + alt44=2; + } + break; + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + { + alt44=3; + } + break; + default: + if (backtracking>0) {failed=true; return e;} + NoViableAltException nvae = + new NoViableAltException("205:1: featureCall returns [FeatureCall e] : (id1= identifier '(' (l= parameterList )? ')' | t= type | x= collectionExpression );", 44, 0, input); + + throw nvae; + } + + switch (alt44) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:206:2: id1= identifier '(' (l= parameterList )? ')' + { + pushFollow(FOLLOW_identifier_in_featureCall1368); + id1=identifier(); + _fsp--; + if (failed) return e; + match(input,28,FOLLOW_28_in_featureCall1370); if (failed) return e; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:206:21: (l= parameterList )? + int alt43=2; + int LA43_0 = input.LA(1); + + if ( ((LA43_0>=StringLiteral && LA43_0<=Identifier)||LA43_0==23||LA43_0==28||(LA43_0>=38 && LA43_0<=41)||(LA43_0>=47 && LA43_0<=48)||LA43_0==62||(LA43_0>=64 && LA43_0<=78)) ) { + alt43=1; + } + switch (alt43) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:206:22: l= parameterList + { + pushFollow(FOLLOW_parameterList_in_featureCall1375); + l=parameterList(); + _fsp--; + if (failed) return e; + + } + break; + + } + + match(input,31,FOLLOW_31_in_featureCall1379); if (failed) return e; + if ( backtracking==0 ) { + e = factory.createOperationCall(id1,l); + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:207:5: t= type + { + pushFollow(FOLLOW_type_in_featureCall1389); + t=type(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =factory.createFeatureCall(t,null); + } + + } + break; + case 3 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:208:5: x= collectionExpression + { + pushFollow(FOLLOW_collectionExpression_in_featureCall1400); + x=collectionExpression(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e =x; + } + + } + break; + + } + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end featureCall + + + // $ANTLR start listLiteral + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:211:1: listLiteral returns [Expression e] : '{' (l= parameterList )? '}' ; + public Expression listLiteral() throws RecognitionException { + Expression e = null; + + List<Expression> l = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:212:2: ( '{' (l= parameterList )? '}' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:212:2: '{' (l= parameterList )? '}' + { + match(input,48,FOLLOW_48_in_listLiteral1417); if (failed) return e; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:212:6: (l= parameterList )? + int alt45=2; + int LA45_0 = input.LA(1); + + if ( ((LA45_0>=StringLiteral && LA45_0<=Identifier)||LA45_0==23||LA45_0==28||(LA45_0>=38 && LA45_0<=41)||(LA45_0>=47 && LA45_0<=48)||LA45_0==62||(LA45_0>=64 && LA45_0<=78)) ) { + alt45=1; + } + switch (alt45) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:212:7: l= parameterList + { + pushFollow(FOLLOW_parameterList_in_listLiteral1422); + l=parameterList(); + _fsp--; + if (failed) return e; + + } + break; + + } + + match(input,51,FOLLOW_51_in_listLiteral1426); if (failed) return e; + if ( backtracking==0 ) { + e =factory.createListLiteral(l); + } + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end listLiteral + + + // $ANTLR start constructorCall + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:215:1: constructorCall returns [Expression e] : 'new' t= simpleType ; + public Expression constructorCall() throws RecognitionException { + Expression e = null; + + Identifier t = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:216:2: ( 'new' t= simpleType ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:216:2: 'new' t= simpleType + { + match(input,66,FOLLOW_66_in_constructorCall1443); if (failed) return e; + pushFollow(FOLLOW_simpleType_in_constructorCall1447); + t=simpleType(); + _fsp--; + if (failed) return e; + if ( backtracking==0 ) { + e = factory.createConstructorCall(t); + } + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end constructorCall + + + // $ANTLR start booleanLiteral + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:220:1: booleanLiteral returns [Expression e=factory.createBooleanLiteral(id(input.LT(1)))] : ( 'false' | 'true' ); + public Expression booleanLiteral() throws RecognitionException { + Expression e = factory.createBooleanLiteral(id(input.LT(1))); + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:221:2: ( 'false' | 'true' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g: + { + if ( (input.LA(1)>=67 && input.LA(1)<=68) ) { + input.consume(); + errorRecovery=false;failed=false; + } + else { + if (backtracking>0) {failed=true; return e;} + MismatchedSetException mse = + new MismatchedSetException(null,input); + recoverFromMismatchedSet(input,mse,FOLLOW_set_in_booleanLiteral0); throw mse; + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end booleanLiteral + + + // $ANTLR start nullLiteral + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:224:1: nullLiteral returns [Expression e=factory.createNullLiteral(id(input.LT(1)))] : 'null' ; + public Expression nullLiteral() throws RecognitionException { + Expression e = factory.createNullLiteral(id(input.LT(1))); + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:225:2: ( 'null' ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:225:2: 'null' + { + match(input,69,FOLLOW_69_in_nullLiteral1482); if (failed) return e; + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end nullLiteral + + + // $ANTLR start numberLiteral + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:228:1: numberLiteral returns [Expression e] : (a= IntLiteral | a= IntLiteral b= '.' c= IntLiteral ); + public Expression numberLiteral() throws RecognitionException { + Expression e = null; + + Token a=null; + Token b=null; + Token c=null; + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:229:4: (a= IntLiteral | a= IntLiteral b= '.' c= IntLiteral ) + int alt46=2; + int LA46_0 = input.LA(1); + + if ( (LA46_0==IntLiteral) ) { + int LA46_1 = input.LA(2); + + if ( (LA46_1==36) ) { + int LA46_2 = input.LA(3); + + if ( (LA46_2==IntLiteral) ) { + alt46=2; + } + else if ( (LA46_2==Identifier||(LA46_2>=38 && LA46_2<=40)||(LA46_2>=70 && LA46_2<=78)) ) { + alt46=1; + } + else { + if (backtracking>0) {failed=true; return e;} + NoViableAltException nvae = + new NoViableAltException("228:1: numberLiteral returns [Expression e] : (a= IntLiteral | a= IntLiteral b= '.' c= IntLiteral );", 46, 2, input); + + throw nvae; + } + } + else if ( (LA46_1==EOF||LA46_1==19||(LA46_1>=24 && LA46_1<=26)||(LA46_1>=29 && LA46_1<=31)||(LA46_1>=43 && LA46_1<=46)||(LA46_1>=49 && LA46_1<=63)) ) { + alt46=1; + } + else { + if (backtracking>0) {failed=true; return e;} + NoViableAltException nvae = + new NoViableAltException("228:1: numberLiteral returns [Expression e] : (a= IntLiteral | a= IntLiteral b= '.' c= IntLiteral );", 46, 1, input); + + throw nvae; + } + } + else { + if (backtracking>0) {failed=true; return e;} + NoViableAltException nvae = + new NoViableAltException("228:1: numberLiteral returns [Expression e] : (a= IntLiteral | a= IntLiteral b= '.' c= IntLiteral );", 46, 0, input); + + throw nvae; + } + switch (alt46) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:229:4: a= IntLiteral + { + a=(Token)input.LT(1); + match(input,IntLiteral,FOLLOW_IntLiteral_in_numberLiteral1501); if (failed) return e; + if ( backtracking==0 ) { + e =factory.createIntegerLiteral(id(a)); + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:230:4: a= IntLiteral b= '.' c= IntLiteral + { + a=(Token)input.LT(1); + match(input,IntLiteral,FOLLOW_IntLiteral_in_numberLiteral1510); if (failed) return e; + b=(Token)input.LT(1); + match(input,36,FOLLOW_36_in_numberLiteral1514); if (failed) return e; + c=(Token)input.LT(1); + match(input,IntLiteral,FOLLOW_IntLiteral_in_numberLiteral1518); if (failed) return e; + if ( backtracking==0 ) { + e =factory.createRealLiteral(id(a).append(id(b)).append(id(c))); + } + + } + break; + + } + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end numberLiteral + + + // $ANTLR start collectionExpression + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:233:1: collectionExpression returns [FeatureCall e] : (name= 'typeSelect' '(' t= type ')' | name= ( 'collect' | 'select' | 'selectFirst' | 'reject' | 'exists' | 'notExists' | 'sortBy' | 'forAll' ) '(' (var= identifier '|' )? x= expression ')' ); + public FeatureCall collectionExpression() throws RecognitionException { + FeatureCall e = null; + + Token name=null; + Identifier t = null; + + Identifier var = null; + + Expression x = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:234:3: (name= 'typeSelect' '(' t= type ')' | name= ( 'collect' | 'select' | 'selectFirst' | 'reject' | 'exists' | 'notExists' | 'sortBy' | 'forAll' ) '(' (var= identifier '|' )? x= expression ')' ) + int alt48=2; + int LA48_0 = input.LA(1); + + if ( (LA48_0==70) ) { + alt48=1; + } + else if ( ((LA48_0>=71 && LA48_0<=78)) ) { + alt48=2; + } + else { + if (backtracking>0) {failed=true; return e;} + NoViableAltException nvae = + new NoViableAltException("233:1: collectionExpression returns [FeatureCall e] : (name= 'typeSelect' '(' t= type ')' | name= ( 'collect' | 'select' | 'selectFirst' | 'reject' | 'exists' | 'notExists' | 'sortBy' | 'forAll' ) '(' (var= identifier '|' )? x= expression ')' );", 48, 0, input); + + throw nvae; + } + switch (alt48) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:234:3: name= 'typeSelect' '(' t= type ')' + { + name=(Token)input.LT(1); + match(input,70,FOLLOW_70_in_collectionExpression1538); if (failed) return e; + match(input,28,FOLLOW_28_in_collectionExpression1542); if (failed) return e; + pushFollow(FOLLOW_type_in_collectionExpression1546); + t=type(); + _fsp--; + if (failed) return e; + match(input,31,FOLLOW_31_in_collectionExpression1548); if (failed) return e; + if ( backtracking==0 ) { + e = factory.createTypeSelectExpression(id(name),t); + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:237:5: name= ( 'collect' | 'select' | 'selectFirst' | 'reject' | 'exists' | 'notExists' | 'sortBy' | 'forAll' ) '(' (var= identifier '|' )? x= expression ')' + { + name=(Token)input.LT(1); + if ( (input.LA(1)>=71 && input.LA(1)<=78) ) { + input.consume(); + errorRecovery=false;failed=false; + } + else { + if (backtracking>0) {failed=true; return e;} + MismatchedSetException mse = + new MismatchedSetException(null,input); + recoverFromMismatchedSet(input,mse,FOLLOW_set_in_collectionExpression1561); throw mse; + } + + match(input,28,FOLLOW_28_in_collectionExpression1611); if (failed) return e; + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:244:19: (var= identifier '|' )? + int alt47=2; + int LA47_0 = input.LA(1); + + if ( (LA47_0==Identifier) ) { + int LA47_1 = input.LA(2); + + if ( (LA47_1==79) ) { + alt47=1; + } + } + switch (alt47) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:244:20: var= identifier '|' + { + pushFollow(FOLLOW_identifier_in_collectionExpression1616); + var=identifier(); + _fsp--; + if (failed) return e; + match(input,79,FOLLOW_79_in_collectionExpression1618); if (failed) return e; + + } + break; + + } + + pushFollow(FOLLOW_expression_in_collectionExpression1624); + x=expression(); + _fsp--; + if (failed) return e; + match(input,31,FOLLOW_31_in_collectionExpression1626); if (failed) return e; + if ( backtracking==0 ) { + e = factory.createCollectionExpression(id(name),var,x); + } + + } + break; + + } + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return e; + } + // $ANTLR end collectionExpression + + + // $ANTLR start declaredParameterList + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:250:1: declaredParameterList returns [List<DeclaredParameter> l = new ArrayList<DeclaredParameter>()] : dp= declaredParameter ( ',' dp1= declaredParameter )* ; + public List<DeclaredParameter> declaredParameterList() throws RecognitionException { + List<DeclaredParameter> l = new ArrayList<DeclaredParameter>(); + + DeclaredParameter dp = null; + + DeclaredParameter dp1 = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:251:2: (dp= declaredParameter ( ',' dp1= declaredParameter )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:251:2: dp= declaredParameter ( ',' dp1= declaredParameter )* + { + pushFollow(FOLLOW_declaredParameter_in_declaredParameterList1650); + dp=declaredParameter(); + _fsp--; + if (failed) return l; + if ( backtracking==0 ) { + l.add(dp); + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:251:36: ( ',' dp1= declaredParameter )* + loop49: + do { + int alt49=2; + int LA49_0 = input.LA(1); + + if ( (LA49_0==29) ) { + int LA49_1 = input.LA(2); + + if ( (LA49_1==Identifier||(LA49_1>=38 && LA49_1<=40)) ) { + alt49=1; + } + + + } + + + switch (alt49) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:251:37: ',' dp1= declaredParameter + { + match(input,29,FOLLOW_29_in_declaredParameterList1654); if (failed) return l; + pushFollow(FOLLOW_declaredParameter_in_declaredParameterList1658); + dp1=declaredParameter(); + _fsp--; + if (failed) return l; + if ( backtracking==0 ) { + l.add(dp1); + } + + } + break; + + default : + break loop49; + } + } while (true); + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return l; + } + // $ANTLR end declaredParameterList + + + // $ANTLR start declaredParameter + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:254:1: declaredParameter returns [DeclaredParameter dp] : t= type name= identifier ; + public DeclaredParameter declaredParameter() throws RecognitionException { + DeclaredParameter dp = null; + + Identifier t = null; + + Identifier name = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:255:2: (t= type name= identifier ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:255:2: t= type name= identifier + { + pushFollow(FOLLOW_type_in_declaredParameter1678); + t=type(); + _fsp--; + if (failed) return dp; + pushFollow(FOLLOW_identifier_in_declaredParameter1682); + name=identifier(); + _fsp--; + if (failed) return dp; + if ( backtracking==0 ) { + dp = factory.createDeclaredParameter(t,name); + } + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return dp; + } + // $ANTLR end declaredParameter + + + // $ANTLR start parameterList + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:258:1: parameterList returns [List<Expression> list = new ArrayList<Expression>()] : a= expression ( ',' b= expression )* ; + public List<Expression> parameterList() throws RecognitionException { + List<Expression> list = new ArrayList<Expression>(); + + Expression a = null; + + Expression b = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:259:5: (a= expression ( ',' b= expression )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:259:5: a= expression ( ',' b= expression )* + { + pushFollow(FOLLOW_expression_in_parameterList1704); + a=expression(); + _fsp--; + if (failed) return list; + if ( backtracking==0 ) { + list.add(a); + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:259:34: ( ',' b= expression )* + loop50: + do { + int alt50=2; + int LA50_0 = input.LA(1); + + if ( (LA50_0==29) ) { + alt50=1; + } + + + switch (alt50) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:259:35: ',' b= expression + { + match(input,29,FOLLOW_29_in_parameterList1709); if (failed) return list; + pushFollow(FOLLOW_expression_in_parameterList1713); + b=expression(); + _fsp--; + if (failed) return list; + if ( backtracking==0 ) { + list.add(b); + } + + } + break; + + default : + break loop50; + } + } while (true); + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return list; + } + // $ANTLR end parameterList + + + // $ANTLR start type + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:264:1: type returns [Identifier id] : (a= collectionType | b= simpleType ); + public Identifier type() throws RecognitionException { + Identifier id = null; + + Identifier a = null; + + Identifier b = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:265:2: (a= collectionType | b= simpleType ) + int alt51=2; + int LA51_0 = input.LA(1); + + if ( ((LA51_0>=38 && LA51_0<=40)) ) { + alt51=1; + } + else if ( (LA51_0==Identifier) ) { + alt51=2; + } + else { + if (backtracking>0) {failed=true; return id;} + NoViableAltException nvae = + new NoViableAltException("264:1: type returns [Identifier id] : (a= collectionType | b= simpleType );", 51, 0, input); + + throw nvae; + } + switch (alt51) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:265:2: a= collectionType + { + pushFollow(FOLLOW_collectionType_in_type1739); + a=collectionType(); + _fsp--; + if (failed) return id; + if ( backtracking==0 ) { + id =a; + } + + } + break; + case 2 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:266:2: b= simpleType + { + pushFollow(FOLLOW_simpleType_in_type1749); + b=simpleType(); + _fsp--; + if (failed) return id; + if ( backtracking==0 ) { + id =b; + } + + } + break; + + } + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return id; + } + // $ANTLR end type + + + // $ANTLR start collectionType + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:269:1: collectionType returns [Identifier id ] : cl= ( 'Collection' | 'List' | 'Set' ) (b= '[' id1= simpleType c= ']' )? ; + public Identifier collectionType() throws RecognitionException { + Identifier id = null; + + Token cl=null; + Token b=null; + Token c=null; + Identifier id1 = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:270:3: (cl= ( 'Collection' | 'List' | 'Set' ) (b= '[' id1= simpleType c= ']' )? ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:270:3: cl= ( 'Collection' | 'List' | 'Set' ) (b= '[' id1= simpleType c= ']' )? + { + cl=(Token)input.LT(1); + if ( (input.LA(1)>=38 && input.LA(1)<=40) ) { + input.consume(); + errorRecovery=false;failed=false; + } + else { + if (backtracking>0) {failed=true; return id;} + MismatchedSetException mse = + new MismatchedSetException(null,input); + recoverFromMismatchedSet(input,mse,FOLLOW_set_in_collectionType1771); throw mse; + } + + if ( backtracking==0 ) { + id = id(cl); + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:271:3: (b= '[' id1= simpleType c= ']' )? + int alt52=2; + int LA52_0 = input.LA(1); + + if ( (LA52_0==80) ) { + alt52=1; + } + switch (alt52) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:271:4: b= '[' id1= simpleType c= ']' + { + b=(Token)input.LT(1); + match(input,80,FOLLOW_80_in_collectionType1792); if (failed) return id; + pushFollow(FOLLOW_simpleType_in_collectionType1796); + id1=simpleType(); + _fsp--; + if (failed) return id; + c=(Token)input.LT(1); + match(input,81,FOLLOW_81_in_collectionType1800); if (failed) return id; + if ( backtracking==0 ) { + id.append(id(b));id.append(id1);id.append(id(c)); + } + + } + break; + + } + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return id; + } + // $ANTLR end collectionType + + + // $ANTLR start simpleType + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:274:1: simpleType returns [Identifier id] : x= identifier (d= '::' end= identifier )* ; + public Identifier simpleType() throws RecognitionException { + Identifier id = null; + + Token d=null; + Identifier x = null; + + Identifier end = null; + + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:275:2: (x= identifier (d= '::' end= identifier )* ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:275:2: x= identifier (d= '::' end= identifier )* + { + pushFollow(FOLLOW_identifier_in_simpleType1820); + x=identifier(); + _fsp--; + if (failed) return id; + if ( backtracking==0 ) { + id =x; + } + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:276:2: (d= '::' end= identifier )* + loop53: + do { + int alt53=2; + int LA53_0 = input.LA(1); + + if ( (LA53_0==32) ) { + alt53=1; + } + + + switch (alt53) { + case 1 : + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:276:3: d= '::' end= identifier + { + d=(Token)input.LT(1); + match(input,32,FOLLOW_32_in_simpleType1828); if (failed) return id; + pushFollow(FOLLOW_identifier_in_simpleType1832); + end=identifier(); + _fsp--; + if (failed) return id; + if ( backtracking==0 ) { + id.append(id(d)); id.append(end); + } + + } + break; + + default : + break loop53; + } + } while (true); + + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return id; + } + // $ANTLR end simpleType + + + // $ANTLR start identifier + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:279:1: identifier returns [Identifier r] : x= Identifier ; + public Identifier identifier() throws RecognitionException { + Identifier r = null; + + Token x=null; + + try { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:280:4: (x= Identifier ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:280:4: x= Identifier + { + x=(Token)input.LT(1); + match(input,Identifier,FOLLOW_Identifier_in_identifier1855); if (failed) return r; + if ( backtracking==0 ) { + r =id(x); + } + + } + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + } + finally { + } + return r; + } + // $ANTLR end identifier + + // $ANTLR start synpred1 + public void synpred1_fragment() throws RecognitionException { + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:117:5: ( '(' type ')' castedExpression ) + // ../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g:117:6: '(' type ')' castedExpression + { + match(input,28,FOLLOW_28_in_synpred1655); if (failed) return ; + pushFollow(FOLLOW_type_in_synpred1657); + type(); + _fsp--; + if (failed) return ; + match(input,31,FOLLOW_31_in_synpred1659); if (failed) return ; + pushFollow(FOLLOW_castedExpression_in_synpred1661); + castedExpression(); + _fsp--; + if (failed) return ; + + } + } + // $ANTLR end synpred1 + + public final boolean synpred1() { + backtracking++; + int start = input.mark(); + try { + synpred1_fragment(); // can never throw exception + } catch (RecognitionException re) { + System.err.println("impossible: "+re); + } + boolean success = !failed; + input.rewind(start); + backtracking--; + failed=false; + return success; + } + + + protected DFA26 dfa26 = new DFA26(this); + static final String DFA26_eotS = + "\67\uffff"; + static final String DFA26_eofS = + "\6\uffff\1\2\60\uffff"; + static final String DFA26_minS = + "\2\4\1\uffff\1\36\1\34\1\6\1\4\1\6\1\40\16\uffff\1\4\1\uffff\1\36"+ + "\1\6\1\36\3\0\2\34\4\0\2\6\1\0\1\40\1\6\3\0\2\37\1\6\1\0\1\6\1\40"+ + "\1\37\1\6\1\37\1\40"; + static final String DFA26_maxS = + "\2\116\1\uffff\1\120\1\77\1\6\1\116\1\6\1\121\16\uffff\1\116\1\uffff"+ + "\1\77\1\6\1\77\3\0\2\34\4\0\2\6\1\0\1\121\1\50\3\0\1\120\1\40\1"+ + "\6\1\0\1\6\1\121\1\40\1\6\1\37\1\121"; + static final String DFA26_acceptS = + "\2\uffff\1\2\6\uffff\16\1\1\uffff\1\1\36\uffff"; + static final String DFA26_specialS = + "\6\uffff\1\4\25\uffff\1\6\1\7\1\13\2\uffff\1\14\1\5\1\2\1\3\2\uffff"+ + "\1\1\2\uffff\1\12\1\11\1\10\3\uffff\1\0\6\uffff}>"; + static final String[] DFA26_transitionS = { + "\3\2\20\uffff\1\2\4\uffff\1\1\11\uffff\3\2\6\uffff\2\2\15\uffff"+ + "\1\2\1\uffff\17\2", + "\2\2\1\4\20\uffff\1\2\4\uffff\1\2\11\uffff\3\3\1\2\5\uffff\2"+ + "\2\15\uffff\1\2\1\uffff\17\2", + "", + "\1\2\1\6\4\uffff\1\2\6\uffff\2\2\7\uffff\14\2\20\uffff\1\5", + "\1\2\1\uffff\1\2\1\6\1\7\3\uffff\1\2\6\uffff\2\2\7\uffff\14"+ + "\2", + "\1\10", + "\1\12\1\20\1\13\14\uffff\1\2\3\uffff\1\30\3\2\1\uffff\1\25\3"+ + "\2\4\uffff\1\2\1\uffff\3\14\2\uffff\2\2\2\uffff\1\11\1\22\2"+ + "\uffff\13\2\1\27\1\2\1\26\1\24\1\23\2\17\1\21\1\15\10\16", + "\1\31", + "\1\32\60\uffff\1\33", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "\1\34\1\42\1\35\25\uffff\1\47\11\uffff\3\36\7\uffff\1\44\15"+ + "\uffff\1\2\1\uffff\1\2\1\46\1\45\2\41\1\43\1\37\10\40", + "", + "\1\2\1\6\1\7\3\uffff\1\2\6\uffff\2\2\7\uffff\14\2", + "\1\50", + "\1\2\1\6\4\uffff\1\2\6\uffff\2\2\7\uffff\14\2", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\51", + "\1\52", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\53", + "\1\54", + "\1\uffff", + "\1\32\60\uffff\1\33", + "\1\56\37\uffff\3\55", + "\1\uffff", + "\1\uffff", + "\1\uffff", + "\1\60\60\uffff\1\57", + "\1\60\1\61", + "\1\62", + "\1\uffff", + "\1\63", + "\1\64\60\uffff\1\65", + "\1\60\1\61", + "\1\66", + "\1\60", + "\1\64\60\uffff\1\65" + }; + + static final short[] DFA26_eot = DFA.unpackEncodedString(DFA26_eotS); + static final short[] DFA26_eof = DFA.unpackEncodedString(DFA26_eofS); + static final char[] DFA26_min = DFA.unpackEncodedStringToUnsignedChars(DFA26_minS); + static final char[] DFA26_max = DFA.unpackEncodedStringToUnsignedChars(DFA26_maxS); + static final short[] DFA26_accept = DFA.unpackEncodedString(DFA26_acceptS); + static final short[] DFA26_special = DFA.unpackEncodedString(DFA26_specialS); + static final short[][] DFA26_transition; + + static { + int numStates = DFA26_transitionS.length; + DFA26_transition = new short[numStates][]; + for (int i=0; i<numStates; i++) { + DFA26_transition[i] = DFA.unpackEncodedString(DFA26_transitionS[i]); + } + } + + class DFA26 extends DFA { + + public DFA26(BaseRecognizer recognizer) { + this.recognizer = recognizer; + this.decisionNumber = 26; + this.eot = DFA26_eot; + this.eof = DFA26_eof; + this.min = DFA26_min; + this.max = DFA26_max; + this.accept = DFA26_accept; + this.special = DFA26_special; + this.transition = DFA26_transition; + } + public String getDescription() { + return "116:1: castedExpression returns [Expression e] : ( ( '(' type ')' castedExpression )=> '(' t= type ')' x= chainExpression | x= chainExpression );"; + } + public int specialStateTransition(int s, IntStream input) throws NoViableAltException { + int _s = s; + switch ( s ) { + case 0 : + int LA26_48 = input.LA(1); + + + int index26_48 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1()) ) {s = 24;} + + else if ( (true) ) {s = 2;} + + + input.seek(index26_48); + if ( s>=0 ) return s; + break; + case 1 : + int LA26_39 = input.LA(1); + + + int index26_39 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1()) ) {s = 24;} + + else if ( (true) ) {s = 2;} + + + input.seek(index26_39); + if ( s>=0 ) return s; + break; + case 2 : + int LA26_35 = input.LA(1); + + + int index26_35 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1()) ) {s = 24;} + + else if ( (true) ) {s = 2;} + + + input.seek(index26_35); + if ( s>=0 ) return s; + break; + case 3 : + int LA26_36 = input.LA(1); + + + int index26_36 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1()) ) {s = 24;} + + else if ( (true) ) {s = 2;} + + + input.seek(index26_36); + if ( s>=0 ) return s; + break; + case 4 : + int LA26_6 = input.LA(1); + + + int index26_6 = input.index(); + input.rewind(); + s = -1; + if ( (LA26_6==47) && (synpred1())) {s = 9;} + + else if ( (LA26_6==StringLiteral) && (synpred1())) {s = 10;} + + else if ( (LA26_6==Identifier) && (synpred1())) {s = 11;} + + else if ( ((LA26_6>=38 && LA26_6<=40)) && (synpred1())) {s = 12;} + + else if ( (LA26_6==70) && (synpred1())) {s = 13;} + + else if ( ((LA26_6>=71 && LA26_6<=78)) && (synpred1())) {s = 14;} + + else if ( ((LA26_6>=67 && LA26_6<=68)) && (synpred1())) {s = 15;} + + else if ( (LA26_6==IntLiteral) && (synpred1())) {s = 16;} + + else if ( (LA26_6==69) && (synpred1())) {s = 17;} + + else if ( (LA26_6==48) && (synpred1())) {s = 18;} + + else if ( (LA26_6==66) && (synpred1())) {s = 19;} + + else if ( (LA26_6==65) && (synpred1())) {s = 20;} + + else if ( (LA26_6==28) && (synpred1())) {s = 21;} + + else if ( (LA26_6==64) && (synpred1())) {s = 22;} + + else if ( (LA26_6==62) ) {s = 23;} + + else if ( (LA26_6==23) && (synpred1())) {s = 24;} + + else if ( (LA26_6==EOF||LA26_6==19||(LA26_6>=24 && LA26_6<=26)||(LA26_6>=29 && LA26_6<=31)||LA26_6==36||(LA26_6>=43 && LA26_6<=44)||(LA26_6>=51 && LA26_6<=61)||LA26_6==63) ) {s = 2;} + + + input.seek(index26_6); + if ( s>=0 ) return s; + break; + case 5 : + int LA26_34 = input.LA(1); + + + int index26_34 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1()) ) {s = 24;} + + else if ( (true) ) {s = 2;} + + + input.seek(index26_34); + if ( s>=0 ) return s; + break; + case 6 : + int LA26_28 = input.LA(1); + + + int index26_28 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1()) ) {s = 24;} + + else if ( (true) ) {s = 2;} + + + input.seek(index26_28); + if ( s>=0 ) return s; + break; + case 7 : + int LA26_29 = input.LA(1); + + + int index26_29 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1()) ) {s = 24;} + + else if ( (true) ) {s = 2;} + + + input.seek(index26_29); + if ( s>=0 ) return s; + break; + case 8 : + int LA26_44 = input.LA(1); + + + int index26_44 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1()) ) {s = 24;} + + else if ( (true) ) {s = 2;} + + + input.seek(index26_44); + if ( s>=0 ) return s; + break; + case 9 : + int LA26_43 = input.LA(1); + + + int index26_43 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1()) ) {s = 24;} + + else if ( (true) ) {s = 2;} + + + input.seek(index26_43); + if ( s>=0 ) return s; + break; + case 10 : + int LA26_42 = input.LA(1); + + + int index26_42 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1()) ) {s = 24;} + + else if ( (true) ) {s = 2;} + + + input.seek(index26_42); + if ( s>=0 ) return s; + break; + case 11 : + int LA26_30 = input.LA(1); + + + int index26_30 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1()) ) {s = 24;} + + else if ( (true) ) {s = 2;} + + + input.seek(index26_30); + if ( s>=0 ) return s; + break; + case 12 : + int LA26_33 = input.LA(1); + + + int index26_33 = input.index(); + input.rewind(); + s = -1; + if ( (synpred1()) ) {s = 24;} + + else if ( (true) ) {s = 2;} + + + input.seek(index26_33); + if ( s>=0 ) return s; + break; + } + if (backtracking>0) {failed=true; return -1;} + NoViableAltException nvae = + new NoViableAltException(getDescription(), 26, _s, input); + error(nvae); + throw nvae; + } + } + + + public static final BitSet FOLLOW_nsImport_in_file51 = new BitSet(new long[]{0x000001E608540040L}); + public static final BitSet FOLLOW_extImport_in_file61 = new BitSet(new long[]{0x000001E608500040L}); + public static final BitSet FOLLOW_extension_in_file71 = new BitSet(new long[]{0x000001E608400040L}); + public static final BitSet FOLLOW_around_in_file81 = new BitSet(new long[]{0x000001E608400040L}); + public static final BitSet FOLLOW_check_in_file91 = new BitSet(new long[]{0x000001E608400040L}); + public static final BitSet FOLLOW_EOF_in_file99 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_18_in_nsImport117 = new BitSet(new long[]{0x000001C000000040L}); + public static final BitSet FOLLOW_type_in_nsImport121 = new BitSet(new long[]{0x0000000000080000L}); + public static final BitSet FOLLOW_19_in_nsImport125 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_20_in_extImport140 = new BitSet(new long[]{0x000001C000000040L}); + public static final BitSet FOLLOW_type_in_extImport144 = new BitSet(new long[]{0x0000000000280000L}); + public static final BitSet FOLLOW_21_in_extImport149 = new BitSet(new long[]{0x0000000000080000L}); + public static final BitSet FOLLOW_19_in_extImport153 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_22_in_check168 = new BitSet(new long[]{0x000001C000000040L}); + public static final BitSet FOLLOW_type_in_check172 = new BitSet(new long[]{0x0000000003800000L}); + public static final BitSet FOLLOW_23_in_check175 = new BitSet(new long[]{0x400183C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_expression_in_check179 = new BitSet(new long[]{0x0000000003000000L}); + public static final BitSet FOLLOW_24_in_check186 = new BitSet(new long[]{0x400183C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_25_in_check188 = new BitSet(new long[]{0x400183C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_expression_in_check193 = new BitSet(new long[]{0x0000000004000000L}); + public static final BitSet FOLLOW_26_in_check195 = new BitSet(new long[]{0x400183C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_expression_in_check200 = new BitSet(new long[]{0x0000000000080000L}); + public static final BitSet FOLLOW_19_in_check202 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_27_in_around223 = new BitSet(new long[]{0x0000000040000040L}); + public static final BitSet FOLLOW_pointcut_in_around227 = new BitSet(new long[]{0x0000000010000000L}); + public static final BitSet FOLLOW_28_in_around229 = new BitSet(new long[]{0x000001C0C0000040L}); + public static final BitSet FOLLOW_declaredParameterList_in_around234 = new BitSet(new long[]{0x00000000E0000000L}); + public static final BitSet FOLLOW_29_in_around237 = new BitSet(new long[]{0x0000000040000000L}); + public static final BitSet FOLLOW_30_in_around242 = new BitSet(new long[]{0x0000000080000000L}); + public static final BitSet FOLLOW_30_in_around250 = new BitSet(new long[]{0x0000000080000000L}); + public static final BitSet FOLLOW_31_in_around254 = new BitSet(new long[]{0x0000000004000000L}); + public static final BitSet FOLLOW_26_in_around256 = new BitSet(new long[]{0x400183C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_expression_in_around265 = new BitSet(new long[]{0x0000000000080000L}); + public static final BitSet FOLLOW_19_in_around267 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_30_in_pointcut295 = new BitSet(new long[]{0x0000000140000042L}); + public static final BitSet FOLLOW_identifier_in_pointcut304 = new BitSet(new long[]{0x0000000140000042L}); + public static final BitSet FOLLOW_30_in_pointcut315 = new BitSet(new long[]{0x0000000140000042L}); + public static final BitSet FOLLOW_identifier_in_pointcut326 = new BitSet(new long[]{0x0000000140000042L}); + public static final BitSet FOLLOW_32_in_pointcut337 = new BitSet(new long[]{0x0000000140000042L}); + public static final BitSet FOLLOW_33_in_extension365 = new BitSet(new long[]{0x000001C400000040L}); + public static final BitSet FOLLOW_34_in_extension372 = new BitSet(new long[]{0x000001C000000040L}); + public static final BitSet FOLLOW_type_in_extension379 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_identifier_in_extension385 = new BitSet(new long[]{0x0000000010000000L}); + public static final BitSet FOLLOW_28_in_extension387 = new BitSet(new long[]{0x000001C080000040L}); + public static final BitSet FOLLOW_declaredParameterList_in_extension392 = new BitSet(new long[]{0x0000000080000000L}); + public static final BitSet FOLLOW_31_in_extension396 = new BitSet(new long[]{0x0000000004000000L}); + public static final BitSet FOLLOW_26_in_extension398 = new BitSet(new long[]{0x400183C810800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_35_in_extension405 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_javaType_in_extension409 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_36_in_extension411 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_identifier_in_extension415 = new BitSet(new long[]{0x0000000010000000L}); + public static final BitSet FOLLOW_28_in_extension417 = new BitSet(new long[]{0x0000000080000040L}); + public static final BitSet FOLLOW_javaType_in_extension421 = new BitSet(new long[]{0x00000000A0000000L}); + public static final BitSet FOLLOW_29_in_extension425 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_javaType_in_extension429 = new BitSet(new long[]{0x00000000A0000000L}); + public static final BitSet FOLLOW_31_in_extension437 = new BitSet(new long[]{0x0000000000080000L}); + public static final BitSet FOLLOW_19_in_extension439 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_expression_in_extension449 = new BitSet(new long[]{0x0000000000080000L}); + public static final BitSet FOLLOW_19_in_extension451 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_33_in_extension465 = new BitSet(new long[]{0x0000002000000000L}); + public static final BitSet FOLLOW_37_in_extension471 = new BitSet(new long[]{0x000001C000000040L}); + public static final BitSet FOLLOW_type_in_extension475 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_identifier_in_extension480 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_identifier_in_extension486 = new BitSet(new long[]{0x0000000010000000L}); + public static final BitSet FOLLOW_28_in_extension488 = new BitSet(new long[]{0x000001C080000040L}); + public static final BitSet FOLLOW_declaredParameterList_in_extension493 = new BitSet(new long[]{0x0000000080000000L}); + public static final BitSet FOLLOW_31_in_extension497 = new BitSet(new long[]{0x0000000004000000L}); + public static final BitSet FOLLOW_26_in_extension499 = new BitSet(new long[]{0x400183C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_expression_in_extension505 = new BitSet(new long[]{0x0000000000080000L}); + public static final BitSet FOLLOW_19_in_extension507 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_identifier_in_javaType529 = new BitSet(new long[]{0x0000001000000002L}); + public static final BitSet FOLLOW_36_in_javaType538 = new BitSet(new long[]{0x000001C000000040L}); + public static final BitSet FOLLOW_identifier_in_javaType544 = new BitSet(new long[]{0x0000001000000002L}); + public static final BitSet FOLLOW_38_in_javaType550 = new BitSet(new long[]{0x0000001000000002L}); + public static final BitSet FOLLOW_39_in_javaType559 = new BitSet(new long[]{0x0000001000000002L}); + public static final BitSet FOLLOW_40_in_javaType565 = new BitSet(new long[]{0x0000001000000002L}); + public static final BitSet FOLLOW_letExpression_in_expression587 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_41_in_letExpression606 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_identifier_in_letExpression610 = new BitSet(new long[]{0x0000040000000000L}); + public static final BitSet FOLLOW_42_in_letExpression612 = new BitSet(new long[]{0x400181C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_castedExpression_in_letExpression616 = new BitSet(new long[]{0x0000000004000000L}); + public static final BitSet FOLLOW_26_in_letExpression618 = new BitSet(new long[]{0x400183C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_expression_in_letExpression622 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_castedExpression_in_letExpression635 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_28_in_castedExpression666 = new BitSet(new long[]{0x000001C000000040L}); + public static final BitSet FOLLOW_type_in_castedExpression670 = new BitSet(new long[]{0x0000000080000000L}); + public static final BitSet FOLLOW_31_in_castedExpression672 = new BitSet(new long[]{0x400181C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_chainExpression_in_castedExpression676 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_chainExpression_in_castedExpression685 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_ifExpression_in_chainExpression705 = new BitSet(new long[]{0x0000080000000002L}); + public static final BitSet FOLLOW_43_in_chainExpression711 = new BitSet(new long[]{0x400181C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_ifExpression_in_chainExpression715 = new BitSet(new long[]{0x0000080000000002L}); + public static final BitSet FOLLOW_switchExpression_in_ifExpression736 = new BitSet(new long[]{0x0000100000000002L}); + public static final BitSet FOLLOW_44_in_ifExpression740 = new BitSet(new long[]{0x400181C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_switchExpression_in_ifExpression744 = new BitSet(new long[]{0x0000000004000000L}); + public static final BitSet FOLLOW_26_in_ifExpression746 = new BitSet(new long[]{0x400181C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_switchExpression_in_ifExpression750 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_23_in_ifExpression758 = new BitSet(new long[]{0x400181C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_switchExpression_in_ifExpression762 = new BitSet(new long[]{0x0000200000000000L}); + public static final BitSet FOLLOW_45_in_ifExpression764 = new BitSet(new long[]{0x400181C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_switchExpression_in_ifExpression768 = new BitSet(new long[]{0x0000400000000002L}); + public static final BitSet FOLLOW_46_in_ifExpression771 = new BitSet(new long[]{0x400183C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_expression_in_ifExpression775 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_47_in_switchExpression802 = new BitSet(new long[]{0x0001000010000000L}); + public static final BitSet FOLLOW_28_in_switchExpression805 = new BitSet(new long[]{0x400101C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_orExpression_in_switchExpression811 = new BitSet(new long[]{0x0000000080000000L}); + public static final BitSet FOLLOW_31_in_switchExpression813 = new BitSet(new long[]{0x0001000000000000L}); + public static final BitSet FOLLOW_48_in_switchExpression820 = new BitSet(new long[]{0x0006000000000000L}); + public static final BitSet FOLLOW_49_in_switchExpression833 = new BitSet(new long[]{0x400101C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_orExpression_in_switchExpression837 = new BitSet(new long[]{0x0000000004000000L}); + public static final BitSet FOLLOW_26_in_switchExpression840 = new BitSet(new long[]{0x400101C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_orExpression_in_switchExpression845 = new BitSet(new long[]{0x0006000000000000L}); + public static final BitSet FOLLOW_50_in_switchExpression863 = new BitSet(new long[]{0x0000000004000000L}); + public static final BitSet FOLLOW_26_in_switchExpression865 = new BitSet(new long[]{0x400101C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_orExpression_in_switchExpression871 = new BitSet(new long[]{0x0008000000000000L}); + public static final BitSet FOLLOW_51_in_switchExpression876 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_orExpression_in_switchExpression888 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_andExpression_in_orExpression908 = new BitSet(new long[]{0x0010000000000002L}); + public static final BitSet FOLLOW_52_in_orExpression915 = new BitSet(new long[]{0x400101C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_andExpression_in_orExpression919 = new BitSet(new long[]{0x0010000000000002L}); + public static final BitSet FOLLOW_impliesExpression_in_andExpression942 = new BitSet(new long[]{0x0020000000000002L}); + public static final BitSet FOLLOW_53_in_andExpression949 = new BitSet(new long[]{0x400101C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_impliesExpression_in_andExpression953 = new BitSet(new long[]{0x0020000000000002L}); + public static final BitSet FOLLOW_relationalExpression_in_impliesExpression975 = new BitSet(new long[]{0x0040000000000002L}); + public static final BitSet FOLLOW_54_in_impliesExpression982 = new BitSet(new long[]{0x400101C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_relationalExpression_in_impliesExpression986 = new BitSet(new long[]{0x0040000000000002L}); + public static final BitSet FOLLOW_additiveExpression_in_relationalExpression1010 = new BitSet(new long[]{0x1F80000000000002L}); + public static final BitSet FOLLOW_set_in_relationalExpression1018 = new BitSet(new long[]{0x400101C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_additiveExpression_in_relationalExpression1044 = new BitSet(new long[]{0x1F80000000000002L}); + public static final BitSet FOLLOW_multiplicativeExpression_in_additiveExpression1065 = new BitSet(new long[]{0x6000000000000002L}); + public static final BitSet FOLLOW_set_in_additiveExpression1075 = new BitSet(new long[]{0x400101C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_multiplicativeExpression_in_additiveExpression1084 = new BitSet(new long[]{0x6000000000000002L}); + public static final BitSet FOLLOW_unaryExpression_in_multiplicativeExpression1103 = new BitSet(new long[]{0x8000000040000002L}); + public static final BitSet FOLLOW_set_in_multiplicativeExpression1111 = new BitSet(new long[]{0x400101C010000070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_unaryExpression_in_multiplicativeExpression1121 = new BitSet(new long[]{0x8000000040000002L}); + public static final BitSet FOLLOW_infixExpression_in_unaryExpression1142 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_64_in_unaryExpression1150 = new BitSet(new long[]{0x000101C010000070L,0x0000000000007FFEL}); + public static final BitSet FOLLOW_infixExpression_in_unaryExpression1154 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_62_in_unaryExpression1162 = new BitSet(new long[]{0x000101C010000070L,0x0000000000007FFEL}); + public static final BitSet FOLLOW_infixExpression_in_unaryExpression1166 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_primaryExpression_in_infixExpression1184 = new BitSet(new long[]{0x0000001000000002L}); + public static final BitSet FOLLOW_36_in_infixExpression1190 = new BitSet(new long[]{0x000001C000000040L,0x0000000000007FC0L}); + public static final BitSet FOLLOW_featureCall_in_infixExpression1194 = new BitSet(new long[]{0x0000001000000002L}); + public static final BitSet FOLLOW_StringLiteral_in_primaryExpression1220 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_featureCall_in_primaryExpression1231 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_booleanLiteral_in_primaryExpression1241 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_numberLiteral_in_primaryExpression1251 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_nullLiteral_in_primaryExpression1261 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_listLiteral_in_primaryExpression1271 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_constructorCall_in_primaryExpression1281 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_globalVarExpression_in_primaryExpression1291 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_paranthesizedExpression_in_primaryExpression1301 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_28_in_paranthesizedExpression1320 = new BitSet(new long[]{0x400183C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_expression_in_paranthesizedExpression1324 = new BitSet(new long[]{0x0000000080000000L}); + public static final BitSet FOLLOW_31_in_paranthesizedExpression1326 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_65_in_globalVarExpression1346 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_identifier_in_globalVarExpression1350 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_identifier_in_featureCall1368 = new BitSet(new long[]{0x0000000010000000L}); + public static final BitSet FOLLOW_28_in_featureCall1370 = new BitSet(new long[]{0x400183C090800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_parameterList_in_featureCall1375 = new BitSet(new long[]{0x0000000080000000L}); + public static final BitSet FOLLOW_31_in_featureCall1379 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_type_in_featureCall1389 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_collectionExpression_in_featureCall1400 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_48_in_listLiteral1417 = new BitSet(new long[]{0x400983C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_parameterList_in_listLiteral1422 = new BitSet(new long[]{0x0008000000000000L}); + public static final BitSet FOLLOW_51_in_listLiteral1426 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_66_in_constructorCall1443 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_simpleType_in_constructorCall1447 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_set_in_booleanLiteral0 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_69_in_nullLiteral1482 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_IntLiteral_in_numberLiteral1501 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_IntLiteral_in_numberLiteral1510 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_36_in_numberLiteral1514 = new BitSet(new long[]{0x0000000000000020L}); + public static final BitSet FOLLOW_IntLiteral_in_numberLiteral1518 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_70_in_collectionExpression1538 = new BitSet(new long[]{0x0000000010000000L}); + public static final BitSet FOLLOW_28_in_collectionExpression1542 = new BitSet(new long[]{0x000001C000000040L}); + public static final BitSet FOLLOW_type_in_collectionExpression1546 = new BitSet(new long[]{0x0000000080000000L}); + public static final BitSet FOLLOW_31_in_collectionExpression1548 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_set_in_collectionExpression1561 = new BitSet(new long[]{0x0000000010000000L}); + public static final BitSet FOLLOW_28_in_collectionExpression1611 = new BitSet(new long[]{0x400183C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_identifier_in_collectionExpression1616 = new BitSet(new long[]{0x0000000000000000L,0x0000000000008000L}); + public static final BitSet FOLLOW_79_in_collectionExpression1618 = new BitSet(new long[]{0x400183C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_expression_in_collectionExpression1624 = new BitSet(new long[]{0x0000000080000000L}); + public static final BitSet FOLLOW_31_in_collectionExpression1626 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_declaredParameter_in_declaredParameterList1650 = new BitSet(new long[]{0x0000000020000002L}); + public static final BitSet FOLLOW_29_in_declaredParameterList1654 = new BitSet(new long[]{0x000001C000000040L}); + public static final BitSet FOLLOW_declaredParameter_in_declaredParameterList1658 = new BitSet(new long[]{0x0000000020000002L}); + public static final BitSet FOLLOW_type_in_declaredParameter1678 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_identifier_in_declaredParameter1682 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_expression_in_parameterList1704 = new BitSet(new long[]{0x0000000020000002L}); + public static final BitSet FOLLOW_29_in_parameterList1709 = new BitSet(new long[]{0x400183C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_expression_in_parameterList1713 = new BitSet(new long[]{0x0000000020000002L}); + public static final BitSet FOLLOW_collectionType_in_type1739 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_simpleType_in_type1749 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_set_in_collectionType1771 = new BitSet(new long[]{0x0000000000000002L,0x0000000000010000L}); + public static final BitSet FOLLOW_80_in_collectionType1792 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_simpleType_in_collectionType1796 = new BitSet(new long[]{0x0000000000000000L,0x0000000000020000L}); + public static final BitSet FOLLOW_81_in_collectionType1800 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_identifier_in_simpleType1820 = new BitSet(new long[]{0x0000000100000002L}); + public static final BitSet FOLLOW_32_in_simpleType1828 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_identifier_in_simpleType1832 = new BitSet(new long[]{0x0000000100000002L}); + public static final BitSet FOLLOW_Identifier_in_identifier1855 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_28_in_synpred1655 = new BitSet(new long[]{0x000001C000000040L}); + public static final BitSet FOLLOW_type_in_synpred1657 = new BitSet(new long[]{0x0000000080000000L}); + public static final BitSet FOLLOW_31_in_synpred1659 = new BitSet(new long[]{0x400181C010800070L,0x0000000000007FFFL}); + public static final BitSet FOLLOW_castedExpression_in_synpred1661 = new BitSet(new long[]{0x0000000000000002L}); + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/Xtend__.g b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/Xtend__.g new file mode 100644 index 00000000..260d27ec --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/parser/Xtend__.g @@ -0,0 +1,175 @@ +lexer grammar Xtend; +@header { +package org.eclipse.xtend.xtend.parser; + +import java.util.ArrayList; +import java.util.List; +import java.util.Collections; + +import org.eclipse.xtend.expression.ast.*; +import org.eclipse.xtend.xtend.ast.*; +} + +T18 : 'import' ; +T19 : ';' ; +T20 : 'extension' ; +T21 : 'reexport' ; +T22 : 'context' ; +T23 : 'if' ; +T24 : 'ERROR' ; +T25 : 'WARNING' ; +T26 : ':' ; +T27 : 'around' ; +T28 : '(' ; +T29 : ',' ; +T30 : '*' ; +T31 : ')' ; +T32 : '::' ; +T33 : 'private' ; +T34 : 'cached' ; +T35 : 'JAVA' ; +T36 : '.' ; +T37 : 'create' ; +T38 : 'Collection' ; +T39 : 'List' ; +T40 : 'Set' ; +T41 : 'let' ; +T42 : '=' ; +T43 : '->' ; +T44 : '?' ; +T45 : 'then' ; +T46 : 'else' ; +T47 : 'switch' ; +T48 : '{' ; +T49 : 'case' ; +T50 : 'default' ; +T51 : '}' ; +T52 : '||' ; +T53 : '&&' ; +T54 : 'implies' ; +T55 : '==' ; +T56 : '!=' ; +T57 : '>=' ; +T58 : '<=' ; +T59 : '>' ; +T60 : '<' ; +T61 : '+' ; +T62 : '-' ; +T63 : '/' ; +T64 : '!' ; +T65 : 'GLOBALVAR' ; +T66 : 'new' ; +T67 : 'false' ; +T68 : 'true' ; +T69 : 'null' ; +T70 : 'typeSelect' ; +T71 : 'collect' ; +T72 : 'select' ; +T73 : 'selectFirst' ; +T74 : 'reject' ; +T75 : 'exists' ; +T76 : 'notExists' ; +T77 : 'sortBy' ; +T78 : 'forAll' ; +T79 : '|' ; +T80 : '[' ; +T81 : ']' ; + +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 284 +IntLiteral : ('0' | '1'..'9' '0'..'9'*) ; + +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 286 +StringLiteral + : '"' ( EscapeSequence | ~('\\'|'"') )* '"' + | '\'' ( EscapeSequence | ~('\''|'\\') )* '\'' + ; + +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 291 +fragment +EscapeSequence + : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') + | UnicodeEscape + | OctalEscape + ; + +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 298 +fragment +OctalEscape + : '\\' ('0'..'3') ('0'..'7') ('0'..'7') + | '\\' ('0'..'7') ('0'..'7') + | '\\' ('0'..'7') + ; + +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 305 +fragment +UnicodeEscape + : '\\' 'u' HexDigit HexDigit HexDigit HexDigit + ; +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 309 +fragment +HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ; + +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 312 +Identifier + : ('^')? Letter (Letter|JavaIDDigit)* + ; + +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 316 +fragment +Letter + : '\u0024' | + '\u0041'..'\u005a' | + '\u005f' | + '\u0061'..'\u007a' | + '\u00c0'..'\u00d6' | + '\u00d8'..'\u00f6' | + '\u00f8'..'\u00ff' | + '\u0100'..'\u1fff' | + '\u3040'..'\u318f' | + '\u3300'..'\u337f' | + '\u3400'..'\u3d2d' | + '\u4e00'..'\u9fff' | + '\uf900'..'\ufaff' + ; + +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 333 +fragment +JavaIDDigit + : '\u0030'..'\u0039' | + '\u0660'..'\u0669' | + '\u06f0'..'\u06f9' | + '\u0966'..'\u096f' | + '\u09e6'..'\u09ef' | + '\u0a66'..'\u0a6f' | + '\u0ae6'..'\u0aef' | + '\u0b66'..'\u0b6f' | + '\u0be7'..'\u0bef' | + '\u0c66'..'\u0c6f' | + '\u0ce6'..'\u0cef' | + '\u0d66'..'\u0d6f' | + '\u0e50'..'\u0e59' | + '\u0ed0'..'\u0ed9' | + '\u1040'..'\u1049' + ; + +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 352 +WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;} + ; + +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 355 +COMMENT + : '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;} + ; + +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 359 +LINE_COMMENT + : '//' ~('\n'|'\r')* ('\r'? '\n'|EOF) {$channel=HIDDEN;} + ; + + +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 364 +XPAND_TAG_OPEN + : '\u00AB'; +// $ANTLR src "../core.expressions/main/src/org/openarchitectureware/xtend/parser/Xtend.g" 366 +XPAND_TAG_CLOSE + : '\u00BB'; diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/types/AdviceContext.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/types/AdviceContext.java new file mode 100644 index 00000000..3cb8ed57 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/types/AdviceContext.java @@ -0,0 +1,54 @@ +package org.eclipse.internal.xtend.xtend.types; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.typesystem.Type; + +public class AdviceContext { + + private final Extension ext; + + private final ExecutionContext ctx; + + private Object[] parameters; + + + public AdviceContext(final Extension ext, final ExecutionContext ctx, Object[] parameters2) { + super(); + this.ext = ext; + this.ctx = ctx; + this.parameters = parameters2; + } + + public String getName() { + return ext.getName(); + } + + public List<Type> getParamTypes() { + return ext.getParameterTypes(); + } + + public List<String> getParamNames() { + return ext.getParameterNames(); + } + public List<Object> getParamValues() { + return new ArrayList<Object>(Arrays.asList(parameters)); + } + + public Object proceed() { + return ext.evaluate(parameters,ctx); + } + + public Object proceed(final Object[] params) { + return ext.evaluate(params,ctx); + } + + @Override + public String toString() { + return ext.toString(); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/types/AdviceContextType.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/types/AdviceContextType.java new file mode 100644 index 00000000..81bb9c45 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/types/AdviceContextType.java @@ -0,0 +1,66 @@ +package org.eclipse.internal.xtend.xtend.types; + +import java.util.List; + +import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; +import org.eclipse.internal.xtend.type.baseimpl.PropertyImpl; +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.AbstractTypeImpl; +import org.eclipse.xtend.typesystem.Feature; + +public class AdviceContextType extends AbstractTypeImpl { + + public static final String TYPE_NAME = "xtend::AdviceContext"; + + public AdviceContextType(TypeSystem typeSystem) { + super(typeSystem, TYPE_NAME); + } + @Override + public Feature[] getContributedFeatures() { + return new Feature[] { + new PropertyImpl(AdviceContextType.this,"name",getTypeSystem().getStringType()) { + public Object get(Object target) { + return ((AdviceContext)target).getName(); + } + }, + new PropertyImpl(AdviceContextType.this,"paramTypes",getTypeSystem().getListType(getTypeSystem().getTypeType())) { + public Object get(Object target) { + return ((AdviceContext)target).getParamTypes(); + } + }, + new PropertyImpl(AdviceContextType.this,"paramNames",getTypeSystem().getListType(getTypeSystem().getStringType())) { + public Object get(Object target) { + return ((AdviceContext)target).getParamNames(); + } + }, + new PropertyImpl(AdviceContextType.this,"paramValues",getTypeSystem().getListType(getTypeSystem().getObjectType())) { + public Object get(Object target) { + return ((AdviceContext)target).getParamValues(); + } + }, + new OperationImpl(AdviceContextType.this,"proceed",getTypeSystem().getObjectType()) { + + @Override + protected Object evaluateInternal(Object target, Object[] params) { + return ((AdviceContext)target).proceed(); + } + }, + new OperationImpl(AdviceContextType.this,"proceed",getTypeSystem().getObjectType(),getTypeSystem().getListType(getTypeSystem().getObjectType())) { + + @Override + protected Object evaluateInternal(Object target, Object[] params) { + return ((AdviceContext)target).proceed(((List<Object>)params[0]).toArray()); + } + } + }; + } + + public boolean isInstance(Object o) { + return o instanceof AdviceContext; + } + + public Object newInstance() { + throw new UnsupportedOperationException(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/types/XtendMetaModel.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/types/XtendMetaModel.java new file mode 100644 index 00000000..9e0387de --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/types/XtendMetaModel.java @@ -0,0 +1,60 @@ +package org.eclipse.internal.xtend.xtend.types; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.xtend.expression.TypeSystem; +import org.eclipse.xtend.typesystem.MetaModel; +import org.eclipse.xtend.typesystem.Type; + +public class XtendMetaModel implements MetaModel { + + private final Map<String, Type> types = new HashMap<String, Type>(); + + public XtendMetaModel(TypeSystem ts) { + setTypeSystem(ts); + AdviceContextType t = new AdviceContextType(ts); + types.put(t.getName(), t); + } + + public Set<? extends Type> getKnownTypes() { + return new HashSet<Type>(types.values()); + } + + public String getName() { + return "xtend"; + } + + public Type getType(Object obj) { + Type bestMatch = null; + for (Type aType : getKnownTypes()) { + if (aType.isInstance(obj)) { + if (bestMatch == null || bestMatch.isAssignableFrom(aType)) { + bestMatch = aType; + } + } + } + return bestMatch; + } + + public Type getTypeForName(String typeName) { + return types.get(typeName); + } + + private TypeSystem ts = null; + + public TypeSystem getTypeSystem() { + return ts; + } + + public void setTypeSystem(TypeSystem typeSystem) { + ts = typeSystem; + } + + public Set<String> getNamespaces() { + return new HashSet<String>(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/XtendComponent.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/XtendComponent.java new file mode 100644 index 00000000..a79dafc5 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/XtendComponent.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.xtend; + +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.emf.mwe.core.WorkflowContext; +import org.eclipse.emf.mwe.core.issues.Issues; +import org.eclipse.emf.mwe.core.monitor.ProgressMonitor; +import org.eclipse.emf.mwe.core.resources.ResourceLoaderFactory; +import org.eclipse.internal.xtend.util.ProfileCollector; +import org.eclipse.xtend.expression.AbstractExpressionsUsingWorkflowComponent; +import org.eclipse.xtend.expression.ExecutionContextImpl; +import org.eclipse.xtend.expression.ExpressionFacade; +import org.eclipse.xtend.expression.Resource; +import org.eclipse.xtend.expression.Variable; + +public class XtendComponent extends AbstractExpressionsUsingWorkflowComponent { + + private final Log log = LogFactory.getLog(getClass()); + + String extensionFile = null; + + private List<String> extensionAdvices = new ArrayList<String>(); + + public void addExtensionAdvice(String extensionAdvices) { + if ( !this.extensionAdvices.contains(extensionAdvices) ) + this.extensionAdvices.add( extensionAdvices ); + } + + /** Stores the value of the 'invoke' property. Needed for error analysis. */ + private String invokeExpression; + private String expression = null; + + private String collectProfileSummary = null; + private String verboseProfileFilename = null; + + public void setCollectProfileSummary (String c) { + collectProfileSummary = c; + } + + public void setVerboseProfileFilename (String f) { + verboseProfileFilename = f; + } + + + @Override + public String getLogMessage() { + return "executing '"+extensionFile+"'"; + } + + public void setInvoke(final String invoke) { + invokeExpression = invoke; + final int i = invoke.lastIndexOf("::"); + if (i != -1) { + extensionFile = invoke.substring(0, i); + expression = invoke.substring(i + 2); + } else { + expression = invoke; + } + } + + private String outputSlot = WorkflowContext.DEFAULT_SLOT; + + public void setOutputSlot(final String outputSlot) { + this.outputSlot = outputSlot; + } + + + + @Override + public void invokeInternal2(final WorkflowContext ctx, final ProgressMonitor monitor, final Issues issues) { + + final InputStream in = getExtFileIS(); + if (in == null) { + issues.addError("Cannot find extension file: "+extensionFile); + return; + } + + OutputStream verboseProfileOutputStream = null; + + if (verboseProfileFilename != null) { + try { + verboseProfileOutputStream = new BufferedOutputStream (new FileOutputStream (verboseProfileFilename)); + ProfileCollector.getInstance().setDetailedLoggingWriter(verboseProfileOutputStream); + } + catch (IOException exc) { + log.warn("could not open profiling log file", exc); + } + } + + + ExecutionContextImpl ec = getExecutionContext(ctx); + + for (String advice : extensionAdvices) { + final String[] allAdvices = advice.split(","); + for (int i = 0; i < allAdvices.length; i++) { + final String string = allAdvices[i]; + ec.registerExtensionAdvices(string.trim()); + } + } + + ec = (ExecutionContextImpl) ec.cloneWithResource(new Resource() { + private String name = "noName"; + + public String getFullyQualifiedName() { + return name; + } + + public void setFullyQualifiedName(final String fqn) { + name = fqn; + } + + public String[] getImportedNamespaces() { + return new String[0]; + } + + public String[] getImportedExtensions() { + return new String[] { extensionFile }; + } + }); + final String[] slots = ctx.getSlotNames(); + for (int i = 0; i < slots.length; i++) { + ec = (ExecutionContextImpl) ec.cloneWithVariable(new Variable(slots[i], ctx.get(slots[i]))); + } + + if (monitor!=null) { + ec.setMonitor(monitor); + } + + final Object result = new ExpressionFacade(ec).evaluate(expression); + ctx.set(outputSlot, result); + + ProfileCollector.getInstance().finish(); + if ("true".equalsIgnoreCase(this.collectProfileSummary)) { + log.info ("profiling info: \n" + ProfileCollector.getInstance().toString()); + } + + if (verboseProfileOutputStream != null) { + try { + verboseProfileOutputStream.close (); + } + catch (IOException exc) { + log.warn("problem closing profile log file", exc); + } + } + } + + private InputStream getExtFileIS() { + final InputStream in = ResourceLoaderFactory.createResourceLoader().getResourceAsStream( + extensionFile.replace("::", "/")+".ext"); + return in; + } + + @Override + public void checkConfiguration(final Issues issues) { + super.checkConfiguration(issues); + + // Try to create detailed error message (see Bug#172567) + String compPrefix = getId()!=null ? getId()+": " : ""; + + if (invokeExpression==null || invokeExpression.trim().length()==0) { + issues.addError(compPrefix+"Property 'invoke' not specified."); + return; + } + if (extensionFile==null) { + issues.addError(compPrefix+"Error parsing property 'invoke': Could not extract name of the extension file."); + return; + } + if (getExtFileIS()==null || expression == null) { + issues.addError(compPrefix+"Property 'invoke' not specified properly. AbstractExtension file '"+extensionFile+"' not found."); + return; + } + if (expression==null) { + issues.addError(compPrefix+"Error parsing property 'invoke': Could not extract the expression to invoke in extension file '"+extensionFile+"'."); + return; + } + + } + + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/XtendFacade.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/XtendFacade.java new file mode 100644 index 00000000..e8d9e488 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/XtendFacade.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.xtend; + +import java.io.StringReader; +import java.util.Set; + +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.internal.xtend.xtend.ast.ExtensionFile; +import org.eclipse.internal.xtend.xtend.parser.ParseFacade; +import org.eclipse.xtend.expression.AnalysationIssue; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.ExecutionContextImpl; +import org.eclipse.xtend.expression.Resource; +import org.eclipse.xtend.expression.TypeSystemImpl; +import org.eclipse.xtend.typesystem.MetaModel; +import org.eclipse.xtend.typesystem.Type; + +public class XtendFacade { + + private ExecutionContext ctx; + + private XtendFacade(final ExecutionContext ctx) { + this.ctx = ctx; + } + + public final XtendFacade cloneWithExtensions(String extensionCode) { + return new XtendFacade( ctx.cloneWithResource(parse(extensionCode))); + } + + public final void registerMetaModel(final MetaModel mm) { + if (ctx instanceof ExecutionContextImpl) { + ((ExecutionContextImpl) ctx).registerMetaModel(mm); + } else { + throw new IllegalStateException("Couldn't register Metamodel - ExecutionContextImpl expected."); + } + } + + private ExtensionFile parse(final String extFile) { + return ParseFacade.file(new StringReader(extFile), "nofile"); + } + + public final static XtendFacade create(final String... extFile) { + return create(new ExecutionContextImpl(new TypeSystemImpl()),extFile); + } + + public final static XtendFacade create(ExecutionContext ctx,final String... extFile) { + ctx = ctx.cloneWithResource(new Resource() { + + public String getFullyQualifiedName() { + return null; + } + + public void setFullyQualifiedName(final String fqn) { + + } + + public String[] getImportedNamespaces() { + return null; + } + + public String[] getImportedExtensions() { + return extFile; + } + }); + return new XtendFacade(ctx); + } + + public Object call(final String ext, Object... params) { + if (params==null) + params = new Object[] {null}; + final Extension extension = ctx.getExtension(ext, params); + if (extension == null) + throw new IllegalArgumentException("Couldn't find extension " + ext); + return extension.evaluate(params, ctx); + } + + public Type analyze(final String string, Object[] objects, final Set<AnalysationIssue> issues) { + if (objects == null) { + objects = new Object[0]; + } + final Extension extension = ctx.getExtension(string, objects); + final Type[] params = new Type[objects.length]; + for (int i = 0; i < params.length; i++) { + params[i] = ctx.getType(objects[i]); + } + return extension.getReturnType(params, ctx, issues); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/check/CheckComponent.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/check/CheckComponent.java new file mode 100644 index 00000000..1354e2e2 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/check/CheckComponent.java @@ -0,0 +1,131 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.check; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.emf.mwe.core.WorkflowContext; +import org.eclipse.emf.mwe.core.WorkflowInterruptedException; +import org.eclipse.emf.mwe.core.issues.Issues; +import org.eclipse.emf.mwe.core.monitor.ProgressMonitor; +import org.eclipse.xtend.expression.AbstractExpressionsUsingWorkflowComponent; +import org.eclipse.xtend.expression.ExecutionContext; +import org.eclipse.xtend.expression.ExecutionContextImpl; +import org.eclipse.xtend.expression.ExpressionFacade; + +public class CheckComponent extends AbstractExpressionsUsingWorkflowComponent { + + private String expression = null; + + private List<String> checkFiles = new ArrayList<String>(); + + private boolean abortOnError = true; + + private boolean warnIfNothingChecked = false; + + private String emfAllChildrenSlot; + + public void setAbortOnError(final boolean abortOnError) { + this.abortOnError = abortOnError; + } + + public void addCheckFile(final String checkFile) { + this.checkFiles.add(checkFile); + } + + public void setExpression(final String expression) { + this.expression = expression; + } + + public void setWarnIfNothingChecked(boolean b) { + warnIfNothingChecked = b; + } + + public void setEmfAllChildrenSlot(final String childExpression) { + emfAllChildrenSlot = childExpression; + } + + public String getLogMessage() { + StringBuilder b = new StringBuilder(); + if ( emfAllChildrenSlot != null ) { + b.append("slot "+emfAllChildrenSlot+" "); + } else { + b.append("expression "+expression+" "); + } + b.append( "check file(s): "); + for (String f: checkFiles) { + b.append( f+" "); + } + return b.toString(); + } + + + @Override + protected void invokeInternal2(final WorkflowContext ctx, final ProgressMonitor monitor, final Issues issues) { + final ExecutionContextImpl executionContext = getExecutionContext(ctx); + if (monitor!=null) { + executionContext.setMonitor(monitor); + } + + final Collection<?> model = getExpressionResult(executionContext, ctx, expression); + + for (String checkFile : checkFiles) { + CheckFacade.checkAll(checkFile, model, executionContext, issues, warnIfNothingChecked); + } + + if (abortOnError && issues.hasErrors()) + throw new WorkflowInterruptedException("Errors during validation."); + } + + + + public void checkConfiguration(final Issues issues) { + super.checkConfiguration(issues); + + if ((expression == null) && (emfAllChildrenSlot != null)) { + expression = emfAllChildrenSlot + ".eAllContents.union( {" + emfAllChildrenSlot + "} )"; + } else if ((expression != null) && (emfAllChildrenSlot == null)) { + // ok - do nothing, expression already has a reasonable value + } else { + issues.addError(this, "You have to set one of the properties 'expression' and 'emfAllChildrenSlot'!"); + } + if (checkFiles.isEmpty()) { + issues.addError(this, "Property 'checkFile' not set!"); + } + } + + private Collection<?> getExpressionResult(final ExecutionContext exeCtx, final WorkflowContext context, final String expression2) { + final ExpressionFacade f = new ExpressionFacade(exeCtx); + final Map<String, Object> ctx = new HashMap<String, Object>(); + final String[] names = context.getSlotNames(); + for (int i = 0; i < names.length; i++) { + final String name = names[i]; + ctx.put(name, context.get(name)); + } + final Object result = f.evaluate(expression2, ctx); + if (result instanceof Collection) + return (Collection<?>) result; + else if (result == null) + return Collections.EMPTY_SET; + else + return Collections.singleton(result); + + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/check/CheckFacade.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/check/CheckFacade.java new file mode 100644 index 00000000..aa4768ef --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/check/CheckFacade.java @@ -0,0 +1,53 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.check; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Collection; + +import org.eclipse.emf.mwe.core.ConfigurationException; +import org.eclipse.emf.mwe.core.issues.Issues; +import org.eclipse.emf.mwe.core.resources.ResourceLoaderFactory; +import org.eclipse.internal.xtend.xtend.ast.ExtensionFile; +import org.eclipse.internal.xtend.xtend.parser.ParseFacade; +import org.eclipse.xtend.expression.ExecutionContext; + +public class CheckFacade { + + public final static void checkAll(final String checkFile, final Collection<?> toCheck, final ExecutionContext ctx, final Issues issues) { + checkAll(checkFile, toCheck, ctx, issues, false); + } + + public final static void checkAll(final String checkFile, final InputStream in, final Collection<?> toCheck, final ExecutionContext ctx, + final Issues issues) { + checkAll(checkFile,in, toCheck, ctx, issues, false); + } + + public final static void checkAll(final String checkFile, final InputStream in, final Collection<?> toCheck, final ExecutionContext ctx, + final Issues issues, boolean warnIfNothingChecked) { + if (in == null) + throw new ConfigurationException("Couldn't find check file :'" + checkFile + "'"); + ExtensionFile file = ParseFacade.file(new InputStreamReader(in), checkFile); + file.check(ctx, toCheck, issues, warnIfNothingChecked); + } + + public final static void checkAll(final String checkFile, final Collection<?> toCheck, final ExecutionContext ctx, final Issues issues, + boolean warnIfNothingChecked) { + + final InputStream in = ResourceLoaderFactory.createResourceLoader().getResourceAsStream(CheckUtils.getJavaResourceName(checkFile)); + checkAll(checkFile,in, toCheck, ctx, issues, warnIfNothingChecked); + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/check/CheckUtils.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/check/CheckUtils.java new file mode 100644 index 00000000..ffad4e29 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/check/CheckUtils.java @@ -0,0 +1,31 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.check; + +import org.eclipse.internal.xtend.expression.parser.SyntaxConstants; + +public class CheckUtils { + + public static final String FILE_EXTENSION = "chk"; + + private static final String SLASH = "/"; + + public static final String NS_DELIM = SyntaxConstants.NS_DELIM; + + public final static String getJavaResourceName(final String fqn) { + return fqn.replaceAll(NS_DELIM, SLASH) + "." + FILE_EXTENSION; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/AbstractExpressionsUsingWorkflowComponent.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/AbstractExpressionsUsingWorkflowComponent.java new file mode 100644 index 00000000..6bcb9fe3 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/AbstractExpressionsUsingWorkflowComponent.java @@ -0,0 +1,240 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 committers of openArchitectureWare and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * committers of openArchitectureWare - initial API and implementation + *******************************************************************************/ +package org.eclipse.xtend.expression; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.emf.mwe.core.WorkflowContext; +import org.eclipse.emf.mwe.core.WorkflowInterruptedException; +import org.eclipse.emf.mwe.core.issues.Issues; +import org.eclipse.emf.mwe.core.lib.AbstractWorkflowComponent; +import org.eclipse.emf.mwe.core.monitor.ProgressMonitor; +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; +import org.eclipse.internal.xtend.util.Pair; +import org.eclipse.xtend.typesystem.MetaModel; + +public abstract class AbstractExpressionsUsingWorkflowComponent extends + AbstractWorkflowComponent { + protected final Log log = LogFactory.getLog(getClass()); + + protected final List<MetaModel> metaModels = new ArrayList<MetaModel>(); + + private List<GlobalVarDef> globalVarDefs = new ArrayList<GlobalVarDef>(); + + public void addMetaModel(final MetaModel metaModel) { + assert metaModel != null; + metaModels.add(metaModel); + } + + public static class GlobalVarDef { + private String name; + + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + public void addGlobalVarDef(GlobalVarDef def) { + globalVarDefs.add(def); + } + + protected Map<String, Variable> getGlobalVars(WorkflowContext ctx) { + final Map<String, Variable> result = new HashMap<String, Variable>(); + + ExecutionContextImpl ec = new ExecutionContextImpl(); + for (String slot : ctx.getSlotNames()) { + ec = (ExecutionContextImpl) ec.cloneWithVariable(new Variable(slot, + ctx.get(slot))); + } + for (MetaModel mm : metaModels) { + ec.registerMetaModel(mm); + } + + final ExpressionFacade ef = new ExpressionFacade(ec); + for (GlobalVarDef def : globalVarDefs) { + final Object value = ef.evaluate(def.getValue()); + result.put(def.getName(), new Variable(def.getName(), value)); + } + + return result; + } + + protected ExecutionContextImpl getExecutionContext(final WorkflowContext ctx) { + final ExecutionContextImpl executionContext = new ExecutionContextImpl( + new ResourceManagerDefaultImpl(), null, new TypeSystemImpl(), + new HashMap<String, Variable>(), getGlobalVars(ctx), null, + null, null, getNullEvaluationHandler(),null); + for (MetaModel mm : metaModels) { + executionContext.registerMetaModel(mm); + } + return executionContext; + } + + public NullEvaluationHandler getNullEvaluationHandler() { + if (exceptionsOnNullEvaluation) + return new ExceptionRaisingNullEvaluationHandler(); + return null; + } + + public void checkConfiguration(Issues issues) { + if (metaModels.isEmpty()) { + issues + .addWarning("no metamodels specified (use 'metaModel' property)!"); + } + } + + private List<Debug> debugExpressions = new ArrayList<Debug>(); + + public void addDebug(Debug expr) { + this.debugExpressions.add(expr); + } + + private boolean dumpContext = false; + + public void setDumpContext(boolean dumpContext) { + this.dumpContext = dumpContext; + } + + public static class Debug { + private String expression; + + private boolean dumpContext = false; + + public void setDumpContext(boolean dumpContext) { + this.dumpContext = dumpContext; + } + + public boolean isDumpContext() { + return dumpContext; + } + + public void setExpression(String expression) { + this.expression = expression; + } + + public String getExpression() { + return expression; + } + } + + @Override + protected void invokeInternal(WorkflowContext ctx, ProgressMonitor monitor, + Issues issues) { + try { + invokeInternal2(ctx, monitor, issues); + } catch (EvaluationException e) { + log.error("Error in Component" + (getId()==null?" ":" "+getId()) + " of type " + + getClass().getName() + ": \n\t" + + "" +toString(e, debugExpressions)); + throw new WorkflowInterruptedException(); + } + } + + public String toString(EvaluationException ex, List<Debug> debugEntries) { + StringBuffer result = new StringBuffer("EvaluationException : " + + ex.getMessage() + "\n"); + int widest = 0; + for (Pair<SyntaxElement, ExecutionContext> ele : ex.getXtendStackTrace()) { + int temp = EvaluationException.getLocationString(ele.getFirst()) + .length(); + if (temp > widest) + widest = temp; + } + String indent = ""; + for (int l = 0; l < widest + 7; l++) + indent += " "; + + for (int i = 0, x = ex.getXtendStackTrace().size(); i < x; i++) { + Pair<SyntaxElement, ExecutionContext> ele = ex.getXtendStackTrace() + .get(i); + StringBuffer msg = new StringBuffer(EvaluationException + .getLocationString(ele.getFirst())); + for (int j = msg.length(); j < widest; j++) { + msg.append(" "); + } + if (debugEntries.size() > i + && debugEntries.get(i).getExpression() != null) { + Debug d = debugEntries.get(i); + try { + msg.append(" -- debug '").append(d.getExpression()).append( + "' = "); + msg.append(new ExpressionFacade(ele.getSecond()) + .evaluate("let x = " + d.getExpression() + + " : x!=null ? x.toString() : 'null'")); + } catch (Exception e) { + msg.append("Exception : ").append(e.getMessage()); + } + msg.append("\n"); + } + if (dumpContext || debugEntries.size() > i + && debugEntries.get(i).isDumpContext()) { + ExpressionFacade f = new ExpressionFacade(ele.getSecond()); + msg.append(" -- context dump : "); + + Iterator<String> iter = ele.getSecond().getVisibleVariables() + .keySet().iterator(); + while (iter.hasNext()) { + String v = iter.next(); + msg.append(v).append(" = ").append( + f + .evaluate(v + "!=null?" + v + + ".toString():'null'")); + if (iter.hasNext()) { + msg.append(", \n"); + } + } + msg.append("\n"); + } + // formatting + String[] evals = msg.toString().split("\n"); + for (int j = 0; j < evals.length; j++) { + String string = evals[j]; + result.append(string); + if (j + 1 < evals.length) { + result.append("\n").append(indent); + } + } + result.append("\n"); + } + return result.toString(); + } + + protected void invokeInternal2(WorkflowContext ctx, + ProgressMonitor monitor, Issues issues) { + }; + + protected boolean exceptionsOnNullEvaluation = false; + + public void setExceptionsOnNullEvaluation(boolean exceptionsOnNullEvaluation) { + this.exceptionsOnNullEvaluation = exceptionsOnNullEvaluation; + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/AnalysationIssue.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/AnalysationIssue.java new file mode 100644 index 00000000..67cc7450 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/AnalysationIssue.java @@ -0,0 +1,82 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class AnalysationIssue { + + public final static AnalysationIssueType INCOMPATIBLE_TYPES = new AnalysationIssueType("Incompatible types"); + + public final static AnalysationIssueType UNNECESSARY_CAST = new AnalysationIssueType("Unnecessary cast"); + + public final static AnalysationIssueType FEATURE_NOT_FOUND = new AnalysationIssueType("Callable not found"); + + public static final AnalysationIssueType TYPE_NOT_FOUND = new AnalysationIssueType("AnalysationIssueType not found"); + + public static final AnalysationIssueType INTERNAL_ERROR = new AnalysationIssueType("Internal error"); + + public static final AnalysationIssueType JAVA_TYPE_NOT_FOUND = new AnalysationIssueType("Java AnalysationIssueType not found"); + + public static final AnalysationIssueType SYNTAX_ERROR = new AnalysationIssueType("Syntax error"); + + public static final AnalysationIssueType RESOURCE_NOT_FOUND = new AnalysationIssueType("Resource not found"); + + public final static class AnalysationIssueType { + String name; + + public AnalysationIssueType(final String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } + } + + private AnalysationIssueType analysationIssueType; + + private String message; + + private SyntaxElement element; + + public AnalysationIssue(final AnalysationIssueType analysationIssueType, final String message, final SyntaxElement element) { + this.analysationIssueType = analysationIssueType; + this.message = message; + this.element = element; + } + + public SyntaxElement getElement() { + return element; + } + + public String getMessage() { + return message; + } + + public AnalysationIssueType getType() { + return analysationIssueType; + } + + @Override + public String toString() { + return "[" + analysationIssueType.name + "] - " + message + " : " + element; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/Analyzable.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/Analyzable.java new file mode 100644 index 00000000..24cabfa4 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/Analyzable.java @@ -0,0 +1,27 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +import java.util.Set; + +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface Analyzable { + public abstract Type analyze(ExecutionContext ctx, Set<AnalysationIssue> issues); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/Evaluatable.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/Evaluatable.java new file mode 100644 index 00000000..4364d7e9 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/Evaluatable.java @@ -0,0 +1,23 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface Evaluatable { + public abstract Object evaluate(ExecutionContext ctx); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/EvaluationException.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/EvaluationException.java new file mode 100644 index 00000000..163e1c71 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/EvaluationException.java @@ -0,0 +1,108 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +import java.util.List; +import java.util.Stack; +import java.util.regex.Matcher; + +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; +import org.eclipse.internal.xtend.util.Pair; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class EvaluationException extends RuntimeException { + + private static final long serialVersionUID = 3781834199930386623L; + + private List<Pair<SyntaxElement, ExecutionContext>> xtendStackTrace = new Stack<Pair<SyntaxElement, ExecutionContext>>(); + + public EvaluationException(final String msg, final SyntaxElement element, + final ExecutionContext ctx) { + super(msg); + addStackElement(element, ctx); + } + + public EvaluationException(final Throwable ex, final SyntaxElement element, + final ExecutionContext ctx) { + super((ex.getMessage() == null ? ex.getClass().getName() : ex + .getMessage()), ex); + addStackElement(element, ctx); + } + + public void addStackElement(SyntaxElement ele, ExecutionContext ctx) { + this.xtendStackTrace.add(new Pair<SyntaxElement, ExecutionContext>(ele, + ctx)); + } + + @Override + public String toString() { + StringBuffer result = new StringBuffer("EvaluationException : " + + getMessage() + "\n"); + for (Pair<SyntaxElement, ExecutionContext> ele : xtendStackTrace) { + result.append(getLocationString(ele.getFirst())).append("\n"); + } + return result.toString(); + } + + public List<Pair<SyntaxElement, ExecutionContext>> getXtendStackTrace() { + return xtendStackTrace; + } + + static String getLocationString(SyntaxElement element) { + StringBuffer b = new StringBuffer("\t"); + if (element != null) { + if (element.getFileName() != null) { + b.append(element.getFileName().replaceAll("/", "::")); + } + b.append("[" + element.getStart() + "," + + (element.getEnd() - element.getStart()) + "] on line " + + element.getLine() + " '" + element + "'"); + } else { + b.append("Internal error : element was null"); + } + return b.toString(); + } + + public final static java.util.regex.Pattern P = java.util.regex.Pattern + .compile("([\\w::]+)\\.(\\w+)\\[(\\d+),(\\d+)\\]"); + + public static String getExtXptNamespace(String extXptId) { + Matcher m = P.matcher(extXptId); + m.find(); + return m.group(1); + } + + public static String getExtXptExtension(String extXptId) { + Matcher m = P.matcher(extXptId); + m.find(); + return m.group(2); + } + + public static Integer getOffSet(String extXptId) { + Matcher m = P.matcher(extXptId); + m.find(); + return Integer.valueOf(m.group(3)); + } + + public static Integer getLength(String extXptId) { + Matcher m = P.matcher(extXptId); + m.find(); + return Integer.valueOf(m.group(4)); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExceptionHandler.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExceptionHandler.java new file mode 100644 index 00000000..4a11cdc7 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExceptionHandler.java @@ -0,0 +1,9 @@ +package org.eclipse.xtend.expression; + +import java.util.Map; + +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; + +public interface ExceptionHandler { + void handleRuntimeException (RuntimeException ex, SyntaxElement element, ExecutionContext ctx, Map<String,Object> additionalContextInfo); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExceptionRaisingNullEvaluationHandler.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExceptionRaisingNullEvaluationHandler.java new file mode 100644 index 00000000..5f57e5d3 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExceptionRaisingNullEvaluationHandler.java @@ -0,0 +1,12 @@ +package org.eclipse.xtend.expression; + +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; + +public class ExceptionRaisingNullEvaluationHandler implements + NullEvaluationHandler { + + public Object handleNullEvaluation(SyntaxElement element, ExecutionContext ctx) { + throw new EvaluationException("null evaluation",element, ctx); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExecutionContext.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExecutionContext.java new file mode 100644 index 00000000..ca6234f3 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExecutionContext.java @@ -0,0 +1,81 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.emf.mwe.core.monitor.ProgressMonitor; +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; +import org.eclipse.internal.xtend.xtend.ast.Around; +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface ExecutionContext extends TypeSystem { + String IMPLICIT_VARIABLE = "this"; + + ExecutionContext cloneWithVariable(Variable v); + + ExecutionContext cloneWithoutVariables(); + + Variable getVariable(String name); + + Map<String, Variable> getVisibleVariables(); + + /** + * accessible only through special extension methods + */ + Map<String, Variable> getGlobalVariables(); + + ExecutionContext cloneWithResource(Resource ns); + + ExecutionContext cloneWithoutResource(); + + ExecutionContext cloneWithoutMonitor(); + + Resource currentResource(); + + Extension getExtensionForTypes(String functionName, Type[] parameterTypes); + + Extension getExtension(String functionName, Object[] actualParameters); + + Set<? extends Extension> getAllExtensions(); + + List<Around> getExtensionAdvices(); + + void preTask(Object element); + + void postTask(Object element); + + /** + * Retrieves the associated ResourceManager + * @since 4.1.2 + */ + ResourceManager getResourceManager (); + + /** + * Retrieves the associated ProgressMonitor + * @since 4.1.2 + */ + ProgressMonitor getMonitor (); + void handleRuntimeException (RuntimeException ex, SyntaxElement element, Map<String,Object> additionalContextInfo); + Object handleNullEvaluation(SyntaxElement element); + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExecutionContextImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExecutionContextImpl.java new file mode 100644 index 00000000..e264217f --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExecutionContextImpl.java @@ -0,0 +1,518 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2007 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.emf.mwe.core.monitor.ProgressMonitor; +import org.eclipse.internal.xtend.expression.ast.DeclaredParameter; +import org.eclipse.internal.xtend.expression.ast.Identifier; +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; +import org.eclipse.internal.xtend.type.baseimpl.PolymorphicResolver; +import org.eclipse.internal.xtend.type.baseimpl.TypesComparator; +import org.eclipse.internal.xtend.xtend.XtendFile; +import org.eclipse.internal.xtend.xtend.ast.Around; +import org.eclipse.internal.xtend.xtend.ast.Extension; +import org.eclipse.internal.xtend.xtend.ast.ExtensionFile; +import org.eclipse.internal.xtend.xtend.types.AdviceContext; +import org.eclipse.xtend.typesystem.MetaModel; +import org.eclipse.xtend.typesystem.Operation; +import org.eclipse.xtend.typesystem.Property; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Peter Friese + */ +public class ExecutionContextImpl implements ExecutionContext { + private final static Log log = LogFactory.getLog(ExecutionContextImpl.class); + + protected final ResourceManager resourceManager; + + private final Map<String, Variable> variables = new HashMap<String, Variable>(); + + private final Map<String, Variable> globalVars = new HashMap<String, Variable>(); + + private ProgressMonitor monitor; + + /** + * this field is conceptually final, i.e. it is set only at object + * construction time. To simplify implementation, it is however technically + * not final. This is done so that the cloneWith/WithoutResource methods can + * delegate to cloneContext and afterwards modify the instance. That + * provides cloneContext as a single method for subclasses to override. + */ + private Resource currentResource; + + protected final TypeSystemImpl typeSystem; + + protected ExceptionHandler exceptionHandler; + + protected NullEvaluationHandler nullEvaluationHandler = null; + + public ExecutionContextImpl() { + this((Map<String, Variable>) null); + } + + public ExecutionContextImpl(TypeSystemImpl ts) { + this(ts, null); + } + + public ExecutionContextImpl(Map<String, Variable> globalVars) { + this(new ResourceManagerDefaultImpl(), null, new TypeSystemImpl(), new HashMap<String, Variable>(), globalVars, null, + null, null, null, null); + } + + public ExecutionContextImpl(TypeSystemImpl ts, Map<String, Variable> globalVars) { + this(new ResourceManagerDefaultImpl(), null, ts, new HashMap<String, Variable>(), globalVars, null, null, null, null, + null); + } + + public ExecutionContextImpl(ResourceManager resourceManager, TypeSystemImpl typeSystem, Map<String, Variable> globalVars) { + this(resourceManager, null, typeSystem, new HashMap<String, Variable>(), globalVars, null, null, null, null, null); + } + + public ExecutionContextImpl(ResourceManager resourceManager, Resource resource, TypeSystemImpl typeSystem, + Map<String, Variable> variables, Map<String, Variable> globalVars, ProgressMonitor monitor, + ExceptionHandler exceptionHandler, List<Around> advices, NullEvaluationHandler neh2, + Map<Resource, Set<Extension>> extensionPerResourceMap) { + if (extensionPerResourceMap != null) { + this.allExtensionsPerResource = extensionPerResourceMap; + } else { + this.allExtensionsPerResource = new HashMap<Resource, Set<Extension>>(); + } + this.resourceManager = resourceManager; + this.currentResource = resource; + this.typeSystem = typeSystem; + this.variables.putAll(variables); + if (globalVars != null) { + this.globalVars.putAll(globalVars); + } + this.monitor = monitor; + this.exceptionHandler = exceptionHandler; + if (advices != null) { + registeredExtensionAdvices = advices; + } + + this.nullEvaluationHandler = neh2; + } + + public void registerMetaModel(final MetaModel mm) { + typeSystem.registerMetaModel(mm); + } + + public Operation findOperation(final String name, final Object target, final Object[] params) { + return typeSystem.findOperation(name, target, params); + } + + public Property findProperty(final String name, final Object target) { + return typeSystem.findProperty(name, target); + } + + public Type[] findTypesForPrefix(final String prefix) { + return typeSystem.findTypesForPrefix(prefix, getImportedNamespaces()); + } + + public Type[] getAllTypes() { + return typeSystem.getAllTypes(); + } + + public Set<String> getNamespaces() { + return typeSystem.getNamespaces(); + } + + public Type getBooleanType() { + return typeSystem.getBooleanType(); + } + + public Type getCollectionType(final Type innerType) { + return typeSystem.getCollectionType(innerType); + } + + public Type getFeatureType() { + return typeSystem.getFeatureType(); + } + + public Type getIntegerType() { + return typeSystem.getIntegerType(); + } + + public Type getListType(final Type innerType) { + return typeSystem.getListType(innerType); + } + + public Type getObjectType() { + return typeSystem.getObjectType(); + } + + public Type getOperationType() { + return typeSystem.getOperationType(); + } + + public Type getPropertyType() { + return typeSystem.getPropertyType(); + } + + public Type getRealType() { + return typeSystem.getRealType(); + } + + public Type getSetType(final Type innerType) { + return typeSystem.getSetType(innerType); + } + + public Type getStaticPropertyType() { + return typeSystem.getStaticPropertyType(); + } + + public Type getStringType() { + return typeSystem.getStringType(); + } + + public Type getType(final Object obj) { + return typeSystem.getType(obj); + } + + public Type getTypeForName(final String name) { + return typeSystem.getTypeForName(name, getImportedNamespaces()); + } + + protected String[] getImportedNamespaces() { + return currentResource != null ? currentResource.getImportedNamespaces() : new String[0]; + } + + public Type getTypeType() { + return typeSystem.getTypeType(); + } + + public Type getVoidType() { + return typeSystem.getVoidType(); + } + + public ExecutionContextImpl cloneContext() { + return new ExecutionContextImpl(resourceManager, currentResource, typeSystem, variables, globalVars, monitor, + exceptionHandler, registeredExtensionAdvices, nullEvaluationHandler, allExtensionsPerResource); + } + + public void setFileEncoding(final String encoding) { + if (resourceManager != null) { + resourceManager.setFileEncoding(encoding); + } + } + + public Variable getVariable(final String name) { + return variables.get(name); + } + + public Map<String, Variable> getVisibleVariables() { + return Collections.unmodifiableMap(variables); + } + + public Map<String, Variable> getGlobalVariables() { + return Collections.unmodifiableMap(globalVars); + } + + public ExecutionContext cloneWithVariable(final Variable v) { + final ExecutionContextImpl result = cloneContext(); + result.variables.put(v.getName(), v); + return result; + } + + public ExecutionContext cloneWithoutVariables() { + final ExecutionContextImpl result = cloneContext(); + result.variables.clear(); + return result; + } + + public ExecutionContext cloneWithResource(final Resource ns) { + final ExecutionContextImpl ctx = cloneContext(); + ctx.currentResource = ns; + return ctx; + } + + public ExecutionContext cloneWithoutResource() { + final ExecutionContextImpl ctx = cloneContext(); + ctx.currentResource = null; + return ctx; + } + + public ExecutionContext cloneWithoutMonitor() { + final ExecutionContextImpl ctx = cloneContext(); + ctx.setMonitor(null); + return ctx; + } + + public Resource currentResource() { + return currentResource; + } + + protected Map<Resource, Set<Extension>> allExtensionsPerResource = null; + + public Set<? extends Extension> getAllExtensions() { + Set<Extension> allExtensions = allExtensionsPerResource.get(currentResource()); + if (allExtensions == null) { + allExtensions = new HashSet<Extension>(); + final Resource res = currentResource(); + if (res != null) { + if (res instanceof XtendFile) { + final List<Extension> extensionList = ((XtendFile) res).getExtensions(); + for (Extension element : extensionList) { + element.init(this); + allExtensions.add(advise(element)); + } + } + final String[] extensions = res.getImportedExtensions(); + for (final String extension : extensions) { + final Object o = resourceManager.loadResource(extension, XtendFile.FILE_EXTENSION); + final XtendFile extFile = (XtendFile) o; + if (extFile == null) { + throw new RuntimeException("Unable to load extension file : " + extension); + } + final ExecutionContext ctx = cloneWithResource(extFile); + final List<Extension> extensionList = extFile.getPublicExtensions(resourceManager, ctx); + for (final Extension element : extensionList) { + element.init(ctx); + allExtensions.add(advise(element)); + } + } + } + allExtensionsPerResource.put(currentResource(), allExtensions); + } + return allExtensions; + } + + public Extension getExtensionForTypes(final String functionName, final Type[] parameterTypes) { + return PolymorphicResolver.getExtension(getAllExtensions(), functionName, Arrays.asList(parameterTypes)); + } + + public Extension getExtension(final String functionName, final Object[] actualParameters) { + final Type[] types = new Type[actualParameters.length]; + for (int i = 0; i < types.length; i++) { + types[i] = getType(actualParameters[i]); + } + return getExtensionForTypes(functionName, types); + } + + public void setMonitor(ProgressMonitor monitor) { + this.monitor = monitor; + } + + public ProgressMonitor getMonitor() { + return monitor; + } + + public void preTask(Object element) { + if (monitor == null) { + return; + } + monitor.preTask(element, this); + } + + public void postTask(Object element) { + if (monitor == null) { + return; + } + monitor.postTask(element, this); + } + + public void handleRuntimeException(RuntimeException ex, SyntaxElement element, Map<String, Object> additionalContextInfo) { + if (this.exceptionHandler == null) { + throw ex; + } + exceptionHandler.handleRuntimeException(ex, element, this, additionalContextInfo); + } + + public ResourceManager getResourceManager() { + return this.resourceManager; + } + + protected List<Around> registeredExtensionAdvices = new ArrayList<Around>(); + + public void registerExtensionAdvices(final String fullyQualifiedName) { + final XtendFile ext = (XtendFile) resourceManager.loadResource(fullyQualifiedName, XtendFile.FILE_EXTENSION); + if (ext == null) { + throw new IllegalArgumentException("Couldn't find extension file '" + fullyQualifiedName + "'"); + } + final List<Around> as = ext.getArounds(); + for (Around around : as) { + if (registeredExtensionAdvices.contains(around)) { + log.warn("advice " + around.toString() + " allready registered!"); + } else { + registeredExtensionAdvices.add(around); + } + } + } + + public List<Around> getExtensionAdvices() { + return registeredExtensionAdvices; + } + + private final TypesComparator typesComparator = new TypesComparator(); + + private Extension advise(Extension element) { + if (!getExtensionAdvices().isEmpty()) { + for (Around a : getExtensionAdvices()) { + if (a.nameMatches(element.getQualifiedName())) { + List<Type> paramTypes = a.getParamTypes(this); + List<Type> extPTypes = element.getParameterTypes(); + int diff = extPTypes.size() - paramTypes.size(); + if (diff >= 0) { + if (diff > 0 && a.isWildparams()) { // fill wildcard + // params with + // Object types + for (int i = 0; i < diff; i++) { + paramTypes.add(getObjectType()); + } + } + if (typesComparator.compare(paramTypes, extPTypes) >= 0) { + element = new ExtensionAdvisor(a, element); + } + } + } + } + } + return element; + } + + class ExtensionAdvisor implements Extension { + + private final Extension delegate; + + private final Around advice; + + public ExtensionAdvisor(Around advice, Extension delegate) { + this.delegate = delegate; + this.advice = advice; + } + + public Object evaluate(Object[] parameters, ExecutionContext ctx) { + + ctx = ctx.cloneWithVariable(new Variable(Around.CONTEXT_PARAM_NAME, new AdviceContext(delegate, ctx, parameters))); + for (int i = 0; i < advice.getParams().size(); i++) { + ctx = ctx.cloneWithVariable(new Variable(advice.getParams().get(i).getName().getValue(), parameters[i])); + } + ctx = ctx.cloneWithResource(advice.getParent()); + return advice.getExpression().evaluate(ctx); + } + + public void analyze(ExecutionContext ctx, Set<AnalysationIssue> issues) { + delegate.analyze(ctx, issues); + } + + public int getEnd() { + return delegate.getEnd(); + } + + public ExtensionFile getExtensionFile() { + return delegate.getExtensionFile(); + } + + public String getFileName() { + return delegate.getFileName(); + } + + public List<DeclaredParameter> getFormalParameters() { + return delegate.getFormalParameters(); + } + + public int getLine() { + return delegate.getLine(); + } + + public String getName() { + return delegate.getName(); + } + + public List<String> getParameterNames() { + return delegate.getParameterNames(); + } + + public List<Type> getParameterTypes() { + return delegate.getParameterTypes(); + } + + public Type getReturnType(Type[] parameters, ExecutionContext ctx, Set<AnalysationIssue> issues) { + return delegate.getReturnType(parameters, ctx, issues); + } + + public Type getReturnType() { + return delegate.getReturnType(); + } + + public Identifier getReturnTypeIdentifier() { + return delegate.getReturnTypeIdentifier(); + } + + public int getStart() { + return delegate.getStart(); + } + + public String getNameString(ExecutionContext context) { + return delegate.getNameString(context); + } + + public void init(ExecutionContext ctx) { + delegate.init(ctx); + } + + public boolean isCached() { + return delegate.isCached(); + } + + public boolean isPrivate() { + return delegate.isPrivate(); + } + + public void setExtensionFile(ExtensionFile file) { + delegate.setExtensionFile(file); + } + + public String toOutlineString() { + return delegate.toOutlineString(); + } + + @Override + public String toString() { + return delegate.toString(); + } + + public String getQualifiedName() { + return delegate.getQualifiedName(); + } + + } + + public Object handleNullEvaluation(SyntaxElement element) { + if (nullEvaluationHandler != null) { + return nullEvaluationHandler.handleNullEvaluation(element, this); + } + return null; + } + + public void release() { + typeSystem.release(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExpressionFacade.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExpressionFacade.java new file mode 100644 index 00000000..aa2b8395 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ExpressionFacade.java @@ -0,0 +1,71 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.eclipse.internal.xtend.expression.ast.Expression; +import org.eclipse.internal.xtend.xtend.parser.ParseFacade; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class ExpressionFacade { + + private ExecutionContext execContext; + + public ExecutionContext getExecContext() { + return execContext; + } + + public ExpressionFacade(final ExecutionContext execCtx) { + execContext = execCtx; + } + + public Type analyze(final String expression, final Set<AnalysationIssue> issues) { + final Expression expr = parse(expression); + return expr.analyze(execContext, issues); + } + + public Object evaluate(final String expression) { + return evaluate(expression, Collections.<String,Object>emptyMap()); + } + + public Object evaluate(final String expression, final Map<String, ?> context) { + final Expression expr = parse(expression); + ExecutionContext ctx = execContext; + for (final Iterator<String> iter = context.keySet().iterator(); iter.hasNext();) { + final String key = iter.next(); + final Variable v = new Variable(key, context.get(key)); + ctx = ctx.cloneWithVariable(v); + } + return expr.evaluate(ctx); + } + + public Expression parse(final String expression) { + return ParseFacade.expression(expression); + } + + public ExpressionFacade cloneWithVariable(final Variable variable) { + final ExecutionContext ctx = execContext.cloneWithVariable(variable); + return new ExpressionFacade(ctx); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/NullEvaluationHandler.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/NullEvaluationHandler.java new file mode 100644 index 00000000..91ede529 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/NullEvaluationHandler.java @@ -0,0 +1,7 @@ +package org.eclipse.xtend.expression; + +import org.eclipse.internal.xtend.expression.ast.SyntaxElement; + +public interface NullEvaluationHandler { + public Object handleNullEvaluation(SyntaxElement element, ExecutionContext ctx); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/Resource.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/Resource.java new file mode 100644 index 00000000..b2b7fa91 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/Resource.java @@ -0,0 +1,26 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +public interface Resource { + public String getFullyQualifiedName(); + + public void setFullyQualifiedName(String fqn); + + public String[] getImportedNamespaces(); + + public String[] getImportedExtensions(); + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ResourceManager.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ResourceManager.java new file mode 100644 index 00000000..667b6eab --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ResourceManager.java @@ -0,0 +1,24 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +public interface ResourceManager { + + public abstract Resource loadResource(String fullyQualifiedName, String extension); + + public abstract void setFileEncoding(String fileEncoding); + + public abstract void registerParser(String template_extension, ResourceParser parser); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ResourceManagerDefaultImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ResourceManagerDefaultImpl.java new file mode 100644 index 00000000..06b7b140 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ResourceManagerDefaultImpl.java @@ -0,0 +1,155 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.emf.mwe.core.resources.ResourceLoaderFactory; +import org.eclipse.internal.xtend.expression.parser.SyntaxConstants; +import org.eclipse.internal.xtend.util.internal.icu.CharsetDetector; +import org.eclipse.internal.xtend.util.internal.icu.CharsetMatch; +import org.eclipse.internal.xtend.xtend.XtendFile; +import org.eclipse.internal.xtend.xtend.XtendResourceParser; + +public class ResourceManagerDefaultImpl implements ResourceManager { + + private final Log log = LogFactory.getLog(getClass()); + + private String fileEncoding = null; + + private final Map<String, Resource> resources = new HashMap<String, Resource>(); + + public ResourceManagerDefaultImpl() { + registeredParsers.put(XtendFile.FILE_EXTENSION, + new XtendResourceParser()); + } + + public Resource loadResource(final String fullyQualifiedName, + final String extension) { + final String resourceName = fullyQualifiedName.replace( + SyntaxConstants.NS_DELIM, "/") + + "." + extension; + if (resources.containsKey(resourceName)) + return resources.get(resourceName); + final InputStream in = ResourceLoaderFactory.createResourceLoader() + .getResourceAsStream(resourceName); + + if (in == null) + return null; + else { + Reader reader = createReader(in); + final ResourceParser parser = registeredParsers.get(extension); + if (parser == null) + throw new RuntimeException( + "No Parser registered for extension '" + extension + + "'! Known extensions are '" + + registeredParsers.keySet() + "'"); + final Resource res = parser.parse(reader, resourceName); + res.setFullyQualifiedName(fullyQualifiedName); + resources.put(resourceName, res); + return res; + } + } + + /** + * Creates a Reader for the given InputStream. If no explicit file encoding + * is set this method will try to autodetect the file's encoding. + * + * @param in + * Some resource input stream + * @return A Reader for the stream + * @since 4.2 + */ + protected Reader createReader(final InputStream in) { + Reader reader = null; + if (fileEncoding != null) { + try { + reader = new InputStreamReader(in, fileEncoding); + } catch (final UnsupportedEncodingException e) { + log.error("Unsupported encoding falling back to default...", e); + reader = new InputStreamReader(in); + } + } else { + Charset encoding = null; + // Buffer the original stream since we want to re-read it + BufferedInputStream is = new BufferedInputStream(in); + + try { + // Read some bytes from the stream + is.mark(65); + byte[] buf = new byte[64]; + is.read(buf); + // reset the stream + is.reset(); + + // Special handling for Xpand files on Mac: Try to detect + // the opening Guillemot bracket for MacRoman encoding + for (int i = 0; i < buf.length; i++) { + if (buf[i] == -57) { // opening Guillemot bracket + encoding = Charset.forName("MacRoman"); + break; + } + } + // Use com.ibm.icu for autodetection + if (encoding == null) { + CharsetDetector det = new CharsetDetector(); + det.setText(buf); + CharsetMatch match = det.detect(); + if (match != null) { + encoding = Charset.forName(match.getName()); + } + } + + // Create the reader with the detected encoding + if (encoding != null) { + reader = new InputStreamReader(is, encoding); + } else { + log + .warn("Failed autodetecting encoding. Falling back to default..."); + reader = new InputStreamReader(is); + } + } catch (IOException e) { + log + .warn( + "Failed autodetecting encoding. Falling back to default...", + e); + reader = new InputStreamReader(in); + } + } + return reader; + } + + public void setFileEncoding(final String fileEncoding) { + this.fileEncoding = fileEncoding; + } + + protected Map<String, ResourceParser> registeredParsers = new HashMap<String, ResourceParser>(); + + public void registerParser(final String extension, + final ResourceParser parser) { + registeredParsers.put(extension, parser); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ResourceParser.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ResourceParser.java new file mode 100644 index 00000000..85a73ce7 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/ResourceParser.java @@ -0,0 +1,21 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +import java.io.Reader; + +public interface ResourceParser { + Resource parse(Reader in, String fileName); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/TypeNameUtil.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/TypeNameUtil.java new file mode 100644 index 00000000..f5e9b4cf --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/TypeNameUtil.java @@ -0,0 +1,174 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.internal.xtend.expression.parser.SyntaxConstants; + +/** + * Utility class for retrieving information from various type name presentations + * used within oAW's type system. + * <p> + * The following type formats can occur: + * <ul> + * <li> <code><typename></code> + * <li> <code><collectionTypeName>[<typename>]</code> + * <li> + * <code><collectionTypeName>[<metamodelname>!<typename>]</code> + * </ul> + * Examples: + * <ul> + * <li> <code>entities::Account</code> + * <li> <code>List[entities::Account]</code> + * </ul> + * <p> '<code><typename></code>' is the fully qualified name + * <code>namespace1::namespace2::name</code> + * + * @author Sven Efftinge (http://www.efftinge.de) - Initial implementation + * @author Arno Haase - Initial implementation + * @author Karsten Thoms - Documentation + * @since 4.0 + */ +public class TypeNameUtil { + /** + * This pattern is used to find the type name within possible query strings + */ + private final static Pattern TYPE_PATTERN = Pattern.compile("\\A(?:(\\w+)\\[)?(?:(\\w+)!)?([\\w:]*\\w+)(?:\\])?\\z"); + + /** + * Retrieves the collection type. + * + * @param name + * Qualified type string + * @return The name of the collection type if present ('List', 'Set'), + * otherwise <code>null</code> + */ + public static String getCollectionTypeName(final String name) { + return getGroup(name, 1); + } + + /** + * Retrieves the type name + * + * @param name + * Qualified type string + * @return The type's name + */ + public static String getTypeName(final String name) { + String group = getGroup(name, 3); + if (group == null) { + group = ""; + } + return group; + } + + private static String getGroup(final String input, final int group) { + final Matcher m = TYPE_PATTERN.matcher(input); + + if (m.matches() && m.groupCount() >= group) { + return m.group(group); + } + return null; + } + + /** + * Gets the internal representation of a class name. + * + * @param class1 + * A class instance for which the name should be retrieved + * @return oAW's classname representation (<code>package1::package2::TheClassname</code>) + */ + public static String getName(final Class<?> class1) { + return class1.getName().replaceAll("\\.", SyntaxConstants.NS_DELIM); + } + + /** + * Cuts the last segment from a qualified type name. + * + * @param fqn + * Qualified type name + * @return + * + * <pre> + * ns1::ns2::name -> ns1::ns2 + * name -> <null> + * </pre> + */ + public static String withoutLastSegment(final String fqn) { + if (fqn.lastIndexOf(SyntaxConstants.NS_DELIM) == -1) { + return null; + } + return fqn.substring(0, fqn.lastIndexOf(SyntaxConstants.NS_DELIM)); + } + + /** + * Retrieves only the last segment of a qualified name and therefore cuts + * the namespace part + * + * @param fqn + * Qualified type name + * @return + * + * <pre> + * ns1::ns2::name -> name + * name -> name + * </pre> + */ + public static String getLastSegment(final String fqn) { + if (fqn.lastIndexOf(SyntaxConstants.NS_DELIM) == -1) { + return fqn; + } + return fqn.substring(fqn.lastIndexOf(SyntaxConstants.NS_DELIM) + SyntaxConstants.NS_DELIM.length()); + } + + /** + * Cuts the namespace qualification from the type string. + * + * @param fqn + * Qualified type string + * @return + * + * <pre> + * ns1::ns2::type -> type + * List[type] -> List[type] + * List[Metamodel!ns1::type] -> List[Metamodel!type] + * </pre> + */ + public static String getSimpleName(final String fqn) { + final String ct = getCollectionTypeName(fqn); + final String inner = getLastSegment(getTypeName(fqn)); + final StringBuffer sb = new StringBuffer(); + if (ct != null) { + sb.append(ct).append("["); + } + sb.append(inner); + if (ct != null) { + sb.append("]"); + } + return sb.toString(); + } + + public static Object getPackage(String insertString) { + if (insertString == null || insertString.trim().length() == 0) + return null; + int index = insertString.indexOf(SyntaxConstants.NS_DELIM); + if (index != -1) { + return insertString.substring(0, index); + } + return null; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/TypeSystem.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/TypeSystem.java new file mode 100644 index 00000000..b420d490 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/TypeSystem.java @@ -0,0 +1,76 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +import java.util.Set; + +import org.eclipse.xtend.typesystem.Operation; +import org.eclipse.xtend.typesystem.Property; +import org.eclipse.xtend.typesystem.Type; + + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface TypeSystem { + Type getType(Object obj); + + Type getTypeForName(String name); + + Type[] getAllTypes(); + + Type[] findTypesForPrefix(String prefix); + + Set<String> getNamespaces(); + + Operation findOperation(String name, Object target, Object[] params); + + Property findProperty(String name, Object target); + + // Convenience shortcuts for access to built-in types + + Type getVoidType(); + + Type getBooleanType(); + + Type getIntegerType(); + + Type getRealType(); + + Type getStringType(); + + Type getObjectType(); + + Type getListType(Type innerType); + + Type getSetType(Type innerType); + + Type getCollectionType(Type innerType); + + Type getTypeType(); + + Type getFeatureType(); + + Type getPropertyType(); + + Type getOperationType(); + + Type getStaticPropertyType(); + + /** Clears internal resources (caches). */ + void release(); + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/TypeSystemImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/TypeSystemImpl.java new file mode 100644 index 00000000..acd10ae5 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/TypeSystemImpl.java @@ -0,0 +1,338 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.internal.xtend.expression.parser.SyntaxConstants; +import org.eclipse.internal.xtend.type.baseimpl.BuiltinMetaModel; +import org.eclipse.internal.xtend.util.Cache; +import org.eclipse.internal.xtend.xtend.types.XtendMetaModel; +import org.eclipse.xtend.typesystem.MetaModel; +import org.eclipse.xtend.typesystem.Operation; +import org.eclipse.xtend.typesystem.ParameterizedType; +import org.eclipse.xtend.typesystem.Property; +import org.eclipse.xtend.typesystem.Type; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + */ +public class TypeSystemImpl implements TypeSystem { + private final Map<String, Map<List<String>, Type>> TYPE_CACHE = new HashMap<String, Map<List<String>, Type>>(); + + protected BuiltinMetaModel builtin; + + protected final List<MetaModel> metaModels = new ArrayList<MetaModel>(); + + public TypeSystemImpl() { + setBuiltinMetamodel(new BuiltinMetaModel(this)); + registerMetaModel(new XtendMetaModel(this)); + } + + public void setBuiltinMetamodel(final BuiltinMetaModel builtinMetaModel) { + builtin = builtinMetaModel; + registerMetaModel(builtin); + } + + public final void registerMetaModel(final MetaModel metaModel) { + if (metaModels.contains(metaModel)) { + return; + } + metaModel.setTypeSystem(this); + metaModels.add(metaModel); + } + + private Type[] toTypes(final Object[] params) { + final Type[] types = new Type[params.length]; + for (int i = 0; i < types.length; i++) { + types[i] = getType(params[i]); + } + return types; + } + + public Operation findOperation(final String name, final Object target, final Object[] params) { + final Type t = getType(target); + final Operation op = t.getOperation(name, toTypes(params)); + return op; + } + + public Property findProperty(final String name, final Object target) { + final Type t = getType(target); + final Property prop = t.getProperty(name); + return prop; + } + + public Type getObjectType() { + return builtin.getObjectType(); + } + + public Type getVoidType() { + return builtin.getVoidType(); + } + + public Type getBooleanType() { + return builtin.getBooleanType(); + } + + public Type getIntegerType() { + return builtin.getIntegerType(); + } + + public Type getRealType() { + return builtin.getRealType(); + } + + public Type getStringType() { + return builtin.getStringType(); + } + + public Type getTypeType() { + return builtin.getTypeType(); + } + + public Type getCollectionType(Type innerType) { + if (innerType == null) { + innerType = getObjectType(); + } + return builtin.getCollectionType(innerType); + } + + public Type getListType(Type innerType) { + if (innerType == null) { + innerType = getObjectType(); + } + return builtin.getListType(innerType); + } + + public Type getSetType(Type innerType) { + if (innerType == null) { + innerType = getObjectType(); + } + return builtin.getSetType(innerType); + } + + private final Cache<Object, Type> typeCache = new Cache<Object, Type>() { + + @Override + protected Type createNew(Object obj) { + Type bestMatch = null; + for (int i = 0; i < metaModels.size(); i++) { + final MetaModel curMeta = metaModels.get(i); + Type t = curMeta.getType(obj); + if (t != null) { + if (bestMatch == null || bestMatch.isAssignableFrom(t)) { + bestMatch = t; + } + } + } + return bestMatch; + } + + }; + + public Type getType(final Object obj) { + return typeCache.get(obj); + } + + private Type internalGetTypeForName(final String name) { + if (name == null || name.trim().equals("")) { + return null; + } + final String typeName = TypeNameUtil.getTypeName(name); + if (typeName == null || name.trim().equals("")) { + return null; + } + final String collectionTypeName = TypeNameUtil.getCollectionTypeName(name); + ParameterizedType t = null; + if (collectionTypeName != null) { + t = (ParameterizedType) builtin.getTypeForName(collectionTypeName); + if (t == null) { + return null; + } + } + Type r = null; + for (int i = 0; i < metaModels.size() && r == null; i++) { + final MetaModel curMeta = metaModels.get(i); + r = curMeta.getTypeForName(typeName); + } + if (r == null) { + return null; + } else if (t == null) { + return r; + } else { + return t.cloneWithInnerType(r); + } + } + + public Type getFeatureType() { + return builtin.getFeatureType(); + } + + public Type getPropertyType() { + return builtin.getPropertyType(); + } + + public Type getOperationType() { + return builtin.getOperationType(); + } + + public Type getTypeForName(final String typeName) { + if (typeName == null) { + return null; + } + return getTypeForName(typeName, new String[0]); + } + + public Type getTypeForName(final String typeName, final String[] importedNamespaces) { + // Shortcut: return null if typename was not specified + if (typeName == null || "".equals(typeName.trim())) { + return null; + } + Map<List<String>, Type> cacheMap = TYPE_CACHE.get(typeName); + if (cacheMap == null) { + // creating new cacheMap entry for this typeName + cacheMap = new HashMap<List<String>, Type>(); + TYPE_CACHE.put(typeName, cacheMap); + } + + List<String> importedNamespacesList = Arrays.asList(importedNamespaces); + Type type = cacheMap.get(importedNamespacesList); + if (type == null) { + if (cacheMap.containsKey(importedNamespacesList)) { + // null entry cached for typeName and importedNamespaces! + return null; + } + if (typeName.indexOf(SyntaxConstants.NS_DELIM) >= 0) { + type = internalGetTypeForName(typeName); + } else { + final List<String> possibleNames = getPossibleNames(typeName, importedNamespaces); + for (String name : possibleNames) { + type = internalGetTypeForName(name); + if (type != null) { + break; + } + } + } + if (type != null) { + cacheMap.put(importedNamespacesList, type); + } + } + return type; + } + + public Type[] findTypesForPrefix(final String prefix) { + return findTypesForPrefix(prefix, new String[0]); + } + + public Type[] findTypesForPrefix(final String prefix, final String[] importedNamespaces) { + List<String> possibleNames = null; + if (prefix.indexOf(SyntaxConstants.NS_DELIM) >= 0) { + possibleNames = new ArrayList<String>(); + possibleNames.add(prefix); + } else { + possibleNames = getPossibleNames(prefix, importedNamespaces); + } + final Set<Type> result = new HashSet<Type>(); + for (final String name : possibleNames) { + final String typeName = TypeNameUtil.getTypeName(name); + if (typeName == null) { + return new Type[0]; + } + final String colTypeName = TypeNameUtil.getCollectionTypeName(name); + ParameterizedType colType = null; + if (colTypeName != null) { + colType = (ParameterizedType) builtin.getTypeForName(colTypeName); + if (colType == null) { + return new Type[0]; + } + } + + for (int i = 0; i < metaModels.size(); i++) { + final MetaModel curMeta = metaModels.get(i); + result.addAll(filterTypes(typeName, curMeta.getKnownTypes(), colType)); + } + } + return result.toArray(new Type[result.size()]); + } + + public Type[] getAllTypes() { + final List<Type> result = new ArrayList<Type>(); + for (int i = 0; i < metaModels.size(); i++) { + final MetaModel curMeta = metaModels.get(i); + result.addAll(curMeta.getKnownTypes()); + } + return result.toArray(new Type[result.size()]); + } + + public Set<String> getNamespaces() { + Set<String> result = new HashSet<String>(); + for (MetaModel metaModel : metaModels) { + result.addAll(metaModel.getNamespaces()); + } + return result; + } + + public List<String> getPossibleNames(final String name, final String[] importedNs) { + final String typeName = TypeNameUtil.getTypeName(name); + final String collectionTypeName = TypeNameUtil.getCollectionTypeName(name); + + final List<String> result = new ArrayList<String>(); + result.add(name); + + for (final String string : importedNs) { + final StringBuffer s = new StringBuffer(); + if (collectionTypeName != null) { + s.append(collectionTypeName).append("["); + } + s.append(string).append(SyntaxConstants.NS_DELIM).append(typeName); + if (collectionTypeName != null) { + s.append("]"); + } + result.add(s.toString()); + } + return result; + } + + private Set<Type> filterTypes(final String prefix, final Set<? extends Type> knownTypes, ParameterizedType colType) { + final Set<Type> result = new HashSet<Type>(); + for (final Type t : knownTypes) { + if (prefix.equals("") || t.getName().startsWith(prefix)) { + if (colType != null) { + colType = (ParameterizedType) builtin.getTypeForName(colType.getName()); + colType = colType.cloneWithInnerType(t); + result.add(colType); + } else { + result.add(t); + } + } + } + return result; + } + + public Type getStaticPropertyType() { + return builtin.getStaticPropertyType(); + } + + public void release() { + TYPE_CACHE.clear(); + } + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/Variable.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/Variable.java new file mode 100644 index 00000000..522fbec4 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/expression/Variable.java @@ -0,0 +1,80 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.expression; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public class Variable { + + private String name; + + private Object value; + + public Variable(final String name, final Object value) { + if (name == null) + throw new IllegalArgumentException("name must not be null!"); + this.name = name; + this.value = value; + } + + public Object getValue() { + return value; + } + + public void setValue(final Object value) { + this.value = value; + } + + public String getName() { + return name; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = PRIME * result + ((name == null) ? 0 : name.hashCode()); + result = PRIME * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final Variable other = (Variable) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (value == null) { + if (other.value != null) + return false; + } else if (!value.equals(other.value)) + return false; + return true; + } + + public String toString () { + return "Variable [" + name + "="+ value + "]"; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/AbstractTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/AbstractTypeImpl.java new file mode 100644 index 00000000..660fa87c --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/AbstractTypeImpl.java @@ -0,0 +1,203 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.typesystem; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.internal.xtend.type.baseimpl.PolymorphicResolver; +import org.eclipse.internal.xtend.util.Cache; +import org.eclipse.internal.xtend.util.Pair; +import org.eclipse.xtend.expression.TypeSystem; + +public abstract class AbstractTypeImpl implements Type { + + private final static Log log = LogFactory.getLog(AbstractTypeImpl.class); + + private final TypeSystem typeSystem; + + private String _name; + + public AbstractTypeImpl(final TypeSystem typeSystem, final String name) { + this.typeSystem = typeSystem; + _name = name; + } + + public final TypeSystem getTypeSystem() { + return typeSystem; + } + + public final String getName() { + return _name; + } + + public abstract Feature[] getContributedFeatures(); + + private Set<Callable> allFeatures = null; + + /** + * Return all features defined by the type + */ + public final Set<Callable> getAllFeatures() { + if (allFeatures == null) { + allFeatures = new HashSet<Callable>(); + allFeatures.addAll(Arrays.asList(getContributedFeatures())); + final Set<? extends Type> superTypes = getSuperTypes(); + for (final Iterator<? extends Type> iter = superTypes.iterator(); iter.hasNext();) { + final Type type = iter.next(); + if (type != null) { + allFeatures.addAll(type.getAllFeatures()); + } else { + log.error("A supertype of " + getName() + " is null!"); + } + } + } + return allFeatures; + } + + public StaticProperty getStaticProperty(final String name) { + return PolymorphicResolver.getStaticProperty(getAllFeatures(), name, this); + } + + private final Cache<String,Property> propertyCache = new Cache<String,Property>() { + + @Override + protected Property createNew(String name) { + return PolymorphicResolver.getProperty(getAllFeatures(), (String) name, AbstractTypeImpl.this); + } + }; + + public Property getProperty(final String name) { + return propertyCache.get(name); + } + + public Callable getFeature(final String name, final Type[] parameterTypes) { + Property property = null; + if (parameterTypes == null || parameterTypes.length == 0) { + property = getProperty(name); + } + final Operation operation = getOperation(name, parameterTypes); + if (property != null && operation != null) { + if (property.getOwner().equals(operation.getOwner())) + throw new RuntimeException(); + else if (property.getOwner().isAssignableFrom(operation.getOwner())) + return operation; + else + return property; + } else if (property != null) + return property; + else + return operation; + } + + private final Cache<Pair<String,List<Type>>, Operation> operationsCache = new Cache<Pair<String,List<Type>>, Operation>() { + + @Override + protected Operation createNew(Pair<String,List<Type>> arg0) { + return PolymorphicResolver.getOperation(getAllFeatures(), arg0.getFirst(), + AbstractTypeImpl.this, (List<? extends Type>) arg0.getSecond()); + } + }; + + public Operation getOperation(final String name, final Type[] parameterTypes) { + return (Operation) operationsCache.get(new Pair<String,List<Type>>(name, Arrays.asList(parameterTypes != null ? parameterTypes + : new Type[0]))); + } + + public Set<? extends StaticProperty> getAllStaticProperties() { + return PolymorphicResolver.select(getAllFeatures(), StaticProperty.class); + } + + public Set<? extends Property> getAllProperties() { + return PolymorphicResolver.select(getAllFeatures(), Property.class); + } + + public Set<? extends Operation> getAllOperations() { + return PolymorphicResolver.select(getAllFeatures(), Operation.class); + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) + return false; + if (this == obj) + return true; + if (obj instanceof Type) + return getName().equals(((Type) obj).getName()); + return false; + } + + @Override + public int hashCode() { + return getName().hashCode(); + } + + @Override + public String toString() { + return getName(); + } + + public final boolean isAssignableFrom(final Type t) { + if (t == null) + return false; + if (equals(t)) + return true; + if (t.equals(getTypeSystem().getVoidType())) + return true; + return internalIsAssignableFrom(t); + } + + protected boolean internalIsAssignableFrom(final Type t) { + final Set<? extends Type> superTypes = t.getSuperTypes(); + for (Type type : superTypes) { + if (isAssignableFrom(type)) + return true; + } + return false; + } + + public Object convert(final Object src, final Class<?> targetType) { + if (targetType.isInstance(src)) + return src; + else + throw new IllegalArgumentException(getName() + " is not responsible for java type " + targetType.getName()); + } + + public String getDocumentation() { + return ""; + } + + private Set<? extends Type> superTypes = null; + + public Set<? extends Type> getSuperTypes() { + if (superTypes==null) + superTypes = internalGetSuperTypes(); + return superTypes; + } + + protected Set<? extends Type> internalGetSuperTypes() { + return Collections.singleton(getTypeSystem().getObjectType()); + } + + public boolean isAbstract() { + return false; + } +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Callable.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Callable.java new file mode 100644 index 00000000..d679e902 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Callable.java @@ -0,0 +1,25 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.typesystem; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface Callable { + String getName(); + + Type getReturnType(); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Feature.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Feature.java new file mode 100644 index 00000000..b33c286a --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Feature.java @@ -0,0 +1,25 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.typesystem; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface Feature extends Callable { + Type getOwner(); + + String getDocumentation(); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/MetaModel.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/MetaModel.java new file mode 100644 index 00000000..2f5656fa --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/MetaModel.java @@ -0,0 +1,67 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.typesystem; + +import java.util.Set; + +import org.eclipse.xtend.expression.TypeSystem; + + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Peter Friese + */ +public interface MetaModel { + + TypeSystem getTypeSystem(); + + void setTypeSystem(TypeSystem typeSystem); + + /** + * if this metamodel is responsible for a type with the given name, it + * returns the corresponding type. Otherwise returns <code>null</code> + * + * @param typeName + * @return + */ + Type getTypeForName(String typeName); + + /** + * if this metamodel is responsible for a types which are responsible for + * the given object, it returns the corresponding type. Otherwise returns + * <code>null</code> + * + * @param obj + * @return + */ + Type getType(Object obj); + + /** + * returns all types this metamodel is responsible for + * + * @return + */ + Set<? extends Type> getKnownTypes(); + + /** + * Returns all namespaces provided by this metamodel. + * + * @return A {@link Set} containing the names of all namespaces provided by + * this metamodel. + */ + Set<String> getNamespaces(); + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Operation.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Operation.java new file mode 100644 index 00000000..b95dc68c --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Operation.java @@ -0,0 +1,25 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.typesystem; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface Operation extends ParameterizedCallable, Feature { + Object evaluate(Object target, Object[] params); + + Type getReturnType(Type targetType, Type[] paramTpes); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/ParameterizedCallable.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/ParameterizedCallable.java new file mode 100644 index 00000000..ef5713af --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/ParameterizedCallable.java @@ -0,0 +1,27 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.typesystem; + +import java.util.List; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface ParameterizedCallable extends Callable { + + List<Type> getParameterTypes(); + +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/ParameterizedType.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/ParameterizedType.java new file mode 100644 index 00000000..4b99a65c --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/ParameterizedType.java @@ -0,0 +1,25 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.typesystem; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface ParameterizedType extends Type { + Type getInnerType(); + + ParameterizedType cloneWithInnerType(Type t); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Property.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Property.java new file mode 100644 index 00000000..c4bf9d95 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Property.java @@ -0,0 +1,25 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.typesystem; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface Property extends Callable, Feature { + Object get(Object target); + + void set(Object target, Object newValue); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/StaticProperty.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/StaticProperty.java new file mode 100644 index 00000000..67c6b205 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/StaticProperty.java @@ -0,0 +1,23 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.typesystem; + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface StaticProperty extends Callable, Feature { + Object get(); +} diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Type.java b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Type.java new file mode 100644 index 00000000..72e13759 --- /dev/null +++ b/plugins/org.eclipse.xtend/src/org/eclipse/xtend/typesystem/Type.java @@ -0,0 +1,100 @@ +/* + * <copyright> + * + * Copyright (c) 2005-2006 Sven Efftinge (http://www.efftinge.de) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sven Efftinge (http://www.efftinge.de) - Initial API and implementation + * + * </copyright> + */ +package org.eclipse.xtend.typesystem; + +import java.util.Set; + +import org.eclipse.xtend.expression.TypeSystem; + + +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + */ +public interface Type { + TypeSystem getTypeSystem(); + + boolean isAssignableFrom(Type t); + + boolean isInstance(Object o); + + boolean isAbstract(); + + String getName(); + + Object newInstance(); + + Set<? extends Type> getSuperTypes(); + + /** + * finds a static property with the given name + * + * @param name + * @return + */ + StaticProperty getStaticProperty(String name); + + /** + * finds a property with the given name + * + * @param name + * @return + */ + Property getProperty(String name); + + /** + * finds an operation with the given name on the given type with respect to + * the given parametertypes this method handles polymorphistic resolution + * for parameter types + * + * @param type + * @param name + * @param paramTypes + * @return + */ + Operation getOperation(String name, Type[] parameterTypes); + + /** + * finds a feature with the given name on the given type with respect to the + * given parametertypes this method handles polymorphistic resolution for + * parameter types + * + * @param type + * @param name + * @param paramTypes + * @return + */ + Callable getFeature(String name, Type[] parameterTypes); + + Set<? extends StaticProperty> getAllStaticProperties(); + + Set<? extends Property> getAllProperties(); + + Set<? extends Operation> getAllOperations(); + + Set<? extends Callable> getAllFeatures(); + + /** + * converts the given Object to an instance of the given Class, if this type + * is responsible for java objects of the given Class and the given Object + * + * @param src + * @param targetType + * @return + */ + Object convert(Object src, Class<?> targetType); + + public String getDocumentation(); +} |